Emacs Main Configuration File
Core
Literal Configuration Bootstrap
(setq .org " ~/.emacs.d/emacs-config.org" )
(setq .el (concat (file-name-sans-extension .org) " .el" ))
(defun mk/sync-emacs-config ()
" Synchronize config from org to el and compile to elc."
(interactive )
; ; Avoid running hooks when tangling. From https://delta.re/emacs-config-org/
(let ((prog-mode-hook nil ))
(require 'ob-tangle )
; ; Tangle the file. It's fast.
(org-babel-tangle-file .org .el " emacs-lisp" )
(message " [CONFIG] Config is synchronized. " )
; ; Async compile the config.
(async-start
; ; What to do in the child process
; ; the backquote and the set are necessary to capture vars
`(lambda () ; ` is necessary to capture vars.
(set 'el-file ,.el) ; Get the captured var.
(byte-compile-file el-file) ; Compile the el file.
el-file) ; Return the file name.
; ; What to do when it finishes
(lambda (res ) (message " [CONFIG] Config %s is async-compiled. " res))
)))
; ; Sync config when the config file is saved.
(add-hook 'after-save-hook
(lambda ()
(if (equal (buffer-file-name ) (expand-file-name .org))
(mk/sync-emacs-config))))
Fonts
We need to setup fonts early.
(when (eq system-type 'darwin )
(dolist (charset '(kana han symbol cjk-misc bopomofo))
(set-fontset-font (frame-parameter nil 'font )
charset (font-spec :family " LXGW WenKai Screen" )))
(setq face-font-rescale-alist '((" LXGW WenKai Screen" . 1.24 )))
(set-fontset-font t 'emoji (font-spec :family " Apple Color Emoji" ) nil 'prepend )
(set-fontset-font t '(#x2ff0 . #x9ffc ) (font-spec :name " TsangerJinKai01" :size 14 ))
)
Bootstrap
Custom Files
(setq custom-file " ~/.emacs.d/customs.el" )
(load custom-file t )
Packages
straight.el replacing package.el
(defvar bootstrap-version )
(let ((bootstrap-file
(expand-file-name " straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 6 ))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
" https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies )
(goto-char (point-max ))
(eval-print-last-sexp )))
(load bootstrap-file nil 'nomessage ))
use-package: A use-package declaration for simplifying your .emacs
(setq use-package-compute-statistics t )
(straight-use-package 'use-package )
(setq straight-use-package-by-default t ) ; Ensure :straight t
Benchmarks
(cl-letf (((symbol-function 'define-obsolete-function-alias ) #'defalias ))
(use-package benchmark-init
:init
(require 'benchmark-init-modes ) ; explicitly required
; ; To disable collection of benchmark data after init is done.
(add-hook 'after-init-hook #'benchmark-init/deactivate )))
Emacs Server
; ;; The server part may not be configured so early.
(load " server" ) ; Load and start server if it's not running
(unless (server-running-p ) (server-start ))
The PATH
; ;; Get shell env from user shell.
; ; https://apple.stackexchange.com/questions/51677/how-to-set-path-for-finder-launched-applications
; ; $ sudo launchctl config user path /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
; ; We need to at least make the /usr/local/bin in the path so that imagemagick can use rsgv rather than its built-in svg renderer.
; ; The above command works.
(use-package exec-path-from-shell
:init
(exec-path-from-shell-initialize))
Options
(defvar mk-feature/bibliography t " Enable bibliography." )
(defvar mk-feature/gui t " Enable GUI-related packages." )
(defvar mk-feature/noteman t " Enable note management." )
(defvar mk-feature/light t " Use light mode." )
(defvar mk-feature/news-mail t " Enable news and mails." )
SETQs
(setq
; ; Backups
backup-by-copying t
backup-directory-alist '((" ." . " ~/.emacs.d/backups" ))
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t
vc-make-backup-files t
; ;(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
; ;(setq delete-old-versiojns -1)
; ;(setq version-control t)
auto-save-file-name-transforms '((" .*" " ~/.emacs.d/auto-save-list/" t ))
; ; History
savehist-file " ~/.emacs.d/savehist"
history-length t
history-delete-duplicates t
savehist-save-minibuffer-history 1
savehist-additional-variables '(kill-ring search-ring regex-search-ring))
(savehist-mode 1 )
(setq-default
; ; From: https://stackoverflow.com/questions/4657142/how-do-i-encourage-emacs-to-follow-the-compilation-buffer
compilation-scroll-output t
; ; (setq compilation-scroll-output 'first-error)
; ; Prevent Extraneous Tabs
indent-tabs-mode nil
fill-column 100
; ; line-spacing 0.1
)
(setq enable-recursive-minibuffers t )
(minibuffer-depth-indicate-mode 1 )
(defun mkvoya/better-wrap ()
" Make the word wrap better."
(interactive )
(progn
(visual-line-mode t )
(setq word-wrap nil )
))
(blink-cursor-mode 1 )
(when (> emacs-major-version 28 )
(pixel-scroll-precision-mode))
(setq delete-by-moving-to-trash t )
(use-package ns-win
:if (memq window-system '(mac ns))
:straight nil
:init
; ; (setq mac-right-command-modifier 'control)
; ; (setq mac-right-option-modifier 'control)
)
Basic libraries
(use-package async :defer t )
(use-package bind-key :defer t )
(use-package marquee-header :defer t ) ; This is really an interesting package.
(use-package dash :defer t )
(use-package ts :defer t )
(use-package s :defer t )
(use-package reveal-in-osx-finder :defer t )
(use-package crux :defer t )
(use-package ranger :defer t ) ; The ranger mode
(use-package vlf :defer t ) ; View large files
Private-built Top-bar
(when (eq system-type 'darwin )
(require 'top-bar )
(defun mk/enable-top-bar (frame )
" Setup top-bar for FRAME."
(set-frame-parameter frame 'top-bar-lines 1 )
(mk/set-frame-top-bar-format mk/default-frame-top-bar-format)
)
(defun mk/disable-top-bar (frame )
" Setup top-bar for FRAME."
(set-frame-parameter frame 'top-bar-lines 0 )
)
(mk/enable-top-bar nil )
(add-hook 'after-make-frame-function #'mk/enable-top-bar )
(set-face-attribute 'top-bar nil :background " #EFEFEF" :font " Menlo-12" ) ; ; default
; ; (set-face-attribute 'top-bar nil :background "#2F2F2F" :foreground "#fFeF5F" :font "Menlo-12")
)
M-x and Auto-completion
M-x: Vertico
Alternatives (Check the selectrum repo README)
(use-package vertico
:init
(setq vertico-scroll-margin 0 )
(setq vertico-count 20 ) ; Show more candidates.
(setq vertico-resize nil ) ; Do NOT grow and shrink the Vertico minibuffer.
(setq vertico-cycle t ) ; Cycling the candidates. E.g., the next to the last is the first.
; ; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt ))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode )
(setq enable-recursive-minibuffers nil )
(vertico-mode)
)
(use-package orderless
:init
(setq completion-styles '(orderless))
(setq completion-category-defaults nil )
(setq completion-category-overrides '((file (styles partial-completion))))
)
(use-package marginalia
:init
(marginalia-mode))
(use-package consult
:bind (
; ; C-x bindings (ctl-x-map)
(" C-x M-:" . consult-complex-command) ; ; orig. repeat-complex-command
(" C-x b" . consult-buffer) ; ; orig. switch-to-buffer
(" C-x 4 b" . consult-buffer-other-window) ; ; orig. switch-to-buffer-other-window
(" C-x 5 b" . consult-buffer-other-frame) ; ; orig. switch-to-buffer-other-frame
(" C-x r b" . consult-bookmark) ; ; orig. bookmark-jump
(" C-x p b" . consult-project-buffer) ; ; orig. project-switch-to-buffer
; ; Custom M-# bindings for fast register access
; ; Other custom bindings
(" M-g i" . consult-imenu)
(" M-g I" . consult-imenu-multi)
; ; M-s bindings (search-map)
(" M-s d" . consult-find)
(" M-s D" . consult-locate)
(" M-s g" . consult-grep)
(" M-s G" . consult-git-grep)
(" M-s r" . consult-ripgrep)
(" M-s l" . consult-line)
(" M-s L" . consult-line-multi)
(" M-s m" . consult-multi-occur)
(" M-s k" . consult-keep-lines)
(" M-s u" . consult-focus-lines)
; ; Isearch integration
(" M-s e" . consult-isearch-history)
:map isearch-mode-map
(" M-e" . consult-isearch-history) ; ; orig. isearch-edit-string
(" M-s e" . consult-isearch-history) ; ; orig. isearch-edit-string
(" M-s l" . consult-line) ; ; needed by consult-line to detect isearch
(" M-s L" . consult-line-multi)) ; ; needed by consult-line to detect isearch
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
; ; Configure the register formatting
(setq register-preview-delay 0 )
(setq register-preview-function #'consult-register-format )
; ; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref )
(setq xref-show-definitions-function #'consult-xref )
; ; Optionally tweak the register preview window.
; ; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window )
)
(use-package all-the-icons-completion
:after (all-the-icons marginalia)
:init
(all-the-icons-completion-mode)
(add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup ))
; ; (use-package mini-popup
; ; :straight (:host github :repo "minad/mini-popup")
; ; :config
; ; ;; Configure a height function (Example for Vertico)
; ; (defun mini-popup-height-resize ()
; ; (* (1+ (min vertico--total vertico-count)) (default-line-height)))
; ; (defun mini-popup-height-fixed ()
; ; (* (1+ (if vertico--input vertico-count 0)) (default-line-height)))
; ; (setq mini-popup--height-function #'mini-popup-height-fixed)
; ; ;; Disable the minibuffer resizing of Vertico (HACK)
; ; (advice-add #'vertico--resize-window :around
; ; (lambda (&rest args)
; ; (unless mini-popup-mode
; ; (apply args))))
; ; ;; Ensure that the popup is updated after refresh (Consult-specific)
; ; (add-hook 'consult--completion-refresh-hook
; ; (lambda (&rest _) (mini-popup--setup)) 99)
; ; (mini-popup-mode 1))
(use-package mini-frame
:disabled
:init
(setq mini-frame-internal-border-color " blue" )
(setq mini-frame-show-parameters
'((top . 50 )
(width . 0.9 )
(left . 0.5 )
(background-color . " ivory" )
))
; ; (mini-frame-mode 1)
)
(use-package embark
:disabled
:demand
:bind
((" C-." . embark-act) ; ; pick some comfortable binding
(" C-;" . embark-dwim) ; ; good alternative: M-.
(" C-h B" . embark-bindings)) ; ; alternative for `describe-bindings'
:init
; ; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command )
:config
; ; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'(" \\ `\\ *Embark Collect \\ (Live\\ |Completions\\ )\\ *"
nil
(window-parameters (mode-line-format . none)))))
; ; Consult users will also want the embark-consult package.
(use-package embark-consult
:disabled
:after (embark consult)
:demand t ; only necessary if you have the hook below
; ; if you want to have consult previews as you move around an
; ; auto-updating embark collect buffer
:hook
(embark-collect-mode . consult-preview-at-point-mode))
Auto-completion
(use-package corfu
; ; Optional customizations
:custom
(corfu-cycle t ) ; ; Enable cycling for `corfu-next/previous'
(corfu-auto t ) ; ; Enable auto completion
(corfu-separator ?\s ) ; ; Orderless field separator
(corfu-quit-at-boundary nil ) ; ; Never quit at completion boundary
:bind (:map corfu-map
(" C-n" . corfu-next)
(" C-p" . corfu-previous))
:init
(global-corfu-mode))
; ; Add extensions
(use-package cape
:custom
(cape-line-buffer-function #'current-buffer )
; ; Bind dedicated completion commands
; ; Alternative prefix keys: C-c p, M-p, M-+, ...
:bind ((" C-c e p" . completion-at-point) ; ; capf
(" C-c e t" . complete-tag) ; ; etags
(" C-c e d" . cape-dabbrev) ; ; or dabbrev-completion
(" C-c e h" . cape-history)
(" C-c e f" . cape-file)
(" C-c e k" . cape-keyword)
(" C-c e s" . cape-symbol)
(" C-c e a" . cape-abbrev)
(" C-c e i" . cape-ispell)
(" C-c e l" . cape-line)
(" C-c e w" . cape-dict)
(" C-c e \\ " . cape-tex)
(" C-c e _" . cape-tex)
(" C-c e ^" . cape-tex)
(" C-c e &" . cape-sgml)
(" C-c e r" . cape-rfc1345))
:init
; ; Add `completion-at-point-functions' , used by `completion-at-point' .
(add-to-list 'completion-at-point-functions #'cape-file )
(add-to-list 'completion-at-point-functions #'cape-dabbrev )
(add-to-list 'completion-at-point-functions #'cape-history )
(add-to-list 'completion-at-point-functions #'cape-keyword )
(add-to-list 'completion-at-point-functions #'cape-tex )
(add-to-list 'completion-at-point-functions #'cape-sgml )
(add-to-list 'completion-at-point-functions #'cape-rfc1345 )
(add-to-list 'completion-at-point-functions #'cape-abbrev )
; ; (add-to-list 'completion-at-point-functions #'cape-ispell)
; ; (add-to-list 'completion-at-point-functions #'cape-dict)
; ; (add-to-list 'completion-at-point-functions #'cape-symbol)
; ; (add-to-list 'completion-at-point-functions #'cape-line)
)
; ; Use Dabbrev with Corfu!
(use-package dabbrev
; ; Swap M-/ and C-M-/
:bind ((" M-/" . dabbrev-completion)
(" C-M-/" . dabbrev-expand))
; ; Other useful Dabbrev configurations.
:custom
(dabbrev-ignored-buffer-regexps '(" \\ .\\ (?:pdf\\ |jpe?g\\ |png\\ )\\ '" )))
(use-package kind-icon
:ensure t
:after corfu
:custom
(kind-icon-default-face 'corfu-default ) ; to compute blended backgrounds correctly
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter ))
Templating: Yasnippet
(use-package yasnippet
:init (yas-global-mode 1 ))
(use-package yasnippet-snippets
:after yasnippet)
; ; Configure Tempel
(use-package tempel
; ; Require trigger prefix before template name when completing.
; ; :custom
; ; (tempel-trigger-prefix "<")
; ; :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
; ; ("M-*" . tempel-insert))
:init
; ; Setup completion at point
(defun tempel-setup-capf ()
; ; Add the Tempel Capf to `completion-at-point-functions' .
; ; `tempel-expand' only triggers on exact matches. Alternatively use
; ; `tempel-complete' if you want to see all matches, but then you
; ; should also configure `tempel-trigger-prefix' , such that Tempel
; ; does not trigger too often when you don't expect it. NOTE: We add
; ; `tempel-expand' *before* the main programming mode Capf, such
; ; that it will be tried first.
(setq-local completion-at-point-functions
(cons #'tempel-expand
completion-at-point-functions)))
(add-hook 'prog-mode-hook 'tempel-setup-capf )
(add-hook 'text-mode-hook 'tempel-setup-capf )
; ; Optionally make the Tempel templates available to Abbrev,
; ; either locally or globally. `expand-abbrev' is bound to C-x '.
; ; (add-hook 'prog-mode-hook #'tempel-abbrev-mode)
; ; (global-tempel-abbrev-mode)
)
LSP
(use-package flymake
:straight (:type built-in) ; built-in
:config
(setq flymake-no-changes-timeout 2 )
)
(use-package flyspell-correct
:after flyspell
:bind (:map flyspell-mode-map (" C-;" . flyspell-correct-wrapper)))
(use-package grammarly
:straight (:host github :repo " emacs-grammarly/grammarly" )
:config
; ; (require 'grammarly)
(grammarly-load-from-authinfo)
)
(use-package eglot
:straight (:type built-in) ; built-in
; ; :after (flymake)
:init
(use-package eglot-grammarly
:after (grammarly)
:straight (:host github :repo " emacs-grammarly/eglot-grammarly" )
:defer t ; defer package loading
; ; :hook ((text-mode markdown-mode). (lambda ()
; ; (require 'eglot-grammarly)
; ; (eglot-ensure)))
:config
(defun mk/enable-grammarly ()
" Enable grammarly for the current buffer."
(interactive )
(require 'eglot-grammarly )
(eglot-ensure))
)
)
; ; Two other flymake grammarly checkers
(use-package flymake-grammarly
:disabled t ; use eglot
:straight (:host github :repo " emacs-grammarly/flymake-grammarly" )
:init
:config
; ; (flymake-grammarly-setup)
(setq flymake-grammarly-check-time 2 )
)
(use-package flymake-languagetool
; ; :disabled t
:after flymake
:hook ((text-mode . flymake-languagetool-load)
(latex-mode . flymake-languagetool-load)
(org-mode . flymake-languagetool-load)
(markdown-mode . flymake-languagetool-load))
:init
; ; Remote server config with LanguageTool's free API
; ; (setq flymake-languagetool-url "https://api.languagetool.org")
; ; (setq flymake-languagetool-server-port nil)
; ; (setq flymake-languagetool-server-jar nil)
; ; Local server config
(setq flymake-languagetool-server-jar " /usr/local/Cellar/languagetool/5.9/libexec/languagetool-server.jar" )
)
Language and spelling
Input method
(use-package rime
:straight (rime :type git
:host github
:repo " DogLooksGood/emacs-rime"
:files (" *.el" " Makefile" " lib.c" ))
:custom
(default-input-method " rime" )
(rime-librime-root " ~/.emacs.d/librime/dist" )
(rime-share-data-dir " ~/Library/Rime" )
(rime-user-data-dir " ~/Library/Rime" )
(rime-show-candidate 'posframe )
(rime-posframe-properties
(list :background-color " #000000" ; 不要在这里设置字体,会影响后面 face 里字体的
:foreground-color " #f33333"
:internal-border-width 10 ))
:config
(set-face-attribute 'rime-default-face nil
:background " #000000"
:foreground " honeydew1"
:font " Hei-20" )
(set-face-attribute 'rime-highlight-candidate-face nil
; ; :background "#f33333"
:foreground " #FFFF00"
:font " Hei-20" )
(set-face-attribute 'rime-code-face nil
:font " Hei-20" )
)
CJK font jumping
(use-package jieba
:delight
:after (evil)
:straight (:host github :repo " mkvoya/jieba.el" :files (" *" ))
:init ; We need to enable jieba during init so that it can construct the jieba in background, rather than when autoloading the functions.
(jieba-mode)
(defun mk/forward-word ()
" mk's better forward-word."
(interactive )
(let ((char (char-after )))
(if (memq char (string-to-list " \n\r\\ " ))
(re-search-forward " \\\s +" )
(jieba-forward-word))))
(define-key evil-motion-state-map (kbd " w" ) #'mk/forward-word )
(define-key evil-motion-state-map (kbd " b" ) #'jieba-backward-word )
)
CJK font alignment
(use-package valign
:hook (org-mode-hook . valign-mode)
)
Word count
(load-file " ~/.emacs.d/site-lisp/wc.el" )
Navigation in code
Citre: Tag jumps
(use-package citre
:defer t
:after (evil)
:init
; ; This is needed in `:init' block for lazy load to work.
(require 'citre-config )
:config
; ; Bind your frequently used commands.
(global-set-key (kbd " C-x c j" ) 'citre-jump )
(global-set-key (kbd " C-x c J" ) 'citre-jump-back )
(global-set-key (kbd " C-x c p" ) 'citre-ace-peek )
(global-set-key (kbd " C-]" ) 'citre-jump )
(global-set-key (kbd " C-t" ) 'citre-jump-back )
(define-key evil-motion-state-map (kbd " C-]" ) 'citre-jump )
(define-key evil-motion-state-map (kbd " C-t" ) 'citre-jump-back )
(define-key evil-normal-state-map (kbd " C-]" ) 'citre-jump )
(define-key evil-normal-state-map (kbd " C-t" ) 'citre-jump-back )
(setq citre-project-root-function
#' (lambda ()
(when-let ((project (project-current nil )))
(expand-file-name (nth 2 project)))))
)
Config
Save hist
; ; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:straight nil
:config
(savehist-mode ))
delight: altering mode appearences on mode line
(use-package delight) ; Actually, we don't even show minor modes in the modeline.
Scroll bar
Currently, yascroll won’t show upon mouse-triggerred scrolling.
(use-package yascroll
:disabled t ; This sometimes causes 99% CPU usage.
:delight
:config
; ; (advice-add :after 'pixel-scroll-up 'run-window-scroll-functions)
; ; (advice-add :after 'pixel-scroll-down 'run-window-scroll-functions)
(global-yascroll-bar-mode 1 )
)
; ; (use-package nyan-mode :disabled t :config (nyan-mode t))
Magit
(use-package magit
:straight nil ; built-in
:after (project)
:defer t
:init
(setq magit-diff-refine-hunk t )
:config
(use-package magit-extras
:straight nil
:init
(setq magit-bind-magit-project-status t )
)
)
(use-package git-link :defer t )
(use-package forge :after (magit) :defer t )
; ; (use-package git-timemachine)
(use-package diff-hl
:defer t
:after (magit)
:config
(global-diff-hl-mode)
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh )
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh ))
; ; Winner mode
(use-package winner :defer t :config (winner-mode 1 ))
; ;minibuffer editing
; ;(use-package miniedit
; ; :defer t
; ; :commands minibuffer-edit
; ; :init (miniedit-install))
(use-package blamer
:ensure t
:bind ((" s-i" . blamer-show-commit-info))
:defer 20
:custom
(blamer-idle-time 0.3 )
(blamer-min-offset 70 )
:custom-face
(blamer-face ((t :foreground " #7a88cf"
:background nil
:height 110
:italic t )))
:config
; ; (global-blamer-mode 1)
)
Undo
undo-tree built-in
undo-fu
(use-package undo-fu :ensure t )
(use-package undo-tree
:disabled
:config
(setq undo-tree-visualizer-timestamps t )
(setq undo-tree-visualizer-diff t )
(global-undo-tree-mode))
Evil
(use-package evil
:straight t
:after (undo-fu)
:init
(setq evil-want-C-i-jump nil )
:config
; ; Use man (instead of WoMan) for man pages, although is slow in Emacs.
; ; Install man-db, check this: https://www.reddit.com/r/emacs/comments/mfmg3x/disabling_ivy_for_a_specific_command/
(evil-define-motion evil-lookup ()
" Look up the keyword at point. Calls `evil-lookup-func' ."
(call-interactively #'man ))
(setq evil-want-fine-undo t )
(define-key evil-normal-state-map (kbd " C-u" ) 'evil-scroll-up )
(evil-set-undo-system 'undo-fu )
(use-package evil-numbers
:demand t
:config
(define-key evil-normal-state-map (kbd " C-a" ) 'evil-numbers/inc-at-pt )
(define-key evil-normal-state-map (kbd " C-S-a" ) 'evil-numbers/dec-at-pt ))
; ; Evil rebind
; ; :q should kill the current buffer rather than quitting emacs entirely
(defun mk/ex-quit ()
" Evil ex quit."
(interactive )
(if (one-window-p " visible" )
(kill-this-buffer )
(evil-window-delete)))
(evil-ex-define-cmd " q" #'mk/ex-quit )
; ; Need to type out :quit to close emacs
(evil-ex-define-cmd " quit" 'evil-quit )
; ; (setq evil-emacs-state-cursor '("SkyBlue2" bar))
; ; (setq evil-emacs-state-cursor '(hollow))
(setq evil-emacs-state-cursor '(bar . 3 ))
; ; Disable Evil in snails-mode
(dolist (nonevil-mode '(snails-mode
notdeft-mode
vterm-mode
netease-cloud-music-mode
cnfonts-ui-mode
Ilist-mode
TeX-output-mode
ebib-index-mode
ebib-entry-mode
ebib-strings-mode
minibuffer-mode
corfu-mode
motd-message-mode
special-mode
))
(evil-set-initial-state nonevil-mode 'emacs ))
(evil-mode 1 ))
Evil: Easy Motion
(use-package evil-easymotion
:after (evil)
:demand t
:config
(evilem-default-keybindings " SPC" )
(defun avy-goto-char (char &optional arg )
" Jump to the currently visible CHAR.
The window scope is determined by `avy-all-windows' (ARG negates it)."
(interactive (list (read-char " char: " t )
current-prefix-arg))
(if (= ? char)
(counsel-M-x)
(avy-with avy-goto-char
(avy-jump
(if (= 13 char)
" \n "
(regexp-quote (string char)))
:window-flip arg))))
(define-key evil-normal-state-map (kbd " SPC" ) 'avy-goto-char ))
Evil: Magit
; ; optional: this is the evil state that evil-magit will use
; ; (setq evil-magit-state 'normal)
; ; optional: disable additional bindings for yanking text
; ; (setq evil-magit-use-y-for-yank nil)
(use-package evil-magit
:after (evil magit)
:defer t )
Dir
(use-package neotree :defer t )
; ; (use-package perspective :config (persp-mode))
Ctrl-f
(use-package ctrlf
:defer t
:config
(ctrlf-mode +1 ))
smart-tab
; ;; Smart Tab
(use-package smart-tab
:straight nil
:defer t
:config
(smart-tabs-insinuate 'c 'javascript ))
Which-Key: Emacs package that displays available keybindings in popup
; ; which-key is a fork of guide-key
(use-package which-key
:bind (
(" C-h ,m" . which-key-show-major-mode)
(" C-h ,t" . which-key-show-top-level)
(" C-h ,n" . which-key-show-next-page)
)
:init
(setq which-key-show-remaining-keys t )
(setq which-key-show-early-on-C-h t )
(setq which-key-idle-delay 2 )
(setq which-key-allow-imprecise-window-fit t )
(setq which-key-sort-order 'which-key-prefix-then-key-order )
; ; (which-key-setup-minibuffer)
(which-key-mode)
)
Calendar
(use-package calendar
:init
(setq calendar-longitude 121.4737
calendar-latitude 31.2304
calendar-location-name " SH" )
(use-package celestial-mode-line
:disabled
:init
; ; (defvar celestial-mode-line-phase-representation-alist '((0 . "○") (1 . "☽") (2 . "●") (3 . "☾")))
; ; (defvar celestial-mode-line-sunrise-sunset-alist '((sunrise . "☀↑") (sunset . "☀↓")))
:config
; ; add to end of global-mode-string
(if (null global-mode-string)
(setq global-mode-string '(" " celestial-mode-line-string))
(add-to-list 'global-mode-string 'celestial-mode-line-string t ))
(celestial-mode-line-start-timer)
)
:config
(defun mk/notmuch-open-unread-view ()
" Open notmuch panel for unread mails."
(interactive )
(require 'notmuch )
(notmuch-search " tag:unread" ))
(defun mk/notmuch-count-unread ()
" Get the notmuch unread mail count if notmuch is loaded."
(if (fboundp 'notmuch-command-to-string )
(replace-regexp-in-string " \n " " "
(notmuch-command-to-string " count"
" tag:unread" ))
" ?" ))
(defun mk/mode-line-mail ()
" Show the unread mail count in the mode line."
)
(setq display-time-string-forms
'((format-time-string " %F %H:%M" )
(propertize
(format " [M:%s ] " (mk/notmuch-count-unread))
'help-echo " Unread!"
'keymap (let ((map (make-sparse-keymap )))
(define-key map [mouse-1]
#'mk/notmuch-open-unread-view )
map))))
(display-time-mode 1 ))
Rainbow
(use-package rainbow-mode
:defer t
:config (rainbow-mode t ))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
Calender
(setq calendar-chinese-all-holidays-flag t )
(use-package cal-china-x
:defer t
:config
(setq mark-holidays-in-calendar t )
(setq cal-china-x-important-holidays cal-china-x-chinese-holidays)
(setq cal-china-x-general-holidays '((holiday-lunar 1 15 " 元宵节" )))
(setq calendar-holidays
(append cal-china-x-important-holidays
cal-china-x-general-holidays))
)
Calfw - A calendar framework for Emacs
(use-package calfw
:init
(use-package calfw-org :after (org ))
:config
(defun mk/open-calendar ()
(interactive )
(cfw:open-calendar-buffer
:contents-sources
(list
(cfw:org-create-source " Green" ) ; orgmode source
; ; (cfw:howm-create-source "Blue") ; howm source
; ; (cfw:cal-create-source "Orange") ; diary source
; ; (cfw:ical-create-source "Moon" "~/moon.ics" "Gray") ; ICS source1
; ; (cfw:ical-create-source "gcal" "https://..../basic.ics" "IndianRed") ; google calendar ICS
)))
)
whitespace
; ;; Use whitespace (instead of column-marker, column-enforce-mode)
(use-package whitespace
:ensure nil
:config
(setq whitespace-style
'(face trailing tabs newline tab-mark newline-mark))
; ; '(face trailing tabs newline tab-mark newline-mark lines-tail)
(setq whitespace-display-mappings
'((newline-mark 10 [8617 10])
(tab-mark 9 [8594 9] [92 9])))
(set-face-background 'trailing-whitespace " #ffaf5f" )
(set-face-background 'whitespace-trailing " #ffaf5f" )
(if mk-feature/gui
(set-face-background 'whitespace-tab " #FAFAFA" )
(set-face-background 'whitespace-tab " undefined" )
)
; ; (global-whitespace-mode t)
(add-hook 'prog-mode-hook 'whitespace-mode )
)
Appearance
(use-package emacs
:straight nil
:config
(setq-default prettify-symbols-alist '((" #+BEGIN_SRC" . " λ" ) ; previously ✎
(" #+END_SRC" . " □" )
(" #+begin_src" . " λ" )
(" #+end_src" . " □" )
(" #+begin_quote" . ?» )
(" #+end_quote" . ?« )
(" #+BEGIN_QUOTE" . ?» )
(" #+END_QUOTE" . ?« )
))
(global-prettify-symbols-mode )
(setq-default indicate-buffer-boundaries 'left )
)
Theme and modeline
monokai-theme
grandshell-theme
alect-themes
airline-themes
manoj-light
doom-one-light
hemisu-light
doom-modeline
smart-mode-line
awesome-tray
spaceline
(use-package emacs
:straight nil
:config
(setq window-divider-default-right-width 2 )
(setq window-divider-default-bottom-width 2 )
(setq window-divider-default-places t )
(window-divider-mode 1 ))
(defun mk/modeline-setup ()
" Setup my modeline."
(progn
; ; mode line
(column-number-mode 1 )
(if mk-feature/light
(progn
; ; light theme
(set-face-attribute 'mode-line nil :background " #CFEF9F" )
(set-face-attribute 'mode-line-buffer-id nil :background " #3F2F1F" :foreground " white" )
(set-face-attribute 'mode-line-highlight nil :box nil :background " black" )
(set-face-attribute 'mode-line-inactive nil :inherit 'default )
(when (eq system-type 'darwin )
(set-face-attribute 'top-bar nil :background " #EFEFEF" :foreground " #333333" :font " Menlo-12" )
)
)
; ; dark theme
(set-face-attribute 'mode-line nil :background " #CF3F1F" )
(set-face-attribute 'mode-line-buffer-id nil :background " #3F2F1F" :foreground " white" )
(set-face-attribute 'mode-line-highlight nil :box nil :background " black" )
(set-face-attribute 'mode-line-inactive nil :inherit 'default )
(when (eq system-type 'darwin )
(set-face-attribute 'top-bar nil :background " #2F2F2F" :foreground " #fFeF5F" :font " Menlo-12" )
)
)
; ; Thank https://emacs.stackexchange.com/a/37270/30542
(defun simple-mode-line-render (left right )
" Return a string of `window-width' length. Containing LEFT, and RIGHT aligned respectively."
(let ((available-width (- (window-total-width )
(+ (length (format-mode-line left))
(length (format-mode-line right))
))))
(append left
(list (format (format " %%%d s" available-width) " " ))
right)))
(require 'uniquify )
(setq uniquify-buffer-name-style 'forward )
(setq-default mode-line-format
'((:eval
(simple-mode-line-render
; ; Left.
'(" [%*]"
evil-mode-line-tag
mode-line-buffer-identification
)
; ; Right.
'(" %e %o %l:%c "
mode-line-frame-identification
; ; mode-line-modes
" %m "
mode-line-misc-info
" " )))))
))
(use-package hemisu-theme
:straight (:host github :repo " mkvoya/hemisu-theme" :files (" *.el" ))
:disabled
:config
; ; (load-theme (if mk-feature/light 'hemisu-light 'hemisu-dark) t)
)
(use-package abyss-theme)
(use-package dracula-theme
:after (org )
:config
; ; (load-theme 'dracula t)
; ; (setq mk-feature/light nil)
)
(use-package emacs
:after (org )
:config
(set-face-attribute 'org-level-1 nil :height 1.1 )
(set-face-attribute 'fringe nil :background nil ) ; Visually hide left-right margins
(mk/modeline-setup)
)
(use-package keycast
:disabled
:straight (:type git :host github :repo " tarsius/keycast" )
:init
(keycast-mode)
)
Beacon - A light that follows your cursor around so you don’t lose it!
(use-package beacon
:defer t
:config
(setq beacon-color " #00ff00" )
; ; (setq beacon-size 40)
(beacon-mode 1 ))
Smooth scrolling
sublimity
smooth-scrolling
good-scroll
; ; Mouse scrolling in terminal emacs
(unless (display-graphic-p )
; ; activate mouse-based scrolling
; ; ensure mouse
(xterm-mouse-mode t )
(global-set-key (kbd " <mouse-4>" ) 'scroll-down-line )
(global-set-key (kbd " <mouse-5>" ) 'scroll-up-line ))
Dashboard
(use-package xkcd :defer )
(use-package all-the-icons
:if (display-graphic-p ))
(use-package dashboard
:if (< (length command-line-args) 2 )
:diminish dashboard-mode
:init
(use-package page-break-lines :ensure t :defer nil )
:config
(setq dashboard-banner-logo-title " What a nice day!" )
; ;(setq dashboard-startup-banner "/path/to/image")
(setq dashboard-projects-backend 'project-el )
(setq dashboard-items '((recents . 10 )
; ; (bookmarks . 10)
(projects . 5 )
(agenda . 5 )
; ; (registers . 5)
))
(setq dashboard-set-heading-icons t )
(setq dashboard-set-file-icons t )
(setq dashboard-agenda-sort-strategy '(time-up todo-state-up))
(setq initial-buffer-choice (lambda () (get-buffer " *dashboard*" )))
(dashboard-setup-startup-hook))
Symbol Overlay
; ; Thank https://github.com/Eason0210/emacs.d
(use-package symbol-overlay
:hook ((prog-mode html-mode yaml-mode conf-mode) . symbol-overlay-mode)
:bind (:map symbol-overlay-mode-map
(" M-i" . symbol-overlay-put)
(" M-n" . symbol-overlay-jump-next)
(" M-p" . symbol-overlay-jump-prev)))
Volatile highlights
(use-package volatile-highlights
:delight
:straight (:host github :repo " k-talo/volatile-highlights.el" )
:config
; ;-----------------------------------------------------------------------------
; ; Supporting evil-mode.
; ;-----------------------------------------------------------------------------
(vhl/define-extension 'evil 'evil-paste-after 'evil-paste-before
'evil-paste-pop 'evil-move )
(vhl/install-extension 'evil )
(volatile-highlights-mode t )
)
Programming Languages
Programming mode
Better line number from https://github.com/Eason0210/emacs.d/blob/330d530f56659338ff1fdf8f8089a7a6f66beed2/init.el#L796-L800
(defun make-underscore-part-of-words () (modify-syntax-entry ?_ " w" ))
(add-hook 'prog-mode-hook #'make-underscore-part-of-words )
(use-package display-line-numbers
:straight nil
:hook (prog-mode . display-line-numbers-mode)
:config
; ; (setq-default display-line-numbers-width 3)
)
C
(add-hook 'c-mode-hook
(lambda () (setq tab-width 8
c-default-style " linux"
c-basic-offset 8
c-indent-tabs-mode t )))
C++
(add-to-list 'auto-mode-alist '(" \\ .h\\ '" . c++-mode))
; ; style I want to use in c++ mode
(c-add-style " my-style"
'(" stroustrup"
(c-basic-offset . 4 ) ; indent by four spaces
(tab-width . 4 )
(indent-tabs-mode . t ) ; use tabs
(c-offsets-alist . ((inline-open . 0 ) ; custom indentation rules
(brace-list-open . 0 )
(innamespace . [0])
(statement-case-open . + )))))
(c-add-style " my-ycsb-c++-style"
'(" stroustrup"
(c-basic-offset . 2 ) ; indent by four spaces
(tab-width . 2 )
(indent-tabs-mode . nil ) ; use tabs
(c-offsets-alist . ((inline-open . 0 ) ; custom indentation rules
(brace-list-open . 0 )
(innamespace . [0])
(statement-case-open . + )))))
(defun my-c++-mode-hook ()
(c-set-style " my-ycsb-c++-style" )) ; use my-style defined above
(add-hook 'c++-mode-hook 'my-c++-mode-hook )
(use-package modern-cpp-font-lock
:defer t
:ensure t )
Markdown
(use-package markdown-mode
:defer t
:mode ((" README\\ .md\\ '" . gfm-mode)
(" \\ .md\\ '" . markdown-mode)
(" \\ .markdown\\ '" . markdown-mode))
:init (setq markdown-command " multimarkdown" )
:config
; ; (custom-set-variables '(markdown-command "/usr/local/bin/pandoc"))
(setq markdown-command " /usr/local/bin/pandoc" )
(setq markdown-preview-stylesheets (list " https://raw.githubusercontent.com/sindresorhus/github-markdown-css/gh-pages/github-markdown.css" ))
; ;"http://thomasf.github.io/solarized-css/solarized-light.min.css"
)
(use-package flymd
:after (markdown-mode ))
LaTeX
(use-package tex
:straight auctex
:defer t
:init
(setq TeX-source-correlate-method 'synctex )
(setq TeX-source-correlate-mode t )
(setq TeX-source-correlate-start-server t )
(provide 'tex-buf ) ; We don't have tex-buf anymore, just add this to make some packages happy.
:config
; ; make latexmk available via C-c C-c
; ; Note: SyncTeX is setup via ~/.latexmkrc (see below)
; ; (add-to-list 'TeX-command-list '("latexmk" "latexmk -pdf -escape-shell %s" TeX-run-TeX nil t :help "Run latexmk on file"))
(add-to-list 'TeX-command-list '(" Make" " make" TeX-run-command nil t ))
(add-to-list 'TeX-command-list '(" Make Clean" " make clean" TeX-run-command nil t ))
(add-to-list 'TeX-command-list '(" Make Clean & Make" " make clean && make" TeX-run-command nil t ))
; ; (setq-default TeX-command-default "Make")
; ; from https://gist.github.com/stefano-meschiari/9217695
(setq TeX-auto-save t )
(setq Tex-parse-self t )
; ; Guess/Ask for the master file.
(setq-default TeX-master nil )
; ; Thank https://tex.stackexchange.com/a/167097/122482
(defun mk/shadow-iffalse-block ()
(font-lock-add-keywords
'latex-mode
'((" \\\\ iffalse\\ (\\ (.\\ |\n\\ )*\\ )\\\\ fi" 0 'font-lock-comment-face append ))
t ))
(add-hook 'latex-mode-hook #'mk/shadow-iffalse-block )
(add-hook 'TeX-mode-hook (lambda () (setq TeX-command-default " Make" )))
(add-hook 'LaTeX-mode-hook (lambda ()
(mkvoya/better-wrap)
(flyspell-mode )
(LaTeX-math-mode)
(darkroom-mode)
(visual-line-mode )
(visual-line-mode )
))
; ; (add-hook 'TeX-output-mode (lambda () (goto-char (point-max))))
(setq reftex-refstyle " \\ ref" )
(setq reftex-plug-into-AUCTeX t )
(setq TeX-PDF-mode t )
(setq TeX-view-program-selection '((output-pdf " PDF Viewer" )))
(setq TeX-view-program-list
'((" PDF Viewer" " /Applications/Skim.app/Contents/SharedSupport/displayline -b -g %n %o %b" )))
(setq TeX-error-overview-open-after-TeX-run t )
; ; (setq mkvoya/tex-auto-compile nil)
; ; (defun mkvoya/tex-try-auto-compile ()
; ; (when (and (eq major-mode 'TeX-mode)
; ; (mkvoya/tex-auto-compile))
; ; (TeX-command-run))
; ; )
; ; (add-hook 'after-save-hook #'mkvoya/tex-try-auto-compile)
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer )
(use-package reftex
:defer t
:config
(add-hook 'LaTeX-mode-hook 'turn-on-reftex ) ; with AUCTeX LaTeX mode
(add-hook 'latex-mode-hook 'turn-on-reftex ) ; with Emacs latex mode
; ; (setq reftex-default-bibliography '("./references.bib"))
)
(use-package company-auctex :defer t :after (company) :config (company-auctex-init))
(use-package company-reftex :defer t :after (company reftex)
:config
(add-to-list 'company-backends 'company-reftex-labels )
(add-to-list 'company-backends 'company-reftex-citations ))
; ; (use-package auctex-latexmk :config (auctex-latexmk-setup))
)
PDF Tools
(use-package pdf-tools :defer t
:if mk-feature/gui
:init
:mode (" \\ .pdf\\ '" . pdf-view-mode)
:magic (" %PDF" . pdf-view-mode)
:bind (:map pdf-view-mode-map
(" <wheel-right>" . image-forward-hscroll)
(" <wheel-left>" . image-backward-hscroll)
(" <pinch>" . mk/pdf-tools-scale-pinch)
)
:config
(defun mk/pdf-tools-scale-pinch (event )
" Adjust the height of the default face by the scale in the pinch event EVENT."
(interactive " e" )
(when (not (eq (event-basic-type event) 'pinch ))
(error " bad event type " ))
(let ((window (posn-window (nth 1 event)))
(scale (nth 4 event))
(dx (nth 2 event))
(dy (nth 3 event))
(angle (nth 5 event)))
(with-selected-window window
(when (< scale 1 )
(pdf-view-shrink 1.1 ))
(when (> scale 1 )
(pdf-view-enlarge 1.1 )))))
(pdf-loader-install)
(add-hook 'pdf-view-mode-hook #' (lambda () (pixel-scroll-precision-mode -1 )))
)
; ; (use-package pdf-tools
; ; :magic ("%PDF" . pdf-view-mode)
; ; :config
; ; (pdf-tools-install :no-query))
; ; https://emacs.stackexchange.com/questions/45546/per-mode-value-for-fill-column
(defun mkvoya/tex-mode-hook ()
(setq fill-column 1024 ))
(add-hook 'TeX-mode-hook #'mkvoya/tex-mode-hook )
Python & Web
; ; Python Support
(use-package elpy :defer t )
(use-package py-autopep8
:defer t
:config
(setq py-autopep8-options '(" --max-line-length=120" )))
(use-package blacken
:defer t
:config
(setq blacken-line-length 120 ))
(use-package ein :defer t )
(use-package live-py-mode :defer t )
(use-package jinja2-mode :mode " \\ .jinja2\\ '" :defer t )
(use-package vue-mode :mode " \\ .vue\\ '" :defer t )
Asciidoc
(use-package adoc-mode
:defer t
:straight (:host github :repo " sensorflo/adoc-mode" ))
Tramp
(use-package tramp
:straight nil
:init
(use-package tramp-sh :straight nil :defer t )
; ; (setq tramp-debug-buffer t)
(setq tramp-verbose 10 )
(setq tramp-ssh-controlmaster-options
(concat
" -o ControlPath=/Volumes/ramfs/ssh-ControlPath-%%r@%%h:%%p "
" -o ControlMaster=auto -o ControlPersist=yes" ))
:defer t
:config
(setq tramp-remote-path
(append tramp-remote-path
'(tramp-own-remote-path)))
; ; Speedup the C++ file over Tramp.
(setq remote-file-name-inhibit-cache nil )
(setq vc-ignore-dir-regexp
(format " %s \\ |%s "
vc-ignore-dir-regexp
tramp-file-name-regexp))
(setq tramp-verbose 1 )
)
(modify-syntax-entry ?_ " w" )
Built in packages
Check https://emacs-china.org/t/emacs-builtin-mode/11937
(use-package paren
:defer t
:config
(setq show-paren-when-point-inside-paren t
show-paren-when-point-in-periphery t )
(show-paren-mode )
)
(use-package so-long
:defer t
:config (global-so-long-mode 1 ))
(use-package simple
:straight nil
:hook (after-init . (lambda ()
(line-number-mode )
(column-number-mode )
(size-indication-mode )
; ; better line wrapping for cjk. Try =toggle-word-wrap=
(setq-default word-wrap nil )
(setq word-wrap nil )
)))
Mail Client
; ; Mails
(use-package notmuch
:if mk-feature/news-mail
:after (exec-path-from-shell)
:ensure nil
:defer 5 ) ; start after being idle for 5s
Feeding (RSS & Atom)
(use-package elfeed
:if mk-feature/news-mail
:defer t
:config
; ; Global key
(global-set-key (kbd " C-x w" ) 'elfeed )
; ; The feed list
(setq elfeed-feeds
'((" http://nullprogram.com/feed/" blog emacs)
" http://www.50ply.com/atom.xml" ; no autotagging
(" http://nedroid.com/feed/" webcomic)
" http://planet.emacsen.org/atom.xml" ))
; ; (setq-default elfeed-search-filter "@1-week-ago +unread ")
)
Org-mode
Org
; ; Enable Org mode
(use-package org
:straight nil
:defer 2
:mode (" \\ .org\\ '" . org-mode)
:bind ((" C-c a" . #'org-agenda )
(" C-c c" . #'org-capture )
)
:init
; ; (setq org-latex-create-formula-image-program 'dvisvgm)
(setq org-latex-create-formula-image-program 'imagemagick )
(setq org-support-shift-select t ) ; Use shift to select region when possible.
(setq org-clock-idle-time 10 ) ; Clock will prompt to stop after 10 min of idle.
; ; Thanks! https://emacs.stackexchange.com/a/68321/30542
(defun org-syntax-table-modify ()
" Modify `org-mode-syntax-table' for the current org buffer."
(modify-syntax-entry ?< " ." org-mode-syntax-table)
(modify-syntax-entry ?> " ." org-mode-syntax-table))
(add-hook 'org-mode-hook #'org-syntax-table-modify )
; ; Thank https://emacs-china.org/t/org-link-echo-area-link/19927/2
(defun org-show-link-when-idle ()
; ; 在echo area中显示链接详情
(require 'help-at-pt )
(setq help-at-pt-display-when-idle t ) ; ; 不会立即生效
(setq help-at-pt-timer-delay 0.5 )
(help-at-pt-set-timer ) ; ; 调用才会生效
)
(add-hook 'org-mode-hook #'org-show-link-when-idle )
(setq org-modules '(ol-doi
; ; ol-w3m o-bbdb ol-gnus ol-mhe ol-rmail ol-eww
ol-bibtex
ol-docview
ol-irc
ol-info))
(setq org-element-use-cache nil ) ; cache sometimes causes problems
(use-package org-num-mode
:defer t
:straight nil ; built-in with org-mode
:hook (org-mode . org-num-mode))
:config
(setq org-display-remote-inline-images 'download )
; ; Auto add DONE TIME, from https://orgmode.org/guide/Progress-Logging.html
(setq org-log-done 'time )
; ; Org mode TODO states
(setq org-todo-keywords
'((sequence
" TODO(t)" ; New task
" HAND(h)" ; Doing
" WAIT(w)" ; Procrastinated on purpose
" LONG-TERM(l)" ; Long-term
" DELEGATE(g)" ; Delegated
" IDEA(i)" " EXP(e)" " TIP(i)" " COLL(C)"
" CONFDDL(C)"
" PROJECT(p)"
" GOAL(G)"
" |"
" DONE(d!)" ; Done
" CANCELED(c@)" ; Eliminated
)))
; ; Keyword colors
(setf org-todo-keyword-faces
'(
; ; Many styles from https://github.com/GTrunSec/my-profile/blob/master/dotfiles/doom-emacs/config.org
; ; ("TODO" . (:foreground "#ff39a3" :weight bold))
(" TODO" . (:foreground " #dfffff" :background " #ff19a3" :weight bold ))
(" HAND" . " orangered" )
(" WAIT" . " pink" )
; ; ("CANCELED" . (:foreground "white" :background "#4d4d4d" :weight bold :strike-through "#0d0d0d"))
(" CANCELED" . (:foreground " white" :background " #4d4d4d" ))
; ; ("DONE" . "#008080")
(" DONE" . (:foreground " #008080" ))
(" DELEGATE" . " DeepSkyBlue" )
))
; ; Strike through the whole line with DONE entry
; ; (font-lock-add-keywords
; ; 'org-mode
; ; '(
; ; ("\\* \\<DONE .*" 0 'shr-strike-through append)
; ; ("\\* \\<CANCELED .*" 0 'shr-strike-through append))
; ; t)
; ; …, ➡, ⚡, ▼, ↴, , ∞, ⬎, ⤷, ⤵ "↴▾▽▼↩↘↸"
(setq org-ellipsis " ▾" )
; ; https://stackoverflow.com/questions/17590784/how-to-let-org-mode-open-a-link-like-file-file-org-in-current-window-inste
(defun org-force-open-current-window ()
" Open at current window."
(interactive )
(let ((org-link-frame-setup (quote
((vm . vm-visit-folder)
(vm-imap . vm-visit-imap-folder)
(file . find-file)
(wl . wl)))
))
(org-open-at-point )))
; ; Depending on universal argument try opening link
(defun org-open-maybe (&optional arg )
" Open maybe ARG."
(interactive " P" )
(if arg (org-open-at-point )
(org-force-open-current-window)))
; ; Redefine file opening without clobbering universal argument
(define-key org-mode-map " \C -c\C -o" 'org-open-maybe )
(org-babel-do-load-languages
'org-babel-load-languages
'((dot . t )
(C . t )
(python . t )))
; ; https://emacs.stackexchange.com/questions/3302/live-refresh-of-inline-images-with-org-display-inline-images
; ; Always redisplay inline images after executing SRC block
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images )
(require 'color )
(when mk-feature/gui
(set-face-attribute 'org-block nil :background
(color-darken-name
(face-attribute 'default :background ) 3 ))
(set-face-attribute 'org-code nil :background
(color-darken-name
(face-attribute 'default :background ) 3 ))
(set-face-attribute 'org-quote nil :background
(color-darken-name
(face-attribute 'default :background ) 3 ))
(set-face-attribute 'org-block-begin-line nil :background
" #F1E6F8" )
(set-face-attribute 'org-block-end-line nil :background
(color-darken-name
(face-attribute 'default :background ) 4 )))
(setq org-fontify-quote-and-verse-blocks t )
(add-hook 'org-mode-hook
(lambda ()
; ; (org-shifttab 5)
; ; (add-to-list 'write-file-functions 'delete-trailing-whitespace)
(electric-indent-local-mode -1 )
(mkvoya/better-wrap)
(prettify-symbols-mode )
; ; (org-hide-properties)
))
; ; According to https://orgmode.org/manual/Hard-indentation.html#Hard-indentation
; ; But I don't need the odd levels only
(setq org-adapt-indentation t
org-hide-leading-stars t )
; ;org-odd-levels-only t
(use-package org-contrib :disabled )
(use-package org-inline-pdf :defer t )
(use-package org-super-agenda
:init
(org-super-agenda-mode)
:config
(setq org-super-agenda-groups
'((:name " Next Items"
:time-grid t
:tag (" NEXT" " outbox" ))
(:name " Important"
:priority " A" )
(:name " Quick Picks"
:effort< " 0:30" )
(:priority<= " B"
:scheduled future
:order 1 )))
)
(set-face-attribute 'outline-1 nil :foreground " purple2" )
(set-face-attribute 'org-level-1 nil :height 1.2 )
(set-face-attribute 'org-level-1 nil :height 1.1 )
(set-face-attribute 'outline-2 nil :foreground " violetRed2" )
(set-face-attribute 'outline-3 nil :foreground " cyan4" )
(set-face-attribute 'outline-4 nil :foreground " springgreen4" )
)
SVG checkboxs
Add svg checkbox that can be clicked.
An example:
[X] item1
[ ] item2
[X] item 3
[X] item3
(use-package svg-lib :demand t )
(use-package svg-tag-mode
:disabled t
:if mk-feature/gui
:commands svg-tag-mode
:hook (org-mode . svg-tag-mode)
:demand t
:after (svg-lib org )
:straight (:host github :repo " rougier/svg-tag-mode" :files (" svg-tag-mode.el" ))
:config
(defun mk/svg-prop-drawer (props )
(let* ((svg (svg-create 14 14 )))
(svg-rectangle svg 0 0 14 14 :fill 'white :rx 2 :stroke-width 2.5 :stroke-color 'black )
(svg-image svg :ascent 'center )
))
(defun mk/svg-checkbox-empty ()
(let* ((svg (svg-create 14 14 )))
(svg-rectangle svg 0 0 14 14 :fill 'white :rx 2 :stroke-width 2.5 :stroke-color 'black )
(svg-image svg :ascent 'center )
))
(defun mk/svg-checkbox-filled ()
(let* ((svg (svg-create 14 14 )))
(svg-rectangle svg 0 0 14 14 :fill " #FFFFFF" :rx 2 )
(svg-polygon svg '((5.5 . 11 ) (12 . 3.5 ) (11 . 2 ) (5.5 . 9 ) (1.5 . 5 ) (1 . 6.5 ))
:stroke-color 'black :stroke-width 1 :fill 'black )
(svg-image svg :ascent 'center )
))
; ; (insert-image (svg-checkbox-empty))
; ; (insert-image (svg-checkbox-filled))
(defun mk/svg-checkbox-toggle ()
(interactive )
(save-excursion
(let* ((start-pos (line-beginning-position ))
(end-pos (line-end-position ))
(text (buffer-substring-no-properties start-pos end-pos))
(case-fold-search t ) ; Let X and x be the same in search
)
(beginning-of-line )
(cond ((string-match-p " \\ [X\\ ]" text)
(progn
(re-search-forward " \\ [X\\ ]" end-pos)
(replace-match " [ ]" )))
((string-match-p " \\ [ \\ ]" text)
(progn
(search-forward " [ ]" end-pos)
(replace-match " [X]" )))
))))
(defconst date-re " [0-9]\\ {4\\ }-[0-9]\\ {2\\ }-[0-9]\\ {2\\ }" )
(defconst time-re " [0-9]\\ {2\\ }:[0-9]\\ {2\\ }" )
(defconst day-re " [A-Za-z]\\ {3\\ }" )
(defconst day-time-re (format " \\ (%s \\ )? ?\\ (%s \\ )?" day-re time-re))
(setq svg-tag-tags
`(
; ; Properties
; ; ("^:PROPERTIES:\n\\(:ID:.*\n\\)*?:END:$" . ((lambda (tag)
; ; (string-match ":ID:[[:space:]]*\\(.*\\)$" tag)
; ; (svg-tag-make (concat "⚙ ID: " (match-string 1 tag))))))
; ; Org tags
; ; (":\\([A-Za-z0-9]+\\)" . ((lambda (tag) (svg-tag-make tag))))
; ; (":\\([A-Za-z0-9]+[ \-]\\)" . ((lambda (tag) tag)))
; ; Task priority
(" \\ [#[A-Z]\\ ]" . ( (lambda (tag )
(svg-tag-make tag :face 'org-priority
:beg 2 :end -1 :margin 0 ))))
; ; TODO / DONE
(" TODO" . ((lambda (tag ) (svg-tag-make " TODO" :face 'org-todo :inverse t :margin 0 ))))
(" DONE" . ((lambda (tag ) (svg-tag-make " DONE" :face 'org-done :margin 0 ))))
; ; Active date (with or without day name, with or without time)
(,(format " \\ (<%s >\\ )" date-re) .
((lambda (tag )
(svg-tag-make tag :beg 1 :end -1 :margin 0 ))))
(,(format " \\ (<%s \\ )%s >" date-re day-time-re) .
((lambda (tag )
(svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0 ))))
(,(format " <%s \\ (%s >\\ ) " date-re day-time-re) .
((lambda (tag )
(svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0 ))))
; ; Inactive date (with or without day name, with or without time)
(,(format " \\ (\\ [%s \\ ]\\ )" date-re) .
((lambda (tag )
(svg-tag-make tag :beg 1 :end -1 :margin 0 :face 'org-date ))))
(,(format " \\ (\\ [%s \\ )%s \\ ]" date-re day-time-re) .
((lambda (tag )
(svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0 :face 'org-date ))))
(,(format " \\ [%s \\ (%s \\ ]\\ )" date-re day-time-re) .
((lambda (tag )
(svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0 :face 'org-date ))))
; ; TODO-list
(" \\ [ \\ ]" . ((lambda (_tag ) (mk/svg-checkbox-empty))
(lambda () (interactive ) (mk/svg-checkbox-toggle))
" Click to toggle."
))
(" \\ (\\ [[Xx]\\ ]\\ )" . ((lambda (_tag ) (mk/svg-checkbox-filled))
(lambda () (interactive ) (mk/svg-checkbox-toggle))
" Click to toggle." ))
))
)
; ;; Org Style
; ; from https://www.lijigang.com/blog/2018/08/08/神器-org-mode/#org4288876
(setq org-startup-indented t )
(use-package org-superstar
:defer t
:disabled t ; disable for now
:after (org )
:hook (org-mode . org-superstar-mode)
:config
; ; Stop cycling bullets to emphasize hierarchy of headlines.
(setq org-superstar-cycle-headline-bullets nil )
; ; Hide away leading stars on terminal.
(setq org-superstar-leading-fallback ?\s )
(setq org-indent-mode-turns-on-hiding-stars nil )
(setq org-hide-leading-stars t )
(setq org-superstar-item-bullet-alist
'((?* . ?⌬ ) ; * ; previously used: 8226
(?+ . ?⋇ ) ; + ; previously used: 10210
(?- . ?▪ ))) ; - ; previously used: 8211
; ; ●◆◼►▸▮▪■⚈⚉⌫⌦☑ ◉◈○▷①②③④⑤⑥⑦⑧⑨⎋〄
(setq org-superstar-headline-bullets-list
'(9673 9675 ?◇ 10047 10040 ))
)
(use-package org-bars
:straight (:host github :repo " tonyaldon/org-bars" )
:defer t
:after (org )
:config
(setq org-bars-with-dynamic-stars-p nil )
)
; ; agenda 里面时间块彩色显示
; ; From: https://emacs-china.org/t/org-agenda/8679/3
(defun ljg/org-agenda-time-grid-spacing ()
" Set different line spacing w.r.t. time duration."
(save-excursion
(let* ((background (alist-get 'background-mode (frame-parameters )))
(background-dark-p (string= background " dark" ))
(colors (list " #1ABC9C" " #2ECC71" " #3498DB" " #9966ff" ))
pos
duration)
(nconc colors colors)
(goto-char (point-min ))
(while (setq pos (next-single-property-change (point ) 'duration ))
(goto-char pos)
(when (and (not (equal pos (point-at-eol )))
(setq duration (org-get-at-bol 'duration )))
(let ((line-height (if (< duration 30 ) 1.0 (+ 0.5 (/ duration 60 ))))
(ov (make-overlay (point-at-bol ) (1+ (point-at-eol )))))
(overlay-put ov 'face `(:background ,(car colors)
:foreground
,(if background-dark-p " black" " white" )))
(setq colors (cdr colors))
(overlay-put ov 'line-height line-height)
(overlay-put ov 'line-spacing (1- line-height))))))))
(add-hook 'org-agenda-finalize-hook #'ljg/org-agenda-time-grid-spacing )
; ;; Paste Image From https://emacs-china.org/t/topic/6601/4
(defun org-insert-image ()
" Insert a image from clipboard."
(interactive )
(let* ((path (concat default-directory
(buffer-name )
" .assets/" ))
(image-file (concat
path
(buffer-name )
(format-time-string " _%Y%m%d_%H%M%S.png" ))))
(if (not (file-exists-p path))
(mkdir path))
(do-applescript (concat
" set the_path to \" " image-file " \" \n "
" set png_data to the clipboard as «class PNGf» \n "
" set the_file to open for access (POSIX file the_path as string) with write permission \n "
" write png_data to the_file \n "
" close access the_file" ))
; ; (shell-command (concat "pngpaste " image-file))
(org-insert-link nil
(concat " file:" image-file)
" " )
(message image-file))
(org-display-inline-images )
)
appt MELPA, Appointment package
(use-package ox-html
:straight nil
:after (org )
:defer t
:config
; ; Org export code style
(setq org-html-htmlize-output-type 'css )
(setq-default org-html-doctype " html5" )
(setq-default org-html-html5-fancy t )
)
Calender sync
(use-package ox-icalendar
:defer t
:straight nil
:after (org )
:config
(setq org-icalendar-alarm-time 5 )
(setq org-icalendar-combined-agenda-file " ~/Dropbox/Dreams/Org/org.ics"
org-icalendar-include-todo 'all
org-icalendar-store-UID t
org-icalendar-timezone " "
org-icalendar-use-deadline
'(event-if-not-todo event-if-todo event-if-todo-not-done todo-due)
org-icalendar-use-scheduled
'(event-if-not-todo event-if-todo event-if-todo-not-done todo-start))
)
(use-package org-caldav
:defer t
; ; :after (async)
:init
(require 'async )
; ; (setq org-caldav-url "https://dong.mk/radicale/mkvoya/")
(setq org-caldav-url " https://mail.sjtu.edu.cn/dav/mingkaidong@sjtu.edu.cn/" )
(setq org-caldav-calendars
'(
(:calendar-id " 9d6f9f39-cba5-fe5b-bd49-c61168d64f81"
:inbox " ~/Dropbox/Dreams/Org/Caldav.inbox.org"
:files (" ~/Dropbox/Dreams/Org/Main.org"
" ~/Dropbox/Dreams/Org/Inbox.org"
)
:type-regex " VEVENT" )
(:calendar-id " e08e1f91-e359-0e59-3a72-b8b0ea70a783"
:inbox " ~/Dropbox/Dreams/Org/Caldav.inbox.org"
:files (
; ; "~/Dropbox/Dreams/Org/Main.org"
; ; "~/Dropbox/Dreams/Org/Inbox.org"
" ~/Dropbox/Dreams/Org/Ebib-ReadingList.org"
)
:type-regex " VTODO" )
))
; ; (setq org-caldav-calendar-id "f846603c-c54c-c73f-f009-e7331ef16216")
; ; (setq org-caldav-inbox "~/Dropbox/Dreams/Org/Caldav.inbox.org")
; ; (setq org-caldav-files '("~/Dropbox/Dreams/Org/Main.org"
; ; "~/Dropbox/Dreams/Org/Inbox.org"
; ; ))
; ; (setq org-icalendar-timezone "America/Los_Angeles")
(setq org-icalendar-timezone " Asia/Shanghai" )
)
OrgRoam
org-roam
org-roam-ui
org-roam-server (use org-roam-ui)
org-mindmap creates graphviz directed graphs from headings of an org file
Org-transclusion
Modes to embed one buffer in another buffer and keep them in sync
(use-package org-transclusion
:defer t
:after org
:config
(set-face-attribute
'org-transclusion-fringe nil
:foreground " lightgrey"
:background " lightgreen" )
(set-face-attribute
'org-transclusion-source-fringe nil
:foreground " lightblue"
:background " blue" )
)
; ; :bind (("<f12>" . #'org-transclusion-add))
; ; ("C-n t" . #'org-transclusion-mode)
NotDeft
(use-package notdeft
:if mk-feature/noteman
:defer t
:straight (:host github :repo " hasu/notdeft" :files (" *.el" " xapian" ))
:config
(setq notdeft-directories '(" ~/Dropbox/Dreams" " ~/Dropbox/IPADS" ))
(setq notdeft-extension " org" )
(setq notdeft-secondary-extensions '(" md" " txt" " scrbl" ))
(setq notdeft-allow-org-property-drawers t )
)
Denote
(use-package websocket :defer t )
(use-package simple-httpd :defer t )
(use-package denote
:if mk-feature/noteman
:straight (:type git :host github :repo " protesilaos/denote" )
:config
; ; Remember to check the doc strings of those variables.
(setq denote-directory (expand-file-name " ~/Dropbox/Dreams/Org/" ))
(setq denote-known-keywords '(" emacs" " philosophy" " research" " economics" ))
(setq denote-infer-keywords t )
(setq denote-sort-keywords t )
(setq denote-file-type nil ) ; Org is the default, set others here
(setq denote-prompts '(title keywords))
(setq denote-excluded-directories-regexp nil )
(setq denote-date-prompt-use-org-read-date t ) ; Pick dates, where relevant, with Org's advanced interface
(setq denote-allow-multi-word-keywords t ) ; Allow multi-word keywords
(setq denote-date-format nil ) ; read doc string
; ; By default, we do not show the context of links. We just display
; ; file names. This provides a more informative view.
(setq denote-backlinks-show-context t )
; ; We use different ways to specify a path for demo purposes.
(setq denote-dired-directories
(list denote-directory
(thread-last denote-directory (expand-file-name " attachments" ))
(expand-file-name " ~/Documents/books" )))
(add-hook 'dired-mode-hook #'denote-dired-mode-in-directories )
; ; Here is a custom, user-level command from one of the examples we
; ; showed in this manual. We define it here and add it to a key binding
; ; below.
(defun my-denote-journal ()
" Create an entry tagged 'journal', while prompting for a title."
(interactive )
(denote
(denote--title-prompt)
'(" journal" )))
)
(use-package org-capture
:if mk-feature/noteman
:straight nil
:after (denote)
:config
(setq denote-org-capture-specifiers " %l\n %i\n %?" )
(defvar mk/org-capture-people-path )
(defun mk/org-capture-people ()
(interactive )
(format " * %s \n %% ? " (read-string " 姓名: " nil ))
)
(setq org-capture-templates
'((" n" " New DeNote" plain (file denote-last-path)
#'denote-org-capture
:no-save t
:immediate-finish nil
:kill-buffer t
:jump-to-captured t )
(" p" " New People" entry (file+headline " ~/Dropbox/Dreams/Org/People/General.org" " People" )
#'mk/org-capture-people
)))
)
(use-package consult-notes
:straight (:type git :host github :repo " mclear-tools/consult-notes" )
:commands (consult-notes
consult-notes-search-in-all-notes)
:bind (" C-c d f" . consult-notes)
:config
(setq consult-notes-sources
'((" denote" ?d " ~/Dropbox/Dreams/Org" )
))
)
Bibliography
; ; Common
(setq mk/bib-main-file " ~/Dropbox/Dreams/Research/Papers/Papers.bib" )
(setq mk/bib-pdf-dir " ~/Dropbox/Dreams/Research/Papers/" )
(setq reftex-default-bibliography `(" paper.bib" " references.bib" , mk/bib-main-file ))
Bibtex
(use-package bibtex
:if mk-feature/bibliography
:straight nil ; built in
:defer
:init
(setq bibtex-dialect 'biblatex )
; ; Bibtex autokey is used by Ebib.
(setq bibtex-autokey-year-length 4 ; Full year format
bibtex-autokey-name-year-separator " -"
bibtex-autokey-year-title-separator " -"
bibtex-autokey-titleword-separator " -"
bibtex-autokey-titlewords 2 ; Use two words from the title
bibtex-autokey-titlewords-stretch 0
bibtex-autokey-titleword-length nil ; Use whole word
)
(setq bibtex-autokey-titleword-ignore
'(" A" " An" " On" " The" " Eine?" " Der" " Die" " Das"
" The" " on"
" a" " an"
" and" " the" " of" " .*[^[:upper:][:lower:]0-9].*" ))
(setq bibtex-completion-bibliography `(, mk/bib-main-file )
bibtex-completion-library-path nil ; TODO
bibtex-completion-notes-path nil ) ; TODO
(setq bibtex-completion-notes-template-multiple-files
" * ${author-or-editor}, ${title}, ${journal}, (${year}) :${=type=}: \n\n See [[cite:&${=key=}]]\n "
bibtex-completion-additional-search-fields '(keywords)
bibtex-completion-display-formats
'((article . " ${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${journal:40}" )
(inbook . " ${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} Chapter ${chapter:32}" )
(incollection . " ${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${booktitle:40}" )
(inproceedings . " ${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${booktitle:40}" )
(t . " ${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*}" )))
(setq bibtex-completion-pdf-open-function
(lambda (fpath ) (call-process " open" nil 0 nil fpath)))
:config
(use-package bibtex-completion
:defer
:config
(bibtex-completion-init) ; This will set the XXX-format-internal variable
)
)
Citar
; ; citar
(use-package citar
:if mk-feature/bibliography
:straight (:host github :repo " bdarcus/citar" )
:defer
:demand
:bind ((" C-c b" . citar-insert-citation)
:map minibuffer-local-map
(" M-b" . citar-insert-preset))
:init
(setq citar-notes-paths '(" ~/Dropbox/Dreams/Org/PaperNotes" ))
(setq org-cite-global-bibliography `(,(expand-file-name mk/bib-main-file)))
(setq org-cite-insert-processor 'citar )
(setq org-cite-follow-processor 'citar )
(setq org-cite-activate-processor 'citar )
(setq citar-bibliography org-cite-global-bibliography)
(setq citar-symbols
`((file ,(all-the-icons-faicon " file-o" :face 'all-the-icons-green :v-adjust -0.1 ) . " " )
(note ,(all-the-icons-material " speaker_notes" :face 'all-the-icons-blue :v-adjust -0.3 ) . " " )
(link ,(all-the-icons-octicon " link" :face 'all-the-icons-orange :v-adjust 0.01 ) . " " )))
(setq citar-symbol-separator " " )
; ; (require 'embark)
; ; (setq citar-at-point-function 'embark-act)
; ; (use-package citar-embark
; ; :after citar embark
; ; :no-require
; ; :config (citar-embark-mode))
:config
(use-package org-roam-bibtex
:defer
:after org-roam
:config
(setq orb-roam-ref-format 'org-cite )
(setq orb-use-bibdesk-attachments 't )
)
(require 'org-roam-bibtex )
(setq citar-open-note-function #' (lambda (key entry ) (orb-edit-note key)))
; ; (citar-filenotify-setup '(LaTeX-mode-hook org-mode-hook))
)
Biblio
(use-package biblio
:if mk-feature/bibliography
:defer
:init
(setq biblio-arxiv-bibtex-header " misc" )
(setq biblio-bibtex-use-autokey nil ) ; Don't use autokey of biblio
; ; Some backends fail upon async queries.
(setq biblio-synchronous t )
:config
; ; Override
(defun biblio--completing-read-function ()
" Override to always return the defualt one"
completing-read-function)
; ; Override to add url
(defun biblio-arxiv--build-bibtex-1 (metadata )
" Create an unformated BibTeX record for METADATA."
(let-alist metadata
(format " @%s {NO_KEY,
author = {%s },
title = {{%s }},
year = {%s },
url = {%s },
series = {arXiv %s },
archivePrefix = {arXiv},
eprint = {%s },
primaryClass = {%s }} "
biblio-arxiv-bibtex-header
(biblio-join-1 " AND " .authors)
.title .year .url .year .identifier .category)))
)
Ebib
(use-package ebib
:if mk-feature/bibliography
:defer
; ; :after (biblio bibtex citar)
:init
(require 'biblio )
(require 'bibtex )
(require 'citar )
(require 'dbus ) ; A function from dbus is used in ebib.
(defun mk/ebib-create-org-schedule (_key _db )
(format " SCHEDULED: <%s > " (org-read-date nil nil " +1d" ))
)
(setq ebib-reading-list-template-specifiers '((?K . ebib-reading-list-create-org-identifier)
(?T . ebib-create-org-title)
(?M . ebib-reading-list-todo-marker)
(?L . ebib-create-org-link)
(?F . ebib-create-org-file-link)
(?D . ebib-create-org-doi-link)
(?U . ebib-create-org-url-link)
(?S . mk/ebib-create-org-schedule)))
(setq ebib-reading-list-template " * %M %T\n %S\n :PROPERTIES:\n %K\n :END:\n %F\n " )
(setq ebib-autogenerate-keys t ) ; Use bibtex autokey.
(setq ebib-uniquify-keys t )
(setq ebib-bibtex-dialect 'biblatex ) ; biblatex is better than xxx.
(setq ebib-index-window-size 10 )
(setq ebib-preload-bib-files `(, mk/bib-main-file ))
(setq ebib-file-search-dirs `(, mk/bib-pdf-dir ))
(setq ebib-notes-storage 'one-file-per-note )
(setq ebib-reading-list-file " ~/Dropbox/Dreams/Org/Ebib-ReadingList.org" )
(setq ebib-notes-directory " ~/Dropbox/Dreams/Org/PaperNotes/" )
(setq ebib-notes-locations `(, ebib-notes-directory ))
; ; ebib-keywords-file "~/Dropbox/Bibliography/ebib-keywords.txt"
(setq ebib-keywords-field-keep-sorted t )
(setq ebib-keywords-file-save-on-exit 'always )
; ; ebib-file-associations '(("pdf")) "using Emacs to open pdf"
(setq ebib-use-timestamp t ) ; recording the time that entries are added
(setq ebib-index-columns '((" Year" 4 t )
(" Entry Key" 30 t )
(" Title" 50 t )
(" Series/Journal" 20 t )
(" Author/Editor" 40 nil )))
(setq ebib-index-default-sort '(" timestamp" . descend))
(defun mk/ebib-display-series-or-journal (field key db )
" Return series/journal FIELD content from KEY and DB."
(or (ebib-get-field-value " Series" key db 'noerror 'unbraced 'xref )
(ebib-get-field-value " Journal" key db " (No Series/Journal)" 'unbraced 'xref ))
)
(setq ebib-field-transformation-functions
'((" Title" . ebib-clean-TeX-markup-from-entry)
(" Doi" . ebib-display-www-link)
(" Url" . ebib-display-www-link)
(" Note" . ebib-notes-display-note-symbol)
(" Series/Journal" . mk/ebib-display-series-or-journal)
))
:config
(setq ebib-index-mode-line '(" %e"
mode-line-front-space
ebib--mode-line-modified
mode-line-buffer-identification
(:eval (if (and ebib--cur-db (ebib-db-dependent-p ebib--cur-db))
(format " [%s ] " (ebib-db-get-filename (ebib-db-get-main ebib--cur-db) t ))))
(:eval (format " (%s ) " (ebib--get-dialect ebib--cur-db)))
(:eval (if (and ebib--cur-db (ebib--get-key-at-point))
(format " Entry %d /%d " (line-number-at-pos ) (count-lines (point-min ) (point-max )))
" No Entries" ))
(:eval (if (and ebib--cur-db (ebib-db-get-filter ebib--cur-db))
(format " |%s | " (ebib--filters-pp-filter (ebib-db-get-filter ebib--cur-db)))
" " ))))
(defun mk/ebib--clean-string (str )
" Clean the format of STR."
(or (substring-no-properties (remove ?\n (format " %s " str))) " " ))
(defun mk/ebib--clean-field (key db field )
" Clean the format of FIELD of KEY in DB."
(mk/ebib--clean-string (ebib-get-field-value field key db 'noerror 'unbraced 'xref )))
(defun mk/read-file-content (filename )
" Read the file content of FILENAME."
(with-temp-buffer
(insert-file-contents filename)
(buffer-string )))
(defun mk/ebib-complete-rest-note-content (key db )
" Gerneate the rest content of the note template accroding to KEY in DB."
(let ((template (mk/read-file-content " ~/.emacs.d/snippets/ebib/ebib-notes-template.org" ))
(title (mk/ebib--clean-field key db " title" ))
(date (format-time-string " %FT%T%z" ))
(authors (mk/ebib--clean-field key db " author" ))
(series (mk/ebib--clean-field key db " series" )))
(setq template (string-replace " ${citekey}" key template))
(setq template (string-replace " ${orgid}" (org-id-new ) template))
(setq template (string-replace " ${title}" title template))
(setq template (string-replace " ${date}" date template))
(setq template (string-replace " ${authors}" authors template))
(setq template (string-replace " ${series}" series template))
template))
(setq ebib-notes-template-specifiers '((?K . ebib-create-org-identifier)
(?T . ebib-create-org-description)
(?X . ebib-create-org-title)
(?C . ebib-create-org-cite)
(?L . ebib-create-org-link)
(?F . ebib-create-org-file-link)
(?D . ebib-create-org-doi-link)
(?U . ebib-create-org-url-link)
(?P . mk/ebib-complete-rest-note-content)))
(setq ebib-notes-template " %%?%P\n " )
)
(defun mk/ebib-reading-list-show-entry ()
" Jump to the ebib entry from the current reading list item."
(interactive )
(let ((custom-id (org-entry-get (point ) " Custom_id" )))
(when (string-prefix-p " reading_" custom-id)
(let ((ebib-key (substring custom-id 8 )))
(message " Jumping to ebib entry with key: %s " ebib-key)
(ebib nil ebib-key)
))))
(use-package ebib-biblio
:if mk-feature/bibliography
:after (ebib biblio)
:straight nil
:demand
:bind (:map biblio-selection-mode-map
(" e" . ebib-biblio-selection-import)))
Paper and Research
(use-package emacs
:if mk-feature/bibliography
:after (ebib)
:init
; ; My source code for bib
(setq paper-root-dir (expand-file-name " ~/Dropbox/Dreams/Research/Papers" ))
(defun mk/normalize-paper-title (title )
" Remove bad chars in the paper TITLE."
(replace-regexp-in-string
" [\s\n ]+" " " (replace-regexp-in-string
" /" " " (replace-regexp-in-string
" :" " ," title)))
)
(defun paper-root ()
" Open the paper root."
(interactive )
(find-file paper-root-dir))
(defun paper-find (&optional initial )
" Search a paper in your Dreamland, by title, with INITIAL input."
(interactive " P" )
(let ((consult-find-args (concat
(expand-file-name " ~/.emacs.d/bin/paperfind.sh" )
" "
paper-root-dir)))
(find-file (concat (file-name-as-directory paper-root-dir)
(consult--find " Dreamland's Paper Find: "
#'consult--find-builder initial)))))
(defun paper-open ()
" Open the file in PDF Expert. Code borrowed from the crux package."
(interactive )
(let ((current-file-name
(if (eq major-mode 'dired-mode )
(dired-get-file-for-visit )
buffer-file-name)))
(call-process " open" nil 0 nil " -a" " /Applications/PDF Expert.app" current-file-name))
)
; ; Automatically choose the file to link with according to the selected text.
(defvar autolink-directory " ~/Dropbox/Dreams" )
(defun autolink--get-candidates (text )
" Search for the file name with TEXT."
(let* ((cmd (concat " find " autolink-directory " -iname \" *" (string-replace " :" " ?" text) " *\" " ))
(candidates (mapcar 'abbreviate-file-name (delete " " (split-string (shell-command-to-string cmd) " \n " )))))
(completing-read " Choose the one to link: " candidates)))
(defun paper-link (start end )
" Try to guess the file to link according to the region between START and END."
(interactive " r" ) ; The "r" here will fill the start and end automatically.
(let* ((text (buffer-substring start end))
(file (autolink--get-candidates text)))
(goto-char end)
(insert " ]]" )
(goto-char start)
(insert (concat " [[" file " ][" ))))
(setq mk/ebib-dir-root " ~/Dropbox/Dreams/Research/Papers" )
(defun mk/ebib--format-full-dir (dir title )
" Get the full dir name from DIR and TITLE."
(format " %s /%s /%s " mk/ebib-dir-root dir title))
(defun mk/ebib-get-series-dirname-candidate (title series journal year publisher )
" Form the name of given TITLE, SERIES, JOURNAL, YEAR, PUBLISHER"
(cond
; ; Use series if set
((not (string= series " no-series" )) (string-replace " " " ." (string-replace " '" " " series)))
; ; Hard coded
((string= journal " scientific reports" ) (format " nat.sci.rep.%s " year))
((string= journal " commun. acm" ) (format " commun.acm.%s " year))
((string= journal " nature communications" ) (format " nat.comm.%s " year))
((string= journal " acs nano" ) (format " acs.nano.%s " year))
((string= journal " bmc bioinformatics" ) (format " bioinfo.%s " year))
((string= journal " ieee transactions on computer-aided design of integrated circuits and systems" ) (format " tcad.%s " year))
((string= journal " ieee transactions on parallel and distributed systems" ) (format " tpds.%s " year))
((string= journal " ieee transactions on computers" ) (format " tc.%s " year))
((string= journal " briefings in bioinformatics" ) (format " bib.%s " year))
((string= journal " acs synthetic biology" ) (format " acs.syn.bio.%s " year))
; ; arXiv
((string= publisher " arxiv" ) (format " arxiv%s " year))
(t " XXXX" )))
(defun mk/ebib-get-dir (title series journal year publisher )
" Calculate the directory for TITLE and SERIES and JOURNAL and PUBLISHER."
(let* ((series-dir (mk/ebib-get-series-dirname-candidate title series journal year publisher))
(fulldir (mk/ebib--format-full-dir series-dir title)))
(if (file-exists-p fulldir) fulldir nil )
))
(defun mk/ebib-open-dir (key )
" Open the directory for KEY."
(interactive (list (ebib--get-key-at-point)))
(ebib--execute-when
(entries
(let* ((title (mk/normalize-paper-title (ebib-get-field-value " title" key ebib--cur-db nil t )))
(series (downcase (ebib-get-field-value " series" key ebib--cur-db " no-series" t )))
(publisher (downcase (ebib-get-field-value " publisher" key ebib--cur-db " no-publisher" t )))
(journal (downcase (ebib-get-field-value " journal" key ebib--cur-db " no-journal" t )))
(year (ebib-get-field-value " year" key ebib--cur-db " 0000" t ))
(series-dirname (mk/ebib-get-series-dirname-candidate title series journal year publisher))
(cand (mk/ebib-get-dir title series journal year publisher)))
(if cand (find-file cand)
(print " No such dir, creating with prompt..." )
(let* ((conf (string-trim (read-string " The conf abbr: " series-dirname)))
(target (format " %s /%s /%s " mk/ebib-dir-root conf title)))
(make-directory target t )
(find-file target)
))))
(default
(beep ))))
(define-key ebib-index-mode-map (kbd " O" ) #'mk/ebib-open-dir )
(defun mk/paper-get-dirs ()
" Get all conf dirs."
(let* ((cmd (format " find %s -type d -maxdepth 1 -exec realpath --relative-to %s {} \\ ; " mk/ebib-dir-root mk/ebib-dir-root))
(candidates (mapcar 'abbreviate-file-name (delete " " (split-string (shell-command-to-string cmd) " \n " ))))
(choice (completing-read " Choose the one to link: " candidates)))
(print choice)
))
(defun mk/ebib-open-file (key )
" Open files for KEY."
(interactive (list (ebib--get-key-at-point)))
(ebib--execute-when
(entries
(let* ((title (mk/normalize-paper-title (ebib-get-field-value " title" key ebib--cur-db nil t )))
(cmd (format " find %s -type d -iname \" %s \" " mk/ebib-dir-root title))
(candidates (mapcar 'abbreviate-file-name (delete " " (split-string (shell-command-to-string cmd) " \n " ))))
(cand (cond
((= 0 (length candidates)) nil )
((= 1 (length candidates)) (car candidates))
(t (completing-read " Choose the one to link: " candidates)))))
(if cand (find-file cand)
())))
(default
(beep ))))
)
MISC
(use-package image-click-mode
:if mk-feature/gui
:delight
:ensure t
:after (org )
:straight (:host github :repo " mkvoya/image-click-mode" :files (" *.el" ))
:config
(setq org-image-actual-width 400 )
(add-hook 'org-mode-hook (lambda () (image-click-mode))))
Popweb
(use-package popweb
:if mk-feature/gui
:defer t
:disabled t
:straight (:type git :host github :repo " manateelazycat/popweb" :files (" *" ))
:config
(setq popweb-root (file-name-directory (locate-library " popweb.el" )))
(add-to-list 'load-path (concat popweb-root " extension/latex" ))
(require 'popweb-latex )
(add-to-list 'load-path (concat popweb-root " extension/dict" ))
(require 'popweb-dict-bing )
(require 'popweb-dict-youdao )
)
vterm
(use-package vterm
:defer t
:config
(defun vterm-new ()
" Add a new vterm session with given name."
(interactive )
(let ((session-name (string-trim (read-string " Enter the name for the session: " ))))
(vterm session-name)
)
)
)
(use-package highlight-indent-guides :defer t )
(use-package hl-line
:config
(set-face-background 'hl-line " #d0fed0" )
(set-face-foreground 'hl-line nil )
(set-face-foreground 'highlight nil )
; ; (global-hl-line-mode t)
)
(use-package gitlab-ci-mode :defer t )
(use-package dockerfile-mode :mode " Dockerfile" :defer t )
(use-package imenu-list
:after (org )
:demand
:bind ((" C-\" " . #'imenu-list-smart-toggle ))
:config
(setq imenu-list-auto-resize nil )
(setq imenu-list-position 'left )
(setq org-imenu-depth 5 )
)
(use-package org-sidebar :defer t )
Custom functions
Interactive Utilities
(defun mk/insert-datetime ()
" Insert the current date and time."
(interactive )
(insert (format-time-string " %F %T" )))
; ; From https://emacs.stackexchange.com/questions/47627/identify-buffer-by-part-of-its-name
(defun switch-to-existing-buffer-other-window (part )
" Switch to buffer with PART in its name."
(interactive
(list (read-buffer-to-switch " Switch to buffer in other window: " )))
(let ((candidates
(cl-remove
nil
(mapcar (lambda (buf )
(let ((pos (string-match part (buffer-name buf))))
(when pos
(cons pos buf))))
(buffer-list )))))
(unless candidates
(user-error " There is no buffers with %S in its name." part))
(setq candidates (cl-sort candidates #'< :key 'car ))
(switch-to-buffer-other-window (cdr (car candidates)))))
(defun mk/open-orgroam-panel ()
" Open the Org-roam client at [http://127.0.0.1:35901]."
(interactive )
; ; Ensure the server is running.
(unless org-roam-ui-mode (org-roam-ui-mode))
; ; Ensure the session is running.
(xwidget-webkit-browse-url " http://127.0.0.1:35901" nil )
; ; Switch to the buffer
(switch-to-existing-buffer-other-window " Roam Server" )
)
(defun mk/webkit-new-url (url &optional new-session )
" Create a new session to browse the URL."
(interactive (progn
(require 'browse-url )
(browse-url-interactive-arg " xwidget-webkit URL: " )))
(xwidget-webkit-browse-url url t )
)
Notionify
(defun mk/notionify-turn-to-page (@begin @end )
" Turn the selected text to a page link. If the function is called in the page =file.org=, a directory called =file.org.dir= will be auto created if not exists. A new file will be created with the name of selected text + '.org' (@BEGIN -to- @END .org) suffix. This mimics the action of turning the selected line into a new page in Notion.so, while this function is better since the page does not need to be a single line. The text will be turned into a hyperlink to the new file."
(interactive
(if (use-region-p )
(list (region-beginning ) (region-end ))
(list (line-beginning-position ) (line-end-position ))))
(save-excursion
(save-restriction
(narrow-to-region @begin @end)
(let (($dir (concat (string-trim-right (buffer-name ) " .dir" ))
($subpage (buffer-substring-no-properties (point-min ) (point-max ))))
(make-directory $dir t )
(goto-char (point-min ))
(insert (concat " [[file:./" $dir " /" $subpage) " .org][" )
(goto-char (point-max ))
(insert " ]]" )))
)))
Launcher
(defun is-floating-frame (f )
(equal (frame-parameter f 'name ) " *Floating*" )
)
(defun get-floating-frame ()
(car (filtered-frame-list #'is-floating-frame )))
(defun toggle-floating-frame ()
" Make/Delete a frame that is floating."
(interactive )
; ; ((w (display-pixel-width))
; ; (h (/ (display-pixel-height) 2)))
(let* ((geo (cdr (assq 'geometry (car (display-monitor-attributes-list )))))
(x (nth 0 geo))
(y (nth 1 geo))
(w (nth 2 geo))
(h (nth 3 geo))
(f (get-floating-frame)))
(if f
(progn
; ; (keyboard-quit)
; ; (make-frame-invisible f)
(delete-frame )
)
(progn
(setq f (make-frame '((undecorated . 1 )
(name . " *Floating*" )))) ; TODO: do not make-frame every time.
(set-frame-position f 0 0 )
(set-frame-size f w (/ h 2 ) t )
(make-frame-visible f)
(select-frame f)
(select-frame-set-input-focus f)
(switch-to-buffer " *scratch*" )
; ; (call-interactively (global-key-binding "\M-x"))
))))
(use-package popwin
:disabled t
:config
(popwin-mode 1 )
)
Custom key-bindings
; ; from https://stackoverflow.com/questions/1250846/wrong-type-argument-commandp-error-when-binding-a-lambda-to-a-key
(global-set-key (kbd " C-h c" ) #'describe-char )
(global-set-key (kbd " C-c h" ) (lambda () (interactive ) (find-file " ~/Dropbox/Dreams/Org/Main.org" )))
(global-set-key (kbd " C-c r" ) (lambda () (interactive ) (find-file " ~/.emacs.d/emacs-config.org" )))
(global-set-key (kbd " C-c p" ) (lambda () (interactive ) (find-file " ~/Dropbox/Dreams/Org/Projects.org" )))
(global-set-key (kbd " M-s-<left>" ) 'tab-previous )
(global-set-key (kbd " M-s-<right>" ) 'tab-next )
(global-set-key (kbd " M-s-n" ) 'tab-new )
(global-set-key (kbd " C-c w" ) (lambda () (interactive ) (find-file " ~/Dropbox/Dreams/Org/Weights.org" )))
; ; Open ibuffer upon "C-c i"
(global-set-key (kbd " C-c i" ) 'ibuffer )
; ; (global-set-key (kbd "C-c C-m e") (lambda () (interactive) (find-file "~/.emacs.d/emacs-config.org")))
; ; (global-unset-key [mouse-3])
; ; (global-set-key [down-mouse-3]
; ; `(menu-item ,(purecopy "Menu Bar") ignore
; ; :filter (lambda (_)
; ; (if (zerop (or (frame-parameter nil 'menu-bar-lines) 0))
; ; (mouse-menu-bar-map)
; ; (mouse-menu-major-mode-map)))))
Publish & Blog
Org-based Blog
(use-package org-static-blog
:defer t
:init
(use-package htmlize)
:config
(setq org-static-blog-publish-title " Mika.blog" )
(setq org-static-blog-publish-url " https://blog.dong.mk/" )
(setq org-static-blog-publish-directory " ~/Dropbox/Dreams/Org/Blog/Publish/" )
(setq org-static-blog-posts-directory " ~/Dropbox/Dreams/Org/Blog/Posts/" )
(setq org-static-blog-drafts-directory " ~/Dropbox/Dreams/Org/Blog/Drafts/" )
(setq org-static-blog-use-preview t ) ; enable preview
; ; Use “#+filetags: τ₁ τ₂ … τₙ”
(setq org-static-blog-enable-tags t )
; ; I'd like to have tocs and numbered headings
(setq org-export-with-toc t )
(setq org-export-with-section-numbers t )
(setq org-static-blog-page-header
" <meta name=\" author\" content=\" Mingkai Dong\" >
<meta name=\" referrer\" content=\" no-referrer\" >
<link href= \" static/style.css\" rel=\" stylesheet\" type=\" text/css\" />
<link rel=\" icon\" href=\" static/favicon.ico\" >" )
(setq org-static-blog-page-preamble " " )
; ; ("<div class=\"header\">
; ; <a href=\"https://blog.dong.mk\">Mika, Mika, Mika.</a>
; ; </div>")
(setq org-static-blog-page-postamble " " )
; ; (setq org-static-blog-page-postamble
; ; "<div id=\"archive\">
; ; <a href=\"https://blog.dong.mk/archive.html\">Other posts</a>
; ; </div>
; ; <center></center>")
(setq org-static-blog-index-front-matter " " )
; ; "<h1> Hey it is </h1>\n"
)
Org Publish
Do we still use this?
(use-package ox-publish
:defer t
:straight nil
:after (org )
:config
(setq org-publish-project-alist
'(
(" org-notes"
:base-directory " ~/Dropbox/Dreams/Org/Public"
:base-extension " org"
:publishing-directory " /Volumes/ramfs/public_html/"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 4 ; Just the default for this project.
:auto-preamble t
)
(" org-static"
:base-directory " ~/Dropbox/Dreams/Org/Public"
:base-extension " css\\ |js\\ |png\\ |jpg\\ |gif\\ |pdf\\ |mp3\\ |ogg\\ |swf"
:publishing-directory " /Volumes/ramfs/public_html/"
:recursive t
:publishing-function org-publish-attachment
)
(" org" :components (" org-notes" " org-static" ))
)))
Disabled Pool
(use-package maple-explorer :disabled t )
(use-package org-brain :disabled t )
(use-package deft :disabled t )
(use-package zettledeft :disabled t )
(use-package org-real :disabled t ) ; https://gitlab.com/tygrdev/org-real
(use-package explain-pause-mode :disabled t )
(use-package keystrokes :disabled t
:straight (:type git :host gitlab :repo " marcowahl/keystrokes" ))
(use-package netease-cloud-music :disabled t
:straight (:host github :repo " SpringHan/netease-cloud-music.el" ))
(use-package peep-dired :disabled t ) ; Preview files in dired, but we use ranger instead.
(use-package ns-auto-titlebar :disabled t ) ; We used a better patch.
(use-package telega :disabled t ) ; Prefer the GUI
(use-package elgantt
:disabled
:straight (:type git :host github :repo " legalnonsense/elgantt" ))
(use-package paper :disabled t
:straight (:host github :repo " ymarco/paper-mode" :files (" *.el" " *.so" )))
Fancy Libraries
Less (if ever) used
(use-package chronos :defer t )
(use-package elquery :defer )
(use-package citeproc :defer )
(use-package lua-mode :defer )
; ; (use-package xenops) ; the package causes highlighting issues for latex
(use-package org-download :defer )
(use-package symbol-overlay :defer )
(use-package read-aloud
:disabled
:config
(setq read-aloud-engine " say" ))
(use-package emacs-badge
:defer t
:straight (:type git :host github :repo " mkvoya/emacs-badge" :files (" *" ))
)
(use-package elnode
:defer
:straight (:type git :host github :repo " jcaw/elnode" ))
(use-package multiple-cursors
:bind ((" C-!" . mc/mark-next-like-this)))
(defun mk/ns-get-window-title-and-buffer ()
(interactive )
; ; Apple script from the activitywatch project
(do-applescript "
global frontApp, frontAppName, windowTitle
set windowTitle to \"\"
tell application \" System Events\"
set frontApp to first application process whose frontmost is true
set frontAppName to name of frontApp
tell process frontAppName
try
tell (1st window whose value of attribute \" AXMain\" is true)
set windowTitle to value of attribute \" AXTitle\"
end tell
end try
end tell
end tell
return frontAppName & \"
\" & windowTitle" ))
(defun mk/dired-curl ()
" Get file from url to dired."
(interactive )
(when (equal major-mode 'dired-mode )
(let* ((url (read-string " URL: " ))
(cwd (dired-current-directory ))
(target (concat (file-name-as-directory cwd) (file-name-nondirectory url))))
(url-copy-file url target)
)))
(defun mk/frame-pin ()
" Pin current frame to always-on-top."
(interactive )
(modify-frame-parameters
nil '((z-group . above))))
(defun mk/frame-unpin ()
" Unpin current frame to always-on-top."
(interactive )
(modify-frame-parameters
nil '((z-group . nil ))))
(defun mk/make-pinned-frame ()
" Make a new pined frame."
(interactive )
(make-frame '((undecorated . 1 )
(z-group . above)
(width . 80 )
(height . 10 )
(user-size . t )
(left . 1 )
(top . 1 )
(user-position . t )
(tab-bar-lines . 0 )
(drag-with-header-line . t )
(drag-with-tab-line . t )
(drag-with-mode-line . t ))))
; ; (load-file "~/.emacs.d/site-lisp/wc.el")
(use-package motd
:if mk-feature/noteman
:straight nil
:ensure nil
:load-path " ~/.emacs.d/site-lisp/"
:config
(if mk-feature/light
(progn
(setq motd-background-color " #EFE0C0" )
(setq motd-border-color " #910471" )
)
(setq motd-background-color " #204230" )
(setq motd-border-color " #444444" )
)
(setq motd--git-commit-dir " ~/Dropbox/Dreams" )
(motd-start-timer)
)
(defun mk/--pick-project ()
" Pick a project to do."
(seq-random-elt
(mapcar #' (lambda (h )
(let* ((headline (plist-get h 'headline ))
(title (substring-no-properties (car (plist-get headline :title )))))
title))
(org-ql-query
:select 'element
:from " ~/Dropbox/Dreams/Org/Projects.org"
:where '(todo " PROJECT" )
:order-by 'deadline ))))
(defun mk/pick-project ()
" Pick a project to do."
(interactive )
(message (mk/--pick-project)))
(setq python-shell-completion-native-disabled-interpreters nil )
Rust
(use-package rustic
:custom
(rustic-lsp-setup-p . nil ))
; ; (use-package ox-pandoc)
(defun mk/dired-open-pdf ()
" In dired, open the file named on this line."
(interactive )
(let* ((file (dired-get-filename nil t )))
(message " Opening %s ... " file)
(call-process " open" nil 0 nil " -a" " PDF Expert" file)
(message " Opening %s done " file)))
(use-package diredfl
:config
(diredfl-global-mode))
(use-package linux-kernel-coding-style
:straight (:type git :host github :repo " mkvoya/linux-kernel-coding-style.el" )
)
(use-package tree-sitter
:init
(use-package tree-sitter-langs)
(global-tree-sitter-mode)
(add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode )
)
(use-package org-timeline
:after org
:config
(add-hook 'org-agenda-finalize-hook 'org-timeline-insert-timeline :append )
)
Anki-like
(use-package org-drill
:disabled t )
(use-package org-anki
:after (org )
:config
; ; Override the cloze function
; ; The below function does not work since Anki does not show the back of the card for clozes.
; ; (defun org-anki--region-to-cloze (begin end arg hint)
; ; "Cloze region from BEGIN to END with number ARG."
; ; (let ((region (buffer-substring begin end)))
; ; (save-excursion
; ; (delete-region begin end)
; ; (insert (with-output-to-string
; ; (princ (format "{{c%d::%s" (or arg 1) region))
; ; (unless (string-blank-p hint) (princ (format "::%s" hint)))
; ; (princ "}}")))
; ; (org-end-of-subtree)
; ; (insert "\n" region ": " hint)
; ; )))
)
(use-package define-word)
(use-package sdcv
:disabled t )
; ; via http://www.emacswiki.org/emacs/ThesauriAndSynonyms
; ; The file names are absolute, not relative, locations
; ; - e.g. /foobar/mthesaur.txt.cache, not mthesaur.txt.cache
(use-package synonyms
:ensure t ; ; install package if not found
:init ; ; executed before loading package
(setq synonyms-file " ~/.emacs.d/data/mthesaur.txt" )
(setq synonyms-cache-file " ~/.emacs.d/data/synonyms.cache" )
:config
(defun my-synonym-current-word ()
" Lookup synonyms for current word."
(interactive )
(synonyms-lookup (thing-at-point 'word ) nil nil ))
:bind (:map my-map (" s" . my-synonym-current-word))
)
(use-package ox-hugo
:after ox
:init
(defun mk/sync-to-server (&optional all-subtrees async visible-only noerror )
(async-shell-command " cd ~/Dropbox/Public/essay && hugo -D && rsync -rvP ~/Dropbox/Public/essay/public/ dong.mk:/srv/http/essay" ))
(advice-add 'org-hugo-export-wim-to-md :after #'mk/sync-to-server )
)
(use-package org-pomodoro)