Skip to content

Latest commit

 

History

History
5838 lines (5653 loc) · 182 KB

init.org

File metadata and controls

5838 lines (5653 loc) · 182 KB

Emacs configuration file

About

This is an Emacs configuration file written in org mode. It is strongly inspired by spacemacs, doom-emacs and many other great Emacs configurations I found on Internet.

Table of Contents

early init

   ;;; -*- lexical-binding: t; -*-

 (defvar my--file-name-handler-alist file-name-handler-alist)
 (setq gc-cons-threshold most-positive-fixnum
	gc-cons-percentage 0.6
	file-name-handler-alist nil)

 (if (fboundp 'tool-bar-mode)
   (tool-bar-mode -1))
 (if (fboundp 'set-scroll-bar-mode)
   (set-scroll-bar-mode nil))
 (if (fboundp 'menu-bar-mode)
   (menu-bar-mode -1))

 (setq package-enable-at-startup nil)

 (set-face-attribute 'default nil  :family "Hack" :height 110 :weight 'normal)

initial

lexical binding

;;; -*- lexical-binding: t; -*-

setting up auto tangle

Copy these code from https://github.com/larstvei/dot-emacs

When this configuration is loaded for the first time, the init.el is the file that is loaded. It looks like this:

;; This file replaces itself with the actual configuration at first run.

;; We can't tangle without org!
(require 'org)
;; Open the configuration
(find-file (concat user-emacs-directory "init.org"))
;; tangle it
(org-babel-tangle)
;; load it
(load-file (concat user-emacs-directory "init.el"))
;; finally byte-compile it
(byte-compile-file (concat user-emacs-directory "init.el"))

The init.el should (after the first run) mirror the source blocks in the init.org. We can use C-c C-v t to run org-babel-tangle, which extracts the code blocks from the current file into a source-specific file (in this case a .el-file).

To avoid doing this each time a change is made we can add a function to the after-save-hook ensuring to always tangle and byte-compile the org-document after changes.

 (defun tangle-init ()
   "If the current buffer is 'init.org' the code-blocks are
 tangled, and the tangled file is compiled."
   (interactive)
   (when (equal (buffer-file-name)
		 (expand-file-name (concat user-emacs-directory "init.org")))
     ;; Avoid running hooks when tangling.
     (let ((prog-mode-hook nil))
	(org-babel-tangle)
	(byte-compile-file (concat user-emacs-directory "init.el")))))

 ;; (add-hook 'after-save-hook 'tangle-init)

start time

(setq emacs-load-start-time (current-time))

setting custom file

(setq custom-file (concat user-emacs-directory "custom.el"))
(if (file-exists-p (concat user-emacs-directory "custom.el"))
    (load-file (concat user-emacs-directory "custom.el")))

package related

package

(require 'package)
;; ;;; Install into separate package dirs for each Emacs version, to prevent bytecode incompatibility
;; (let ((versioned-package-dir
;;        (expand-file-name (format "elpa-%s.%s" emacs-major-version emacs-minor-version)
;; 			 user-emacs-directory)))
;;   (setq package-user-dir versioned-package-dir))
(setq package-archives '(("melpa" . "~/elpa/melpa/")
			   ;; ("melpa-stable" . "~/elpa/melpa-stable/")
			   ("gnu" . "~/elpa/gnu/")
			   ("org" . "~/elpa/org/")
			   ("emacswiki" . "~/elpa/emacswiki/")))
;; (setq package-archives '(("gnu" . "https://mirrors.ustc.edu.cn/elpa/gnu/")
;; 			 ("melpa" . "https://mirrors.ustc.edu.cn/elpa/melpa/")
;; 			 ;; ("melpa-stable" . "https://mirrors.ustc.edu.cn/elpa/melpa-stable/")
;; 			 ("org" . "https://mirrors.ustc.edu.cn/elpa/org/")))
(package-initialize)

bootstrap straight

 (defvar bootstrap-version)
 (let ((bootstrap-file
	 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
	(bootstrap-version 5))
   (unless (file-exists-p bootstrap-file)
     (with-current-buffer
	  (url-retrieve-synchronously
	   "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
	   'silent 'inhibit-cookies)
	(goto-char (point-max))
	(eval-print-last-sexp)))
   (load bootstrap-file nil 'nomessage))
   (setq straight-use-package-by-default t)

install use-package and related packages

;; (straight-use-package 'use-package)
;; install use-package
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
;; further reduce load time, from use-package official github page
(eval-when-compile
  (require 'use-package))
(setq use-package-always-ensure t)
(use-package diminish)
(require 'diminish)
(setq use-package-verbose t)

hydra

(use-package hydra
  :config
  (setq hydra-hint-display-type 'my/posframe)
  (defun my/hydra-posframe-show (str)
    (require 'posframe)
    (posframe-show
     " *hydra-posframe*"
     :string str
     :point (point)
     :internal-border-color "gray50"
     :internal-border-width 2
     :poshandler #'posframe-poshandler-frame-top-center))
  (defun my/hydra-posframe-hide ()
    (posframe-hide " *hydra-posframe*"))
  (setq hydra-hint-display-alist
	  (list (list 'my/posframe #'my/hydra-posframe-show #'my/hydra-posframe-hide))
	  hydra--work-around-dedicated nil))

install general

 (use-package general
   :config
   (progn
     (general-create-definer my/normal-keys
	:states 'normal
	:keymaps 'override)
     (general-create-definer my/motion-keys
	:states 'motion
	:keymaps 'override)
     (general-create-definer my/non-insert-keys
	:states '(nromal visual motion)
	:keymaps 'override)
     (general-create-definer my/leader-keys
	:states '(normal visual motion emacs insert)
	:keymaps 'override
	:prefix "SPC"
	:non-normal-prefix "M-SPC")
     (general-create-definer my/leader-keys-major-mode
	:states '(normal visual motion emacs insert)
	:keymaps 'override
	:prefix ","
	:non-normal-prefix "M-,")
     (general-create-definer my/leader-keys-minor-mode
	:states '(normal visual motion emacs insert)
	:keymaps 'override
	:prefix ";"
	:non-normal-prefix "M-;")
     (general-create-definer my/all-states-keys
	:states '(normal visual motion emacs insert)
	:keymaps 'override)
     ;; (general-create-definer my/leader-keys-extra
     ;;   :states '(normal visual motion emacs insert)
     ;;   :keymaps 'override
     ;;   :prefix ";"
     ;;   :non-normal-prefix "M-;")
     ))

 ;;;###autoload
 (defun my/lisp-indent-function (indent-point state)
   "This function is the normal value of the variable `lisp-indent-function'.
 The function `calculate-lisp-indent' calls this to determine
 if the arguments of a Lisp function call should be indented specially.
 INDENT-POINT is the position at which the line being indented begins.
 Point is located at the point to indent under (for default indentation);
 STATE is the `parse-partial-sexp' state for that position.
 If the current line is in a call to a Lisp function that has a non-nil
 property `lisp-indent-function' (or the deprecated `lisp-indent-hook'),
 it specifies how to indent.  The property value can be:
 * `defun', meaning indent `defun'-style
   \(this is also the case if there is no property and the function
   has a name that begins with \"def\", and three or more arguments);
 * an integer N, meaning indent the first N arguments specially
   (like ordinary function arguments), and then indent any further
   arguments like a body;
 * a function to call that returns the indentation (or nil).
   `lisp-indent-function' calls this function with the same two arguments
   that it itself received.
 This function returns either the indentation to use, or nil if the
 Lisp function does not specify a special indentation."
   (let ((normal-indent (current-column))
	  (orig-point (point)))
     (goto-char (1+ (elt state 1)))
     (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
     (cond
      ;; car of form doesn't seem to be a symbol, or is a keyword
      ((and (elt state 2)
	     (or (not (looking-at "\\sw\\|\\s_"))
		 (looking-at ":")))
	(if (not (> (save-excursion (forward-line 1) (point))
		    calculate-lisp-indent-last-sexp))
	    (progn (goto-char calculate-lisp-indent-last-sexp)
		   (beginning-of-line)
		   (parse-partial-sexp (point)
				       calculate-lisp-indent-last-sexp 0 t)))
	;; Indent under the list or under the first sexp on the same
	;; line as calculate-lisp-indent-last-sexp.  Note that first
	;; thing on that line has to be complete sexp since we are
	;; inside the innermost containing sexp.
	(backward-prefix-chars)
	(current-column))
      ((and (save-excursion
	       (goto-char indent-point)
	       (skip-syntax-forward " ")
	       (not (looking-at ":")))
	     (save-excursion
	       (goto-char orig-point)
	       (looking-at ":")))
	(save-excursion
	  (goto-char (+ 2 (elt state 1)))
	  (current-column)))
      (t
	(let ((function (buffer-substring (point)
					  (progn (forward-sexp 1) (point))))
	      method)
	  (setq method (or (function-get (intern-soft function)
					 'lisp-indent-function)
			   (get (intern-soft function) 'lisp-indent-hook)))
	  (cond ((or (eq method 'defun)
		     (and (null method)
			  (> (length function) 3)
			  (string-match "\\`def" function)))
		 (lisp-indent-defform state indent-point))
		((integerp method)
		 (lisp-indent-specform method state
				       indent-point normal-indent))
		(method
		 (funcall method indent-point state))))))))

 (with-eval-after-load 'lisp-mode
   (setq lisp-indent-function 'my/lisp-indent-function))

try

(use-package try
  :commands try)

vim

evil

 (use-package evil
   :general
   (:keymaps 'override
	      :states 'insert
	      "C-j" 'evil-next-line
	      "C-k" 'evil-previous-line
	      "M-o" 'evil-open-below)
   :init
   (setq evil-want-keybinding nil)
   :config
   (define-key evil-insert-state-map [remap evil-complete-previous] 'hippie-expand)
   (my/normal-keys
     "gD" 'xref-find-definitions-other-window
     "gd" 'xref-find-definitions)
   (progn
     (evil-set-initial-state 'pdf-view-mode 'normal)
     (evil-set-initial-state 'pdf-outline-buffer-mode 'normal)
     (evil-set-initial-state 'paradox-menu-mode 'motion)
     (evil-set-initial-state 'calendar-mode 'normal)
     (evil-set-initial-state 'process-menu-mode 'motion)
     (evil-set-initial-state 'special-mode 'motion)
     (evil-set-initial-state 'pdf-occur-buffer-mode 'normal)
     (evil-set-initial-state 'imenu-list-major-mode 'normal)
     (evil-set-initial-state 'neotree-mode 'normal)
     (evil-set-initial-state 'youdao-dictionary-mode 'motion)
     (evil-set-initial-state 'flycheck-error-list-mode 'normal)
     (evil-set-initial-state 'nov-mode 'normal)
     (evil-set-initial-state 'lsp-ui-imenu-mode 'normal)
     (evil-set-initial-state 'helpful-mode 'normal)
     (evil-set-initial-state 'Custom-mode 'normal)
     (evil-set-initial-state 'occur-mode 'normal)
     (setq evil-insert-state-cursor '(bar "LimeGreen")
	    evil-normal-state-cursor '(box "darkorange")
	    evil-visual-state-cursor '(box "LightGoldenrod")
	    evil-emacs-state-cursor '(box "MediumPurple2")
	    evil-echo-state nil)
 ;;;###autoload
     (defun my/end-of-buffer ()
	"Go to beginning of last line in buffer.
 If last line is empty, go to beginning of penultimate one
 instead."
	(interactive)
	(goto-char (point-max))
	(beginning-of-line (and (looking-at-p "^$") 0)))
 ;;;###autoload
     (evil-define-motion my/evil-goto-line (count)
	"Go to the first non-blank character of line COUNT.
 By default the last line."
	:jump t
	:type line
	(if (null count)
	    (with-no-warnings (my/end-of-buffer))
	  (goto-char (point-min))
	  (forward-line (1- count)))
	(evil-first-non-blank))

     (global-set-key [remap evil-goto-line] #'my/evil-goto-line)
     (evil-mode 1)))

evil escape

 (use-package evil-escape
   :diminish evil-escape-mode
   :init
   (with-eval-after-load 'company
	(add-hook 'evil-normal-state-entry-hook #'company-cancel))
   (setq evil-escape-key-sequence "jk"
	  evil-escape-unordered-key-sequence t)
   :config
   (evil-escape-mode))

evil anzu

(use-package evil-anzu
  :ghook ('after-init-hook #'global-anzu-mode)
  :general
  (my/leader-keys
    "rs" 'anzu-query-replace
    "rr" 'anzu-query-replace-regexp)
  :config
  (global-set-key [remap query-replace] 'anzu-query-replace)
  (global-set-key [remap query-replace-regexp] 'anzu-query-replace-regexp))

evil exchange

(use-package evil-exchange
  :general
  (my/normal-keys
    "gx" 'evil-exchange
    "gX" 'evil-exchange-cancel))

evil nerd commenter

(use-package evil-nerd-commenter
  :general
  (my/leader-keys
    ";" 'evilnc-comment-operator
    "M-;" 'evilnc-copy-and-comment-operator
    "cl" 'evilnc-comment-or-uncomment-lines
    "cp" 'evilnc-comment-or-uncomment-paragraphs))

evil matchit

(use-package evil-matchit
  :general
  (:keymaps 'override
   :states '(normal visual)
   "%" 'evilmi-jump-items)
  (:keymaps 'evil-inner-text-objects-map
   "%" 'evilmi-jump-items)
  (:keymaps 'evil-outer-text-objects-map
   "%" 'evilmi-jump-items)
  :config
  (setq evilmi-always-simple-jump t)
  (global-evil-matchit-mode))

evil surround

(use-package evil-surround
  :after evil
  :config
  (global-evil-surround-mode 1))

evil snipe

(use-package evil-snipe
  :diminish evil-snipe-local-mode
  :init
  (setq evil-snipe-show-prompt nil)
  :config
  (evil-snipe-mode 1)
  (evil-snipe-override-mode 1)
  (my/normal-keys
    "s" 'evil-snipe-s
    "S" 'evil-snipe-S))

evil goggles

(use-package evil-goggles
  :diminish evil-goggles-mode
  :after evil
  :config
  (evil-goggles-mode))

evil indent plus

(use-package evil-indent-plus
  :general
  (:keymaps 'evil-inner-text-objects-map
   "i" 'evil-indent-plus-i-indent
   "I" 'evil-indent-plus-i-indent-up
   "J" 'evil-indent-plus-i-indent-up-down)
  (:keymaps 'evil-outer-text-objects-map
   "i" 'evil-indent-plus-a-indent
   "I" 'evil-indent-plus-a-indent-up
   "J" 'evil-indent-plus-a-indent-up-down))

eivl iedit state

(use-package evil-iedit-state
  :general
  (my/leader-keys "se" 'evil-iedit-state/iedit-mode)
  :config
  (setq iedit-current-symbol-default t
	  iedit-only-at-symbol-boundaries t
	  iedit-toggle-key-default nil))

evil numbers

(use-package evil-numbers
  :general
  (my/leader-keys
    "n" '(:ignore t :wk "numbers")
    "ni" 'evil-numbers/inc-at-pt
    "nd" 'evil-numbers/dec-at-pt
    "n." 'hydra-evil-numbers/body)
  :config
  (defhydra hydra-evil-numbers (:hint nil)
    "
Evil Numbers: [_i_] increase [_d_] decrease [0..9] prefix [_q_] exit
"
    ("i" evil-numbers/inc-at-pt)
    ("d" evil-numbers/dec-at-pt)
    ("q" nil :exit t)))

evil args

(use-package evil-args
  :after evil
  :general
  (my/normal-keys
    "gL" 'evil-forward-arg
    "gh" 'evil-backward-arg
    "gK" 'evil-jump-out-args)
  :config
  (define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
  (define-key evil-outer-text-objects-map "a" 'evil-outer-arg))

evil mc

(use-package evil-mc
  :commands (evil-mc-make-cursor-here
	       evil-mc-make-all-cursors
	       evil-mc-undo-all-cursors evil-mc-pause-cursors
	       evil-mc-resume-cursors evil-mc-make-and-goto-first-cursor
	       evil-mc-make-and-goto-last-cursor
	       evil-mc-make-cursor-move-next-line
	       evil-mc-make-cursor-move-prev-line evil-mc-make-cursor-at-pos
	       evil-mc-has-cursors-p evil-mc-make-and-goto-next-cursor
	       evil-mc-skip-and-goto-next-cursor evil-mc-make-and-goto-prev-cursor
	       evil-mc-skip-and-goto-prev-cursor evil-mc-make-and-goto-next-match
	       evil-mc-skip-and-goto-next-match evil-mc-skip-and-goto-next-match
	       evil-mc-make-and-goto-prev-match evil-mc-skip-and-goto-prev-match)
  :init
  (add-hook 'prog-mode-hook #'evil-mc-mode)
  (add-hook 'text-mode-hook #'evil-mc-mode)
  (my/normal-keys
    "gr" '(:ignore t :wk "evil-mc"))
  (setq evil-mc-incompatible-minor-modes
	  '(evil-escape-mode aggressive-indent-mode flycheck-mode flyspell-mode haskell-indent-mode haskell-indentation-mode yas-minor-mode)))

evil lion

(use-package evil-lion
  :general
  (:states '(normal visual)
    "ga" 'evil-lion-left
    "gA" 'evil-lion-right)
  :config
  (setq evil-lion-left-align-key nil
	  evil-lion-right-align-key nil))

evil owl

(use-package evil-owl
  :after evil
  :config
  (setq evil-owl-register-char-limit 100
	  evil-owl-display-method 'posframe
	  evil-owl-extra-posframe-args '(:internal-border-color "gray50"
					 :internal-border-width 2
					 :width 80))
  (evil-owl-mode))

evil collection

(use-package evil-collection
  :config
  (with-eval-after-load 'reftex (evil-collection-reftex-setup))
  (with-eval-after-load 'magit (evil-collection-magit-todos-setup)))

autoload

 ;;;###autoload
 (defun my/kill-this-buffer (&optional arg)
   ;; copy from spacemacs
   "Kill the current buffer.
 If the universal prefix argument is used then kill also the window."
   (interactive "P")
   (if (window-minibuffer-p)
	(abort-recursive-edit)
     (if (equal '(4) arg)
	  (kill-buffer-and-window)
	(kill-buffer))))

 ;;;###autoload
 ;; from https://gist.github.com/3402786
 (defun my/toggle-maximize-buffer ()
   "Maximize buffer"
   (interactive)
   (if (and (= 1 (length (window-list)))
	     (assoc ?_ register-alist))
	(jump-to-register ?_)
     (progn
	(window-configuration-to-register ?_)
	(delete-other-windows))))

 ;;;###autoload
 (defun my/toggle-syntax-checking ()
   (interactive)
   (if (bound-and-true-p flycheck-mode)
	(progn
	  (flycheck-mode -1)
	  (message "Flycheck mode disabled in current buffer"))
     (progn
	(flycheck-mode 1)
	(message "Flycheck mode enabled in current buffer"))))

 ;;;###autoload
 (defun my/byte-compile-init-dir ()
   "Byte-compile all your dotfiles."
   (interactive)
   (byte-recompile-directory user-emacs-directory 0))

 ;; copy from spacemacs
 ;;;###autoload
 (defun my/alternate-buffer (&optional window)
   "Switch back and forth between current and last buffer in the
 current window."
   (interactive)
   (let ((current-buffer (window-buffer window)))
     ;; if no window is found in the windows history, `switch-to-buffer' will
     ;; default to calling `other-buffer'.
     (without-purpose (switch-to-buffer
			(cl-find-if (lambda (buffer)
				      (not (eq buffer current-buffer)))
				    (mapcar #'car (window-prev-buffers window)))))))

 ;;;###autoload
 (defun my/org-ref-open-pdf-at-point ( )
   "Open the pdf for bibtex key under point if it exists."
   (interactive)
   (require 'ivy-bibtex)
   (let* ((results (org-ref-get-bibtex-key-and-file))
	   (key (car results))
	   (pdf-file (car (bibtex-completion-find-pdf key))))
     (if (file-exists-p pdf-file)
	  (org-open-file pdf-file)
	(message "No PDF found for %s" key))))

 ;; restart emacs with --debut-init, copy from spacemacs
 ;;;###autoload
 (defun my/restart-emacs-debug-init (&optional args)
   "Restart emacs and enable debug-init."
   (interactive)
   (restart-emacs (cons "--debug-init" args)))

 ;;;###autoload
 (defun my/toggle-highlight-symbol ()
   (interactive)
   (if (bound-and-true-p highlight-symbol-mode)
	(progn
	  (highlight-symbol-mode -1)
	  (hl-line-mode 1)
	  (message "Highlight symbol mode disabled and hl-line-mode enabled in current buffer"))
     (progn
	(highlight-symbol-mode 1)
	(hl-line-mode -1)
	(message "Highlight symbol mode enabled and hl-line-mode disabled in current buffer"))))

 ;;;###autoload
 (defun my/toggle-flyspell ()
   (interactive)
   (if (bound-and-true-p flyspell-mode)
	(progn
	  (flyspell-mode -1)
	  (message "Flyspell mode disabled in current buffer"))
     (progn
	(flyspell-mode 1)
	(message "Flyspell mode enabled in current buffer"))))
 ;;;###autoload
 (defun my/toggle-color-identifiers ()
   (interactive)
   (if (bound-and-true-p color-identifiers-mode)
	(progn
	  (color-identifiers-mode -1)
	  (message "Color identifiers mode disabled in current buffer"))
     (progn
	(color-identifiers-mode 1)
	(message "Color identifiers mode enabled in current buffer"))))

 ;;;###autoload
 (defun my/show-current-time ()
   ;; show current time in minibuffer
   (interactive)
   (message (current-time-string)))

 ;;;###autoload
 (defun my/copy-file-name-to-clipboard ()
   "Copy the current buffer file name to the clipboard."
   (interactive)
   (let ((filename (if (equal major-mode 'dired-mode)
			default-directory
		      (buffer-file-name))))
     (when filename
	(kill-new filename)
	(message "Copied buffer file name '%s' to the clipboard." filename))))

defaults

setting related in build-in features

 (prefer-coding-system 'utf-8)
 (set-default-coding-systems 'utf-8)
 ;; replace "yes" and "no" by "y" and "n"
 (defalias 'yes-or-no-p 'y-or-n-p)
 ;;display-time-mode
 (setq display-time-24hr-format t
	display-time-default-load-average nil
	display-time-day-and-date t)
 ;; (display-time-mode t)
 ;;
 (column-number-mode t)
 (size-indication-mode t)
 (blink-cursor-mode 0)
 (add-to-list 'default-frame-alist '(fullscreen . maximized))
 ;; auto save
 (auto-save-visited-mode t)
 (setq  auto-save-default t
	 auto-save-timeout 20
	 auto-save-interval 20)
 (defvar emacs-autosave-directory
   (concat user-emacs-directory "autosaves/"))

 (unless (file-exists-p emacs-autosave-directory)
   (make-directory emacs-autosave-directory))

 (setq auto-save-file-name-transforms
	`((".*" ,emacs-autosave-directory t)))
 ;; backup
 (setq backup-directory-alist '(("." . "~/.emacs.d/backups"))
	kept-new-versions 10
	kept-old-versions 0
	delete-old-versions t
	backup-by-copying t
	vc-make-backup-files t)
 (setq delete-by-moving-to-trash t)
 ;; scratch buffer message
 (setq initial-scratch-message ";; Better to run than curse the road.\n")
 ;; scratch major mode
 (setq initial-major-mode 'emacs-lisp-mode)
 ;; save system clipboard contents to emacs kill ring
 (setq save-interprogram-paste-before-kill t)
 ;; change emacs frame title
 (setq frame-title-format
	'("" invocation-name ": " (:eval (replace-regexp-in-string
					  "^ +" "" (buffer-name)))))
 (use-package desktop
   :config
   (add-to-list 'desktop-globals-to-save 'register-alist)
   (setq desktop-lazy-verbose nil
	  desktop-restore-eager 15)
   (desktop-save-mode 1))

 ;; (use-package hl-line
 ;;   :init
 ;;   (add-hook 'prog-mode-hook (lambda () (hl-line-mode t)))
 ;;   (add-hook 'text-mode-hook (lambda () (hl-line-mode t))))
 ;; text-scale
 (defhydra hydra-text-scale ()
   "text-scale"
   ("i" text-scale-increase "in")
   ("o" text-scale-decrease "out")
   ("r" (text-scale-set 0) "reset")
   ("q" nil "quit"))
 (my/leader-keys
   "xz" 'hydra-text-scale/body)

 ;; window-scale
 (defhydra hydra-window-scale ()
   "window-scale"
   ("i" (lambda () (interactive) (enlarge-window-horizontally 10)) "in")
   ("o" (lambda () (interactive) (shrink-window-horizontally 10)) "out")
   ("I" (lambda () (interactive) (enlarge-window 5)) "IN")
   ("O" (lambda () (interactive) (shrink-window 5)) "OUT")
   ("r" balance-windows "reset")
   ("q" nil "quit"))
 (my/leader-keys
   "wz" 'hydra-window-scale/body)

 ;; build-in modes
 (use-package eldoc
   :ghook ('(emacs-lisp-mode-hook
	      lisp-interaction-mode-hook
	      ielm-mode-hook
	      eval-expression-minibuffer-setup-hook)))

 (use-package display-line-numbers
   :if (version<= "26.1" emacs-version)
   :ghook ('after-init-hook #'global-display-line-numbers-mode)
   :general
   (my/leader-keys
     "tl" 'my/toggle-line-numbers-type)
   :config
   (setq display-line-numbers-type 'visual)
 ;;;###autoload
   (defun my/toggle-line-numbers-type ()
     (interactive)
     (if (eq display-line-numbers t)
	  (progn
	    (setq display-line-numbers 'visual)
	    (message "show visual line numbers"))
	(progn
	  (setq display-line-numbers t)
	  (message "Show absolute line numbers")))))

 (use-package prettify-symbols-mode
   :ensure nil
   :ghook ('after-init-hook #'global-prettify-symbols-mode)
   :init
   (setq prettify-symbols-unprettify-at-point 'right-edge))

 (use-package recentf
   :ensure nil
   :init
   (add-hook 'find-file-hook (lambda () (unless recentf-mode
						 (recentf-mode)
						 (recentf-track-opened-file))))
   :config
   (progn
     (setq recentf-max-saved-items 2000
	    recentf-auto-cleanup 'never
	    recentf-exclude '("/.emacs.d/pyim/" "/.elfeed/"))
     (recentf-mode 1)))

 (use-package autorevert
   :ensure nil
   :diminish auto-revert-mode
   :config
   (setq auto-revert-interval 0.5)
   (global-auto-revert-mode))

 (use-package server
   :ensure nil
   :ghook ('after-init-hook #'server-start))

 (use-package winner
   :ensure nil
   :init
   (my/leader-keys
     "wu" 'winner-undo
     "wU" 'winner-redo)
   :config
   (setq winner-boring-buffers
	  '("*Completions*"
	    "*Compile-Log*"
	    "*inferior-lisp*"
	    "*Fuzzy Completions*"
	    "*Apropos*"
	    "*Help*"
	    "*cvs*"
	    "*Buffer List*"
	    "*Ibuffer*"
	    "*esh command on file*"
	    "*Youdao Dictionary*"
	    "*PDF-Occur*"
	    "*Google Translate*"
	    "*magit.*"
	    ))
   (winner-mode))

 (use-package savehist
   :ensure nil
   :config
   (progn
     (setq savehist-autosave-interval 10)
     (savehist-mode 1)
     ;; save shell history https://oleksandrmanzyuk.wordpress.com/2011/10/23/a-persistent-command-history-in-emacs/
     (defun comint-write-history-on-exit (process event)
	"Write comint history of PROCESS when EVENT happened to a file specified in buffer local var 'comint-input-ring-file-name' (defined in turn-on-comint-history)."
	(comint-write-input-ring)
	(let ((buf (process-buffer process)))
	  (when (buffer-live-p buf)
	    (with-current-buffer buf
	      (insert (format "\nProcess %s %s" process event))))))
     (defun turn-on-comint-history ()
	"Setup comint history.
 When comint process started set buffer local var
 'comint-input-ring-file-name', so that a file name is specified to write
 and read from comint history.

 That 'comint-input-ring-file-name' is buffer local is determined by the
 4th argument to 'add-hook' below.  And localness is important, because
 otherwise 'comint-write-input-ring' will find mentioned var nil."
	(let ((process (get-buffer-process (current-buffer))))
	  (when process
	    (setq comint-input-ring-file-name
		  (format "~/.emacs.d/inferior-%s-history"
			  (process-name process)))
	    (comint-read-input-ring)
	    (set-process-sentinel process
				  #'comint-write-history-on-exit))))
     (defun mapc-buffers (fn)
	(mapc (lambda (buffer)
		(with-current-buffer buffer
		  (funcall fn)))
	      (buffer-list)))
     (defun comint-write-input-ring-all-buffers ()
	(mapc-buffers 'comint-write-input-ring))
     (add-hook 'inferior-python-mode-hook 'turn-on-comint-history nil nil)
     (add-hook 'kill-buffer-hook 'comint-write-input-ring)
     (add-hook 'kill-emacs-hook 'comint-write-input-ring-all-buffers)))

 (use-package ispell
   :ensure nil
   :config
   (progn
     (setq ispell-program-name "aspell"
	    ispell-silently-savep t
	    ispell-look-command "/bin/grep"
	    ispell-look-options "-Ei")))

 (defun my/ispell-lookup-words (word &optional lookup-dict)
   "Look up WORD in optional word-list dictionary LOOKUP-DICT.
 A `*' serves as a wild card.  If no wild cards, `look' is used if it exists.
 Otherwise the variable `ispell-grep-command' contains the command
 \(usually \"grep\") used to search for the words.

 Optional second argument contains the dictionary to use; the default is
 `ispell-alternate-dictionary', overridden by `ispell-complete-word-dict'
 if defined."
   ;; We don't use the filter for this function, rather the result is written
   ;; into a buffer.  Hence there is no need to save the filter values.
   (if (null lookup-dict)
	(setq lookup-dict (or ispell-complete-word-dict
			      ispell-alternate-dictionary)))

   (if lookup-dict
	(unless (file-readable-p lookup-dict)
	  (error "lookup-words error: Unreadable or missing plain word-list %s."
		 lookup-dict))
     (error (concat "lookup-words error: No plain word-list found at system"
		     "default locations.  "
		     "Customize `ispell-alternate-dictionary' to set yours.")))

   (let* ((process-connection-type ispell-use-ptys-p)
	   (wild-p (string-match "\\*" word))
	   (look-p (and ispell-look-p	; Only use look for an exact match.
			(or ispell-have-new-look (not wild-p))))
	   (prog (if look-p ispell-look-command ispell-grep-command))
	   (args (if look-p ispell-look-options ispell-grep-options))
	   status results loc)
     (with-temp-buffer
	;; (message "Starting \"%s\" process..." (file-name-nondirectory prog))
	(if look-p
	    nil
	  (insert "^" word)
	  ;; When there are no wildcards, append one, for consistency
	  ;; with `look' behavior.
	  (unless wild-p (insert "*"))
	  (insert "$")
	  ;; Convert * to .*
	  (while (search-backward "*" nil t) (insert "."))
	  (setq word (buffer-string))
	  (erase-buffer))
	(setq status (apply 'ispell-call-process prog nil t nil
			    (nconc (if (and args (> (length args) 0))
				       (list args)
				     (if look-p nil
				       (list "-e")))
				   (list word)
				   (if lookup-dict (list lookup-dict)))))
	;; `grep' returns status 1 and no output when word not found, which
	;; is a perfectly normal thing.
	(if (stringp status)
	    (error "error: %s exited with signal %s"
		   (file-name-nondirectory prog) status)
	  ;; Else collect words into `results' in FIFO order.
	  (goto-char (point-max))
	  ;; Assure we've ended with \n.
	  (or (bobp) (= (preceding-char) ?\n) (insert ?\n))
	  (while (not (bobp))
	    (setq loc (point))
	    (forward-line -1)
	    (push (buffer-substring-no-properties (point)
						  (1- loc))
		  results))))
     (if (and results (string-match ".+: " (car results)))
	  (error "%s error: %s" ispell-grep-command (car results)))
     results))

 (advice-add 'ispell-lookup-words :override #'my/ispell-lookup-words)

 (use-package calendar
   :ensure nil
   :commands calendar
   :config
   ;; keybindings are copied from evil-collection
   (my/normal-keys
     :keymaps 'calendar-mode-map
     ;; motion
     "h" 'calendar-backward-day
     "j" 'calendar-forward-week
     "k" 'calendar-backward-week
     "l" 'calendar-forward-day
     "0" 'calendar-beginning-of-week
     "^" 'calendar-beginning-of-week
     "$" 'calendar-end-of-week
     "[" 'calendar-backward-year
     "]" 'calendar-forward-year
     "M-<" 'calendar-beginning-of-year
     "M->" 'calendar-end-of-year
     "(" 'calendar-beginning-of-month
     ")" 'calendar-end-of-month
     "<" 'calendar-scroll-right
     ">" 'calendar-scroll-left
     "C-b" 'calendar-scroll-right-three-months
     "C-f" 'calendar-scroll-left-three-months
     "{" 'calendar-backward-month
     "}" 'calendar-forward-month
     "C-k" 'calendar-backward-month
     "C-j" 'calendar-forward-month
     "gk" 'calendar-backward-month
     "gj" 'calendar-forward-month

     ;; visual
     "v" 'calendar-set-mark

     ;; goto
     "." 'calendar-goto-today
     "gd" 'calendar-goto-date ; "gd" in evil-org-agenda, "gd" in Emacs.
     ;; "gD" 'calendar-other-month ; Not very useful if we have `calendar-goto-date'.

     ;; diary
     "D" 'diary-view-other-diary-entries
     "d" 'diary-view-entries
     "m" 'diary-mark-entries
     "s" 'diary-show-all-entries

     "u" 'calendar-unmark
     "x" 'calendar-mark-holidays

     ;; show
     "gm" 'calendar-lunar-phases ; "gm" in evil-org-agenda.
     "gs" 'calendar-sunrise-sunset ; "gs" in evil-org-agenda
     "gh" 'calendar-list-holidays ; "gh" in evil-org-agenda.
     "ga" 'org-calendar-goto-agenda ; "gc" in evil-org-agenda.
     "r" 'calendar-cursor-holidays

     ;; refresh
     "gr" 'calendar-redraw

     "g?" 'calendar-goto-info-node
     "?" 'calendar-goto-info-node ; Search is not very useful.
     "M-=" 'calendar-count-days-region

     ;; quit
     "q" 'calendar-exit))

 (use-package imenu
   :ensure nil
   :general
   (my/leader-keys
     "ji" 'imenu))

 (use-package image-mode
   :ensure nil
   :mode (".jpg\\'" . image-mode)
   :config
   (progn
     (add-hook 'image-mode-hook (lambda() (display-line-numbers-mode -1)))
     (setq image-animate-loop t)
     (my/leader-keys-major-mode
	:keymaps 'image-mode-map
	"aa" 'image-toggle-animation
	"a+" 'image-increase-speed
	"a-" 'image-decrease-speed
	"ar" 'image-reset-speed
	"gn" 'image-next-file
	"gN" 'image-previous-file
	"t+" 'image-increase-size
	"t-" 'image-decrease-size
	"tf" 'image-mode-fit-frame
	"tr" 'image-transform-reset
	"th" 'image-transform-fit-to-height
	"tw" 'image-transform-fit-to-width
	"ts" 'image-transform-set-scale
	"tr" 'image-transform-rotation)
     (my/leader-keys-major-mode
	:keymaps 'image-mode-map
	:major-modes t
	"a" '(:ignore t :wk "animate")
	"g" '(:ignore t :wk "goto file")
	"t" '(:ignore t :wk "transform/resize"))
     (my/normal-keys
	:keymaps 'image-mode-map
	"h" 'image-backward-hscroll
	"j" 'image-next-line
	"k" 'image-previous-line
	"l" 'image-forward-hscroll)))

 (use-package saveplace
   :ensure nil
   :config
   (save-place-mode))

 (use-package custom
   :ensure nil
   :general
   (my/normal-keys
     :keymaps 'custom-mode-map
     "n" 'widget-forward
     "p" 'widget-backward
     "C-o" 'Custom-goto-parent
     "q" 'Custom-buffer-done))

 (use-package midnight
   :init
   (add-hook 'midnight-hook #'recentf-cleanup)
   :config
   (setq clean-buffer-list-kill-regexps '("^.*")
	  midnight-period 7200
	  clean-buffer-list-delay-special 259200)
   (midnight-mode 1))

 (use-package find-file
   :ensure nil
   :init
   (my/leader-keys
     "fO" 'ff-find-other-file)
   (defvar org-other-file-alist
     '(("\\.org\\'" (".el" ".pdf"))))
   (defvar el-other-file-alist
     '(("\\.el\\'" (".org"))))
   (defvar pdf-other-file-alist
     '(("\\.pdf\\'" (".tex" ".org"))))
   (defvar latex-other-file-alist
     '(("\\.tex\\'" (".pdf"))))
   (add-hook 'org-mode-hook
	      (lambda () (setq ff-other-file-alist 'org-other-file-alist)))
   (add-hook 'emacs-lisp-mode-hook
	      (lambda () (setq ff-other-file-alist 'el-other-file-alist)))
   (add-hook 'LaTeX-mode-hook
	      (lambda () (setq ff-other-file-alist 'latex-other-file-alist)))
   (add-hook 'pdf-view-mode-hook
	      (lambda () (setq ff-other-file-alist 'pdf-other-file-alist))))

 (use-package replace
   :ensure nil
   :general
   (my/normal-keys
     :keymaps 'occur-mode-map
     "RET" 'occur-mode-goto-occurrence-other-window
     "q" 'quit-window))
 ;; key bindings

 (my/all-states-keys
   "C-e" 'move-end-of-line)

 (my/leader-keys
   "!" 'shell-command)

 ;; Universal argument
 (my/leader-keys
   "u" 'universal-argument)

 ;; applications --------------------------------------------------------------
 (my/leader-keys
   ;; "au" 'undo-tree-visualize
   "ac" 'calendar
   "at" 'my/show-current-time
   "aP" 'list-processes)
 ;; buffer --------------------------------------------------------------------
 (my/leader-keys
   "bd" 'my/kill-this-buffer
   "bn" 'next-buffer
   "bp" 'previous-buffer
   "br" 'revert-buffer
   "TAB" 'my/alternate-buffer
   "bx" 'kill-buffer-and-window
   )
 ;; file ----------------------------------------------------------------------
 (my/leader-keys
   "fs" 'save-buffer
   "fn" 'my/copy-file-name-to-clipboard)
 ;; frame
 (my/leader-keys
   "Fd" 'delete-frame
   "Fn" 'make-frame
   "Fo" 'other-frame)
 ;; help ----------------------------------------------------------------------
 (my/leader-keys
   "hdb" 'describe-bindings
   "hdc" 'describe-char
   "hdf" 'describe-function
   "hdk" 'describe-key
   "hdm" 'describe-mode
   "hdp" 'describe-package
   "hdt" 'describe-theme
   "hdv" 'describe-variable
   "hn"  'view-emacs-news
   )
 ;; quit ---------------------------------------------------------------------
 (my/leader-keys
   "qs" 'save-buffers-kill-emacs
   "qr" 'restart-emacs
   "qd" 'my/restart-emacs-debug-init)
 ;; window -------------------------------------------------------------------
 (my/leader-keys
   "wv" 'split-window-right
   "wV" 'my/split-window-right-and-focus
   "ws" 'split-window-below
   "wS" 'my/split-window-below-and-focus
   "w=" 'balance-windows-area
   "wb" 'balance-windows
   "wm" 'my/toggle-maximize-buffer
   "wd" 'delete-window)
 ;; text
 (my/leader-keys
   "xp" 'clipboard-yank
   "xy" 'clipboard-kill-ring-save
   "xc" 'clipboard-kill-region)
 ;; frequently accessed files
 (defhydra hydra-frequently-accessed-files (:exit t)
   "files"
   ("a" (lambda () (interactive) (find-file "~/Dropbox/document/org/appts/appts.org")) "appts.org")
   ("o" (lambda () (interactive) (find-file "~/Dropbox/document/org/main.org")) "main.org")
   ("n" (lambda () (interactive) (find-file "~/Dropbox/document/org/references/ref-notes.org")) "ref-noter.org")
   ("i" (lambda () (interactive) (find-file "~/.emacs.d/init.el")) "init.el")
   ("l" (lambda () (interactive) (find-file "~/Dropbox/document/ledger/ledger.ledger")) "ledger.ledger")
   ("d" (lambda () (interactive) (find-file "~/.dotfiles/README.md")) "dotfiles")
   ("M-d" (lambda () (interactive) (deer "~/Dropbox/")) "Dropbox")
   ("c" (lambda () (interactive) (find-file "~/Dropbox/document/org/capture/capture.org")) "capture.org")
   ("q" nil "quit"))
 (my/leader-keys
   "fo" 'hydra-frequently-accessed-files/body)

 ;;;###autoload
 (defun my/split-window-right-and-focus ()
   "Split the window horizontally and focus the new window."
   (interactive)
   (split-window-right)
   (windmove-right)
   (when (and (boundp 'golden-ratio-mode)
	       (symbol-value golden-ratio-mode))
     (golden-ratio)))

 ;;;###autoload
 (defun my/split-window-below-and-focus ()
   "Split the window vertically and focus the new window."
   (interactive)
   (split-window-below)
   (windmove-down)
   (when (and (boundp 'golden-ratio-mode)
	       (symbol-value golden-ratio-mode))
     (golden-ratio)))

setting about garbage collection

(defun my/defer-garbage-collection ()
  (setq gc-cons-threshold most-positive-fixnum))

(defun my/restore-garbage-collection ()
  (setq gc-cons-threshold 800000))

(add-hook 'minibuffer-setup-hook #'my/defer-garbage-collection)
(add-hook 'minibuffer-exit-hook #'my/restore-garbage-collection)

start-up profiler

 (use-package esup
   :commands esup
   :init
   (progn
     (my/leader-keys
	"ae" 'esup))
   :config
   (my/motion-keys
     :keymaps 'esup-mode-map
     "n" 'esup-next-result
     "p" 'esup-previous-result))

 (use-package benchmark-init
   :commands (benchmark-init/show-durations-tree
	       benchmark-init/durations-tree)
   :init
   (progn
     (my/leader-keys
	"ab" '(:ignore t :which-key "benchmark")
	"abt" 'benchmark-init/show-durations-tabulated
	"abr" 'benchmark-init/show-durations-tree))
   :config
   ;; To disable collection of benchmark data after init is done.
   (add-hook 'after-init-hook 'benchmark-init/deactivate))

UI

GUI frame

;; Suppress GUI features
(setq use-file-dialog nil)
(setq use-dialog-box nil)
(setq inhibit-startup-screen t)
(setq inhibit-startup-echo-area-message t)

;; Show a marker in the left fringe for lines not in the buffer
(setq-default indicate-empty-lines t)

beacon

(use-package beacon
  :diminish beacon-mode
  :config
  (setq beacon-blink-when-window-scrolls nil
	  beacon-dont-blink-major-modes '(t pdf-view-mode)
	  beacon-size 10)
  (beacon-mode 1))

rainbow delimiters

(use-package rainbow-delimiters
  :commands rainbow-delimiters-mode
  :init
  (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
  (add-hook 'text-mode-hook 'rainbow-delimiters-mode))

highlight parentheses

(use-package highlight-parentheses
  :diminish highlight-parentheses-mode
  :ghook ('prog-mode-hook #'highlight-parentheses-mode)
  :config
  (setq hl-paren-delay 0.2)
  (setq hl-paren-colors '("Springgreen3"
			    "IndianRed1"
			    "IndianRed3"
			    "IndianRed4"))
  (set-face-attribute 'hl-paren-face nil :weight 'ultra-bold))

highligh indeantation

(use-package highlight-indentation
    :diminish highlight-indentation-mode
    :commands highlight-indentation-mode
    :init
    (add-hook 'prog-mode-hook #'highlight-indentation-mode))

highligh numbers

(use-package highlight-numbers
  :commands highlight-numbers-mode
  :init
  (add-hook 'prog-mode-hook 'highlight-numbers-mode))

highlight symbol

(use-package highlight-symbol
  :diminish highlight-symbol-mode
  :general
  (my/leader-keys
    "tha" 'my/toggle-highlight-symbol
    "sh" 'highlight-symbol-at-point
    "sr" 'highlight-symbol-remove-all)
  (:states '(normal visual motion)
   "M-]" 'highlight-symbol-next
   "M-[" 'highlight-symbol-prev
   "M-'" 'highlight-symbol-query-replace)
  :config
  (setq highlight-symbol-idle-delay 0.5
	  highlight-symbol-occurrence-message '(explicit nivigation temporary)))

color identifiers mode

(use-package color-identifiers-mode
  :diminish color-identifiers-mode
  :commands color-identifiers-mode
  :general
  (my/leader-keys
    "thi" 'my/toggle-color-identifiers))

which key

which key

(use-package which-key
  :diminish which-key-mode
  :config
  (progn
    (setq which-key-idle-secondary-delay 0
	    which-key-sort-order 'which-key-key-order-alpha)
    (my/leader-keys
     "a" '(:ignore t :which-key "applications")
     "ao" '(:ignore t :which-key "org")
     "aof" '(:ignore t :which-key "feed")
     "aok" '(:ignore t :which-key "clock")
     "b" '(:ignore t :which-key "buffers")
     "c" '(:ignore t :which-key "comments")
     "C" '(:ignore t :which-key "Capture")
     "e" '(:ignore t :which-key "errors")
     "f" '(:ignore t :which-key "files")
     "F" '(:ignore t :which-key "Frames")
     "g" '(:ignore t :which-key "git/vc")
     "gf" '(:ignore t :which-key "files")
     "h" '(:ignore t :which-key "help")
     "i" '(:ignore t :which-key "insert")
     "iS" '(:ignore t :which-key "auto-yas")
     "j" '(:ignore t :which-key "jump")
     "p" '(:ignore t :which-key "projects")
     "ps" '(:ignore t :which-key "search")
     "q" '(:ignore t :which-key "quit")
     "r" '(:ignore t :which-key "regs/rings/replace")
     "s" '(:ignore t :which-key "search")
     "M-s" '(:ignore t :which-key "Spell/Grammar")
     "t" '(:ignore t :which-key "toggles")
     "th" '(:ignore t :which-key "highlight")
     "T" '(:ignore t :which-key "Themes")
     "w" '(:ignore t :which-key "windows")
     "wp" '(:ignore t :which-key "popwin")
     "x" '(:ignore t :which-key "text")
     "xS" '(:ignore t :which-key "Synosaurus")
     "z" '(:ignore t :which-key "zoom"))
    (which-key-mode)))

which key posframe

(use-package which-key-posframe
  :if (and (window-system) (version<= "26.1" emacs-version))
  :after (which-key posframe)
  :config
  (setq which-key-posframe-border-width 2)
  (which-key-posframe-mode))

popwin

 (use-package popwin
     :config
     (progn
	(my/leader-keys
	 "wpm" 'popwin:messages
	 "wpp" 'popwin:close-popup-window)
	(popwin-mode 1)
	;; don't use default value but manage it ourselves
	(setq popwin:special-display-config nil)

	;; buffers that we manage
	(push '("*Help*"                 :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*Process List*"         :dedicated t :position bottom :stick t :noselect nil :height 0.4) popwin:special-display-config)
	(push '("*compilation*"          :dedicated t :position bottom :stick t :noselect t   :height 0.4) popwin:special-display-config)
	(push '("*Shell Command Output*" :dedicated t :position bottom :stick t :noselect nil            ) popwin:special-display-config)
	(push '("*Async Shell Command*"  :dedicated t :position bottom :stick t :noselect nil            ) popwin:special-display-config)
	(push '(" *undo-tree*"           :dedicated t :position right  :stick t :noselect nil :width   60) popwin:special-display-config)
	(push '("*undo-tree Diff*"       :dedicated t :position bottom :stick t :noselect nil :height 0.3) popwin:special-display-config)
	(push '("*ert*"                  :dedicated t :position bottom :stick t :noselect nil            ) popwin:special-display-config)
	(push '("*grep*"                 :dedicated t :position bottom :stick t :noselect nil            ) popwin:special-display-config)
	(push '("*nosetests*"            :dedicated t :position bottom :stick t :noselect nil            ) popwin:special-display-config)
	(push '("^\*WoMan.+\*$" :regexp t             :position bottom                                   ) popwin:special-display-config)
	(push '("*Google Translate*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*frequencies*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*Synonyms List*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*Ledger Report*"     :dedicated t :position right :stick t :noselect nil   :width 0.6) popwin:special-display-config)
	(push '("\*Outline.*\*"     :regexp t :dedicated t :position right :stick t :noselect nil   :width 0.3) popwin:special-display-config)
	(push '("*PDF-Occur*"     :dedicated t :position right :stick t :noselect nil   :width 0.4) popwin:special-display-config)
	(push '("*WordNut*"     :dedicated t :position right :stick t :noselect nil   :width 0.5) popwin:special-display-config)
	(push '("*Synonyms List*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*Calendar*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.4) popwin:special-display-config)
	(push '("*Youdao Dictionary*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	(push '("*Anaconda*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	(push '(flycheck-error-list-mode     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	(push '("*Compile-Log*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	(push '("*Apropos*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	(push '("*TeX Help*"     :dedicated t :position bottom :stick t :noselect nil   :height 0.25) popwin:special-display-config)
	))

zoom frm

(use-package zoom-frm
  :commands (zoom-frm-unzoom
	       zoom-frm-out
	       zoom-frm-in)
  :init
  (progn
    (defhydra hydra-zoom-frm ()
	 "zoom-frm"
	 ("i" zoom-frm-in "in")
	 ("o" zoom-frm-out "out")
	 ("0" zoom-frm-unzoom "reset")
	 ("q" nil "quit")
	 )
    (my/leader-keys
     "Fz" 'hydra-zoom-frm/body)))

hide mode line

(use-package hide-mode-line
  :commands my/toggle-hide-mode-line
  :init
  (my/leader-keys
    "tm" 'my/toggle-hide-mode-line))

;;;###autoload
(defun my/toggle-hide-mode-line ()
  (interactive)
  (hide-mode-line-mode (if hide-mode-line-mode -1 +1))
  (unless hide-mode-line-mode
    (redraw-display)))

window purpose

(use-package window-purpose
  :ghook ('after-init-hook #'purpose-mode)
  :general
  (my/leader-keys
    "rb"    'purpose-switch-buffer-with-purpose
    "rB"    'switch-buffer-without-purpose
    "rd"    'purpose-toggle-window-purpose-dedicated
    "r M-d" 'purpose-toggle-window-buffer-dedicated
    "rD"    'purpose-delete-non-dedicated-windows
    "rl"    'purpose-load-window-layout
    "rp"    'purpose-switch-buffer-with-some-purpose
    "rP"    'purpose-set-window-purpose
    "rf"    'purpose-load-window-layout-file)
  :config
  (setq purpose-default-layout-file (concat user-emacs-directory "layouts")
	  default-file-purpose 'general)
  (add-to-list 'purpose-user-mode-purposes '(python-mode . py))
  (add-to-list 'purpose-user-mode-purposes '(inferior-python-mode . py-repl))
  (add-to-list 'purpose-user-mode-purposes '(org-mode . org))
  (add-to-list 'purpose-user-mode-purposes '(pdf-view-mode . pdf))
  (global-set-key [remap ivy-switch-buffer] 'my/ivy-switch-buffer)
  (purpose-compile-user-configuration)
  (defalias 'ranger-find-file-without-purpose
    (without-purpose-command #'ranger-find-file))

(global-set-key [remap ranger-find-file] #'ranger-find-file-without-purpose))

;;;###autoload
(defun my/ivy-switch-buffer ()
  (interactive)
  (without-purpose (ivy-switch-buffer)))

;;;###autoload
(defun my/ranger-close ()
  (interactive)
  (without-purpose (ranger-close)))

(global-set-key [remap ranger-close] 'my/ranger-close)

spacemacs purpose popwin

(use-package spacemacs-purpose-popwin
  :ensure nil
  :load-path "site-lisp/spacemacs-purpose-popwin/"
  :after window-purpose
  :config
  (pupo-mode))

spaceline

 (use-package spaceline-config
   :ensure spaceline
   :init
   (progn
     (setq spaceline-highlight-face-func 'spaceline-highlight-face-evil-state
	    powerline-default-separator 'slant
	    spaceline-purpose-hide-if-not-dedicated t
	    spaceline-window-numbers-unicode nil
	    spaceline-workspace-numbers-unicode nil
	    winum-auto-setup-mode-line nil
	    anzu-cons-mode-line-p nil))
   :config
   (spaceline-compile)
   (spaceline-helm-mode t)
   (spaceline-toggle-buffer-encoding-off)
   (spaceline-toggle-minor-modes-off)
   (spaceline-toggle-buffer-encoding-abbrev-off)
   (spaceline-toggle-major-mode-off)
   (spaceline-toggle-input-method-off)
   (spaceline-define-segment my/pomodoro
     (when (featurep 'pomodoro)
	pomodoro-mode-line-string))
   (spaceline-spacemacs-theme '(my/pomodoro :when active :tight t)))

my modeline

 (setq winum-auto-setup-mode-line nil
	eyebrowse-mode-line-left-delimiter ""
	eyebrowse-mode-line-right-delimiter "")
 (defun my--pdfview-page-number ()
   (format "(%d/%d)"
	    (eval `(pdf-view-current-page))
	    (pdf-cache-number-of-pages)))

 (defvar my--mode-line-line-column
   '(:eval (if (eq major-mode 'pdf-view-mode)
		(my--pdfview-page-number)
	      (if (and
		   (boundp 'column-number-indicator-zero-based)
		   (not column-number-indicator-zero-based))
		  "(%l:%2c)"
		"(%l:%2c)"))))

 (defvar my--window-purpose
   '(:eval (when (and (bound-and-true-p purpose-mode)
		       (or (purpose-window-purpose-dedicated-p)
			   (window-dedicated-p)))
	      (propertize (substring (purpose--modeline-string) 2 -1)))))

 (defvar my--mode-line-pomodoro
   '(:eval
     (if (eq my--selected-window (selected-window))
	  `,pomodoro-mode-line-string)))

 (defvar my--mode-line-eyebrowse
   '(:eval (eyebrowse-mode-line-indicator)))

 (defvar my--mode-line-winum
   '(:eval (winum-get-number-string)))

 (defvar my--mode-line-evil-tag
   '(:eval evil-mode-line-tag))

 (setq-default mode-line-format
   (list
    mode-line-front-space
    "["
    my--mode-line-eyebrowse
    "|"
    my--mode-line-winum
    "]"
    " %*"
    my--mode-line-evil-tag
     ;; the buffer name
    "%b "
     ;; line and column
    my--mode-line-line-column
    '(vc-mode vc-mode)
     mode-line-process
     ;;global-mode-string, org-timer-set-timer in org-mode need this
     "%M"
     my--window-purpose
     " "
     my--mode-line-pomodoro
     ))

 (defvar my--selected-window nil)

 (defun my--record-selected-window ()
   (setq my--selected-window (selected-window)))

 (defun my--update-all ()
   (force-mode-line-update t))

 (add-hook 'post-command-hook 'my--record-selected-window)

 (add-hook 'buffer-list-update-hook 'my--update-all)

ranbow mode

(use-package rainbow-mode
  :commands rainbow-mode
  :init
  (my/leader-keys
    "tc" 'rainbow-mode))

pretty hydra

(use-package pretty-hydra
  :init
  (my/leader-keys
    "t." 'hydra-toggles/body)
  :config
  (pretty-hydra-define hydra-toggles
  (:hint nil :color amaranth :quit-key "q")
  ("Basic"
   (("n" display-line-numbers-mode "line number" :toggle t)
    ("N" my/toggle-line-numbers-type "line number type")
    ("L" linum-mode "Exact line number" :toggle t)
    ("w" whitespace-mode "whitespace" :toggle t)
    ("r" rainbow-mode "rainbow" :toggle t))
   "Highlight"
   (("S" highlight-symbol-mode "symbol" :toggle t)
    ("l" hl-line-mode "line" :toggle t)
    ("t" hl-todo-mode "todo" :toggle t)
    ("i" color-identifiers-mode "identifiers" :toggle t))
   "UI"
   (("m" hide-mode-line-mode "mode line" :toggle t))
   "Coding"
   (("p" smartparens-global-mode "smartparens" :toggle t)
    ("P" smartparens-global-strict-mode "smartparens strict" :toggle t)
    ("c" flycheck-mode "flycheck" :toggle t)
    ("s" flyspell-mode "flyspell" :toggle t)))))

all the icons related

all the icons

(use-package all-the-icons
  :init
  (add-hook 'after-init-hook (lambda () (require 'all-the-icons)))
  :config
  (setq all-the-icons-scale-factor 1.0))

all the icons ivy

 (use-package all-the-icons-ivy
   :after (ivy all-the-icons)
   :init
   (add-hook 'counsel-projectile-mode-hook 'all-the-icons-ivy-setup)
   (add-hook 'ivy-mode-hook 'all-the-icons-ivy-setup)
   :config
   (progn
     (defun all-the-icons-ivy-file-transformer (s)
	"Return a candidate string for filename S preceded by an icon."
	(format "%s %s"
		(propertize "\t" 'display (all-the-icons-ivy-icon-for-file s))
		s))
     (defun all-the-icons-ivy--buffer-transformer (b s)
	"Return a candidate string for buffer B named S preceded by an icon.
 Try to find the icon for the buffer's B `major-mode'.
 If that fails look for an icon for the mode that the `major-mode' is derived from."
	(let ((mode (buffer-local-value 'major-mode b)))
	  (format "%s %s"
		  (propertize "\t" 'display (or
					     (all-the-icons-ivy--icon-for-mode mode)
					     (all-the-icons-ivy--icon-for-mode (get mode 'derived-mode-parent))))
		  (all-the-icons-ivy--buffer-propertize b s))))
     (all-the-icons-ivy-setup)))

all the icons dired

(use-package all-the-icons-dired
  :after ranger
  :init
  (add-hook 'ranger-mode-hook 'all-the-icons-dired-mode)
  (add-hook 'dired-mode-hook 'all-the-icons-dired-mode))

hl todo

(use-package hl-todo
  :commands hl-todo-mode
  :init
  (add-hook 'prog-mode-hook 'hl-todo-mode)
  (add-hook 'LaTeX-mode-hook 'hl-todo-mode))

universal

restart-emacs

(use-package restart-emacs
  :config
  (setq restart-emacs-restore-frame t)
  :general
  (my/leader-keys
    "qr" 'restart-emacs))

undo tree

 (use-package undo-tree
   :ghook ('after-init-hook #'global-undo-tree-mode)
   :diminish undo-tree-mode
   :general
   (my/leader-keys
     "au" 'undo-tree-visualize)
   (my/normal-keys
     "U" 'undo-tree-redo)
   :config
   (progn
     (setq undo-tree-visualizer-timestamps t
	    undo-tree-visualizer-diff t
	    undo-tree-auto-save-history t
	    undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
     (defun spacemacs/undo-tree-restore-default ()
	(setq undo-tree-visualizer-diff t))
     (advice-add 'undo-tree-visualizer-quit :after #'spacemacs/undo-tree-restore-default)))

undo fu

(use-package undo-fu
  :general
  (my/normal-keys
    "U" 'undo-fu-only-redo)
  :config
  (global-undo-tree-mode -1))

(use-package undo-fu-session
  :config
  (setq undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'"))
  (global-undo-fu-session-mode))

expand tree

 (use-package expand-region
     :general
     (my/leader-keys
      "v" 'er/expand-region)
     :config
     (progn
	(setq expand-region-contract-fast-key "V"
	      expand-region-reset-fast-key "r")))

sudo edit

(use-package sudo-edit
  :general
  (my/leader-keys
    "fe" 'sudo-edit))

smartparens related

smartparens

 (use-package smartparens
   :diminish smartparens-mode
   :config
   (smartparens-global-mode t)
   (smartparens-global-strict-mode t)
   ;; :init
   ;; smartparens #431 workaround for fixing conflict between smarparens and yasnippet
   (add-hook 'yas-before-expand-snippet-hook (lambda () (smartparens-mode -1)))
   (add-hook 'yas-after-exit-snippet-hook (lambda () (smartparens-mode 1)))
   (my/leader-keys
     "k{" 'sp-wrap-curly
     "k(" 'sp-wrap-round
     "k[" 'sp-wrap-square
     "ku" 'sp-unwrap-sexp
     "kr" 'sp-rewrap-sexp
     "tp" 'my/toggle-smartparens)
   (my/all-states-keys
     :prefix "M-s"
     "." 'hydra-smartparens/body
     ;; Moving
     "a" 'sp-beginning-of-sexp
     "e" 'sp-end-of-sexp
     "f" 'sp-forward-sexp
     "b" 'sp-backward-sexp
     "n" 'sp-down-sexp
     "N" 'sp-backward-down-sexp
     "p" 'sp-up-sexp
     "P" 'sp-backward-up-sexp

     ;; Slurping & barfing
     "h" 'sp-backward-slurp-sexp
     "H" 'sp-backward-barf-sexp
     "l" 'sp-forward-slurp-sexp
     "L" 'sp-forward-barf-sexp

     ;; Wrapping
     "R" 'sp-rewrap-sexp
     "u" 'sp-unwrap-sexp
     "U" 'sp-backward-unwrap-sexp
     "(" 'sp-wrap-round
     "{" 'sp-wrap-curly
     "[" 'sp-wrap-square
     "'" 'my/sp-wrap-single-quote
     "\"" 'my/sp-wrap-double-quote

     ;; Sexp juggling
     "S" 'sp-split-sexp
     "s" 'sp-splice-sexp
     "r" 'sp-raise-sexp
     "j" 'sp-join-sexp
     "t" 'sp-transpose-sexp
     "A" 'sp-absorb-sexp
     "E" 'sp-emit-sexp
     "o" 'sp-convolute-sexp

     ;; Destructive editing
     "c" 'sp-change-inner :exit t
     "C" 'sp-change-enclosing :exit t
     "k" 'sp-kill-sexp
     "K" 'sp-backward-kill-sexp
     "M-k" 'my/sp-kill-inside-sexp
     "w" 'sp-copy-sexp)
   (defun my/toggle-smartparens ()
     (interactive)
     (if (bound-and-true-p smartparens-mode)
	  (progn
	    (smartparens-mode -1)
	    (smartparens-strict-mode -1)
	    (evil-smartparens-mode -1)
	    (message "Smartparens mode disabled in current buffer"))
	(progn
	  (smartparens-mode 1)
	  (smartparens-strict-mode 1)
	  (evil-smartparens-mode 1)
	  (message "Smartparens mode enabled in current buffer"))))
   (defhydra hydra-smartparens (:hint nil)
     "
  Moving^^^^                       Slurp & Barf^^   Wrapping^^            Sexp juggling^^^^               Destructive
 ------------------------------------------------------------------------------------------------------------------------
  [_a_] beginning  [_n_] down      [_h_] bw slurp   [_R_] rewrap        [_S_] split   [_t_] transpose   [_c_] change inner  [_w_] copy
  [_e_] end        [_N_] bw down   [_H_] bw barf    [_u_] unwrap        [_s_] splice  [_A_] absorb      [_C_] change outer  [_M-k_] kill inside
  [_f_] forward    [_p_] up        [_l_] slurp      [_U_] bw unwrap     [_r_] raise   [_E_] emit        [_k_] kill          [_g_] quit
  [_b_] backward   [_P_] bw up     [_L_] barf       [_(__{__[__'__\"_] wrap      [_j_] join    [_o_] convolute   [_K_] bw kill       [_q_] quit"
     ;; Moving
     ("a" sp-beginning-of-sexp)
     ("e" sp-end-of-sexp)
     ("f" sp-forward-sexp)
     ("b" sp-backward-sexp)
     ("n" sp-down-sexp)
     ("N" sp-backward-down-sexp)
     ("p" sp-up-sexp)
     ("P" sp-backward-up-sexp)

     ;; Slurping & barfing
     ("h" sp-backward-slurp-sexp)
     ("H" sp-backward-barf-sexp)
     ("l" sp-forward-slurp-sexp)
     ("L" sp-forward-barf-sexp)

     ;; Wrapping
     ("R" sp-rewrap-sexp)
     ("u" sp-unwrap-sexp)
     ("U" sp-backward-unwrap-sexp)
     ("(" sp-wrap-round)
     ("{" sp-wrap-curly)
     ("[" sp-wrap-square)
     ("'" my/sp-wrap-single-quote)
     ("\"" my/sp-wrap-double-quote)

     ;; Sexp juggling
     ("S" sp-split-sexp)
     ("s" sp-splice-sexp)
     ("r" sp-raise-sexp)
     ("j" sp-join-sexp)
     ("t" sp-transpose-sexp)
     ("A" sp-absorb-sexp)
     ("E" sp-emit-sexp)
     ("o" sp-convolute-sexp)

     ;; Destructive editing
     ("c" sp-change-inner :exit t)
     ("C" sp-change-enclosing :exit t)
     ("k" sp-kill-sexp)
     ("K" sp-backward-kill-sexp)
     ("M-k" my/sp-kill-inside-sexp)
     ("w" sp-copy-sexp)

     ("q" nil)
     ("g" nil)))

 ;;;###autoload
 (defun my/sp-wrap-single-quote ()
   (interactive)
   (setq current-prefix-arg 0)
   (sp-wrap-with-pair "'"))

 ;;;###autoload
 (defun my/sp-wrap-double-quote ()
   (interactive)
   (setq current-prefix-arg 0)
   (sp-wrap-with-pair "\""))

 ;;;###autoload
 (defun my/sp-kill-inside-sexp ()
   "Kill inside of sexp."
   (interactive)
   (sp-kill-sexp 0))

 (advice-add 'sp-change-inner :after #'evil-insert-state)

evil smartparens

(use-package evil-smartparens
  :after (evil smartparens)
  :diminish evil-smartparens-mode
  :init
  (add-hook 'smartparens-enabled-hook #'evil-smartparens-mode))

move text

(use-package move-text
  :general
  (my/leader-keys
    "xJ" 'move-text-down
    "xK" 'move-text-up))

easy text

(use-package easy-kill
  :commands easy-kill
  :init
  (progn
    (global-set-key [remap kill-ring-save] 'easy-kill)))

zop to char

(use-package zop-to-char
  :commands zop-to-char
  :general
  (my/all-states-keys
    "M-C-z" 'zop-to-char
    "M-z" 'zop-up-to-char)
  :config
  (progn
    (setq zop-to-char-prec-keys '(left ?\M-b)
	    zop-to-char-next-keys '(right ?\M-f))))

imenu list

 (use-package imenu-list
   :commands imenu-list-smart-toggle
   :init
   (progn
     (setq imenu-list-focus-after-activation t
	    imenu-list-auto-resize t)
     (my/leader-keys
	;; "bi" 'imenu-list-smart-toggle
	"bi" 'my/imenu-list))
   :config
   (setq imenu-list-mode-line-format '("%e" (:eval (spaceline-ml-main))))
   (my/normal-keys
     :keymaps 'imenu-list-major-mode-map
     "d" 'imenu-list-display-entry
     "r" 'imenu-list-refresh
     "q" 'imenu-list-quit-window
     "RET" 'imenu-list-goto-entry))

 ;;;###autoload
 (defun my/imenu-list ()
   "Use lsp-ui-imenu if it's feasible, imenu-list-smart-toggle otherwise"
   (interactive)
   (if (bound-and-true-p lsp-mode)
	(lsp-ui-imenu)
     (imenu-list-smart-toggle)))

imenu anywhere

(use-package imenu-anywhere
  :general
  (my/leader-keys
    "jI" 'ivy-imenu-anywhere))

string inflection

 (use-package string-inflection
   :general
   (my/leader-keys
     "xi" 'hydra-string-inflection/body)
   :config
   (progn
     (defhydra hydra-string-inflection ()
	"string inflection"
	("c" string-inflection-lower-camelcase "lower camel")
	("C" string-inflection-camelcase "camel")
	("k" string-inflection-kebab-case "kebab")
	("u" string-inflection-underscore "underscore")
	("U" string-inflection-upcase "upcase")
	("q" nil "quit"))))

unfill

(use-package unfill
  :commands (unfill-region unfill-paragraph unfill-toggle)
  :init
  (my/all-states-keys
    "M-q" 'unfill-toggle))

visual fill column

(use-package visual-fill-column
  :commands visual-fill-column-mode
  :config
  (add-hook 'visual-fill-column-mode-hook 'visual-line-mode))

fix word

(use-package fix-word
  :commands (fix-word-upcase
	       fix-word-downcase
	       fix-word-capitalize)
  :init
  (my/all-states-keys
    "M-u" 'fix-word-upcase
    "M-l" 'fix-word-downcase
    "M-c" 'fix-word-capitalize))

electric operator

(use-package electric-operator
  :commands electric-operator-mode
  :init
  (add-hook 'python-mode-hook #'electric-operator-mode)
  (add-hook 'inferior-python-mode-hook #'electric-operator-mode))

secret information

(load "~/emacs-secrets/secrets.el")

wgrep

(use-package wgrep
  :commands (wgrep-setup wgrep-change-to-wgrep-mode)
  :config
  (setq wgrep-auto-save-buffer t))

parrot

(use-package parrot
  :general
  (my/normal-keys
    "[r" 'parrot-rotate-prev-word-at-point
    "]r" 'parrot-rotate-next-word-at-point)
  :config
  (parrot-mode))

keychain environment

(use-package keychain-environment
  :config
  (keychain-refresh-environment))

comint

(use-package comint
  :ensure nil
  :config
  (setq comint-input-ring-size 1000))

themes

gruvbox

 (use-package gruvbox-theme
   :config
   (load-theme 'gruvbox-light-soft t)
   )
 ;;;###autoload
 (defun my/toggle-next-theme (theme1 theme2)
   (if (-contains? custom-enabled-themes theme1)
	(progn
	  (disable-theme theme1)
	  (load-theme theme2 t))
     (progn
	(disable-theme theme2)
	(load-theme theme1 t))))
 ;;;###autoload
 (defun my/switch-theme ()
   (interactive)
   (my/toggle-next-theme 'gruvbox-dark-soft 'gruvbox-light-soft))

 (my/leader-keys
   "Tn" 'my/switch-theme)

workspaces

eyebrowse

(use-package eyebrowse
  :init
  (add-hook 'after-init-hook 'eyebrowse-mode)
  (add-to-list 'window-persistent-parameters '(quit-restore . writable))
  :general
  (:keymaps 'override
   :states '(normal visual motion)
   ;; "gt" 'eyebrowse-next-window-config
   ;; "gT" 'eyebrowse-prev-window-config
   "gc" 'eyebrowse-close-window-config
   ;; "gr" 'eyebrowse-create-window-config
   "gl" 'eyebrowse-last-window-config
   "g0" 'eyebrowse-switch-to-window-config-0
   "g1" 'eyebrowse-switch-to-window-config-1
   "g2" 'eyebrowse-switch-to-window-config-2
   "g3" 'eyebrowse-switch-to-window-config-3
   "g4" 'eyebrowse-switch-to-window-config-4
   "g5" 'eyebrowse-switch-to-window-config-5
   "g6" 'eyebrowse-switch-to-window-config-6
   "g7" 'eyebrowse-switch-to-window-config-7
   "g8" 'eyebrowse-switch-to-window-config-8
   "g9" 'eyebrowse-switch-to-window-config-9)
  (my/leader-keys
    "w." 'hydra-eyebrowse/body
    "ww" 'eyebrowse-switch-to-window-config
    "wr" 'eyebrowse-rename-window-config)
  :config
  (setq eyebrowse-mode-line-style 'current
	  eyebrowse-new-workspace t)
  (custom-set-faces '(eyebrowse-mode-line-active ((nil))))
  (eyebrowse-mode))

(defhydra hydra-eyebrowse (:hint nil)
  "
 Go to^^^^^^                         Actions^^
 [_0_.._9_]^^     nth/new workspace  [_d_] close current workspace
 [_C-0_.._C-9_]^^ nth/new workspace  [_R_] rename current workspace
 [_<tab>_]^^^^    last workspace     [_q_] quit
 [_c_/_C_]^^      create workspace
 [_l_]^^^^        layouts
 [_n_/_C-l_]^^    next workspace
 [_N_/_p_/_C-h_]  prev workspace
 [_w_]^^^^        workspace w/helm/ivy\n"
  ("0" eyebrowse-switch-to-window-config-0 :exit t)
  ("1" eyebrowse-switch-to-window-config-1 :exit t)
  ("2" eyebrowse-switch-to-window-config-2 :exit t)
  ("3" eyebrowse-switch-to-window-config-3 :exit t)
  ("4" eyebrowse-switch-to-window-config-4 :exit t)
  ("5" eyebrowse-switch-to-window-config-5 :exit t)
  ("6" eyebrowse-switch-to-window-config-6 :exit t)
  ("7" eyebrowse-switch-to-window-config-7 :exit t)
  ("8" eyebrowse-switch-to-window-config-8 :exit t)
  ("9" eyebrowse-switch-to-window-config-9 :exit t)
  ("C-0" eyebrowse-switch-to-window-config-0)
  ("C-1" eyebrowse-switch-to-window-config-1)
  ("C-2" eyebrowse-switch-to-window-config-2)
  ("C-3" eyebrowse-switch-to-window-config-3)
  ("C-4" eyebrowse-switch-to-window-config-4)
  ("C-5" eyebrowse-switch-to-window-config-5)
  ("C-6" eyebrowse-switch-to-window-config-6)
  ("C-7" eyebrowse-switch-to-window-config-7)
  ("C-8" eyebrowse-switch-to-window-config-8)
  ("C-9" eyebrowse-switch-to-window-config-9)
  ("<tab>" eyebrowse-last-window-config)
  ("<return>" nil :exit t)
  ("TAB" eyebrowse-last-window-config)
  ("RET" nil :exit t)
  ("c" eyebrowse-create-window-config :exit t)
  ("C" eyebrowse-create-window-config)
  ("C-h" eyebrowse-prev-window-config)
  ("C-l" eyebrowse-next-window-config)
  ("d" eyebrowse-close-window-config)
  ("l" hydra-persp/body :exit t)
  ("n" eyebrowse-next-window-config)
  ("N" eyebrowse-prev-window-config)
  ("p" eyebrowse-prev-window-config)
  ("R" spacemacs/workspaces-ts-rename :exit t)
  ("w" eyebrowse-switch-to-window-config :exit t)
  ("q" nil))

persp mode

persp

(use-package persp-mode
  :config
  (setq persp-reset-windows-on-nil-window-conf t
	  persp-set-last-persp-for-new-frames nil)
  (persp-mode))

spacemacs persp extra

(use-package spacemacs-persp-extra
  :ensure nil
  :load-path "~/.emacs.d/site-lisp/spacemacs-persp-extra/"
  :commands (spacemacs/update-eyebrowse-for-perspective
	       spacemacs/save-eyebrowse-for-perspective
	       spacemacs/load-eyebrowse-for-perspective
	       spacemacs/load-eyebrowse-for-perspective)
  :general
  (:keymaps 'override
   :states '(normal visual motion)
    "g M-0" 'spacemacs/persp-switch-to-0
    "g M-1" 'spacemacs/persp-switch-to-1
    "g M-2" 'spacemacs/persp-switch-to-2
    "g M-3" 'spacemacs/persp-switch-to-3
    "g M-4" 'spacemacs/persp-switch-to-4
    "g M-5" 'spacemacs/persp-switch-to-5
    "g M-6" 'spacemacs/persp-switch-to-6
    "g M-7" 'spacemacs/persp-switch-to-7
    "g M-8" 'spacemacs/persp-switch-to-8
    "g M-9" 'spacemacs/persp-switch-to-9
    "g M-l" 'spacemacs/jump-to-last-layout
    "g M-c" 'spacemacs/layouts-ts-close)
  (my/leader-keys
    "l" 'hydra-persp/body)
  :init
  (add-hook 'persp-before-switch-functions
	      #'spacemacs/update-eyebrowse-for-perspective)
  (add-hook 'eyebrowse-post-window-switch-hook
	      #'spacemacs/save-eyebrowse-for-perspective)
  (add-hook 'persp-activated-functions
	      #'spacemacs/load-eyebrowse-for-perspective)
  (add-hook 'persp-before-save-state-to-file-functions
	      #'spacemacs/update-eyebrowse-for-perspective)
  (add-hook 'persp-after-load-state-functions
	      #'spacemacs/load-eyebrowse-after-loading-layout)
  (setq dotspacemacs-auto-generate-layout-names t
	  dotspacemacs-default-layout-name 'none)
  :config
  (defadvice persp-activate (before spacemacs//save-toggle-layout activate)
    (setq spacemacs--last-selected-layout persp-last-persp-name))
  (add-hook 'persp-mode-hook 'spacemacs//layout-autosave)
  (add-hook 'persp-created-functions
	      #'spacemacs//add-project-buffers-to-persp)
  (advice-add 'persp-load-state-from-file :before 'spacemacs//layout-wait-for-modeline))
(defhydra hydra-persp (:hint nil)
  "
 Go to^^^^^^                                  Actions^^
 [_0_.._9_]^^     nth/new layout              [_a_]^^   add buffer
 [_C-0_.._C-9_]^^ nth/new layout              [_A_]^^   add all from layout
 [_<tab>_]^^^^    last layout                 [_d_]^^   close current layout
 [_b_]^^^^        buffer in layout            [_D_]^^   close other layout
 [_h_]^^^^        default layout              [_L_]^^   load layouts from file
 [_l_]^^^^        layout w/helm/ivy           [_r_]^^   remove current buffer
 [_n_/_C-l_]^^    next layout                 [_R_]^^   rename current layout
 [_N_/_p_/_C-h_]  prev layout                 [_s_/_S_] save all layouts/save by names
 [_o_]^^^^        custom layout               [_t_]^^   show a buffer without adding it to current layout
 [_w_]^^^^        workspaces transient state  [_x_]^^   kill current w/buffers
 ^^^^^^                                       [_X_]^^   kill other w/buffers
 ^^^^^^                                       [_<_/_>_] move layout left/right
 ^^^^^^                                       "
  ("1" spacemacs/persp-switch-to-1 :exit t)
  ("2" spacemacs/persp-switch-to-2 :exit t)
  ("3" spacemacs/persp-switch-to-3 :exit t)
  ("4" spacemacs/persp-switch-to-4 :exit t)
  ("5" spacemacs/persp-switch-to-5 :exit t)
  ("6" spacemacs/persp-switch-to-6 :exit t)
  ("7" spacemacs/persp-switch-to-7 :exit t)
  ("8" spacemacs/persp-switch-to-8 :exit t)
  ("9" spacemacs/persp-switch-to-9 :exit t)
  ("0" spacemacs/persp-switch-to-0 :exit t)
  ("C-1" spacemacs/persp-switch-to-1)
  ("C-2" spacemacs/persp-switch-to-2)
  ("C-3" spacemacs/persp-switch-to-3)
  ("C-4" spacemacs/persp-switch-to-4)
  ("C-5" spacemacs/persp-switch-to-5)
  ("C-6" spacemacs/persp-switch-to-6)
  ("C-7" spacemacs/persp-switch-to-7)
  ("C-8" spacemacs/persp-switch-to-8)
  ("C-9" spacemacs/persp-switch-to-9)
  ("C-0" spacemacs/persp-switch-to-0)
  ("<tab>" spacemacs/jump-to-last-layout)
  ("<return>" nil :exit t)
  ("TAB" spacemacs/jump-to-last-layout)
  ("RET" nil :exit t)
  ("C-h" persp-prev)
  ("C-l" persp-next)
  ("<" spacemacs/move-current-persp-left)
  (">" spacemacs/move-current-persp-right)
  ("a" persp-add-buffer :exit t)
  ("A" persp-import-buffers :exit t)
  ("b" spacemacs/persp-buffers :exit t)
  ("d" spacemacs/layouts-ts-close)
  ("D" spacemacs/layouts-ts-close-other :exit t)
  ("h" spacemacs/layout-goto-default :exit t)
  ("L" persp-load-state-from-file :exit t)
  ("l" persp-switch :exit t)
  ("n" persp-next)
  ("N" persp-prev)
  ("o" spacemacs/select-custom-layout :exit t)
  ("p" persp-prev)
  ("r" persp-remove-buffer :exit t)
  ("R" spacemacs/layouts-ts-rename :exit t)
  ("s" persp-save-state-to-file :exit t)
  ("S" persp-save-to-file-by-names :exit t)
  ("t" persp-temporarily-display-buffer :exit t)
  ("w" hydra-eyebrowse/body :exit t)
  ("x" spacemacs/layouts-ts-kill)
  ("X" spacemacs/layouts-ts-kill-other :exit t)
  ("q" nil))

project

projectile

(use-package projectile
  :diminish projectile-mode
  :commands (projectile-ack
	       projectile-ag
	       projectile-compile-project
	       projectile-dired
	       projectile-find-dir
	       projectile-find-file
	       projectile-find-tag
	       projectile-test-project
	       projectile-grep
	       projectile-invalidate-cache
	       projectile-kill-buffers
	       projectile-multi-occur
	       projectile-project-p
	       projectile-project-root
	       projectile-recentf
	       projectile-regenerate-tags
	       projectile-replace
	       projectile-replace-regexp
	       projectile-run-async-shell-command-in-root
	       projectile-run-shell-command-in-root
	       projectile-switch-project
	       projectile-switch-to-buffer
	       projectile-vc)
  ;; :general
  ;; (my/leader-keys
  ;;   ;; Project
  ;;   "p!" 'projectile-run-shell-command-in-root
  ;;   "p&" 'projectile-run-async-shell-command-in-root
  ;;   "p%" 'projectile-replace-regexp
  ;;   "pa" 'projectile-toggle-between-implementation-and-test
  ;;   "pb" 'projectile-switch-to-buffer
  ;;   "pc" 'projectile-compile-project
  ;;   "pd" 'projectile-find-dir
  ;;   "pD" 'projectile-dired
  ;;   "pe" 'projectile-edit-dir-locals
  ;;   "pf" 'projectile-find-file
  ;;   "pF" 'projectile-find-file-dwim
  ;;   "pg" 'projectile-find-tag
  ;;   "pG" 'projectile-regenerate-tags
  ;;   "pI" 'projectile-invalidate-cache
  ;;   "pk" 'projectile-kill-buffers
  ;;   "po" 'projectile-find-other-file
  ;;   "pp" 'projectile-switch-project
  ;;   "pr" 'projectile-recentf
  ;;   "pR" 'projectile-replace
  ;;   "pT" 'projectile-test-project
  ;;   "pv" 'projectile-vc)
  :config
  (progn
    (setq projectile-indexing-method 'hybrid)
    (add-to-list 'projectile-other-file-alist '("tex" . ("pdf")))
    (add-to-list 'projectile-other-file-alist '("pdf" . ("tex")))
    (setq projectile-project-root-files-functions
    '(projectile-root-top-down projectile-root-local
    projectile-root-bottom-up
    projectile-root-top-down-recurring))
    (setq projectile-project-root-files #'(".projectile"))
    (projectile-mode)))

navigation

avy

 (use-package avy
   :config
   (setq avy-all-windows nil
	  avy-background t
	  avy-flyspell-correct-function #'flyspell-correct-at-point)
   :general
   (:keymaps 'override
	      [remap evil-find-char] 'my/avy-goto-char-in-line-without-background)
   (my/leader-keys
     "jj" 'avy-goto-char-timer
     "j M-j" 'my/avy-goto-char-timer-all-windows
     "jl" 'avy-goto-line
     "j M-l" 'my/avy-goto-line-all-windows
     "jw" 'avy-goto-word-or-subword-1
     "j M-w" 'my/avy-goto-word-or-subword-1-all-windows
     "jc" 'avy-goto-char
     "j M-c" 'my/avy-goto-char-all-windows)
   (my/leader-keys-major-mode
     :keymaps 'org-mode-map
     "jj" 'avy-org-goto-heading-timer)
   (my/all-states-keys
     "M-e" 'avy-goto-word-1
     "M-r" 'avy-goto-char
     "C-'" 'avy-goto-line))

   ;;;###autoload
   (defun my/avy-goto-char-timer-all-windows ()
     (interactive)
     (let ((avy-all-windows t))
	(avy-goto-char-autoload)))

   ;;;###timer
   (defun my/avy-goto-line-all-windows ()
     (interactive)
     (let ((avy-all-windows t))
	(avy-goto-line)))

   ;;;###autoload
   (defun my/avy-goto-word-or-subword-1-all-windows ()
     (interactive)
     (let ((avy-all-windows t))
	(avy-goto-word-or-subword-1)))

   ;;;###autoload
   (defun my/avy-goto-char-all-windows ()
     (interactive)
     (let ((avy-all-windows t))
	(call-interactively 'avy-goto-char)))

   ;;;###autoload
   (defun my/avy-goto-char-in-line-without-background ()
     (interactive)
     (let ((avy-background nil))
	(call-interactively 'avy-goto-char-in-line)))

winum

(use-package winum
  :ghook ('after-init-hook)
  :general
  (:states '(insert normal visual motion)
	     :keymaps 'override
	     "M-1" 'winum-select-window-1
	     "M-2" 'winum-select-window-2
	     "M-3" 'winum-select-window-3
	     "M-4" 'winum-select-window-4
	     "M-5" 'winum-select-window-5
	     "M-6" 'winum-select-window-6
	     "M-7" 'winum-select-window-7
	     "M-8" 'winum-select-window-8
	     "M-9" 'winum-select-window-9)
  :config
  (setq winum-auto-assign-0-to-minibuffer nil
	  winum-mode-line-position 1
	  winum-ignored-buffers '(" *which-key*" "*helm M-x*" "*helm find files*" "*helm mini*" "*Helm Swoop*")
	  winum-scope 'frame-local
	  winum-reverse-frame-list t)
  (winum-mode))

golden scroll screen

(use-package golden-ratio-scroll-screen
  :general
  (:states '(normal visual motion)
   :keymaps 'override
	     "C-f" 'golden-ratio-scroll-screen-up
	     "C-b" 'golden-ratio-scroll-screen-down))

ace link

 (use-package ace-link
   :commands (ace-link-info
	       ace-link-help
	       ace-link-eww)
   :init
   (progn
     (with-eval-after-load 'info
	(define-key Info-mode-map "o" 'ace-link-info))
     (with-eval-after-load 'help-mode
	(define-key help-mode-map "o" 'ace-link-help))
     (with-eval-after-load 'eww
	(define-key eww-link-keymap "o" 'ace-link-eww)
	(define-key eww-mode-map "o" 'ace-link-eww))))

ace window

(use-package ace-window
  :general
  (my/leader-keys
    "wM" 'ace-swap-window
    "wW" 'ace-window))

dumb jump

(use-package dumb-jump
  :general
  (my/all-states-keys
    :states '(insert emacs normal)
    "M-g o" 'dumb-jump-go-other-window
    "M-g g" 'dumb-jump-go
    "M-g l" 'dumb-jump-quick-look
    "M-g x" 'dumb-jump-go-prefer-external
    "M-g z" 'dumb-jump-go-prefer-external-other-window)
  :config
  (progn
    (setq dumb-jump-selector 'ivy)))

completion

helm related

helm

 (use-package helm
   :commands helm-mode
   :init
   (progn
     (with-eval-after-load 'helm
	(global-set-key (kbd "M-x") #'helm-M-x)
	(define-key helm-map (kbd "C-j") 'helm-next-line)
	(define-key helm-map (kbd "C-k") 'helm-previous-line)
	(define-key helm-map (kbd "C-S-j") 'helm-follow-action-forward)
	(define-key helm-map (kbd "C-S-k") 'helm-follow-action-backward)
	(define-key helm-map (kbd "C-h") 'helm-next-source)
	(define-key helm-map (kbd "C-S-h") 'describe-key)
	(define-key helm-map (kbd "C-l") (kbd "RET")))
     (with-eval-after-load 'helm-files
	(dolist (keymap (list helm-find-files-map helm-read-file-map))
	  (define-key keymap (kbd "C-l") 'helm-execute-persistent-action)
	  (define-key keymap (kbd "C-h") 'helm-find-files-up-one-level)
	  ;; rebind `describe-key' for convenience
	  (define-key keymap (kbd "C-S-h") 'describe-key)))
     (my/leader-keys
	"a'" 'helm-available-repls
	"bb" 'helm-mini
	"Cl"   'helm-colors
	"fb" 'helm-filtered-bookmarks
	"ff"   'helm-find-files
	"fl"   'helm-locate
	"fr"   'helm-recentf
	"hda"  'helm-apropos
	"hdF"  'my/helm-faces
	"hdb" 'describe-bindings
	"hdc" 'describe-char
	"hdf" 'describe-function
	"hdk" 'describe-key
	"hdp" 'describe-package
	"hdt" 'describe-theme
	"hdv" 'describe-variable
	"hn"  'view-emacs-news
	"hPs" 'profiler-start
	"hPk" 'profiler-stop
	"hPr" 'profiler-report
	"hPw" 'profiler-report-write-profile
	"hi"   'helm-info-at-point
	"hm"   'helm-man-woman
	"iu"   'helm-ucs
	"ji" 'helm-imenu
	"jI"   'helm-imenu-in-all-buffers
	"rm"   'helm-all-mark-rings
	"rl"   'helm-resume
	"rr"   'helm-register
	"ry"   'helm-show-kill-ring
	)
     (my/leader-keys-major-mode
	:keymaps 'org-mode-map
	"jh" 'helm-org-in-buffer-headings)
     (my/all-states-keys
	:keymaps 'inferior-python-mode-map
	"M-h" 'helm-comint-input-ring)
     :config
     (progn
	(custom-set-faces '(helm-action ((t (:foreground "dark sea green" :underline nil)))) )
	(setq helm-split-window-inside-p t
	      helm-echo-input-in-header-line t
	      helm-autoresize-min-height 20
	      helm-autoresize-max-height 0
	      helm-mode-fuzzy-match t
	      helm-completion-in-region-fuzzy-match t)
	(defun spacemacs//helm-hide-minibuffer-maybe ()
	  "Hide minibuffer in Helm session if we use the header line as input field."
	  (when (with-helm-buffer helm-echo-input-in-header-line)
	    (let ((ov (make-overlay (point-min) (point-max) nil nil t)))
	      (overlay-put ov 'window (selected-window))
	      (overlay-put ov 'face
			   (let ((bg-color (face-background 'default nil)))
			     `(:background ,bg-color :foreground ,bg-color)))
	      (setq-local cursor-type nil))))
	(add-hook 'helm-minibuffer-set-up-hook
		  'spacemacs//helm-hide-minibuffer-maybe)
	(helm-mode)
	(helm-autoresize-mode))))

helm describe modes

(use-package helm-describe-modes
  :after helm
  :init
  (global-set-key [remap describe-mode] #'helm-describe-modes))

helm projectile

 (use-package helm-projectile
   :commands (helm-projectile-switch-to-buffer
	       helm-projectile-find-dir
	       helm-projectile-dired-find-dir
	       helm-projectile-recentf
	       helm-projectile-find-file
	       helm-projectile-grep
	       helm-projectile
	       helm-projectile-switch-project)
   :init
   (progn
     (my/leader-keys
	"pb"  'helm-projectile-switch-to-buffer
	"pd"  'helm-projectile-find-dir
	"pf"  'helm-projectile-find-file
	"pF"  'helm-projectile-find-file-dwim
	"ph"  'helm-projectile
	"pp"  'helm-projectile-switch-project
	"pr"  'helm-projectile-recentf
	"sgp" 'helm-projectile-grep)))

helm ag

 (use-package helm-ag
   :commands (helm-do-ag
	       helm-do-ag-buffers
	       helm-do-ag-thi-file
	       helm-do-ag-project-root)
   :init
   (progn
     (my/leader-keys
	"sa" 'helm-do-ag
	"sb" 'helm-do-ag-buffers
	"s M-b" 'helm-do-ag-this-file
	"sp" 'helm-do-ag-project-root)))

helm-swoop

 (use-package helm-swoop
   :commands helm-swoop
   :init
   (progn
     (my/leader-keys
	"ss" 'helm-swoop))
   :config
   (progn
     (setq helm-swoop-split-with-multiple-windows t
	    helm-swoop-speed-or-color t
	    helm-swoop-pre-input-function (lambda () "")
	    helm-swoop-move-to-line-cycle nil)
     (custom-set-faces '(helm-swoop-target-word-face ((t (:inherit lazy-highlight)))))))

helm thmes

(use-package helm-themes
  :general
  (my/leader-keys
    "Ts" 'helm-themes))

helm xref

(use-package helm-xref
  :commands (helm-xref-show-xrefs)
  :init
  (progn
    ;; This is required to make `xref-find-references' not give a prompt.
    ;; `xref-find-references' asks the identifier (which has no text property)
    ;; and then passes it to `lsp-mode', which requires the text property at
    ;; point to locate the references.
    ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29619
    (setq xref-prompt-for-identifier '(not xref-find-definitions
					     xref-find-definitions-other-window
					     xref-find-definitions-other-frame
					     xref-find-references
					     spacemacs/jump-to-definition))
    ;; Use helm-xref to display `xref.el' results.
    (setq xref-show-xrefs-function #'helm-xref-show-xrefs)))

helm descbinds

 (use-package helm-descbinds
   :init
   (progn
     (setq helm-descbinds-window-style 'split)
     (add-hook 'helm-mode-hook 'helm-descbinds-mode)
     (my/leader-keys
	"?" 'helm-descbinds)))

helm flx

(use-package helm-flx
  :after helm
  :config
  (helm-flx-mode))

flyspell-correct-helm

(use-package flyspell-correct-helm
  :commands (flyspell-correct-helm)
  :general
  (:keymaps 'override
	      "C-;" 'flyspell-correct-wrapper)
  :init
  (setq flyspell-correct-interface #'flyspell-correct-helm))

helm org rifle

 (use-package helm-org-rifle
   :commands (helm-org-rifle-agenda-files
	       helm-org-rifle-occur-agenda-files)
   :init
   (progn
     (my/leader-keys-major-mode
	:keymaps 'org-mode-map
	"s M-r" 'helm-org-rifle-agenda-files
	"so" 'helm-org-rifle-occur-agenda-files)
     (my/leader-keys
	"aor" 'helm-org-rifle-agenda-files)))

helm bibtex

 (use-package helm-bibtex
   :commands helm-bibtex
   :init
   (progn
     (my/leader-keys
	"ib" 'ivy-bibtex)
     ;; (my/leader-keys-minor-mode
     ;;   :keymaps 'bibtex-completion-notes-mode-map
     ;;   "s" 'bibtex-completion-exit-notes-buffer)
     )
   :general
   (ivy-minibuffer-map
    "C-j" 'ivy-next-line
    "C-k" 'ivy-previous-line
    "C-h" (kbd "DEL")
    "C-l" 'ivy-alt-done)
   :config
   (setq bibtex-completion-pdf-field "file"
	  bibtex-completion-find-additional-pdfs t
	  bibtex-completion-bibliography "~/Dropbox/software/Zotero/bibtex/main.bib"
	  bibtex-completion-notes-path "~/Dropbox/document/org/references/ref-notes.org"
	  bibtex-completion-notes-template-one-file
	  "\n** ${title}\n  :PROPERTIES:\n  :Custom_ID: ${=key=}\n  :NOTER_DOCUMENT: ${file}\n  :END:\n\n"
	  bibtex-completion-additional-search-fields '(eventtitle)
	  bibtex-completion-display-formats
	  '((article       . "${=has-pdf=:1}${=has-note=:1} ${=type=:3} ${year:4} ${author:36} ${title:*} ${journal:40}")
	    (inbook        . "${=has-pdf=:1}${=has-note=:1} ${=type=:3} ${year:4} ${author:36} ${title:*} Chapter ${chapter:32}")
	    (incollection  . "${=has-pdf=:1}${=has-note=:1} ${=type=:3} ${year:4} ${author:36} ${title:*} ${booktitle:40}")
	    (inproceedings . "${=has-pdf=:1}${=has-note=:1} ${=type=:3} ${year:4} ${author:36} ${title:*} ${eventtitle:40}")
	    (t             . "${=has-pdf=:1}${=has-note=:1} ${=type=:3} ${year:4} ${author:36} ${title:*} ${eventtitle:40}"))))

helm pydoc

(use-package helm-pydoc
  :commands helm-pydoc
  :init
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    "hd" 'helm-pydoc))

autoload

;;;###autoload
;; copy from spacemacs
(defun my/helm-faces ()
  "Describe face."
  (interactive)
  (require 'helm-elisp)
  (let ((default (or (face-at-point) (thing-at-point 'symbol))))
    (helm :sources (helm-def-source--emacs-faces
		      (format "%s" (or default "default")))
	    :buffer "*helm faces*")))

helm posframe

(use-package helm-posframe
  :if (and (window-system) (version<= "26.1" emacs-version))
  :init
  (add-hook 'helm-org-rifle-after-command-hook 'helm-posframe-cleanup)
  :config
  (setq helm-posframe-poshandler 'posframe-poshandler-frame-center
	  helm-posframe-height 10
	  helm-posframe-width (round (* (frame-width) 0.49))
	  helm-posframe-parameters '((internal-border-width . 10)))
  (helm-posframe-enable))

ivy related

ivy

(use-package ivy
  :diminish ivy-mode
  :general
  (my/leader-keys
    "bb" 'ivy-switch-buffer)
  (my/non-insert-keys
    "M-b" 'ivy-switch-buffer)
  (:keymaps 'ivy-minibuffer-map
   "C-j" 'ivy-next-line
   "C-k" 'ivy-previous-line
   "C-h" (kbd "DEL")
   "C-l" 'ivy-alt-done)
  (:keymaps 'ivy-switch-buffer-map
   "C-k" 'ivy-previous-line
   "M-k" 'ivy-switch-buffer-kill)
  :config
  (setq ivy-use-virtual-buffers t
	  ivy-re-builders-alist '((t . ivy--regex-ignore-order))
	  ivy-initial-inputs-alist nil
	  ivy-count-format "(%d/%d) ")
  (ivy-mode))

ivy avy

(use-package ivy-avy
  :init
  (setq ivy-avy-style 'at-full))

ivy prescient

(use-package ivy-prescient
  :after (ivy counsel)
  :config
  (ivy-prescient-mode)
  (prescient-persist-mode))

ivy-rich

(use-package ivy-rich
  :after (ivy counsel)
  :config
  (ivy-rich-mode 1))

ivy hydra

(use-package ivy-hydra)

counsel

(use-package counsel
  :after (ivy swiper)
  :general
  ("M-x" 'counsel-M-x)
  (my/non-insert-keys
    "M-f" 'counsel-find-file)
  (my/leader-keys
    ;; files
    "fb" 'counsel-bookmark
    "ff" 'counsel-find-file
    "fl" 'counsel-locate
    "fr" 'counsel-recoll
    ;; help
    "?"   'counsel-descbinds
    "hda" 'counsel-apropos
    "hdf" 'counsel-describe-function
    "hdF" 'counsel-describe-face
    "hdv" 'counsel-describe-variable
    "hi"  'counsel-info-lookup-symbol
    "ji" 'counsel-imenu
    ;; register/ring
    "ry"  'counsel-yank-pop
    "rm"  'counsel-mark-ring
    ;; search
    "sa" 'counsel-ag
    "sp" 'counsel-projectile-ag
    ;; themes
    "Ts"  'counsel-load-theme
    ;; insert color
    "ic" 'counsel-colors-emacs
    "iu" 'counsel-unicode-char)
  (my/all-states-keys
    "M-y" 'counsel-yank-pop)
  (my/all-states-keys
    :keymaps 'inferior-python-mode-map
    "M-h" 'counsel-shell-history)
  :config
  (setq counsel-yank-pop-preselect-last t
	  counsel-ag-base-command "ag --vimgrep --skip-vcs-ignores %s")
  (add-to-list 'ivy-height-alist `(counsel-yank-pop . ,ivy-height))
  (counsel-mode))

swiper

(use-package swiper
  :general
  ("C-s" 'swiper)
  (my/leader-keys
   "ss" 'swiper))

ivy-xref

(use-package ivy-xref
  :after (ivy xref)
  :init
  (when (>= emacs-major-version 27)
    (setq xref-show-definitions-function #'ivy-xref-show-defs))
  ;; Necessary in Emacs <27. In Emacs 27 it will affect all xref-based
  ;; commands other than xref-find-definitions (e.g. project-find-regexp)
  ;; as well
  (setq xref-show-xrefs-function #'ivy-xref-show-xrefs
	  ivy-xref-remove-text-properties t))

amx

(use-package amx
  :commands (counsel-M-X)
  :config
  (amx-mode))

ivy bibtex

 (use-package ivy-bibtex
   :commands ivy-bibtex
   :init
   (progn
     (my/leader-keys
	"ib" 'ivy-bibtex)
     ;; (my/leader-keys-minor-mode
     ;;   :keymaps 'bibtex-completion-notes-mode-map
     ;;   "s" 'bibtex-completion-exit-notes-buffer)
     )
   :config
   (setq bibtex-completion-pdf-field "file"
	  bibtex-completion-cite-prompt-for-optional-arguments nil
	  bibtex-completion-pdf-symbol "ρ"
	  bibtex-completion-notes-symbol "η"
	  bibtex-completion-find-additional-pdfs t
	  bibtex-completion-bibliography "~/Dropbox/software/Zotero/bibtex/main.bib"
	  bibtex-completion-notes-path "~/Dropbox/document/org/references/ref-notes.org"
	  bibtex-completion-notes-template-one-file
	  "\n** ${title}\n  :PROPERTIES:\n  :Custom_ID: ${=key=}\n  :NOTER_DOCUMENT: ${file}\n  :END:"
	  bibtex-completion-additional-search-fields '(eventtitle)
	  bibtex-completion-display-formats
	  '((t . "${=has-pdf=:1} ${=has-note=:1} ${=type=:3} ${year:4} ${author:25} ${title:100}"))))

counsel projectile

(use-package counsel-projectile
  :general
  (my/leader-keys
    "p SPC" 'counsel-projectile
    "pf" 'counsel-projectile-find-file
    "pb" 'counsel-projectile-switch-to-buffer
    "pd" 'counsel-projectile-find-dir
    "pp" 'counsel-projectile-switch-project
    "psg" 'counsel-projectile-grep
    "pss" 'counsel-projectile-ag
    "psr" 'counsel-projectile-rg)
  :config
  (counsel-projectile-mode))

flyspell correct ivy

(use-package flyspell-correct-ivy
  :general
  (my/all-states-keys
    "C-;" 'flyspell-correct-wrapper)
  :init
  (setq flyspell-correct-interface #'flyspell-correct-ivy))

ivy posframe

(use-package ivy-posframe
  :if (and (window-system) (version<= "26.1" emacs-version))
  :after ivy
  :config
  (setq ivy-posframe-hide-minibuffer t
	  ivy-posframe-border-width 2
	  ivy-posframe-min-width 80
	  ivy-posframe-min-height 10
	  ivy-posframe-width nil
	  ivy-posframe-height nil)
  (setq ivy-posframe-display-functions-alist
	  '((swiper . ivy-posframe-display-at-window-bottom-left)
	    (t . ivy-posframe-display-at-frame-center)
	    ))
  (ivy-posframe-mode 1))

counsel dash

(use-package counsel-dash
  :general
  (my/leader-keys
    "d" '(:ignore t :wk "documents")
    "dh" 'counsel-dash)
  :config
  (setq counsel-dash-browser-func 'eww))

company related

company

 (use-package company
   :diminish company-mode
   :init
   (progn
     (add-hook 'after-init-hook 'global-company-mode))
   :config
   ;; (add-hook 'evil-normal-state-entry-hook
   ;; 	    (lambda ()
   ;; 	      (when (or (company-tooltip-visible-p) (my/company-posframe-visible-p company-posframe-buffer))
   ;; 		(company-cancel))))
   (progn
     (let ((map company-active-map))
	(define-key map (kbd "C-j") 'company-select-next)
	(define-key map (kbd "C-k") 'company-select-previous)
	(define-key map (kbd "C-l") 'company-complete-selection))
     (setq company-idle-delay 0.0
	    company-show-numbers t
	    company-tooltip-idle-delay 0.0
	    company-echo-delay 0.0
	    company-minimum-prefix-length 1
	    company-tooltip-align-annotations t
	    company-dabbrev-ignore-case nil
	    company-dabbrev-downcase nil
	    company-ispell-dictionary (file-truename "~/.emacs.d/dict/words_alpha.txt")
	    ispell-alternate-dictionary (file-truename "~/.emacs.d/dict/words_alpha.txt")
	    company-transformers '(company-sort-by-backend-importance)
	    company-dabbrev-code-other-buffers 'code
	    company-dabbrev-ignore-case nil
	    company-dabbrev-downcase nil
	    company-dabbrev-code-time-limit 5
	    company-dabbrev-code-modes '(python-mode inferior-python-mode)
	    company-backends '(company-capf
			       company-dabbrev-code
			       company-keywords
			       company-files
			       company-ispell
			       company-yasnippet
			       company-abbrev))
     (push (apply-partially #'cl-remove-if
			     (lambda (c)
			       (or (string-match-p "[^\x00-\x7F]+" c)
				   (string-match-p "[0-9]+" c)
				   (string-match-p "__.*__" c)
				   )))
	    company-transformers)
     (defun ora-company-number ()
	"Forward to `company-complete-number'. Unless the number is
 potentially part of the candidate. In that case, insert the
 number."
	(interactive)
	(let* ((k (this-command-keys))
	       (re (concat "^" company-prefix k)))
	  (if (or (cl-find-if (lambda (s) (string-match re s))
			      company-candidates)
		  (> (string-to-number k)
		     (length company-candidates))
		  (looking-back "[0-9]+\\.[0-9]*" (line-beginning-position)))
	      (self-insert-command 1)
	    (company-complete-number
	     (if (equal k "0")
		 10
	       (string-to-number k))))))

     (defun ora--company-good-prefix-p (orig-fn prefix)
	(unless (and (stringp prefix) (string-match-p "\\`[0-9]+\\'" prefix))
	  (funcall orig-fn prefix)))

     (advice-add 'company--good-prefix-p :around #'ora--company-good-prefix-p)

     (defun my-space ()
	(interactive)
	(company-abort)
	(self-insert-command 1))

     (let ((map company-active-map))
	(mapc (lambda (x) (define-key map (format "%d" x) 'ora-company-number))
	      (number-sequence 0 9))
	(define-key map " " 'my-space)
	(define-key map (kbd "<return>") nil))))

company statistics

(use-package company-statistics
  :after company
  :config
  (company-statistics-mode))

company prescient

(use-package company-prescient
  :after company
  :config
  (company-prescient-mode))

yasnippet related

yasnippet

(use-package yasnippet
  :ghook ('(prog-mode-hook
	      org-mode-hook
	      LaTeX-mode-hook)
	    #'yas-minor-mode))

yasnippet-snippets

(use-package yasnippet-snippets
  :after yasnippet)

ivy-yasnippet

(use-package ivy-yasnippet
  :commands ivy-yasnippet
  :init
  (progn
    (setq ivy-yasnippet-expand-keys nil)
    (my/leader-keys
     "is" 'ivy-yasnippet)))

auo yasnippet

(use-package auto-yasnippet
  :general
  (my/leader-keys
    "iSc" 'aya-create
    "iSe" 'aya-expand
    "iSw" 'aya-persist-snippet)
  :config
  (setq aya-trim-one-line t))

hippie expand

(use-package hippie-expand
  :ensure nil
  :init
  (setq hippie-expand-try-functions-list
	  '(
	    ;; Try to expand yasnippet snippets based on prefix
	    yas-hippie-try-expand
	    ;; Try to expand word "dynamically", searching the current buffer.
	    try-expand-dabbrev
	    ;; Try to expand word "dynamically", searching all other buffers.
	    try-expand-dabbrev-all-buffers
	    ;; Try to expand word "dynamically", searching the kill ring.
	    try-expand-dabbrev-from-kill
	    ;; Try to complete text as a file name, as many characters as unique.
	    try-complete-file-name-partially
	    ;; Try to complete text as a file name.
	    try-complete-file-name
	    ;; Try to expand word before point according to all abbrev tables.
	    try-expand-all-abbrevs
	    ;; Try to complete the current line to an entire line in the buffer.
	    try-expand-list
	    ;; Try to complete the current line to an entire line in the buffer.
	    try-expand-line
	    ;; Try to complete as an Emacs Lisp symbol, as many characters as
	    ;; unique.
	    try-complete-lisp-symbol-partially
	    ;; Try to complete word as an Emacs Lisp symbol.
	    try-complete-lisp-symbol
	    ))
  :general
  ("M-/" 'hippie-expand))

company posframe

 (use-package company-posframe
   :if (and (window-system) (version<= "26.1" emacs-version))
   :after company
   :config
   (require 'desktop)
   (push '(company-posframe-mode . nil)
	  desktop-minor-mode-table)
   (setq company-posframe-show-indicator nil
	  company-posframe-show-metadata nil
	  company-posframe-quickhelp-delay nil)
   (company-posframe-mode 1)
   (defun my/company-posframe-visible-p (buffer-or-name)
     "Return whether company posframe buffer called BUFFER-OR-NAME is visible.."
     (cl-dolist (frame (frame-list))
	(let ((buffer-info (frame-parameter frame 'posframe-buffer)))
	  (when (or (equal buffer-or-name (car buffer-info))
		    (equal buffer-or-name (cdr buffer-info)))
	    (when (frame-visible-p frame)
	      (cl-return t)))))))

source control

version control

(use-package diff-hl
  :commands (diff-hl-mode
	       diff-hl-flydiff-mode
	       diff-hl-margin-minor-mode)
  :init
  (progn
    (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
    (add-hook 'emacs-lisp-mode-hook (lambda ()
					(diff-hl-mode 1)
					(diff-hl-flydiff-mode 1)
					;; (diff-hl-margin-minor-mode 1)
					))))

git

magit

(use-package magit
  :commands (magit-status magit-init)
  :general
  (:keymaps 'magit-mode-map
   "0" nil
   "1" nil
   "2" nil
   "3" nil
   "4" nil)
  (my/leader-keys
    "gc"  'magit-clone
    "gff" 'magit-find-file
    "gfl" 'magit-log-buffer-file
    "gfd" 'magit-diff-buffer-file-popup
    "gi"  'magit-init
    "gL"  'magit-list-repositories
    "gm"  'magit-dispatch-popup
    "gs"  'magit-status
    "gS"  'magit-stage-file
    "gU"  'magit-unstage-file)
  (:keymaps 'magit-hunk-section-map
   "RET" 'magit-diff-visit-worktree-file-other-window)
  (:keymaps 'magit-file-section-map
   "RET" 'magit-diff-visit-worktree-file-other-window)
  :init
  (add-hook 'magit-popup-mode-hook (lambda () (display-line-numbers-mode -1)))
  (add-hook 'magit-status-mode-hook (lambda () (display-line-numbers-mode 1)))
  (add-hook 'magit-revision-mode-hook (lambda () (display-line-numbers-mode 1)))
  :config
  (setq transient-display-buffer-action '(display-buffer-below-selected)
	  magit-completing-read-function #'ivy-completing-read
	  magit-diff-refine-hunk 'all))

evil magit

(use-package evil-magit
  :after (evil magit))

magit todos

(use-package magit-todos
  :after magit
  :config
  (setq magit-todos-exclude-globs '("*.pdf" "*.eps")
	  magit-todos-update 600)
  (magit-todos-mode))

github

grip mode

(use-package grip-mode
  :commands grip-mode)

checkers

flycheck

flychek

 (use-package flycheck
   :ghook ('(python-mode-hook))
   :init
   (my/leader-keys
     "ts" 'my/toggle-syntax-checking)
   :config
   (setq flycheck-display-errors-delay 0.2)
   (flycheck-add-next-checker 'python-flake8 'python-pylint)
   (my/leader-keys
     "eb" 'flycheck-buffer
     "ec" 'flycheck-clear
     "eh" 'flycheck-describe-checker
     "es" 'flycheck-select-checker
     "eS" 'flycheck-set-checker-executable
     "ev" 'flycheck-verify-setup
     "ey" 'flycheck-copy-errors-as-kill
     "ex" 'flycheck-explain-error-at-point
     ;; navigation
     "en" 'flycheck-next-error
     "ep" 'flycheck-previous-error
     "el" 'flycheck-list-errors)
   (my/normal-keys
     :keymaps 'flycheck-error-list-mode-map
     "RET" 'flycheck-error-list-goto-error
     "j" 'flycheck-error-list-next-error
     "k" 'flycheck-error-list-previous-error
     "q" 'quit-window)
   (progn
     ;; Custom fringe indicator
     (when (and (fboundp 'define-fringe-bitmap)
		 ;; (not syntax-checking-use-original-bitmaps)
		 )
	(define-fringe-bitmap 'my-flycheck-fringe-indicator
	  (vector #b00000000
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00011100
		  #b00111110
		  #b00111110
		  #b00111110
		  #b00011100
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00000000
		  #b00000000)))
     (let ((bitmap 'my-flycheck-fringe-indicator
		    ;; (if syntax-checking-use-original-bitmaps
		    ;;            'flycheck-fringe-bitmap-double-arrow
		    ;;   'my-flycheck-fringe-indicator)
		    ))
	(flycheck-define-error-level 'error
	  :severity 2
	  :overlay-category 'flycheck-error-overlay
	  :fringe-bitmap bitmap
	  :error-list-face 'flycheck-error-list-error
	  :fringe-face 'flycheck-fringe-error)
	(flycheck-define-error-level 'warning
	  :severity 1
	  :overlay-category 'flycheck-warning-overlay
	  :fringe-bitmap bitmap
	  :error-list-face 'flycheck-error-list-warning
	  :fringe-face 'flycheck-fringe-warning)
	(flycheck-define-error-level 'info
	  :severity 0
	  :overlay-category 'flycheck-info-overlay
	  :fringe-bitmap bitmap
	  :error-list-face 'flycheck-error-list-info
	  :fringe-face 'flycheck-fringe-info))))

flychek posframe

(use-package flycheck-posframe
  :if (and (window-system) (version<= "26.1" emacs-version))
  :after flycheck
  :config
  (setq flycheck-posframe-border-width 1)
  (set-face-attribute 'flycheck-posframe-background-face nil :inherit 'default)
  (set-face-attribute 'flycheck-posframe-border-face nil :foreground "gray50")
  (set-face-attribute 'flycheck-posframe-info-face nil :inherit 'flycheck-error-list-info)
  (set-face-attribute 'flycheck-posframe-warning-face nil :inherit 'flycheck-error-list-warning)
  (set-face-attribute 'flycheck-posframe-error-face nil :inherit 'flycheck-error-list-error)
  (add-hook 'flycheck-mode-hook (lambda ()
				    (if (not (bound-and-true-p lsp-ui-sideline-mode))
					(flycheck-posframe-mode))))
  (flycheck-posframe-configure-pretty-defaults))

flyspell related

flyspell

(use-package flyspell
  :diminish flyspell-mode
  :general
  (my/leader-keys
    "t M-s" 'my/toggle-flyspell
    "M-s b" 'flyspell-buffer
    "M-s n" 'flyspell-goto-next-error
    "M-s p" 'flyspell-correct-at-point)
  (my/leader-keys
    "M-s ." 'hydra-spelling/body)
  :init
  (add-hook 'prog-mode-hook #'flyspell-prog-mode)
  (add-hook 'text-mode-hook #'turn-on-flyspell)
  (add-hook 'org-mode-hook #'turn-on-flyspell)
  :config
  (defhydra hydra-spelling ()
    ("b" flyspell-buffer "check buffer")
    ("d" ispell-change-dictionary "change dictionary")
    ("n" flyspell-goto-next-error "next")
    ("c" flyspell-correct-previous-word-generic "correct")
    ("q" nil "quit")))

flyspell correct

(use-package flyspell-correct
  :commands (flyspell-correct-wrapper))

languages

org related

org mode

 (use-package org
   :ensure org-plus-contrib
   :mode ("\\.org\\'" . org-mode)
   :config
   (add-hook 'org-mode-hook (lambda () (setq truncate-lines nil)))
   (add-hook 'org-mode-hook
	      (lambda ()
		(add-to-list (make-local-variable 'company-backends) '(company-ispell company-capf))))
   (add-hook 'org-mode-hook 'turn-on-auto-fill)
   (setq org-src-tab-acts-natively t
	  org-edit-src-auto-save-idle-delay 5
	  org-src-ask-before-returning-to-edit-buffer nil)
   (setq org-directory "~/Dropbox/document/org")
   (setq org-agenda-files (apply 'append
				  (mapcar
				   (lambda (directory)
				     (directory-files-recursively
				      directory org-agenda-file-regexp))
				   '("~/Dropbox/document/org/" ))))
   (setq org-latex-pdf-process
	  '(
	    "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
	    "bibtex %b"
	    "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
	    "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
	    ))
   (with-eval-after-load 'ox-latex
     (add-to-list 'org-latex-classes
		   '("IEEEtran" "\\documentclass{IEEEtran}"
		     ("\\section{%s}" . "\\section*{%s}")
		     ("\\subsection{%s}" . "\\subsection*{%s}")
		     ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
   ;; latex highlight in org mode
   (setq org-highlight-latex-and-related '(latex script entities))

   ;;setting up capture
   (setq org-default-notes-file (concat org-directory "/capture/capture.org"))
					  ; Targets include this file and any file contributing to the agenda - up to 9 levels deep
   (setq org-capture-templates
	  (quote (
		  ("t" "todo" entry (file+headline "~/Dropbox/document/org/capture/capture.org" "Tasks")
		   "* TODO %?\n\s\s%U\n")
		  ("n" "note" entry (file+headline "~/Dropbox/document/org/capture/capture.org" "Notes")
		   "* %?\n\s\s%U\n")
		  ("a" "appointments")
		  ("aa" "appointments" entry (file "~/Dropbox/document/org/appts/appts.org")
		   "* TODO %?")
		  ("ar" "repeating appointments" entry (file "~/Dropbox/document/org/appts/appts_re.org")
		   "* TODO %?")
		  )))
   (setq org-refile-targets (quote ((nil :maxlevel . 4)
				     (org-agenda-files :maxlevel . 3))))
   (setq org-list-allow-alphabetical t
	  org-log-done 'time
	  org-refile-use-outline-path t
	  org-outline-path-complete-in-steps nil
	  org-imenu-depth 5
	  org-src-window-setup 'split-window-below
	  org-export-in-background t
	  org-export-async-init-file (concat user-emacs-directory "init-org-async.el")
	  org-modules '(ol-w3m ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-eww org-special-blocks)
	  org-todo-keywords '((sequence "TODO(t)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c@)")))
   (add-to-list 'org-file-apps '("\\.pdf\\'" . emacs))
   (advice-add 'org-export-to-file
		:before #'(lambda (backend file &optional async subtreep visible-only body-only ext-plist
				      post-process) (save-buffer ())))
   :init
   ;; org-capture
   (with-eval-after-load 'org-capture
     (my/leader-keys-major-mode
	:keymaps 'org-capture-mode-map
	"a" 'org-capture-kill
	"c" 'org-capture-finalize
	"k" 'org-capture-kill
	"r" 'org-capture-refile))
   (add-hook 'org-capture-mode-hook #'evil-normalize-keymaps)
   ;; org-src
   (with-eval-after-load 'org-src
     (my/leader-keys-major-mode
	:keymaps 'org-src-mode-map
	"c" 'org-edit-src-exit
	"a" 'org-edit-src-abort
	"k" 'org-edit-src-abort))
   ;; https://github.com/noctuid/general.el/issues/61
   (add-hook 'org-src-mode-hook #'evil-normalize-keymaps)
   :general
   ;; org-mode
   (my/leader-keys-major-mode
     :keymaps 'org-mode-map
     "'" 'org-edit-special
     "c" 'org-capture
     "Cc" 'org-clock-cancel
     "Ci" 'org-clock-in
     "Co" 'org-clock-out
     "Cr" 'org-resolve-clocks
     "dd" 'org-deadline
     "ds" 'org-schedule
     "dt" 'org-time-stamp
     "dT" 'org-time-stamp-inactive
     "ee" 'org-export-dispatch
     "ep" (lambda () (interactive) (org-latex-export-to-pdf 'async))
     "eb" 'org-beamer-export-to-pdf
     "fi" 'org-feed-goto-inbox
     "fu" 'org-feed-update-all

     "a" 'org-agenda

     "u" 'org-update-checkbox-count
     "Tc" 'org-toggle-checkbox
     "Te" 'org-toggle-pretty-entities
     "Th" 'org-toggle-heading
     "Ti" 'org-toggle-inline-images
     "Tl" 'org-toggle-link-display
     "Tt" 'org-show-todo-tree
     "TT" 'org-todo
     "TV" 'space-doc-mode
     "Tx" 'org-toggle-latex-fragment

     ;; More cycling options (timestamps, headlines, items, properties)
     "L" 'org-shiftright
     "H" 'org-shiftleft
     "J" 'org-shiftdown
     "K" 'org-shiftup

     ;; Change between TODO sets
     "C-S-l" 'org-shiftcontrolright
     "C-S-h" 'org-shiftcontrolleft
     "C-S-j" 'org-shiftcontroldown
     "C-S-k" 'org-shiftcontrolup

     ;; Subtree editing
     "sa" 'org-toggle-archive-tag
     "sA" 'org-archive-subtree
     "sb" 'org-tree-to-indirect-buffer
     "sh" 'org-promote-subtree
     "sj" 'org-move-subtree-down
     "sk" 'org-move-subtree-up
     "sl" 'org-demote-subtree
     "sn" 'org-narrow-to-subtree
     "sN" 'widen
     "sr" 'org-refile
     "ss" 'org-sparse-tree
     "sS" 'org-sort

     ;; tables
     "ta" 'org-table-align
     "tb" 'org-table-blank-field
     "tc" 'org-table-convert
     "tdc" 'org-table-delete-column
     "tdr" 'org-table-kill-row
     "te" 'org-table-eval-formula
     "tE" 'org-table-export
     "th" 'org-table-previous-field
     "tH" 'org-table-move-column-left
     "tic" 'org-table-insert-column
     "tih" 'org-table-insert-hline
     "tiH" 'org-table-hline-and-move
     "tir" 'org-table-insert-row
     "tI" 'org-table-import
     "tj" 'org-table-next-row
     "tJ" 'org-table-move-row-down
     "tK" 'org-table-move-row-up
     "tl" 'org-table-next-field
     "tL" 'org-table-move-column-right
     "tn" 'org-table-create
     "tN" 'org-table-create-with-table.el
     "tr" 'org-table-recalculate
     "ts" 'org-table-sort-lines
     "ttf" 'org-table-toggle-formula-debugger
     "tto" 'org-table-toggle-coordinate-overlays
     "tw" 'org-table-wrap-region

     ;; Source blocks / org-babel
     "bp"     'org-babel-previous-src-block
     "bn"     'org-babel-next-src-block
     "be"     'org-babel-execute-maybe
     "bo"     'org-babel-open-src-block-result
     "bv"     'org-babel-expand-src-block
     "bu"     'org-babel-goto-src-block-head
     "bg"     'org-babel-goto-named-src-block
     "br"     'org-babel-goto-named-result
     "bb"     'org-babel-execute-buffer
     "bs"     'org-babel-execute-subtree
     "bd"     'org-babel-demarcate-block
     "bt"     'org-babel-tangle
     "bf"     'org-babel-tangle-file
     "bc"     'org-babel-check-src-block
     "bj"     'org-babel-insert-header-arg
     "bl"     'org-babel-load-in-session
     "bi"     'org-babel-lob-ingest
     "bI"     'org-babel-view-src-block-info
     "bz"     'org-babel-switch-to-session
     "bZ"     'org-babel-switch-to-session-with-code
     "ba"     'org-babel-sha1-hash
     "bx"     'org-babel-do-key-sequence-in-edit-buffer
     "b."     'spacemacs/org-babel-transient-state/body
     "*" 'org-ctrl-c-star
     "-" 'org-ctrl-c-minus
     "#" 'org-update-statistics-cookies
     "RET"   'org-ctrl-c-ret
     "M-RET" 'org-meta-return
     ;; attachments
     "A" 'org-attach
     ;; insertion
     "id" 'org-insert-drawer
     "ie" 'org-set-effort
     "if" 'org-footnote-new
     "ih" 'org-insert-heading
     "iH" 'org-insert-heading-after-current
     "iK" 'spacemacs/insert-keybinding-org
     "il" 'org-insert-link
     "in" 'org-add-note
     "ip" 'org-set-property
     "is" 'org-insert-subheading
     "it" 'org-set-tags-command)
   ;; org-agenda
   (my/leader-keys
     "ao#" 'org-agenda-list-stuck-projects
     "ao/" 'org-occur-in-agenda-files
     "aoa" 'org-agenda-list
     "aoc" 'org-capture
     "aoe" 'org-store-agenda-views
     "aofi" 'org-feed-goto-inbox
     "aofu" 'org-feed-update-all
     "aokg" 'org-clock-goto
     "aoki" 'org-clock-in-last
     "aokj" 'org-clock-jump-to-current-clock
     "aoko" 'org-clock-out
     "aokr" 'org-resolve-clocks
     "aol" 'org-store-link
     "aom" 'org-tags-view
     "aoo" 'org-agenda
     "aos" 'org-search-view
     "aot" 'org-todo-list
     ;; SPC C- capture/colors
     "Cc" 'org-capture)
   (my/leader-keys-major-mode
     :keymaps 'org-mode-map
     :major-modes t
     "b" '(:ignore t :which-key "babel")
     "C" '(:ignore t :which-key "Clocks")
     ;; "c" '(:ignore t :which-key "org-capture")
     "d" '(:ignore t :which-key "dates")
     "e" '(:ignore t :which-key "export")
     "f" '(:ignore t :which-key "feeds")
     "i" '(:ignore t :which-key "insert")
     "iD" '(:ignore t :which-key "download")
     "s" '(:ignore t :which-key "trees/subtrees")
     "T" '(:ignore t :which-key "toggles")
     "t" '(:ignore t :which-key "tables")
     "td" '(:ignore t :which-key "delete")
     "ti" '(:ignore t :which-key "insert")
     "tt" '(:ignore t :which-key "toggle")
     "x" '(:ignore t :which-key "text"))
   (my/leader-keys-major-mode
     :keymaps 'org-mode-map
     "op" 'org-open-at-point)
   (:keymaps 'org-mode-map
    :states '(normal visual motion)
    "RET" 'org-open-at-point)
   (my/all-states-keys
     :keymaps 'org-read-date-minibuffer-local-map
     "M-h" 'calendar-backward-day
     "M-l" 'calendar-forward-day
     "M-j" 'calendar-forward-week
     "M-k" 'calendar-backward-week
     "M-J" 'calendar-forward-month
     "M-K" 'calendar-backward-month))

 ;;;###autoload
 (defun my/org-meta-return ()
   (interactive)
   (end-of-line)
   (org-meta-return))

 (global-set-key [remap org-meta-return] 'my/org-meta-return)

org agenda

(use-package org-agenda
  :ensure nil
  :commands org-agenda
  :general
  (my/leader-keys-major-mode
    :keymaps 'org-agenda-mode-map
    "." 'hydra-org-agenda/body)
  :config
  (defhydra hydra-org-agenda (:pre (setq which-key-inhibit t) :post (setq which-key-inhibit nil) :hint nil)
    "
Headline^^            Visit entry^^               Filter^^                    Date^^                  Toggle mode^^        View^^             Clock^^        Other^^
--------^^---------   -----------^^------------   ------^^-----------------   ----^^-------------     -----------^^------  ----^^---------    -----^^------  -----^^-----------
[_ht_] set status     [_SPC_] in other window     [_ft_] by tag               [_ds_] schedule         [_tf_] follow        [_vd_] day         [_cI_] in      [_gr_] reload
[_hk_] kill           [_TAB_] & go to location    [_fr_] refine by tag        [_dS_] un-schedule      [_tl_] log           [_vw_] week        [_cO_] out     [_._]  go to today
[_hr_] refile         [_RET_] & del other windows [_fc_] by category          [_dd_] set deadline     [_ta_] archive       [_vt_] fortnight   [_cq_] cancel  [_gd_] go to date
[_hA_] archive        [_o_]   link                [_fh_] by top headline      [_dD_] remove deadline  [_tr_] clock report  [_vm_] month       [_cj_] jump    ^^
[_h:_] set tags       ^^                          [_fx_] by regexp            [_dt_] timestamp        [_td_] diaries       [_vy_] year        ^^             ^^
[_hp_] set priority   ^^                          [_fd_] delete all filters   [_+_]  do later         ^^                   [_vn_] next span   ^^             ^^
^^                    ^^                          ^^                          [_-_]  do earlier       ^^                   [_vp_] prev span   ^^             ^^
^^                    ^^                          ^^                          ^^                      ^^                   [_vr_] reset       ^^             ^^
[_q_] quit
"
    ;; Entry
    ("h:" org-agenda-set-tags)
    ("hA" org-agenda-archive-default)
    ("hk" org-agenda-kill)
    ("hp" org-agenda-priority)
    ("hr" org-agenda-refile)
    ("ht" org-agenda-todo)

    ;; Visit entry
    ("SPC" org-agenda-show-and-scroll-up)
    ("<tab>" org-agenda-goto :exit t)
    ("TAB" org-agenda-goto :exit t)
    ("RET" org-agenda-switch-to :exit t)
    ("o"   link-hint-open-link :exit t)

    ;; Date
    ("ds" org-agenda-schedule)
    ("dS" (lambda () (interactive)
	      (let ((current-prefix-arg '(4)))
		(call-interactively 'org-agenda-schedule))))
    ("dd" org-agenda-deadline)
    ("dt" org-agenda-date-prompt)
    ("dD" (lambda () (interactive)
	      (let ((current-prefix-arg '(4)))
		(call-interactively 'org-agenda-deadline))))
    ("+" org-agenda-do-date-later)
    ("-" org-agenda-do-date-earlier)

    ;; View
    ("vd" org-agenda-day-view)
    ("vw" org-agenda-week-view)
    ("vt" org-agenda-fortnight-view)
    ("vm" org-agenda-month-view)
    ("vy" org-agenda-year-view)
    ("vn" org-agenda-later)
    ("vp" org-agenda-earlier)
    ("vr" org-agenda-reset-view)

    ;; Toggle mode
    ("tf" org-agenda-follow-mode)
    ("tl" org-agenda-log-mode)
    ("ta" org-agenda-archives-mode)
    ("tr" org-agenda-clockreport-mode)
    ("td" org-agenda-toggle-diary)

    ;; Filter
    ("ft" org-agenda-filter-by-tag)
    ("fr" org-agenda-filter-by-tag-refine)
    ("fc" org-agenda-filter-by-category)
    ("fh" org-agenda-filter-by-top-headline)
    ("fx" org-agenda-filter-by-regexp)
    ("fd" org-agenda-filter-remove-all)

    ;; Clock
    ("cI" org-agenda-clock-in :exit t)
    ("cj" org-agenda-clock-goto :exit t)
    ("cO" org-agenda-clock-out)
    ("cq" org-agenda-clock-cancel)

    ;; Other
    ("q" nil :exit t)
    ("gr" org-agenda-redo)
    ("." org-agenda-goto-today)
    ("gd" org-agenda-goto-date))
  )

evil-org

(use-package evil-org
  :diminish evil-org-mode
  :ghook ('org-mode-hook)
  :init
  (with-eval-after-load 'org-agenda
    (require 'evil-org-agenda)
    (evil-org-agenda-set-keys))
  :config
  (add-hook 'evil-org-mode-hook
	      (lambda ()
		(evil-org-set-key-theme))))

org-bullets

(use-package org-bullets
  :ghook ('org-mode-hook)
  :config
  (setq org-bullets-bullet-list '("" "" "" "" "")))

org-ref

 (use-package org-ref
   :after org
   :init
   (setq org-ref-show-citation-on-enter nil)
   :config
   (progn
     (setq org-ref-default-bibliography '("~/Dropbox/software/Zotero/bibtex/main.bib"))
     (setq org-ref-bibliography-notes "~/Dropbox/document/org/references/ref-notes.org"
	    org-ref-default-ref-type "cref")
     (my/leader-keys-major-mode
	:keymaps 'org-mode-map
	"oo" 'my/org-ref-open-pdf-at-point
	"C-j" 'org-ref-next-key
	"C-k" 'org-ref-previous-key
	"nN" 'org-ref-open-notes-at-point)))

org-noter

(use-package org-noter
  :general
  (my/leader-keys-major-mode
    :keymaps 'pdf-view-mode-map
    "n" 'org-noter
    "i" 'org-noter-insert-note
    "k" 'org-noter-kill-session)
  (my/leader-keys-major-mode
    :keymaps 'org-mode-map
    "nn" 'org-noter
    "nk" 'org-noter-kill-session)
  :config
  (progn
    (setq org-noter-default-notes-file-names '("ref-notes.org")
	    org-noter-notes-search-path '("~/Dropbox/document/org/references")
	    org-noter-auto-save-last-location t
	    org-noter-doc-split-percentage '(0.7 . 0.7)
	    org-noter-always-create-frame nil
	    org-noter-insert-note-no-questions t
	    org-noter-notes-window-location 'horizontal-split)))

org journal

(use-package org-journal
  :init
  (setq org-journal-dir "~/Dropbox/document/org/journal"
	  org-journal-file-type 'monthly)
  :general
  (my/leader-keys
    "aoj" '(:ignore t :wk "org-journal")
    "aojj" 'org-journal-new-entry
    "aojs" 'org-journal-search-forever)
  (my/leader-keys-major-mode
    :keymaps 'calendar-mode-map
    "r" 'org-journal-read-entry
    "i" 'org-journal-new-date-entry
    "n" 'org-journal-next-entry
    "p" 'org-journal-previous-entry
    "s" 'org-journal-search-forever
    "w" 'org-journal-search-calendar-week
    "m" 'org-journal-search-calendar-month
    "y" 'org-journal-search-calendar-year)
  (my/normal-keys
    :keymaps 'calendar-mode-map
    "q" 'calendar-exit)
  (my/leader-keys-major-mode
    :keymaps 'org-journal-mode-map
    "j" 'org-journal-new-entry
    "n" 'org-journal-open-next-entry
    "p" 'org-journal-open-previous-entry))

org projectile

(use-package org-projectile
  :commands (org-projectile-location-for-project)
  :init
  (with-eval-after-load 'org-capture
    (require 'org-projectile))
  :config
  (setq org-projectile-projects-file "~/Dropbox/document/org/projectes.org")
  (push (org-projectile-project-todo-entry) org-capture-templates))

idle org agenda

(use-package idle-org-agenda
  :after org-agenda
  :config
  (setq idle-org-agenda-interval 600)
  (advice-add 'idle-org-agenda--jump-to-agenda :before #'eyebrowse-switch-to-window-config-0)
  (idle-org-agenda-mode))

org gcal

(use-package oauth2)
(use-package org-gcal
  :commands (org-gcal-sync
	       org-gcal-fetch
	       org-gcal-delete-at-point
	       org-gcal-post-at-point)
  :init
  (my/leader-keys
    "ag" '(:ignore t :wk "org-gcal")
    "ags" 'org-gcal-sync
    "agf" 'org-gcal-fetch
    "agd" 'org-gcal-delete-at-point
    "agp" 'org-gcal-post-at-point)
  :config
  (setq org-gcal-client-id `,google-calendar-client-id
	  org-gcal-client-secret `,google-calendar-client-secret
	  org-gcal-file-alist `((,google-calendar-id . "~/Dropbox/document/org/org-gcal/schedule.org"))
	  org-gcal-down-days 7
	  org-gcal-up-days 7))

org caldav

(use-package org-caldav
  :config
  (setq org-caldav-url 'google
	  org-caldav-oauth2-client-id `,google-calendar-client-id
	  org-caldav-oauth2-client-secret `,google-calendar-client-secret
	  org-caldav-calendar-id `,google-calendar-id
	  org-caldav-inbox "~/Dropbox/document/org/org-caldav/appointments.org"
	  org-caldav-files '("~/Dropbox/document/org/org-caldav/org-caldav.org")))

org roam related

org roam

(use-package org-roam
  :load-path "~/Program/org-roam"
  :defer nil
  :init
  (my/leader-keys
   "aordy" 'org-roam-dailies-yesterday
   "aordt" 'org-roam-dailies-today
   "aordT" 'org-roam-dailies-tomorrow
   "aorf" 'org-roam-find-file
   "aorg" 'org-roam-graph
   "aori" 'org-roam-insert
   "aorI" 'org-roam-insert-immediate
   "aorl" 'org-roam
   "aorta" 'org-roam-tag-add
   "aortd" 'org-roam-tag-delete)
  (my/leader-keys-major-mode
    :keymmaps 'org-mode
    "rb" 'org-roam-switch-to-buffer
    "rdy" 'org-roam-dailies-yesterday
    "rdt" 'org-roam-dailies-today
    "rdT" 'org-roam-dailies-tomorrow
    "rf" 'org-roam-find-file
    "rg" 'org-roam-graph
    "ri" 'org-roam-insert
    "rI" 'org-roam-insert-immediate
    "rl" 'org-roam
    "rta" 'org-roam-tag-add
    "rtd" 'org-roam-tag-delete))

org roam bibtex

 (use-package org-roam-bibtex
   :after org-roam
   :hook (org-roam-mode . org-roam-bibtex-mode)
   :config
   (setq orb-insert-interface 'ivy-bibtex))

 (setq orb-preformat-keywords
	'("citekey" "title" "url" "author-or-editor" "keywords" "file")
	orb-process-file-field t
	orb-file-field-extensions "pdf")

 (setq orb-templates
	'(("r" "ref" plain (function org-roam-capture--get-point)
	   ""
	   :file-name "${citekey}"
	   :head "#+TITLE: ${citekey}: ${title}\n#+ROAM_KEY: ${ref}

 - tags ::
 - keywords :: ${keywords}

 * ${title}
 :PROPERTIES:
 :Custom_ID: ${citekey}
 :URL: ${url}
 :AUTHOR: ${author-or-editor}
 :NOTER_DOCUMENT: ${file}
 :NOTER_PAGE:
 :END:")))

org roam server

(use-package org-roam-server
  :config
  (setq org-roam-server-host "127.0.0.1"
	  org-roam-server-port 8080
	  org-roam-server-authenticate nil
	  org-roam-server-export-inline-images t
	  org-roam-server-serve-files nil
	  org-roam-server-served-file-extensions '("pdf" "mp4" "ogv")
	  org-roam-server-network-poll t
	  org-roam-server-network-arrows nil
	  org-roam-server-network-label-truncate t
	  org-roam-server-network-label-truncate-length 60
	  org-roam-server-network-label-wrap-length 20))

emacs lisp related

emacs lisp

(use-package emacs-lisp
  :ensure nil
  :mode ("\\.el\\'" . emacs-lisp-mode)
  :init
  (my/leader-keys-major-mode
  :keymaps 'emacs-lisp-mode-map
  :major-modes t
  "c" '(:ignore t :which-key "compile")
  "cc" 'emacs-lisp-byte-compile
  "ci"  'my/byte-compile-init-dir
  "e" '(:ignore t :which-key "eval")
  "eb" 'eval-buffer
  "ee" 'eval-last-sexp
  "er" 'eval-region
  "ef" 'eval-defun
  "ep" 'eval-print-last-sexp))

parinfer mode

(use-package parinfer
  :general
  (my/leader-keys
    "tP" 'parinfer-toggle-mode)
  (setq parinfer-extensions
	  '(defaults       ; should be included.
	     evil           ; If you use Evil.
	     smart-tab      ; C-b & C-f jump positions and smart shift with tab & S-tab.
	     smart-yank))   ; Yank behavior depend on mode.
  (add-hook 'emacs-lisp-mode-hook #'parinfer-mode))

latex

reftex

(use-package reftex
  :commands (turn-on-reftex
	       reftex-mode)
  :init
  (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
  :config
  (setq reftex-plug-into-AUCTeX t
	  reftex-use-fonts t)
  (my/leader-keys-major-mode
    :keymaps 'LaTeX-mode-map
    "r" '(:ignore t :wk "reftex")
    "rc"    'reftex-citation
    "rg"    'reftex-goto-label
    "rG"    'reftex-grep-document
    "ri"    'reftex-index-selection-or-word
    "rI"    'reftex-display-index
    "r TAB" 'reftex-index
    "rl"    'reftex-label
    "rp"    'reftex-index-phrase-selection-or-word
    "rP"    'reftex-index-visit-phrases-buffer
    "rr"    'reftex-reference
    "rs"    'reftex-search-document
    "rt"    'reftex-toc
    "rT"    'reftex-toc-recenter
    "ru"    'reftex-renumber-simple-labels
    "rv"    'reftex-view-crossref))

auctex

(use-package tex
  :ensure auctex
  :mode (".tex\\'" . LaTeX-mode)
  :config
  (progn
    (add-hook 'LaTeX-mode-hook 'turn-on-auto-fill)
    ;; (add-hook 'LaTeX-mode-hook 'visual-line-mode)
    (setq TeX-save-query nil)
    (setq TeX-view-program-selection
	    (quote
	     (((output-dvi has-no-display-manager)
	       "dvi2tty")
	      ((output-dvi style-pstricks)
	       "dvips and gv")
	      (output-dvi "xdvi")
	      (output-pdf "PDF Tools")
	      (output-html "xdg-open"))))
    (setq TeX-auto-save t
	    TeX-parse-self t
	    TeX-syntactic-comment t
	    ;; Synctex support
	    TeX-source-correlate-start-server nil
	    ;; Don't insert line-break at inline math
	    LaTeX-fill-break-at-separators nil
	    TeX-outline-extra '(("\\\\begin\{abstract\}$" 2)))
    (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
    (add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
    (add-hook 'LaTeX-mode-hook 'TeX-PDF-mode)
    (add-hook 'LaTeX-mode-hook (lambda() (setq-local display-line-numbers-type 'relative))))
  :general
  ;; Key bindings for plain Tex
  (my/leader-keys-major-mode
    :major-modes '(latex-mode t)
    :keymaps 'LaTeX-mode-map
    "\\"  'TeX-insert-macro                            ;; C-c C-m
    "-"   'TeX-recenter-output-buffer                  ;; C-c C-l
    "%"   'TeX-comment-or-uncomment-paragraph          ;; C-c %
    ";"   'TeX-comment-or-uncomment-region             ;; C-c ; or C-c :
    ;; TeX-command-run-all runs compile and open the viewer
    "a"   'TeX-command-run-all                         ;; C-c C-a
    "k"   'TeX-kill-job                                ;; C-c C-k
    "l"   'TeX-recenter-output-buffer                  ;; C-c C-l
    "m"   'TeX-insert-macro                            ;; C-c C-m
    "v"   'TeX-view                                    ;; C-c C-v
    "w" 'tex-count-words
    ;; TeX-doc is a very slow function
    "h"   '(:ignore t :which-key "help")
    "hd"  'TeX-doc)
  ;; Key bindings specific to LaTeX
  (my/leader-keys-major-mode
    :major-modes '(latex-mode t)
    :keymaps 'LaTeX-mode-map
    "*"   'LaTeX-mark-section      ;; C-c *
    "."   'LaTeX-mark-environment  ;; C-c .
    "/"   'TeX-command-master
    "c"   'LaTeX-close-environment ;; C-c ]
    ;; "e"   'LaTeX-environment       ;; C-c C-e
    "e"   'cdlatex-environment
    "M-e" 'TeX-next-error
    "i"   '(:ignore t :which-key "insert")
    "ii"   'LaTeX-insert-item       ;; C-c C-j
    "s"   'LaTeX-section           ;; C-c C-s
    "f"   '(:ignore t :which-key "fill")
    "fe"  'LaTeX-fill-environment  ;; C-c C-q C-e
    "fp"  'LaTeX-fill-paragraph    ;; C-c C-q C-p
    "fr"  'LaTeX-fill-region       ;; C-c C-q C-r
    "fs"  'LaTeX-fill-section      ;; C-c C-q C-s
    "p"   '(:ignore t :which-key "preview")
    "pb"  'preview-buffer
    "pc"  'preview-clearout
    "pd"  'preview-document
    "pe"  'preview-environment
    "pf"  'preview-cache-preamble
    "pp"  'preview-at-point
    "pr"  'preview-region
    "ps"  'preview-section))

auctex latexmk

(use-package auctex-latexmk
  :config
  (auctex-latexmk-setup))

company-auctex

(use-package company-auctex
  :mode (".tex\\'" . LaTeX-mode)
  :init
  (add-hook 'LaTeX-mode-hook
	      (lambda ()
		(add-to-list (make-local-variable 'company-backends)
			     '(company-auctex-labels
			       company-auctex-bibs
			       company-auctex-macros
			       company-auctex-symbols
			       company-auctex-environments)))))

cdlatex

(use-package cdlatex
  :diminish cdlatex-mode
  :commands (turn-on-cdlatex
	       cdlatex-mode)
  :init
  (add-hook 'LaTeX-mode-hook 'turn-on-cdlatex)
  (add-hook 'org-mode-hook 'turn-on-cdlatex)
  :config
  (setq cdlatex-simplify-sub-super-scripts nil
	  cdlatex-paired-parens "$[{("
	  cdlatex-sub-super-scripts-outside-math-mode nil
	  cdlatex-insert-auto-labels-in-env-templates nil)
  (defun my-indent-for-tab-command ()
    (indent-for-tab-command)
    t)
  (add-hook 'cdlatex-tab-hook #'my-indent-for-tab-command))

lua

 (use-package lua-mode
   :mode ("\\.lua\\'" . lua-mode)
   :interpreter ("lua" . lua-mode)
   :init
   (progn
     (setq lua-indent-level 2
	    lua-indent-string-contents t)
     (my/leader-keys-major-mode
	:keymaps 'lua-mode
	"d" 'lua-search-documentation
	"sb" 'lua-send-buffer
	"sf" 'lua-send-defun
	"sl" 'lua-send-current-line
	"sr" 'lua-send-region)))

yaml

(use-package yaml-mode
  :commands yaml-mode
  :mode (("\\.\\(yml\\|yaml\\)\\'" . yaml-mode)
	   ("Procfile\\'" . yaml-mode))
  :config (add-hook 'yaml-mode-hook
		      '(lambda ()
			 (define-key yaml-mode-map "\C-m" 'newline-and-indent))))

python related

python

 (use-package python
   :mode (".py\\'" . python-mode)
   :config
   (progn
     (setq python-shell-interpreter "ipython"
	    python-shell-interpreter-args "--simple-prompt"
	    python-indent-offset 4
	    python-indent-guess-indent-offset nil)
     (add-hook 'python-mode-hook (lambda () (set-fill-column 79)))
     (my/leader-keys-major-mode
	:keymaps 'python-mode-map
	:major-modes t
	"'"  'run-python
	"s" '(:ignore t :which-key "REPL")
	"sb" 'my/python-shell-send-buffer-after-save-buffer
	"sf" 'python-shell-send-defun
	"sl" 'my/python-shell-send-line
	"sr" 'python-shell-send-region
	"ss" 'python-shell-send-string
	"sz" 'python-shell-switch-to-shell
	"," 'python-indent-shift-left
	"." 'python-indent-shift-right)
     (my/all-states-keys
	:keymaps 'inferior-python-mode-map
	"M-o" 'ace-link)
     (defun my/company-comint-history (command &optional arg &rest ignore)
	"`company-mode' completion backend for comint history"
	(interactive (list 'interactive))
	(cl-case command
	  (interactive (company-begin-backend 'company-comint-history))
	  (prefix (company-grab-symbol))
	  (candidates
	   (cl-remove-if-not
	    (lambda (c) (string-prefix-p arg c))
	    (ring-elements comint-input-ring)))
	  (no-cache t)
	  (duplicates t)))
     (defun my/python-shell-send-buffer-after-save-buffer ()
	"Save current buffer before save the code to python shell"
	(interactive)
	(if (buffer-modified-p)
	    (progn
	     (save-buffer)
	     (python-shell-send-buffer))
	  (python-shell-send-buffer)))
     (add-hook 'inferior-python-mode-hook
		(lambda ()
		  (add-to-list (make-local-variable 'company-backends) '(company-files company-capf company-dabbrev-code))))))

 ;;;###autoload
 (defun my/run-python (&optional cmd dedicated show)
   "Run an inferior Python process.

 Argument CMD defaults to `python-shell-calculate-command' return
 value.  When called interactively with `prefix-arg', it allows
 the user to edit such value and choose whether the interpreter
 should be DEDICATED for the current buffer.  When numeric prefix
 arg is other than 0 or 4 do not SHOW.

 For a given buffer and same values of DEDICATED, if a process is
 already running for it, it will do nothing.  This means that if
 the current buffer is using a global process, the user is still
 able to switch it to use a dedicated one.

 Runs the hook `inferior-python-mode-hook' after
 `comint-mode-hook' is run.  (Type \\[describe-mode] in the
 process buffer for a list of commands.)"
   (interactive
    (if current-prefix-arg
	 (list
	  (read-shell-command "Run Python: " (python-shell-calculate-command))
	  (y-or-n-p "Make dedicated process? ")
	  (= (prefix-numeric-value current-prefix-arg) 4))
      (list (python-shell-calculate-command) nil t)))
   (let ((buffer
	   (python-shell-make-comint
	    (or cmd (python-shell-calculate-command))
	    (python-shell-get-process-name dedicated) show)))
     (display-buffer buffer)
     (get-buffer-process buffer)))

 (advice-add 'run-python :override 'my/run-python)

 ;;;###autoload
 (defun my/python-shell-send-line ()
   "Send the current line to inferior Python process."
   (interactive)
   (save-excursion
     (python-shell-send-region
      (progn
	 (beginning-of-line 1)
	 (point-marker))
      (progn
	 (end-of-line 1)
	 (point-marker)))))

yapfify

(use-package yapfify
  :diminish yapf-mode
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    "f" '(:ignore t :wk "format")
    "fb" 'yapfify-buffer
    "fr" 'yapfify-region))

pyvenv

(use-package pyvenv
  :ghook ('python-mode-hook #'pyvenv-mode)
  :ghook ('python-mode-hook #'pyvenv-tracking-mode)
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    "v" '(:ignore t :wk "virtualenv")
    "va" 'pyvenv-activate
    "vd" 'pyvenv-deactivate
    "vw" 'pyvenv-workon
    "s R" 'pyvenv-restart-python
    "s M-r" 'my/restart-python-and-send-buffer)
  (my/leader-keys-major-mode
    :keymaps 'inferior-python-mode-map
    "s R" 'pyvenv-restart-python))

;;;###autoload
(defun my/restart-python-and-send-buffer ()
  (interactive)
  (pyvenv-restart-python)
  (my/python-shell-send-buffer-after-save-buffer))

sphinx doc

(use-package sphinx-doc
  :ghook ('python-mode-hook)
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    "d" 'sphinx-doc))

importmagic

(use-package importmagic
  :ghook ('python-mode-hook)
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    :major-modes t
    "r" '(:ignore t :wk "refactor")
    "rf" 'importmagic-fix-imports))

py isort

(use-package py-isort
  :ghook ('before-save-hook #'py-isort-before-save)
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    "ri" 'py-isort-buffer))

anaconda

(use-package anaconda-mode
  :ghook ('python-mode-hook)
  :general
  (my/leader-keys-major-mode
    :keymaps 'python-mode-map
    :major-modes t
    "h" '(:ignore t :which-key "help")
    "hh" 'anaconda-mode-show-doc
    "g" '(:ignore t :which-key "goto")
    "ga" 'anaconda-mode-find-assignments
    "gb" 'anaconda-mode-go-back
    "gu" 'anaconda-mode-find-references
    "gd" 'anaconda-mode-find-definitions
    "gD" 'anaconda-mode-find-definitions-other-window)
  :init
  (add-hook 'python-mode-hook 'anaconda-mode)
  (add-hook 'python-mode-hook 'anaconda-eldoc-mode))

(use-package company-anaconda
  :after anaconda
  :init
  (progn
    (add-hook 'python-mode-hook
		(lambda ()
		  (add-to-list (make-local-variable 'company-backends) '(company-anaconda company-capf company-files company-dabbrev))))
    (add-hook 'inferior-python-mode-hook
		(lambda ()
		  (add-to-list (make-local-variable 'company-backends) '(company-anaconda company-capf company-files company-dabbrev))))
    ))

shell script

sh script

 (use-package sh-script
   :general
   (my/leader-keys-major-mode
     :keymaps 'sh-mode-map
     "\\" 'sh-backslash-region
     "i" '(:ignore t :wk "insert")
     "ic" 'sh-case
     "ii" 'sh-if
     "if" 'sh-function
     "io" 'sh-for
     "ie" 'sh-indexed-loop
     "iw" 'sh-while
     "ir" 'sh-repeat
     "is" 'sh-select
     "iu" 'sh-until
     "ig" 'sh-while-getopts)
   :init
   ;; Use sh-mode when opening `.zsh' files, and when opening Prezto runcoms.
   (dolist (pattern '("\\.zsh\\'"
		       "zlogin\\'"
		       "zlogout\\'"
		       "zpreztorc\\'"
		       "zprofile\\'"
		       "zshenv\\'"
		       "zshrc\\'"))
     (add-to-list 'auto-mode-alist (cons pattern 'sh-mode)))
   (defun spacemacs//setup-shell ()
     (when (and buffer-file-name
		 (string-match-p "\\.zsh\\'" buffer-file-name))
	(sh-set-shell "zsh")))
   (add-hook 'sh-mode-hook 'spacemacs//setup-shell))

lsp

lsp mode

(use-package lsp-mode
  :commands lsp
  :diminish lsp-mode
  :init
  (add-hook 'python-mode-hook (lambda () (lsp-deferred)))
  :general
  (my/leader-keys-major-mode
    :keymaps 'lsp-mode-map
    "=b" 'lsp-format-buffer
    "=r" 'lsp-format-region)
  (my/leader-keys-minor-mode
    :keymaps 'lsp-mode-map
    "ss" 'lsp
    "=b" 'lsp-format-buffer
    "=r" 'lsp-format-region
    "gd" 'lsp-find-definition
    "gr" 'lsp-find-references
    ;; backend
    "bd" #'lsp-describe-session
    "br" #'lsp-workspace-restart
    "bs" #'lsp-workspace-shutdown)
  :config
  (progn
    (setq lsp-message-project-root-warning t
	    lsp-prefer-flymake nil
	    lsp-restart 'ignore
	    lsp-eldoc-hook nil
	    lsp-eldoc-enable-hover nil
	    lsp-auto-configure t
	    lsp-enable-symbol-highlighting nil
	    lsp-enable-file-watchers nil
	    lsp-pyls-plugins-preload-modules ["numpy", "networkx", "cplex"]
	    lsp-pyls-plugins-pydocstyle-enabled t
	    lsp-pyls-plugins-pydocstyle-convention "numpy"
	    lsp-pyls-plugins-rope-completion-enabled t
	    lsp-pyls-plugins-pylint-enabled t
	    lsp-pyls-plugins-flake8-enabled nil
	    lsp-pyls-plugins-pyflakes-enabled nil
	    lsp-pyls-plugins-mccabe-enabled nil
	    lsp-pyls-plugins-yapf-enabled nil
	    lsp-signature-render-documentation nil)))

company lsp

(use-package company-lsp
  :commands company-lsp
  :init
  (progn
    (add-hook 'python-mode-hook
		(lambda ()
		  (add-to-list (make-local-variable 'company-backends) '(company-lsp company-files)))))
  :config
  (progn
    (setq company-lsp-enable-recompletion t
	    company-lsp-async t
	    company-lsp-cache-candidates 'auto
	    company-lsp-match-candidate-predicate 'company-lsp-match-candidate-prefix)))

lsp ui

 (use-package lsp-ui
   :after lsp-mode
   :init
   (add-hook 'lsp-mode-hook 'lsp-ui-mode)
   :general
   (:keymaps 'lsp-ui-peek-mode-map
    "h" 'lsp-ui-peek--select-prev-file
    "j" 'lsp-ui-peek--select-next
    "k" 'lsp-ui-peek--select-prev
    "l" 'lsp-ui-peek--select-next-file)
   (my/normal-keys
     :keymaps 'lsp-ui-imenu-mode-map
     "h" 'lsp-ui-imenu--prev-kind
     "l" 'lsp-ui-imenu--next-kind
     "d" 'lsp-ui-imenu--view
     "M-d" 'lsp-ui-imenu--visit
     "q" 'lsp-ui-imenu--kill)
   :config
   (my/leader-keys-major-mode
     :keymaps 'lsp-ui-mode-map
     "p" '(:ignore t :wk "peek")
     "pd" 'lsp-ui-peek-find-definitions
     "pr" 'lsp-ui-peek-find-references)
   (my/leader-keys-major-mode
     :keymaps 'python-mode-map
     "u" 'my/toggle-lsp-ui-mode)
   (setq lsp-ui-sideline-delay 0
	  lsp-ui-peek-always-show t
	  lsp-ui-doc-use-childframe t
	  lsp-ui-doc-enable nil
	  lsp-ui-flycheck-enable t
	  lsp-ui-sideline-show-hover nil))
 ;;;###autoload
 (defun my/toggle-lsp-ui-mode ()
   (interactive)
   (if (bound-and-true-p lsp-ui-doc-mode)
	(progn
	  (lsp-ui-sideline-mode -1)
	  (lsp-ui-doc-mode -1)
	  (message "Lsp ui sideline/doc mode disabled in current buffer"))
     (progn
	(lsp-ui-sideline-mode 1)
	(lsp-ui-doc-mode 1)
	(message "Lsp ui sideline/doc mode enabled in current buffer"))))

lsp python ms

(use-package lsp-python-ms
  :after (lsp python)
  :init
  (add-hook 'python-mode-hook (lambda () (lsp-deferred)))
  :config
  ;; for dev build of language server
  (setq lsp-python-ms-dir
	  (expand-file-name "~/Program/python-language-server/output/bin/Release/"))
  ;; for executable of language server, if it's not symlinked on your PATH
  (setq lsp-python-ms-executable
	  "~/Program/python-language-server/output/bin/Release/linux-x64/publish/Microsoft.Python.LanguageServer"))

lsp pyright

(use-package lsp-pyright
  :hook (python-mode . (lambda ()
			    (require 'lsp-pyright)
			    (lsp-deferred)))
  :config
  (setq lsp-pyright-multi-root nil))

lsp latex

(use-package lsp-latex
  :load-path "~/Program/lsp-latex"
  :config
  (setq lsp-latex-texlab-executable "~/Program/texlab/texlab")
  (add-to-list 'lsp-language-id-configuration '(latex-mode . "latex")))

writing

academic phrases

(use-package academic-phrases
  :general
  (my/leader-keys-major-mode
    :keymaps 'LaTeX-mode-map
    "iP" 'academic-phrases
    "iS" 'academic-phrases-by-section)
  (my/leader-keys-major-mode
    :keymaps 'org-mode-map
    "iP" 'academic-phrases
    "iS" 'academic-phrases-by-section))

artbollocks

(use-package artbollocks-mode
  :diminish artbollocks-mode
  :ghook ('(org-mode-hook
	      LaTeX-mode-hook))
  :config
  (setq artbollocks-jargon nil
	  artbollocks-passive-voice nil))

synosaurus

(use-package synosaurus
  :commands (synosaurus-lookup synosaurus-choose-and-replace)
  :init
  (my/leader-keys
    "xSl" 'synosaurus-lookup
    "xSr" 'synosaurus-choose-and-replace)
  :config
  (setq synosaurus-backend 'synosaurus-backend-wordnet
	  synosaurus-choose-method 'ivy-read))

langtool

(use-package langtool
  :general
  (my/leader-keys
    "Sc" 'langtool-check
    "SC" 'langtool-correct-buffer
    "Sq" 'langtool-check-done)
  :config
  (setq langtool-java-classpath "/usr/share/languagetool:/usr/share/java/languagetool/*"))

wordnut

(use-package wordnut
  :general
  (my/leader-keys
    "a M-w" 'wordnut-search)
  (my/normal-keys
    :keymaps 'wordnut-mode-map
    "q" 'quit-window))

dict

youdao dictionary

 (use-package youdao-dictionary
   :commands youdao-dictionary-search-from-input
   :init
   (progn
     (my/leader-keys
	"aw" 'youdao-dictionary-search-from-input)))

tools

paradox

 (use-package paradox
   :commands (paradox-list-packages)
   :init
   (progn
     (my/leader-keys
	"ak" 'paradox-list-packages))
   :config
   (setq paradox-github-token t)
   (my/normal-keys
     :keymaps 'paradox-menu-mode-map
     :states 'motion
     "i" 'package-menu-mark-install
     "d" 'package-menu-mark-delete
     "U" 'package-menu-mark-upgrades
     "u" 'package-menu-mark-unmark
     "x" 'package-menu-execute
     "q" 'paradox-quit-and-close))

ranger

(use-package ranger
  :general
  (my/leader-keys
    "ar" 'ranger
    "ad" 'deer)
  :config
  (my/motion-keys
    :keymaps 'ranger-mode-map
    "M-g" 'ranger-go
    "gg" 'ranger-goto-top))

pdf tools

 (use-package pdf-tools
   :diminish pdf-view-midnight-minor-mode
   :mode (("\\.pdf\\'" . pdf-view-mode))
   :config
   (progn
     (require 'pdf-occur)
     (require 'pdf-sync)
     (pdf-tools-install :no-query)

     (defhydra hydra-zoom-pdf ()
	"zoom-pdf"
	("i" pdf-view-enlarge "in")
	("o" pdf-view-shrink "out")
	("w" pdf-view-fit-width-to-window "width")
	("p" pdf-view-fit-page-to-window "page")
	("q" nil "quit"))
     (my/leader-keys-major-mode
	:keymaps 'pdf-view-mode-map
	"z" 'hydra-zoom-pdf/body))
   (add-hook 'pdf-view-mode-hook (lambda()
				    (display-line-numbers-mode -1)
				    (set (make-local-variable 'evil-normal-state-cursor) (list nil))
				    (set (make-local-variable 'evil-insert-state-cursor) (list nil))
				    (set (make-local-variable 'evil-visual-state-cursor) (list nil))))
   (add-hook 'pdf-view-mode-hook (lambda() (pdf-view-midnight-minor-mode 1)))
   ;;turn off cua so copy works
   (add-hook 'pdf-view-mode-hook (lambda () (cua-mode 0)))
   (add-hook 'pdf-view-mode-hook #'pdf-tools-enable-minor-modes)
   :init
   (my/normal-keys
     ;; :states '(normal)
     :keymaps 'pdf-view-mode-map
     ;; navigation
     "J" '(lambda() (interactive) (pdf-view-next-line-or-next-page 35))
     "j" '(lambda() (interactive) (pdf-view-next-line-or-next-page 10))
     "K" '(lambda() (interactive) (pdf-view-previous-line-or-previous-page 35))
     "k" '(lambda() (interactive) (pdf-view-previous-line-or-previous-page 10))
     "h" '(lambda() (interactive) (image-backward-hscroll 20))
     "l" '(lambda() (interactive) (image-forward-hscroll 20))
     "u" 'pdf-view-scroll-down-or-previous-page
     "d" 'pdf-view-scroll-up-or-next-page
     "f" 'pdf-view-next-page
     "b" 'pdf-view-previous-page
     "gg"  'pdf-view-first-page
     "G"  'pdf-view-last-page
     ;; scale/fit
     "w" 'pdf-view-fit-width-to-window
     "H" 'pdf-view-fit-height-to-window
     "p" 'pdf-view-fit-page-to-window
     ;; Search
     "/" 'isearch-forward
     "?" 'isearch-backward
     ;; Actions
     "r"   'pdf-view-revert-buffer
     "o"   'pdf-links-action-perform
     "O"   'pdf-outline
     "zr"  'pdf-view-scale-reset
     "C-s" 'isearch-forward)
   :general
   (:states '(normal visual)
    :keymaps 'pdf-outline-buffer-mode-map
    "RET" 'pdf-outline-follow-link
    "M-RET" 'pdf-outline-follow-link-and-quit
    "TAB" 'pdf-outline-toggle-subtree
    "q" 'pdf-outline-quit)
   (my/leader-keys-major-mode
     ;; :states 'normal
     :keymaps 'pdf-view-mode-map
     :major-modes t
     ;; Slicing image
     "s" '(:ignore t :which-key "slice/occur")
     "sm" 'pdf-view-set-slice-using-mouse
     "sb" 'pdf-view-set-slice-from-bounding-box
     "sr" 'pdf-view-reset-slice
     ;; Annotations
     "a" '(:ignore t :which-key "annotation")
     "aD" 	'pdf-annot-delete
     "at" 	'pdf-annot-attachment-dired
     "ah" 	'pdf-annot-add-highlight-markup-annotation
     "al" 	'pdf-annot-list-annotations
     "am" 	'pdf-annot-add-markup-annotation
     "ao" 	'pdf-annot-add-strikeout-markup-annotation
     "as" 	'pdf-annot-add-squiggly-markup-annotation
     "at" 	'pdf-annot-add-text-annotation
     "au" 	'pdf-annot-add-underline-markup-annotation
     "b" 'pdf-isearch-sync-backward
     ;; Fit image to window
     "f" '(:ignore t :which-key "fit")
     "fw" 'pdf-view-fit-width-to-window
     "fh" 'pdf-view-fit-height-to-window
     "fp" 'pdf-view-fit-page-to-window
     ;; Other
     "ss" 'pdf-occur
     "p" 'pdf-misc-print-document
     "O" 'pdf-outline
     "m" 'pdf-view-midnight-minor-mode)
   (my/normal-keys
     :keymaps 'pdf-occur-buffer-mode-map
     "d" 'pdf-occur-view-occurrence
     "RET" 'pdf-occur-goto-occurrence
     "q" 'tablist-quit)
   (my/leader-keys-major-mode
     :keymaps 'LaTeX-mode-map
     "M-f" 'pdf-sync-forward-search))

org pdftools

(use-package org-pdftools
  :hook (org-load . org-pdftools-setup-link))

keyfreq

 (use-package keyfreq
   :config
   (keyfreq-mode 1)
   (keyfreq-autosave-mode 1)
   (setq keyfreq-excluded-commands
	'(self-insert-command
	  abort-recursive-edit
	  ace-jump-done
	  ace-jump-move
	  backward-char
	  backward-kill-word
	  backward-word
	  browse-kill-ring-forward
	  browse-kill-ring-insert-and-quit
	  browse-kill-ring-quit
	  clipboard-kill-ring-save
	  comint-send-input
	  company-complete-common
	  company-complete-number
	  company-complete-selection
	  company-ignore
	  delete-backward-char
	  describe-variable
	  dired ; nothing to optimize in dired
	  dired-do-async-shell-command
	  dired-find-file
	  diredp-next-line
	  diredp-previous-line
	  erase-message-buffer
	  eval-buffer
	  evil-a-WORD
	  evil-append
	  evil-backward-char
	  evil-backward-word-begin
	  evil-change
	  evil-change-line
	  evil-complete-next
	  evil-complete-previous
	  evil-delete
	  evil-delete-backward-char-and-join
	  evil-delete-char
	  evil-delete-line
	  evil-emacs-state
	  evil-end-of-line
	  evil-escape-emacs-state
	  evil-escape-insert-state
	  evil-escape-isearch
	  evil-escape-minibuffer
	  evil-escape-motion-state
	  evil-escape-visual-state
	  evil-ex
	  evil-ex-command
	  evil-ex-completion
	  evil-ex-delete-backward-char
	  evil-exit-emacs-state
	  evil-exit-visual-state
	  evil-filepath-inner-text-object
	  evil-filepath-outer-text-object
	  evil-find-char
	  evil-find-char-to
	  evil-first-non-blank
	  evil-force-normal-state
	  evil-forward-char
	  evil-forward-word-begin
	  evil-forward-word-end
	  evil-goto-definition
	  evil-goto-first-line
	  evil-goto-line
	  evil-goto-mark-line
	  evil-inner-WORD
	  evil-inner-double-quote
	  evil-inner-single-quote
	  evil-inner-word
	  evil-insert
	  evil-join
	  evil-jump-backward
	  evil-jump-forward
	  evil-mc-make-and-goto-next-match
	  evil-next-line
	  evil-next-visual-line
	  evil-normal-state
	  evil-open-below
	  evil-paste-after
	  evil-paste-before
	  evil-previous-line
	  evil-previous-visual-line
	  evil-record-macro
	  evil-repeat
	  evil-replace
	  evil-ret
	  evil-scroll-page-down
	  evil-scroll-page-up
	  evil-substitute
	  evil-visual-block
	  evil-visual-char
	  evil-visual-line
	  evil-yank
	  exit-minibuffer
	  ffip
	  forward-char
	  forward-word
	  gnus
	  gnus-summary-exit
	  gnus-summary-next-page
	  gnus-summary-scroll-up
	  gnus-topic-select-group
	  goto-line
	  hippie-expand
	  ido-complete
	  ido-delete-backward-updir
	  ido-exit-minibuffer
	  ido-switch-buffer
	  indent-new-comment-line
	  isearch-abort
	  isearch-backward-regexp
	  isearch-cancel
	  isearch-delete-char
	  isearch-exit
	  isearch-forward-regexp
	  isearch-other-control-char
	  isearch-other-meta-char
	  isearch-printing-char
	  isearch-repeat-forward
	  isearch-ring-retreat
	  ispell-minor-check
	  ivy-backward-delete-char
	  ivy-done
	  ivy-next-line
	  ivy-occur-next-line
	  ivy-occur-previous-line
	  ivy-previous-line
	  js-mode
	  js2-line-break
	  keyboard-escape-quit
	  keyboard-quit
	  keyfreq-mode
	  keyfreq-save-now
	  keyfreq-show
	  kill-sentence
	  left-char
	  markdown-exdent-or-delete
	  minibuffer-complete
	  minibuffer-complete-and-exit
	  minibuffer-keyboard-quit
	  move-beginning-of-line
	  move-end-of-line
	  mwheel-scroll
	  my-setup-develop-environment
	  newline-and-indent
	  next-history-element
	  next-line
	  org-beginning-of-line
	  org-ctrl-c-ctrl-c
	  org-cycle
	  org-delete-backward-char
	  org-end-of-line
	  org-force-self-insert
	  org-return
	  org-self-insert-command
	  org-todo
	  orgtbl-self-insert-command
	  package-menu-execute
	  paredit-backward-delete
	  paredit-backward-kill-word
	  paredit-close-round
	  paredit-doublequote
	  paredit-newline
	  paredit-open-round
	  paredit-semicolon
	  pcomplete
	  previous-history-element
	  previous-line
	  push-button
	  pwd
	  quit-window
	  right-char
	  save-buffers-kill-terminal
	  scroll-down-command
	  scroll-up-command
	  select-window-0
	  select-window-1
	  select-window-2
	  select-window-3
	  select-window-4
	  select-window-5
	  select-window-6
	  select-window-7
	  select-window-8
	  select-window-9
	  self-insert-command
	  smarter-move-beginning-of-line
	  suspend-frame
	  term-send-raw
	  turnon-keyfreq-mode
	  undefined ;; lambda function
	  undo-tree-redo
	  undo-tree-undo
	  w3m-goto-url
	  w3m-next-anchor
	  w3m-view-this-url
	  web-mode
	  web-mode-complete
	  web-mode-jshint
	  web-mode-navigate
	  web-mode-part-beginning
	  web-mode-reload
	  web-mode-reveal
	  web-mode-surround
	  web-mode-tag-beginning
	  web-mode-test
	  yank
	  yas-compile-directory
	  yas-expand
	  yas-next-field-or-maybe-expand
	  )))

elfeed related

elfeed

 (use-package elfeed
   :commands (elfeed elfeed-db-load)
   :init (my/leader-keys "af" 'my/elfeed-load-db-and-open)
   :config
   (progn
     (elfeed-goodies/setup)
     (setf elfeed-curl-extra-arguments '("--socks5-hostname" "127.0.0.1:1080"))
     (my/normal-keys
	:keymaps 'elfeed-search-mode-map
	"c"  'elfeed-db-compact
	"u" 'elfeed-update
	"U" 'elfeed-search-update--force
	"gu" 'elfeed-unjam
	"o"  'elfeed-load-opml
	"w"  'elfeed-web-start
	"W"  'elfeed-web-stop
	"q" 'my/elfeed-save-db-and-bury
	"RET" 'elfeed-search-show-entry
	"f" 'elfeed-search-live-filter
	"r" 'my/elfeed-tag-read)
     (my/normal-keys
	:keymaps 'elfeed-show-mode-map
	"C-j" 'elfeed-show-next
	"C-k" 'elfeed-show-prev
	"q" 'elfeed-search-quit-window)
     (my/normal-keys
	:keymaps 'elfeed-search-mode-map
	:states 'normal
	"+"  'elfeed-search-tag-all
	"-"  'elfeed-search-untag-all
	"b"  'elfeed-search-browse-url
	"y"  'elfeed-search-yank))
   ;; (setq elfeed-feeds
   ;;       '(("http://nullprogram.com/feed/" blog emacs)))
   )

elfeed goodies

 (use-package elfeed-goodies
     :commands elfeed-goodies/setup
     :config
     (progn
	(elfeed-goodies/setup)
	(setq elfeed-goodies/feed-source-column-width 40)
	(my/normal-keys
	 :keymaps 'elfeed-show-mode-map
	 "o" 'elfeed-goodies/show-ace-link)))

elfeed org

(use-package elfeed-org
  :after (org elfeed)
  :commands my/elfeed-load-db-and-open
  :config
  (elfeed-org)
  (setq rmh-elfeed-org-files (list "~/.emacs.d/init.org")))

Blogs

Software
Emacs
http://planet.emacsen.org/atom.xmlhttp://pragmaticemacs.com/feed/http://blog.binchen.org/rss.xml
Person
http://feeds.sachachua.com/sachac
Blogs
Comic
http://xkcd.com/rss.xml
News
Reuters
http://feeds.reuters.com/reuters/topNewshttp://feeds.reuters.com/reuters/technologyNews
Science
Science Daily
https://www.sciencedaily.com/rss/computers_math/computer_science.xml
Science American
http://rss.sciam.com/ScientificAmerican-Global

autoload

;;functions to support syncing .elfeed between machines
;;makes sure elfeed reads index from disk before launching
;;;###autoload
(defun my/elfeed-load-db-and-open ()
  "Wrapper to load the elfeed db from disk before opening"
  (interactive)
  (elfeed-db-load)
  (elfeed)
  (elfeed-search-update--force))

;;write to disk when quiting
;;;###autoload
(defun my/elfeed-save-db-and-bury ()
  "Wrapper to save the elfeed db to disk before burying buffer"
  (interactive)
  (elfeed-db-save)
  (quit-window))

;;;###autoload
(defun my/elfeed-tag-read (entry)
  (interactive (list (elfeed-search-selected :ignore-region)))
  (require 'elfeed-show)
  (when (elfeed-entry-p entry)
    (elfeed-untag entry 'unread)
    (elfeed-search-update-entry entry)
    (forward-line)))

shell

eshell

 (use-package eshell
   :commands eshell
   :config
   (progn
     (setq eshell-cmpl-cycle-completions nil)
     (add-hook 'eshell-mode-hook 'my/eshell-set-keys)
     (add-hook 'eshell-after-prompt-hook 'my//protect-eshell-prompt)
     (defun my/eshell-set-keys ()
	(my/all-states-keys
	  :keymaps 'eshell-mode-map
	  "C-j" 'eshell-next-input
	  "C-k" 'eshell-previous-input))
     (defun my//protect-eshell-prompt ()
	"Protect Eshell's prompt like Comint's prompts.
 E.g. `evil-change-whole-line' won't wipe the prompt. This
 is achieved by adding the relevant text properties."
	(let ((inhibit-field-text-motion t))
	  (add-text-properties
	   (point-at-bol)
	   (point)
	   '(rear-nonsticky t
			    inhibit-line-move-field-capture t
			    field output
			    read-only t
			    front-sticky (field inhibit-line-move-field-capture)))))))

shell pop

(use-package shell-pop
  :general
  (my/leader-keys
    "'" 'shell-pop
    "as" 'eshell)
  :init
  (setq shell-pop-shell-type (quote ("vterm" "*vterm*" (lambda nil (vterm))))
	  shell-pop-full-span t))

eshell z

(use-package eshell-z
  :after eshell)

eshell prompt extras

(use-package eshell-prompt-extras
  :after eshell
  :config
  (setq eshell-highlight-prompt nil
	  eshell-prompt-function 'epe-theme-pipeline)
  (custom-set-faces '(epe-pipeline-delimiter-face ((t (:forground lazy-highlight))))))

emacs libvterm

(use-package vterm
  :init
  (add-hook 'vterm-mode-hook
	      (lambda () (display-line-numbers-mode -1))))

ledger related

ledger

 (use-package ledger-mode
   :mode ("\\.\\(ledger\\|ldg\\)\\'" . ledger-mode)
   :init
   (progn
     (setq ledger-post-amount-alignment-column 62)
     (my/leader-keys-major-mode
	:keymaps 'ledger-mode-map
	"hd" 'ledger-delete-current-transaction
	"a" 'ledger-add-transaction
	"b" 'ledger-post-edit-amount
	"c" 'ledger-toggle-current
	"C" 'ledger-mode-clean-buffer
	"l" 'ledger-display-ledger-stats
	"p" 'ledger-display-balance-at-point
	"q" 'ledger-post-align-xact
	"R" 'ledger-reconcile
	"r" 'ledger-report
	"t" 'ledger-insert-effective-date)
     (my/leader-keys-major-mode
	:keymaps 'ledger-reconcile-mode-map
	"a" 'ledger-reconcile-add
	"q" 'ledger-reconcile-quit
	"t" 'ledger-reconcile-change-target
	"RET" 'ledger-reconcile-finish)))

evil ledger

(use-package evil-ledger
  :diminish evil-ledger-mode
  :after ledger-mode
  :config
  (setq evil-ledger-sort-key "S")
  (add-hook 'ledger-mode-hook #'evil-ledger-mode))

flycheck ledger

(use-package flycheck-ledger
  :after (ledger flycheck))

atomic chrome

(use-package atomic-chrome
  :config
  (atomic-chrome-start-server))

crux

(use-package crux
  :general
  (my/all-states-keys
    "C-a" 'crux-move-beginning-of-line)
  (my/leader-keys
    "f M-r" 'crux-rename-file-and-buffer
    "f M-o" 'crux-open-with
    "f M-e" 'my/open-with-evince
    "fi" 'my/find-user-init-org-file)
  :init
  (with-eval-after-load 'counsel
    (ivy-add-actions
     'counsel-find-file
     '(("e" my/open-with-evince "evince"))))
  :config
  (crux-with-region-or-buffer indent-region))

;;;###autoload
(defun my/open-with-evince (&optional x)
  (interactive)
  (call-process "okular" nil 0 nil (or x buffer-file-name)))

;;;###autoload
(defun my/find-user-init-org-file ()
  (interactive)
  (find-file (expand-file-name (concat user-emacs-directory "init.org"))))

neotree

 (use-package neotree
   :commands neo-global--window-exists-p
   :init
   (progn
     (setq neo-window-width 25
	    neo-create-file-auto-open t
	    neo-banner-message "Press ? for neotree help"
	    neo-show-updir-line nil
	    neo-mode-line-type 'neotree
	    neo-smart-open t
	    neo-dont-be-alone t
	    neo-persist-show nil
	    neo-show-hidden-files t
	    neo-auto-indent-point t
	    neo-modern-sidebar t
	    neo-vc-integration nil
	    neo-theme 'ascii)
     (when (eq 'darwin system-type)
	(setq neo-default-system-application "open"))
     (my/leader-keys
	"fT" 'neotree-toggle
	"ft" 'neotree-show
	"pt" 'neotree-find-project-root))
   :config
   (progn
     (my/normal-keys
	:keymaps 'neotree-mode-map
	(kbd "<return>") (neotree-make-executor
			  :file-fn 'neo-open-file
			  :dir-fn 'neo-open-dir)
	(kbd "<tab>") (neotree-make-executor
		       :dir-fn 'neo-open-dir)
	"z" (neotree-make-executor
	     :dir-fn 'neo-open-dir)
	"ZZ" 'quit-window
	"gd" (neotree-make-executor
	      :dir-fn 'neo-open-dired)
	"gD" (neotree-make-executor
	      :dir-fn 'neo-open-dired)
	"go" (neotree-make-executor
	      :file-fn 'neo-open-file
	      :dir-fn 'neo-open-dir)
	"gO" 'neotree-quick-look
	"gr" 'neotree-refresh
	"q" 'neotree-hide
	"H" 'neotree-hidden-file-toggle
	"gh" 'neotree-hidden-file-toggle
	(kbd "C-k") 'neotree-select-up-node
	"gk" 'neotree-select-up-node
	"[" 'neotree-select-up-node
	(kbd "C-j") 'neotree-select-down-node
	"gj" 'neotree-select-down-node
	"]" 'neotree-select-down-node
	"gv" 'neotree-open-file-in-system-application
	"c" 'neotree-create-node
	"y" 'neotree-copy-node
	"r" 'neotree-rename-node
	"R" 'neotree-change-root
	"d" 'neotree-delete-node
	"J" 'neotree-dir
	"+" 'neotree-stretch-toggle
	"=" 'neotree-stretch-toggle
	"ge" 'neotree-enter
	"j" 'neotree-next-line
	"k" 'neotree-previous-line
	;; Unchanged keybings.
	"a" (neotree-make-executor
	     :file-fn 'neo-open-file-ace-window)
	"|" (neotree-make-executor
	     :file-fn 'neo-open-file-vertical-split)
	"-" (neotree-make-executor
	     :file-fn 'neo-open-file-horizontal-split)
	"S" 'neotree-select-previous-sibling-node
	"s" 'neotree-select-next-sibling-node)
     (my/all-states-keys
	"M-0" 'neotree-show)
     (defun winum-assign-0-to-neotree ()
	(when (string-match-p (buffer-name) ".*\\*NeoTree\\*.*") 10))
     (add-to-list 'winum-assign-functions #'winum-assign-0-to-neotree)))

autoload functions

 ;;;###autoload
 (defun neotree-find-project-root ()
   (interactive)
   (if (neo-global--window-exists-p)
	(neotree-hide)
     (let ((origin-buffer-file-name (buffer-file-name)))
	(neotree-find (projectile-project-root))
	(neotree-find origin-buffer-file-name))))

pomodoro

(use-package pomodoro
  :ensure nil
  :load-path "~/Program/pomodoro.el"
  :commands pomodoro-start
  :init
  (my/leader-keys
    "ap" '(:ignore t :wk "pomodoro")
    "apb" 'pomodoro-start
    "app" 'pomodoro-pause
    "apr" 'pomodoro-resume
    "ape" 'pomodoro-stop)
  :config
  (setq pomodoro-time-format "%.2m"
	  pomodoro-work-time 25
	  pomodoro-break-time 5
	  pomodoro-work-cycle "W"
	  pomodoro-break-cycle "B"
	  pomodoro-show-number t
	  pomodoro-work-start-message "You are AWESOME! Let's back to work!"
	  pomodoro-break-start-message "You are AWESOME! Have a break!"
	  pomodoro-desktop-notification t))

nov

(use-package nov
  :mode ("\\.epub\\'" . nov-mode)
  :init
  (add-hook 'nov-mode-hook 'visual-line-mode)
  (add-hook 'nov-mode-hook 'visual-fill-column-mode)
  (add-hook 'nov-mode-hook (lambda ()
			       (setq visual-fill-column-center-text t)
			       (display-line-numbers-mode -1)))
  :config
  (setq visual-fill-column-center-text t)
  (my/normal-keys
    :keymaps 'nov-mode-map
    "H" 'nov-previous-document
    "L" 'nov-next-document
    "[" 'nov-previous-document
    "]" 'nov-next-document
    "d" 'nov-scroll-up
    "u" 'nov-scroll-down
    "gm" 'nov-display-metadata
    "gr" 'nov-render-document
    "gt" 'nov-goto-toc
    "gv" 'nov-view-source
    "gV" 'nov-view-content-source
    "q" 'quit-window))

toc org

(use-package toc-org
  :ghook ('org-mode-hook))

helpful

(use-package helpful
  :general
  (my/leader-keys
    "hf" 'helpful-callable
    "hv" 'helpful-variable
    "hp" 'helpful-at-point
    "hk" 'helpful-key
    "ha" 'helpful-symbol)
  :config
  (my/normal-keys
    :keymaps 'helpful-mode-map
    "o" 'ace-link-help
    "q" 'quit-window))

terminal here

(use-package terminal-here
  :commands (terminal-here
	       terminal-here-launch-in-directory)
  :general
  (my/leader-keys
    "aT" 'terminal-here)
  :config
  (setq terminal-here-terminal-command (list "urxvtc")))

;;;###autoload
(defun my/counsel-terminal-here (x)
  (terminal-here-launch-in-directory x))

(with-eval-after-load 'counsel
  (ivy-add-actions
   'counsel-find-file
   '(("t" my/counsel-terminal-here "terminal"))))

deft

(use-package deft
  :general
  (my/leader-keys
    "an" 'deft)
  :config
  (setq deft-directory "~/Dropbox/document/org/"
	  deft-recursive t
	  deft-window-width 100
	  deft-use-filename-as-title t
	  deft-extensions '("org" "md" "txt")
	  deft-text-mode 'org-mode
	  deft-use-filename-as-title t
	  deft-use-filter-string-for-filename 't)
  (my/leader-keys-major-mode
    :keymaps 'deft-mode-map
    "c" 'deft-filter-clear
    "i" 'deft-toggle-incremental-search
    "n" 'deft-new-file
    "N" 'deft-new-file-named
    "q" 'quit-window
    "o" 'deft-open-file-other-window
    "r" 'deft-rename-file))

proxy mode

(use-package proxy-mode
  :commands proxy-mode
  :config
  (setq url-gateway-local-host-regexp
	  (concat "\\`" (regexp-opt '("localhost" "127.0.0.1")) "\\'")))

spotify

(use-package spotify
  :general
  (my/leader-keys
    "amp" 'spotify-playpause
    "amn" 'spotify-next
    "amN" 'spotify-previous))

Chinese

pyim

pyim

 (use-package pyim
   :commands (pyim-convert-string-at-point toggle-input-method)
   :init
   :general
   ("M-j" 'pyim-convert-string-at-point)
   (:keymaps 'pyim-mode-map
    "," 'pyim-page-previous-page
    "." 'pyim-page-next-page)
   :config
   (setq pyim-fuzzy-pinyin-alist '(("s" "sh")
				    ("c" "ch")
				    ("z" "zh")
				    ("in" "ing")
				    ("en" "eng")
				    ("l" "n")))
   (setq default-input-method "pyim")
   (setq pyim-default-scheme 'quanpin)
   (setq-default pyim-english-input-switch-functions
		  '(pyim-probe-dynamic-english
		    pyim-probe-isearch-mode
		    pyim-probe-program-mode
		    pyim-probe-org-structure-template))

   (setq-default pyim-punctuation-half-width-functions
		  '(pyim-probe-punctuation-line-beginning
		    pyim-probe-punctuation-after-punctuation))
   (if (version<= "26.1" emacs-version)
	(progn
	  (setq pyim-page-tooltip 'posframe)))
   (setq pyim-page-length 7)

   (defun my-pyim-self-insert-command (orig-func)
     (interactive "*")
     (if (and (local-variable-p 'last-event-time)
	       (floatp last-event-time)
	       (< (- (float-time) last-event-time) 0.2))
	  (set (make-local-variable 'temp-evil-escape-mode) t)
	(set (make-local-variable 'temp-evil-escape-mode) nil))
     (if (or (and temp-evil-escape-mode
		   (equal (pyim-entered-get) "j")
		   (equal last-command-event ?k))
	      (and temp-evil-escape-mode
		   (equal (pyim-entered-get) "k")
		   (equal last-command-event ?j)))
	  (progn
	    (push last-command-event unread-command-events)
	    (pyim-outcome-handle 'pyim-entered)
	    (pyim-terminate-translation))
	(progn
	  (call-interactively orig-func)
	  (set (make-local-variable 'last-event-time) (float-time)))))

   (advice-add 'pyim-self-insert-command :around #'my-pyim-self-insert-command))

liberime

(use-package liberime
  :after pyim
  :load-path "~/Program/liberime"
  :config
  (liberime-start (expand-file-name "/usr/share/rime-data")
		    (expand-file-name "~/.emacs.d/pyim/rime"))
  (liberime-select-schema "luna_pinyin_simp")
  (setq pyim-default-scheme 'rime-quanpin))

emacs rime

(use-package rime
  :config
  (setq default-input-method "rime"
	  rime-user-data-dir "~/.config/fcitx/rime"
	  rime-show-candidate 'posframe
	  rime-posframe-style 'horizontal
	  rime-posframe-properties (list :internal-border-width 1)
	  rime-disable-predicates '(rime-predicate-evil-mode-p
				    rime-predicate-after-alphabet-char-p
				    rime-predicate-prog-in-code-p)))

cal china x

(use-package cal-china-x
  :after calendar)

ace pinyin

(use-package ace-pinyin
  :after avy
  :config
  (ace-pinyin-global-mode t))

finishing work

message startup time

(setq inhibit-startup-echo-area-message "yhxie")
(setq inhibit-startup-screen t)
(when (require 'time-date nil t)
    (message "Emacs startup time: %.2f seconds."
	       (time-to-seconds (time-since emacs-load-start-time))))

set best garbage collection threshold

 (setq gc-cons-threshold 800000
	gc-cons-percentage 0.1
	file-name-handler-alist my--file-name-handler-alist)