chunfengd / dotemacs

My .emacs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Emacs Configuration File

Table of Contents

introduction

This is an Emacs configuration file written in Org-mode. It is adapted from Lars Tveito’s excellent config file and Tianxiang Xiong’s config on GitHub.

other references

about me

(customize-set-variable 'user-full-name "chunfengd")
;; (customize-set-variable 'user-mail-address "")

dotemacs path

define my/path

(defvar my/dotemacs-home (file-name-directory load-file-name))

(defun my/path (path)
  (expand-file-name path my/dotemacs-home))

extra load path

(defun my/add-site-dir (site-dir)
  "Add a directory into `load-path'."
  (setq load-path
        (append
         (delq nil
               (mapcar (lambda (dir)
                         (unless (string-match-p "^\\." dir)
                           (expand-file-name dir site-dir)))
                       (directory-files site-dir)))
         load-path)))
(my/add-site-dir (my/path "site"))

how to install

After cloning from GitHub, there is no init.el file, only an init.org file (this file). To produce an init.el file, either:

tangle via org mode

Open init.org and call M-x org-babel-tangle, which extracts code blocks from the current file into init.el

tangle via command line

$ ./tangle.sh

or

$ \
emacs --batch \
        --eval "(require 'ob-tangle)" \
        --eval "(org-babel-tangle-file \"./init.org\")"

automatic tangling

To avoid having to tangle manually each time a change is made, we can add a function to after-save-hook to tangle the init.org after saving.

(defvar my/auto-tangle-init t "auto tangle dotemacs/init.org")
(defun my/tangle-init-file ()
  "Tangle the current buffer if it is the init.org file."
  (interactive)
  (when (and my/auto-tangle-init
             (equal (buffer-file-name) (my/path "init.org")))
    (org-babel-tangle)))

(defun my/toggle-auto-tangle-init ()
  "auto tangle dotemacs/init.org"
  (interactive)
  (setq my/auto-tangle-init (not my/auto-tangle-init))
  (message "auto-tangle-init %s"
	   (if my/auto-tangle-init "enabled" "disabled"))
  (my/tangle-init-file))

(add-hook 'after-save-hook 'my/tangle-init-file)

add the following line into ~/.emacs.d/init.el

;; (load "~/dev/dotemacs/init.el")
(load "/path/to/init.el")

install icons

Run M-x all-the-icons-install-fonts

straight (deprecated)

add the following line into ~/.emacs.d/early-init.el

;; Disable package.el in favor of straight.el
(setq package-enable-at-startup nil)

install

https://jeffkreeftmeijer.com/emacs-straight-use-package/ https://github.com/radian-software/straight.el

(setq straight-repository-branch "master")

;; Install straight.el
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name
        "straight/repos/straight.el/bootstrap.el"
        user-emacs-directory))
      (bootstrap-version 6))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         (format
          "%s/%s/install.el"
          "https://raw.githubusercontent.com/radian-software/straight.el"
          straight-repository-branch)
         'silent
         'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

configure use-package to use straight

(straight-use-package 'use-package)
(use-package straight
  :custom
  (straight-use-package-by-default t))

package management

package init

(require 'package)
(setq package-archives
      '(
        ;; ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("melpa" . "https://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")
        ("elpa" . "https://elpa.gnu.org/packages/")
        ;; ("marmalade" . "https://marmalade-repo.org/packages/")
        ))
(package-initialize)
(unless package-archive-contents
  (package-refresh-contents nil))

use-package

github: https://github.com/jwiegley/use-package doc: https://jwiegley.github.io/use-package/

(unless (package-installed-p 'use-package)
  (package-install 'use-package))

(require 'use-package)
;; make sure packages are installed
(setq use-package-always-ensure t)

install packages manually

;; https://github.com/melpa/melpa/issues/7238
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(package-refresh-contents nil)
(package-install 'lsp-mode)

quelpa

(use-package quelpa)
(use-package quelpa-use-package)
(quelpa-use-package-activate-advice)

before key binding

basic

;; (load-theme 'wombat)
(setq inhibit-startup-message t)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(menu-bar-mode -1)
(set-fringe-mode 10)
(setq visible-bell t)

;; highlight current line
(global-hl-line-mode t)
(if (display-graphic-p)
    (set-face-background hl-line-face "grey20"))

(setq default-fill-column 70)

(setq-default scroll-margin 3
              scroll-conservatively 10000)

;; frame title
(when window-system
  (setq frame-title-format '(buffer-file-name "%f" ("%b"))))

;; frame
(when (display-graphic-p)
  (add-to-list 'default-frame-alist '(height . 42))
  (add-to-list 'default-frame-alist '(width . 85))
  (add-to-list 'default-frame-alist '(left . 650))
  (add-to-list 'default-frame-alist '(top . 100)))

(setq-default indent-tabs-mode nil)
(setq default-tab-width 8)
;; disable sentence end double space
(setq sentence-end-double-space nil)

;; delete selection
(delete-selection-mode 1)

move backup / auto save files out of cwd

  • #xxx# files: emacs#Auto Save Files
  • xxx~ files: emacs#Backup Files/Names
  • .#xxx files: emacs#Interlocking
;; (setq-default make-backup-files nil)
;; https://emacs.stackexchange.com/questions/17210/how-to-place-all-auto-save-files-in-a-directory
;; https://superuser.com/questions/131538/can-i-create-directories-that-dont-exist-while-creating-a-new-file-in-emacs
;; https://emacsredux.com/blog/2013/05/09/keep-backup-and-auto-save-files-out-of-the-way/
(let ((my-backup-directory "~/.emacs-saves/"))
  (unless (file-exists-p my-backup-directory)
    (message "creating backup dir: %s" my-backup-directory)
    (make-directory my-backup-directory t))
  ;; `xxx~` files
  (setq backup-directory-alist
        `((".*" . ,my-backup-directory)))
  ;; `#xxx#` files
  (setq auto-save-file-name-transforms
        `((".*" ,my-backup-directory t)))
  ;; `.#xxx` interlocking files
  (setq lock-file-name-transforms
        `((".*" ,my-backup-directory t)))
  )

key binding

switch C-c & C-g

(keyboard-translate ?\C-c ?\C-g)
(keyboard-translate ?\C-g ?\C-c)

set key bindings function

(defun my/set-key-bindings (action bind-list &optional map)
  "Set key bindings. 'bind-list' is 2-D list."
  (dolist (pair bind-list)
    (if (null map)
	(funcall action (eval `(kbd ,(nth 0 pair))) (nth 1 pair))
      (funcall action map (eval `(kbd ,(nth 0 pair))) (nth 1 pair)))))

global keys

(my/set-key-bindings
 'global-set-key
 '(
   ("C-?" help-command)
   ("C-c C-c" comment-or-uncomment-region)
   ;; ("C-x C-b" consult-buffer)
   ;; ("C-x b" list-buffers)
   ("C-x b" consult-buffer)
   ))
(global-set-key [(hyper c)] 'kill-ring-save)
(global-set-key [(hyper v)] 'yank)

mac key

(cond
 ((string-equal system-type "windows-nt")
  ;; windows
  (progn
    ))
 ((string-equal system-type "darwin")
  ;; mac os x
  (progn
    ;; (setq mac-option-key-is-meta t)
    ;; (setq mac-command-key-is-meta nil)

    ;; works for Emacs Mac Port: https://github.com/railwaycat/homebrew-emacsmacport
    ;; switch key https://gist.github.com/railwaycat/3498096
    (setq mac-option-modifier 'meta)
    (setq mac-command-modifier 'hyper)
    ))
 ((string-equal system-type "gnu/linux")
  (message "linux")
  (progn
    (defconst my/system-include-dirs nil))))

evil

;; Make ESC quit prompts
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

(use-package undo-tree
  :init
  (setq undo-tree-auto-save-history nil)
  (global-undo-tree-mode 1))

(use-package evil
  :init
  (setq evil-want-integration t)
  (setq evil-want-keybinding nil)
  (setq evil-want-C-i-jump t)
  (setq evil-want-C-u-scroll t)
  (setq evil-want-Y-yank-to-eol t)
  (setq evil-shift-width 2)
  (setq evil-undo-system 'undo-tree)
  (setq evil-respect-visual-line-mode nil)
  :config
  (evil-mode 1)
  (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
  (define-key evil-insert-state-map (kbd "C-h")
    'evil-delete-backward-char-and-join)
  (define-key evil-replace-state-map (kbd "C-g") 'evil-normal-state)
  (define-key evil-replace-state-map (kbd "C-h")
    'evil-delete-backward-char-and-join)
  ;(define-key evil-insert-state-map (kbd "C-n") nil)
  (define-key evil-normal-state-map (kbd "C-.") nil)

  ;; Use visual line motions even outside of visual-line-mode buffers
  (evil-global-set-key 'motion "j" 'evil-next-visual-line)
  (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
  (evil-global-set-key 'motion "0" 'evil-beginning-of-visual-line)
  (evil-global-set-key 'motion "$" 'evil-end-of-visual-line)
  (evil-global-set-key 'motion "gj" 'evil-next-line)
  (evil-global-set-key 'motion "gk" 'evil-previous-line)
  (evil-global-set-key 'motion "g0" 'evil-beginning-of-line)
  (evil-global-set-key 'motion "g$" 'evil-end-of-line)

  ;; https://evil.readthedocs.io/en/latest/settings.html#the-initial-state
  ;; config initial-state
  ;;  - 'normal
  ;;  - 'insert
  ;;  - 'emacs
  (evil-set-initial-state 'messages-buffer-mode 'normal)
  (evil-set-initial-state 'dashboard-mode 'normal)
  ;; don't use evil in term-mode
  ;; (evil-set-initial-state 'term-mode 'emacs)
  )

evil-collection

https://github.com/emacs-evil/evil-collection

(use-package evil-collection
  :after evil
  :config
  (evil-collection-init)
  ;; (setq evil-collection-term-sync-state-and-mode-p nil)
  )

which-key

https://github.com/justbur/emacs-which-key

(use-package which-key
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 0.6))

general leader

(use-package general
  :after evil which-key
  :config
  (general-create-definer my/leader-keys
    :keymaps '(normal insert visual emacs)
    :prefix "SPC"
    :global-prefix "C-M-SPC")
  )

my/leader-keys

(my/leader-keys
  ;; x
  "x" '(:ignore t :which-key "x")
  "xf" 'find-file
  "x/" 'find-file-other-window
  ;;"xb" 'switch-to-buffer
  ;; consult-buffer shortcut
  ;;   b<spc> Buffers
  ;;   <spc> Hidden buffers
  ;;   *<spc> Modified buffers
  ;;   f<spc> files
  ;;   r<spc> file registers
  ;;   m<spc> bootmarks
  ;;   p<spc> project
  "xb" 'consult-buffer
  "xp" 'consult-projectile
  "xk" 'kill-buffer
  "xs" 'save-buffer
  "xc" 'save-buffers-kill-terminal
  "xg" 'save-buffers-kill-terminal

  ;; x5
  "x5" '(:ignore t :which-key "x5")
  "x52" 'make-frame-command

  ;; h
  "h" '(:ignore t :which-key "help")
  "hk" 'describe-key
  "hf" 'describe-function
  "hv" 'describe-variable
  "hm" 'describe-mode
  "hb" 'describe-bindings
  )
(my/leader-keys
  "p" '(:ignore t :which-key "projectile")
  "pp" 'consult-projectile
  )
(my/leader-keys
  "v" '(:ignore t :which-key "vertico")
  "vl" 'consult-line
  "vg" 'consult-grep
  "vG" 'consult-git-grep
  "vr" 'consult-ripgrep
  "vy" 'consult-yank-pop
  "vm" 'consult-mark
  )
(my/leader-keys
  "o" '(:ignore t :which-key "org")

  "oh" 'consult-org-heading

  "oi" 'org-insert-structure-template
  "os" 'org-edit-special
  "oe" 'org-edit-src-exit

  "ob" 'org-backward-heading-same-level
  "of" 'org-forward-heading-same-level
  "on" 'outline-next-visible-heading
  "op" 'outline-previous-visible-heading
  "ou" 'outline-up-heading
  )

jump (avy)

(use-package avy
  :after general
  :config
  (my/leader-keys
    ;; avy jump
    "j"  '(:ignore t :which-key "jump")
    "jj"  'avy-goto-word-1
    "jk"  'avy-goto-word-0
    "jf"  'avy-goto-char-2
    "jg"  'avy-goto-char
    "jl"  'avy-goto-line)
  )

after key binding

exec-path-from-shell

(if (package-installed-p 'exec-path-from-shell)
    (progn
     (require 'exec-path-from-shell)
     (cond
      ((string-equal system-type "windows-nt")
       ;; windows
       (progn
         (exec-path-from-shell-initialize)))
      ((string-equal system-type "darwin")
       ;; mac os x
       (progn
         (exec-path-from-shell-initialize)))))
  (message "exec-path-from-shell not installed"))

auto reload

(global-auto-revert-mode t)

uniquify buffer name

(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

default major mode

(setq default-major-mode 'text-mode)

electric pair

(electric-pair-mode 1)
(defun my/inhibit-electric-pair (char)
  (minibufferp))
(setq electric-pair-inhibit-predicate #'my/inhibit-electric-pair)

daemon server

(setq server-name "emacs-server")
(server-start)

narrow

;; Enable narrow-to-region
(put 'narrow-to-region 'disabled nil)

save place

When you visit a file, point goes to the last place where it was when you previously visited the same file.

(setq save-place-file (concat user-emacs-directory "places"))
(save-place-mode 1) 

speed bar

(add-hook
 'speedbar-load-hook
 '(lambda ()
    (add-to-list 'speedbar-frame-parameters '(width . 35))
    (setq speedbar-show-unknown-files t)
    (display-line-numbers-mode 0)))

diff

(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq diff-switches "-u")

doom-modeline

https://github.com/seagle0128/doom-modeline

;; Install icons for doom
;; Run M-x all-the-icons-install-fonts to install
(use-package all-the-icons
  :if (display-graphic-p))

(use-package doom-modeline
  :init (doom-modeline-mode 1)
  :custom
  ((doom-modeline-height 15)
   ))

doom-theme

(use-package doom-themes
  :init (load-theme 'doom-vibrant t))

line number

(global-display-line-numbers-mode)
;; (setq display-line-numbers-type 'visual)
(setq display-line-numbers-type t)
(dolist (mode '(org-mode-hook
                shell-mode-hook
                term-mode-hook
                eshell-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 0))))

parenthesis

(show-paren-mode)
(setq show-paren-style 'mixed)

rainbow-delimiters

https://github.com/Fanael/rainbow-delimiters

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

font

defaults

https://zzamboni.org/post/beautifying-org-mode-in-emacs/

(defvar my/default-font-size 128)
(defvar my/default-variable-font-size 135)

(set-face-attribute 'default
                    nil
                    :height my/default-font-size)

;; Set the fixed pitch face
;; On Mac, find "family" in the "Font Book" application.
(set-face-attribute 'fixed-pitch
                    nil
                    :family (face-attribute 'default :family)
                    ;; :font "Fira Code Retina"
                    :height my/default-font-size)

;; Set the variable pitch face
(set-face-attribute 'variable-pitch
                    nil
                    :family "Helvetica"
                    :height my/default-variable-font-size
                    :weight 'regular)

old font

(cond
 ;; windows
 ((string-equal system-type "windows-nt")
  (progn
    (set-default-font "Consolas:pixelsize=14:antialias=subpixel")
    (set-fontset-font "fontset-default"
		      'han '("Microsoft Yahei" . "unicode-bmp"))
    (add-to-list 'default-frame-alist
		 '(font . "Consolas:pixelsize=14:antialias=subpixel"))))
 ((string-equal system-type "darwin")
  (progn
    (setq default-directory "~/")
    (if (display-graphic-p)
        (set-fontset-font
         t 'han (font-spec :name "Songti SC")))))
 ;; linux
 ((string-equal system-type "gnu/linux")))

recent files

(use-package recentf
  :init (recentf-mode)
  :config
  (setq recentf-max-saved-items 200
        recentf-max-menu-items 15)
  )

auto save

(defvar my/disable-idle-timer nil
  "Function passed to `my/run-with-idle-timer' is run immediately.")

(defun my/run-with-idle-timer (seconds func)
  "After SECONDS, run function FUNC once."
  (cond
   (my/disable-idle-timer
    (funcall func))
   (t
    (run-with-idle-timer seconds nil func))))

(defun setup-auto-save ()
  (autoload 'auto-save-enable "auto-save" "" t)
  (with-eval-after-load 'auto-save
    ;; (push 'my-file-too-big-p auto-save-exclude)
    ;; (push 'my-check-major-mode-for-auto-save auto-save-exclude)
    (setq auto-save-idle 1)
    (setq auto-save-slient t))
  (my/run-with-idle-timer 1 #'auto-save-enable))
(setup-auto-save)

my commands

find map of key binding

Find a key binding is in which map. From stackoverflow

(defun my/overlay-key-binding (key)
  "Keymaps can also be attached to overlays, like yasnippet.
   From: http://stackoverflow.com/questions/18801018/how-to-find-in-which-map-a-key-binding-is-from-programatically-in-emacs"
  (mapcar (lambda (keymap) (lookup-key keymap key))
          (cl-remove-if-not
           #'keymapp
           (mapcar (lambda (overlay)
                     (overlay-get overlay 'keymap))
                   (overlays-at (point))))))

(defun my/find-kbd (key)
  "From: http://stackoverflow.com/questions/18801018/how-to-find-in-which-map-a-key-binding-is-from-programatically-in-emacs"
  (interactive "kInput key: ")
  (message "%s"
   (list
    (my/overlay-key-binding key)
    (minor-mode-key-binding key)
    (local-key-binding key)
    (global-key-binding key))))

dos to unix

From emacswiki.

(defun my/dos2unix ()
  "From: http://www.emacswiki.org/emacs/DosToUnix
Not exactly but it's easier to remember"
  (interactive)
  (set-buffer-file-coding-system 'unix 't))

path related

(defun my/get-path ()
  ""
  (interactive)
  (let ((path
         (or buffer-file-name default-directory)))
    (message path)
    path))

(defun my/copy-path ()
  ""
  (interactive)
  (let ((path (my/get-path)))
    (if path
        (kill-new path))))

eval and replace

From: http://emacsredux.com/blog/2013/06/21/eval-and-replace/

(defun my/eval-and-replace ()
  "Replace the preceding sexp with its value."
  (interactive)
  (backward-kill-sexp)
  (condition-case nil
      (prin1 (eval (read (current-kill 0)))
             (current-buffer))
    (error (message "Invalid expression")
           (insert (current-kill 0)))))

revert all buffers

From: http://blog.plover.com/prog/revert-all.html

(defun my/revert-all-buffers ()
  "Refreshes all open buffers from their respective files"
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (when (and (buffer-file-name buffer)
                 (not (buffer-modified-p buffer)))
        (set-buffer buffer)
        (revert-buffer t t t))
      (setq list (cdr list))
      (setq buffer (car list))))
  (message "Refreshed open files"))

open webstorm (deprecated)

(defun my/run-cmd-on-current-file (command)
  "run a command on the current file"
  (shell-command
   (format "open -a %s %s" command
           (shell-quote-argument (buffer-file-name)))))

(defun my/open-webstorm ()
  (interactive)
  (my/run-cmd-on-current-file "webstorm"))

;; (my/set-key-bindings 'global-set-key '(("C-<f9>" my/open-webstorm)))

vertico

vertico

(use-package vertico
  :bind (:map vertico-map
              ("C-n" . vertico-next)
              ("C-p" . vertico-previous))
  :init
  (vertico-mode)
  :custom
  ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
  (setq vertico-cycle t)
  )

(use-package savehist
  :init
  (savehist-mode))

marginalia

(use-package marginalia
  :after vertico
  :custom
  (marginalia-annotators
   '(marginalia-annotators-heavy marginalia-annotators-light nil))
  :init
  (marginalia-mode))

orderless

(use-package orderless
  :init
  ;; Configure a custom style dispatcher (see the Consult wiki)
  ;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)
  ;;       orderless-component-separator #'orderless-escapable-split-on-space)
  (setq completion-styles '(orderless basic)
        completion-category-defaults nil
        completion-category-overrides '((file (styles partial-completion)))))

embark

https://github.com/oantolin/embark

(use-package embark
  :quelpa (embark :fetcher github :repo "oantolin/embark")
  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ;; executes the default action at point, good alternative: M-.
   ("C-;" . embark-dwim)
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :init

  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  ;;(setq embark-prompter 'embark-completing-read-prompter)
  (setq embark-prompter 'embark-keymap-prompter)

  ;; Show the Embark target at point via Eldoc.  You may adjust the Eldoc
  ;; strategy, if you want to see the documentation from multiple providers.
  (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
  ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)

  :config

  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :after embark consult
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

consult

config

(use-package consult
  :quelpa (consult :fetcher github :repo "minad/consult")
  :bind (
         :map minibuffer-local-map
              ("M-s" . consult-history)
              ("C-r" . consult-history)
         )
  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI.
  :hook (completion-list-mode . consult-preview-at-point-mode)

    ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  (setq consult-preview-key "C-l")
  ;; (setq consult-preview-key '("S-<down>" "S-<up>"))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme
   :preview-key '(:debounce 0.2 any)

   consult-ripgrep
   consult-git-grep
   consult-grep
   consult-line
   consult-xref
   :preview-key '(:debounce 0.4 any)

   ;; ; use C-l to preview
   ;; consult-bookmark
   ;; consult-recent-file
   ;; consult--source-bookmark
   ;; consult--source-file-register
   ;; consult--source-recent-file
   ;; consult--source-project-recent-file
   ;; :preview-key "C-l"
   )
  (defalias 'consult-line-thing-at-point 'consult-line)
  (consult-customize
   consult-line
   :initial
   ;; use region text if selected
   (if (use-region-p)
       (let ((s (buffer-substring-no-properties (mark) (point))))
         (deactivate-mark)
         s))
   consult-line-thing-at-point
   :initial (thing-at-point 'symbol))

  ;; Optionally configure the narrowing key.
  (setq consult-narrow-key "<") ;; "C-+" also works

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)

  ;; By default `consult-project-function' uses `project-root' from project.el.
  ;; Optionally configure a different project root function.
  ;;;; 1. project.el (the default)
  ;; (setq consult-project-function #'consult--default-project--function)
  ;;;; 2. vc.el (vc-root-dir)
  ;; (setq consult-project-function (lambda (_) (vc-root-dir)))
  ;;;; 3. locate-dominating-file
  ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
  ;; 4. projectile.el (projectile-project-root)
  (autoload 'projectile-project-root "projectile")
  (setq consult-project-function (lambda (_) (projectile-project-root)))
  ;;;; 5. No project support
  ;; (setq consult-project-function nil)

  )

consult-buffer narrowing keys

keydesc
bbuffers
<spc>hidden buffers
*modified buffers
ffiles
rfile registers
mbootmarks
pproject

key functions

functiondesc
Consult-history
consult-buffer
consult-bookmark
consult-yank-pop
consult-goto-line
consult-outline
consult-mark
consult-flymake
consult-imenu
consult-find
consult-locate
consult-grep
consult-git-grep
consult-ripgrep
consult-line
consult-line-multi

consult-projectile

(use-package consult-projectile
  :quelpa
  (consult-projectile :fetcher gitlab :repo "OlMon/consult-projectile"))

projectile

(use-package projectile
  :diminish projectile-mode
  :custom (;;(projectile-completion-system 'ivy) switch to vertico
           )
  :bind-keymap ("C-x p" . projectile-command-map)
  :init
  ;; NOTE: Set this to the folder where you keep your Git repos!
  (when (file-directory-p "~/dev")
    (setq projectile-project-search-path '("~/dev")))
  ;; (setq projectile-switch-project-action #'projectile-dired)
  :config
  (projectile-mode)
  )

useful commands

pprojectile-switch-project
fprojectile-find-file
srprojectile-ripgrep
sgprojectile-grep

company

  • user manual: http://company-mode.github.io/manual/index.html
  • useful functions
    • company-show-location
    • company-show-doc-buffer
    • company-diag
    • company-other-backend
    • company-begin-backend
    • company-capf
    • company-yasnippet
  • useful variables
    • company-backends

config

(use-package company
  ;; :after lsp-mode
  ;; :hook (lsp-mode . company-mode)
  :bind (:map evil-insert-state-map
         ("C-n" . company-complete)
         :map company-active-map
         ("C-n" . company-select-next)
         ("C-p" . company-select-previous)
         :map company-active-map
         ("C-n" . company-select-next)
         ("C-p" . company-select-previous))
  :custom
  (company-minimum-prefix-length 3)
  (company-idle-delay 0.0)
  (company-show-numbers t)
  (company-tootip-align-annotations t)
  (campany-dabbrev-downcase nil)
  :config
  (global-company-mode 1))

flycheck

(use-package flycheck)

org-mode

init

(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
(use-package org
  :init
  ;; fold everything at the beginning
  (setq org-startup-folded t)
  ;; hide = and *
  (setq org-hide-emphasis-markers t)
  )

basic config

(defun my/org-mode-setup ()
  (flyspell-mode-off)
  (setq org-src-fontify-natively t)
  (setq org-edit-src-content-indentation 0)
  ;; (setq org-infojs-options my/default-org-infojs-options)
  (setq org-export-html-use-infojs t) ; alternative: when-configured, nil
  (setq org-latex-preview-ltxpng-directory "/tmp/ltxpng/")
  )
(add-hook 'org-mode-hook 'my/org-mode-setup)

keys

(defun my/org-mode-keys ()
  (local-unset-key (kbd "M-j"))
  (local-unset-key (kbd "M-k"))
  (evil-define-key '(normal visual)
    org-mode-map (kbd "M-j") 'org-next-visible-heading)
  (evil-define-key '(normal visual)
    org-mode-map (kbd "M-k") 'org-previous-visible-heading)

  ;; up level
  (evil-define-key '(normal visual)
    org-mode-map (kbd "M-u") 'outline-up-heading)
  ;; previous same level
  (evil-define-key '(normal visual)
    org-mode-map (kbd "M-h") 'org-backward-heading-same-level)
  ;; next same level
  (evil-define-key '(normal visual)
    org-mode-map (kbd "M-l") 'org-forward-heading-same-level)
  )
(add-hook 'org-mode-hook 'my/org-mode-keys)

appearance

https://zzamboni.org/post/beautifying-org-mode-in-emacs/ Set up category table. Use M-x describe-categories to view existing categories.

(defun my/setup-org-category-table ()
  "enable word wrap at - and /"
  ;; https://emacs.stackexchange.com/questions/19027/how-to-wrap-line-at-some-characters-other-than-space
  (setq my/org-category-table (copy-category-table))
  (modify-category-entry ?- ?| my/org-category-table)
  (modify-category-entry ?/ ?| my/org-category-table)
  (modify-category-entry ?& ?| my/org-category-table)
  (modify-category-entry ?? ?| my/org-category-table)
  (modify-category-entry ?# ?| my/org-category-table)
  )
(my/setup-org-category-table)

Set up appearance.

(defun my/org-appearance-setup ()
  ;; set for variable pitch
  (variable-pitch-mode 1)

  ;; visual-line-mode
  (set-category-table my/org-category-table)
  (setq-local word-wrap-by-category t)
  (auto-fill-mode 0)
  (visual-line-mode 1)

  (dolist (face '((org-level-1 . 1.2)
                  (org-level-2 . 1.1)
                  (org-level-3 . 1.05)
                  (org-level-4 . 1.05)
                  (org-level-5 . 1.05)
                  (org-level-6 . 1.05)
                  (org-level-7 . 1.05)
                  (org-level-8 . 1.05)))
    (set-face-attribute (car face)
                        nil
                        ;; :font "Iosevka Aile"
                        :weight 'bold
                        :height (cdr face)))

  (font-lock-add-keywords
   'org-mode
   '(("^ *\\([-]\\) "
      (0 (prog1 ()
           (compose-region (match-beginning 1) (match-end 1) ""))))))


  ;; Ensure that anything that should be fixed-pitch in Org files
  ;; appears that way
  ;;
  ;; To find the face at the point, use `describe-char` function
  (set-face-attribute 'org-block
                      nil :foreground nil :inherit 'fixed-pitch)
  (set-face-attribute 'org-checkbox
                      nil  :inherit 'fixed-pitch)
  (set-face-attribute 'org-checkbox-statistics-todo
                      nil  :inherit '(fixed-pitch org-todo))
  (set-face-attribute 'org-checkbox-statistics-done
                      nil  :inherit '(fixed-pitch org-done))
  (set-face-attribute 'org-code
                      nil :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-date
                      nil  :inherit 'fixed-pitch)
  (set-face-attribute 'org-document-info
                      nil :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-meta-line
                      nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-special-keyword
                      nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-table
                      nil :inherit 'fixed-pitch)
  (set-face-attribute 'org-formula
                      nil :inherit 'fixed-pitch)
  (set-face-attribute 'org-verbatim
                      nil :inherit '(shadow fixed-pitch))

  ;; fix indent faces
  ;; https://emacs.stackexchange.com/a/76133
  (org-indent-mode t)
  (set-face-attribute 'org-indent
                    nil :inherit '(org-hide fixed-pitch))
  (set-face-attribute 'org-hide
                    nil :inherit 'fixed-pitch)

  ;; (set-face-attribute 'org-formula
  ;;                     nil :inherit 'fixed-pitch)
  ;; (set-face-attribute 'line-number
  ;;                     nil :inherit 'fixed-pitch)
  ;; (set-face-attribute 'line-number-current-line
  ;;                     nil :inherit 'fixed-pitch)
  )
(add-hook 'org-mode-hook 'my/org-appearance-setup)

org-superstar

(use-package org-superstar
  :disabled
  :after org
  :hook (org-mode . org-superstar-mode)
  :init
  (setq org-superstar-remove-leading-stars t)
  (setq org-superstar-headline-bullets-list
        '("" "" "" "" "" "" ""))
  )

org-appear

When org-hide-emphasis-markers is turned on. It temporarily shows the emphasis markers around certain markup elements when you place your cursor inside of them.

;; function to show in evil insert mode
(defun my/org-setup-appear ()
  (org-appear-mode)
  (add-hook 'evil-insert-state-entry-hook
            #'org-appear-manual-start
            nil
            t)
  (add-hook 'evil-insert-state-exit-hook
            #'org-appear-manual-stop
            nil
            t)
  )
(use-package org-appear
  :after org
  ;; :init
  ;; (setq org-appear-trigger 'manual)
  ;; (setq org-appear-autolinks t)
  :hook
  ;; (org-mode . my/org-setup-appear)
  (org-mode . org-appear-mode)
  )

structure templates

(with-eval-after-load 'org
  ;; This is needed as of Org 9.2
  (require 'org-tempo)
  (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("ru" . "src rust"))
  )
;; ref: https://stackoverflow.com/a/69765466/3078372
(defun my/org-structure-templates-setup ()
  (setq-local electric-pair-inhibit-predicate
              `(lambda (c)
                 (if (char-equal c ?<)
                     t
                   (,electric-pair-inhibit-predicate c))))
  )
(add-hook 'org-mode-hook 'my/org-structure-templates-setup)

toc-org

Automatically generate a table of contents for org files. Use org-set-tags-command (C-c C-q) to add a TOC tag. Use TOC_2 tag to sets the max depth to 2.

(use-package toc-org
  :init
  (add-hook 'org-mode-hook #'toc-org-enable))

initial visibility

per-file setting

#+STARTUP: overview
#+STARTUP: content
#+STARTUP: showall
#+STARTUP: show2levels
#+STARTUP: show3levels
#+STARTUP: show4levels
#+STARTUP: show5levels
#+STARTUP: showeverything

per entry setting

Set VISIBILITY property to folded, children, content or all.

key shortcut

keyfunc
M-h or C-c C-borg-backward-heading-same-level
M-l or C-c C-forg-forward-heading-same-level
M-j or C-c C-noutline-next-visible-heading
M-k or C-c C-poutline-previous-visible-heading
(shift current item)
M-<left>org-metaleft
M-<right>org-metaright
M-<up>org-metaup
M-<down>org-metadown
(shift recursively)
M-S-<left>org-shiftmetaleft
M-S-<right>org-shiftmetaright
M-S-<up>org-shiftmetaup
M-S-<down>org-shiftmetadown
<tab>org-cycle
S-<tab>org-shifttab (tab all)

org-gtd

add agenda files into ~/.emacs.d/init.el

(setq org-agenda-files
      '("~/path/to/todo/todo.org"))

(setq org-agenda-tetra
      "~/path/to/todo/tetra.org")

agenda-hook

(defun my/org-agenda-mode-hook-func ()
  (my/set-key-bindings
   'define-key
   '(
     ("j" org-agenda-next-line)
     ("k" org-agenda-previous-line)
     ("J" org-agenda-next-item)
     ("K" org-agenda-previous-item)
     ("g" org-agenda-goto-date)
     ("G" org-agenda-clock-goto)
     )
   org-agenda-mode-map))
(add-hook 'org-agenda-mode-hook 'my/org-agenda-mode-hook-func)

custom agenda commands

(setq org-agenda-custom-commands
      '(("d" "Daily Agenda and All TODOs"
         ((agenda "" ((org-agenda-ndays 1)))
          (alltodo ""
                   ((org-agenda-skip-function
                     '(org-agenda-skip-entry-if
                       'todo '("TODO" "HOLD" "MISS")))
                    (org-agenda-overriding-header "In Progress Tasks:")))
          (alltodo ""
                   ((org-agenda-skip-function
                     '(or (org-agenda-skip-entry-if 'scheduled 'deadline)
                          (org-agenda-skip-entry-if 'todo '("HOLD"))))
                    (org-agenda-overriding-header "Todo Tasks without time:"))))
         ;; ((org-agenda-compact-blocks t))
         )
        ("h" "All Holds"
         ((alltodo ""
                   ((org-agenda-skip-function
                     '(org-agenda-skip-entry-if
                       'todo '("TODO" "PROG" "MISS")))
                    (org-agenda-overriding-header "In Progress Tasks:")))))
        ("t" "Tetrascience"
         ((agenda ""
                  ((org-agenda-files `(,org-agenda-tetra))
                   (org-agenda-ndays 1)))
          (alltodo ""
                   ((org-agenda-files `(,org-agenda-tetra))
                    (org-agenda-skip-function
                     '(org-agenda-skip-entry-if
                       'todo '("TODO" "HOLD" "MISS")))
                    (org-agenda-overriding-header "In Progress Tasks:")))
          (alltodo ""
                   ((org-agenda-files `(,org-agenda-tetra))
                    (org-agenda-skip-function
                     '(or (org-agenda-skip-entry-if 'scheduled 'deadline)
                          (org-agenda-skip-entry-if 'todo '("HOLD"))))
                    (org-agenda-overriding-header "Todo Tasks without time:")))))))

todo keyword faces

(setq org-todo-keyword-faces
      '(("TODO" . org-warning)
        ("IN-PROGRESS" . "yellow")
        ("PROG" . "yellow")
        ("PROGRESS" . "yellow")
        ("DONE" . "green")
        ("HOLD" . "red")
        ("CANCELLED" . "purple1")))

deadline warning days

(setq org-deadline-warning-days 10)

shell [0/2]

term mode

ref: https://oremacs.com/2015/01/01/three-ansi-term-tips/

config

(use-package term
  :config
  (setq explicit-shell-file-name "bash")

  ;; make sure C-c C-p / C-c C-n jump to the right place
  (setq term-prompt-regexp "^[^#$%>\n]*[#$%>] *")
  (setq scroll-margin 0)
  :bind (:map term-raw-map
         ("H-v" . term-paste)
         ;; ("C-x C-b" . consult-buffer)
         ;; doesn't work with C-w
         ;; use "C-x o" to jump to the next window
         ;; ("C-w" . nil)
         ;; ("C-w C-w" . evil-window-next)
         )
  ;; :bind (:map term-raw-map
  ;;        ("C-b" . scroll-up-command)
  ;;        :map company-active-map
  ;;        ("C-n" . company-select-next)
  ;;        ("C-p" . company-select-previous)
  ;;        :map company-active-map
  ;;        ("C-n" . company-select-next)
  ;;        ("C-p" . company-select-previous))
  ;;  '(("C-b" scroll-up-command)
  ;;    ("C-f" scroll-down)
  ;;    ("C-y" term-paste)
  ;;    ("s-v" term-paste)
  ;;    ("M-x" nil)
  ;;    ("C-u" universal-argument)
  ;;    ("C-c C-y" term-interrupt-subjob)
  ;;    )
  )

keys

keydesc
C-c C-kchar-mode
C-c C-jline-mode
C-c C-pgo back
C-c C-ngo forward

tm function

(defun tm ()
  "start bash ansi-term with a different name"
  (interactive)
  (let ((sh-name "bash")
        (bf-name "tm")
        )
    (if t ;;current-prefix-arg
        (setq bf-name
              (read-from-minibuffer "name (tm): " bf-name)))
    (if (or (not bf-name)
            (= (length bf-name) 0))
        (setq bf-name "*tm*"))
    (setq bf-name (generate-new-buffer-name bf-name))

    ;; term-mode
    ;; (set-buffer (make-term bf-name sh-name))
    ;; (term-mode)
    ;; (term-char-mode)
    ;; (switch-to-buffer (concat "*" bf-name "*"))

    ;; ansi-term
    (ansi-term sh-name)
    (rename-buffer bf-name)
    ))

sh mode

(add-to-list 'auto-mode-alist '("/\\.bash_[^/]*\\'" . sh-mode))

shell mode

(defun my/shell-mode-hook-func ()
  (my/set-key-bindings
   'local-set-key
   '(
     ;; ("C-d" my/shell-kill)
     ("C-M-l" nil)
     ;;("C-c h" comint-history-isearch-backward)
     ;;("M-s" comint-history-isearch-search)
     ("C-c h" comint-history-isearch-backward-regexp)

     ;;("C-n" comint-next-input)
     ;;("C-p" comint-previous-input)
     ("C-M-n" comint-next-matching-input-from-input)
     ("C-M-p" comint-previous-matching-input-from-input)

     ("C-c C-b" shell-backward-command)
     ("C-c C-f" shell-forward-command)
     ("C-c C-n" comint-next-prompt)
     ("C-c C-p" comint-previous-prompt)

     )
   ;;shell-mode-map
   )
  (evil-define-key
    'insert shell-mode-map (kbd "C-n") 'comint-next-input)
  (evil-define-key
    'insert shell-mode-map (kbd "C-p") 'comint-previous-input)
  )
(add-hook 'shell-mode-hook 'my/shell-mode-hook-func)

sh function

(defun sh ()
  "start-shell"
  (interactive)
  (let (bf-name)
    (setq bf-name
          (read-from-minibuffer "Buffer (*shell*): " bf-name))
    (if (or (not bf-name)
            (= (length bf-name) 0))
        (shell)
      (shell bf-name))))

text-mode

auto fill

(add-hook 'text-mode-hook 'turn-on-auto-fill)

typescript

config

(use-package typescript-mode
  :mode "\\.\\(js\\|jsx\\|ts\\)\\'"
  :hook (typescript-mode . lsp-deferred)
  :config
  (setq typescript-indent-level 2))

manual

  • install js/ts server
  • install eslint globally
  • install eslint server by using M-x lsp-install-server

json-mode

(use-package json-mode)

rust

(use-package rust-mode)

lsp (deprecated)

config

(defun my/lsp-mode-setup ()
  (setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
  (lsp-headerline-breadcrumb-mode))

(use-package lsp-mode
  :commands (lsp lsp-deferred)
  :hook (lsp-mode . my/lsp-mode-setup)
  :init
  (setq lsp-keymap-prefix "C-c l")  ;; Or 'C-l', 's-l'
  :config
  (lsp-enable-which-key-integration t))

(use-package lsp-ui
  :hook (lsp-mode . lsp-ui-mode)
  :custom
  (lsp-ui-doc-position 'bottom))

(use-package lsp-treemacs
  :after lsp)

dap

(use-package dap-mode
  :after lsp-mode
  :config (dap-auto-configure-mode))

java

links

lsp-java

(use-package lsp-java 
  :config (add-hook 'java-mode-hook 'lsp-deferred))

dired

key binding

(defun my/dired-key-binding ()
  (my/set-key-bindings
   'define-key
   '(
     ("j" dired-next-line)
     ("k" dired-previous-line)
     ("r" revert-buffer)
     ("C-t" set-mark-command))
   dired-mode-map))
(add-hook 'dired-mode-hook 'my/dired-key-binding)

Listing Parameters

(setq dired-listing-switches "-alnoh")
(defun my/set-ls (parameter)
  "Set ls parameter in dired mode"
  (interactive "s")
  (setq dired-listing-switches parameter))

folding

main code

(setq default-label 'cycle-fold)

(defun goto-list (count depth)
  (condition-case ex
      (goto-char (scan-lists (point) count depth))
    (error
      (message "Error in goto-list: %s" ex)
      nil)))

(defun scan-lists-safe (from count depth &optional default)
  (condition-case ex
      (scan-lists from count depth)
    (error
      (message "Error in scan-lists: %s" ex)
      default)))

(defun get-bol (pos)
  (save-excursion (goto-char (or pos (point)))
                  (beginning-of-line)
                  (point)))

(defun get-eol (pos)
  (save-excursion (goto-char (or pos (point)))
                  (end-of-line)
                  (point)))

(defun my/filter (condp lst)
  (delq nil
        (mapcar (lambda (x) (and (funcall condp x) x)) lst)))

(defun label->tag (label)
  (intern (concat "tag-" (symbol-name (or label default-label)))))

(defun create-overlay (start end &optional label val)
  (let ((o (make-overlay start end))
        (tag (label->tag label)))
    ;; (message "tag: %s" tag)
    (if val
        (overlay-put o tag val)
      (overlay-put o tag t))
    (overlay-put o 'evaporate t)
    (overlay-put o 'invisible t)
    (overlay-put o 'display `(:string "..."))
    (overlay-put
     o 'isearch-open-invisible
     (lambda (ov)
       (message "open invisible")
       (delete-overlay ov)))
    (overlay-put
     o 'isearch-open-invisible-temporary
     (lambda (ov invisible)
       (overlay-put ov 'invisible invisible)
       (overlay-put ov 'display (and invisible `(:string "...")))))
    o))

(defun get-overlays (start end &optional label val)
  (let ((tag (label->tag label))
        (os (overlays-in start end)))
    (if (null tag)
        os
      (my/filter (lambda (o)
                   (if (null val)
                       (overlay-get o tag)
                     (equal (overlay-get o tag) val)))
                 os))))

(defun delete-overlays (start end &optional label val)
  (dolist (o (get-overlays start end label val))
    (delete-overlay o)))

(defun cal-fold-region-at (&optional pos)
  (interactive)
  (let* ((start (or pos (point)))
         (eol (get-eol start))
         (end (scan-lists start 1 0)))
    (if (> (- end eol) 1)
        (list (cons :start eol)
              (cons :end (1- end))))))

(defun cal-fold-region-line (&optional pos)
  (interactive)
  (let* ((p (or pos (point)))
         (bol (get-bol p))
         (eol (get-eol p))
         (end (scan-lists-safe bol 1 0 (min (1+ bol) eol))))
    (while (< end eol)
      (setq end (scan-lists-safe end 1 0 (min (1+ end) eol))))
    (if (> end eol)
        (cal-fold-region-at (scan-lists end -1 0)))))

(defun current-fold-state (&optional pos)
  (interactive)
  (let ((range (cal-fold-region-line pos)))
    (if range
        (let* ((start (cdr (assoc :start range)))
               (end (cdr (assoc :end range)))
               (os (get-overlays start end)))
          ;; (message "%s %s %s" start end os)
          (if os
              (if (and (null (cdr os))
                       (equal start (overlay-start (car os)))
                       (equal end (overlay-end (car os))))
                  :folded
                :mis-folded)
            :unfolded))
      :no-fold)))

(defun fold-at (&optional pos)
  (interactive)
  (let ((range (cal-fold-region-at pos)))
    (if range
        (create-overlay (cdr (assoc :start range))
                        (cdr (assoc :end range))))))

(defun fold-line (&optional pos)
  (interactive)
  (let ((range (cal-fold-region-line pos)))
    (if range
        (create-overlay (cdr (assoc :start range))
                        (cdr (assoc :end range))))))

(defun fold-at-end (&optional pos)
  (interactive)
  (save-excursion
    (goto-list -1 0)
    (fold-at (point))))

(defun unfold-line (&optional pos)
  (interactive)
  (let ((range (cal-fold-region-line pos)))
    (if range
        (delete-overlays (cdr (assoc :start range))
                         (cdr (assoc :end range))))))

(defun fold-children (&optional pos)
  (interactive)
  (save-excursion
    (let ((range (cal-fold-region-line pos)))
      (when range
        (goto-char (cdr (assoc :start range)))
        (while (goto-list 1 0)
          (fold-at-end))))))

(defun toggle-fold-line (&optional pos)
  (interactive)
  (let ((status (current-fold-state)))
    (cond
     ((eq status :no-fold) nil)
     ((eq status :unfolded) (fold-line pos))
     ((eq status :mis-folded)
      (unfold-line pos)
      (unless (eq last-command 'toggle-fold-line)
        (fold-line pos)))
     ((eq status :folded)
      (unfold-line pos)
      (fold-children pos))
     (t :default))))

(defun toggle-fold-all ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (if (and (eq last-command 'toggle-fold-all)
             (get-overlays (point-min) (point-max)))
        (delete-overlays (point-min) (point-max))
      (progn (delete-overlays (point-min) (point-max))
             (while (goto-list 1 0)
               (fold-at-end))))))

key binding

(my/set-key-bindings
 'global-set-key
 '(("C-<tab>" toggle-fold-line)
   ("C-S-<tab>" toggle-fold-all)))

example

'(a b c
    (d
     e)
    (f g)
    (h
     (i j))
    ((k l
        (m n)
        (p q) (r s))
     o))

test

(message "****************** start *******************")
(message "label->tag: %s" (label->tag 'test))
(message "label->tag === 'tag-test: %s" (eq (label->tag 'test) 'tag-test))
(message "delete-overlays: %s" (delete-overlays 1 100 'test))
(message "create-overlay: %s" (create-overlay 1 10 'test))
(message "get-overlays: %s" (get-overlays 1 100 'test))
(message "delete-overlays: %s" (delete-overlays 1 100 'test))
(message "get-overlays: %s" (get-overlays 1 100 'test))
(message "****************** end *******************")

(overlay-put o 'face `(:background "grey50"))
(overlay-put o 'face nil)
(overlay-put o 'display `(:string "(...)"))
(overlay-put o 'display nil)

todo

  • minor mode
  • ‘helm-after-action-hook
  • ‘helm-after-persistent-action-hook
  • ‘occur-mode-find-occurrence-hook
  • bug of [{\n},{\n},{\n}]
  • lightweight-macro

graphviz dot mode

(defun my/graphviz-mode ()
  ""
  (setq graphviz-dot-indent-width 2)
  ;; (setq graphviz-dot-auto-indent-on-semi nil)
  )
(add-hook 'graphviz-dot-mode-hook 'my/graphviz-mode)

html

web-mode

(use-package web-mode
  :mode "\\.\\(jsx\\|html\\|hbs\\)\\'"
  :config
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-attr-indent-offset 2)
  (setq web-mode-style-padding 2)
  (setq web-mode-script-padding 2)
  (setq web-mode-block-padding 0)
  (set-face-attribute 'web-mode-html-tag-face nil :foreground "SkyBlue1")
  (setq web-mode-enable-current-element-highlight t)
  (set-face-attribute 'web-mode-current-element-highlight-face nil :background "honeydew4")
  (setq web-mode-enable-current-column-highlight nil)
  (setq web-mode-enable-sexp-functions t)
  ;; (setq web-mode-enable-auto-quoting nil)
  ;; (setq web-mode-enable-auto-indentation nil)
  )

js

node-modules-path-setup

From: https://github.com/codesuki/add-node-modules-path

(defun my/node-modules-path-setup ()
  (defvar add-node-modules-path-debug nil
    "Enable verbose output when non nil.")

  (defun add-node-modules-path ()
    "Search the current buffer's parent directories for `node_modules/.bin`.
If it's found, then add it to the `exec-path'."
    (let* ((root (locate-dominating-file
                  (or (buffer-file-name) default-directory)
                  "node_modules"))
           (path (and root
                      (expand-file-name "node_modules/.bin/" root))))
      (if root
          (progn
            (make-local-variable 'exec-path)
            (add-to-list 'exec-path path)
            (when add-node-modules-path-debug
              (message (concat "added " path  " to exec-path"))))
        (when add-node-modules-path-debug
          (message (concat "node_modules not found in " root))))))
  (eval-after-load 'js-mode
    '(add-hook 'js-mode-hook #'add-node-modules-path))
  (eval-after-load 'js2-mode
  '(add-hook 'js2-mode-hook #'add-node-modules-path))
  (eval-after-load 'web-mode
    '(add-hook 'web-mode-hook #'add-node-modules-path)))
(my/node-modules-path-setup)

js-mode (deprecated to typescript)

(defun my/js-setup ()
  (setq-default js-indent-level 2))
(my/js-setup)

js2-mode (deprecated to typescript)

(defun my/js2-setup ()
  ;; js2-mode-hide-comments
  ;; js2-mode-hide-element
  ;; js2-mode-hide-functions
  ;; js2-mode-hide-warnings-and-errors
  ;;
  ;; js2-mode-show-all
  ;; js2-mode-show-comments
  ;; js2-mode-show-element
  ;; js2-mode-show-functions
  ;; js2-mode-show-node
  ;;
  ;; js2-mode-toggle-element "C-c C-o"
  ;; js2-mode-toggle-hide-comments
  ;; js2-mode-toggle-hide-functions
  ;; js2-mode-toggle-warnings-and-errors
  (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
  (setq-default js-indent-level 2)
  ;; this will hide errors & warnings
  (setq-default js2-mode-show-parse-errors nil)
  (setq-default js2-mode-show-strict-warnings nil)
  (setq-default js2-bounce-indent-p t)
  ;; (setq-default js2-strict-inconsistent-return-warning nil)
  (defun my/init-js ()
    ;; (electric-indent-mode -1)
    (my/set-key-bindings
     'local-set-key
     '()))
  (add-hook 'js2-mode-hook 'my/init-js))

;; (if (package-installed-p 'js2-mode)
;;     (my/js2-setup)
;;   (message "js2-mode not installed"))

spell

(setq-default ispell-program-name "aspell")

tramp

(require 'tramp)
(setq tramp-default-method "scp")
;;(custom-set-variables '(tramp-verbose 6))
(eval-after-load 'tramp '(setenv "SHELL" "/bin/bash"))

prettier

(defun my/setup-prettier ()
  ;; (add-hook 'js2-mode-hook
  ;;           #'(lambda ()
  ;;               (if (executable-find "prettier")
  ;;                   (prettier-js-mode))))
  ;; (add-hook 'web-mode-hook
  ;;           #'(lambda ()
  ;;               (if (and (executable-find "prettier")
  ;;                        (buffer-file-name)
  ;;                        (string-match "\\.jsx?\\'" buffer-file-name))
  ;;                   (prettier-js-mode))))
  ;; (add-hook 'yaml-mode-hook
  ;;           #'(lambda ()
  ;;               (if (executable-find "prettier")
  ;;                   (prettier-js-mode))))
  (global-set-key [f8] 'prettier-js)
  )
;; (if (package-installed-p 'prettier-js)
;;     (my/setup-prettier)
;;   (message "prettier-js not installed"))

plantuml

;; use M-x plantuml-download-jar<RET> to download jar
;; use M-x plantuml-preview<RET> to preview
(defun my/plantuml-setup ()
  (setq plantuml-jar-path "~/dev/lib/plantuml.jar")
  (setq plantuml-default-exec-mode 'jar)
  (add-to-list
   'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode))
  ;; add to org-mode
  (add-hook
   'org-mode-hook
   (lambda ()
     (add-to-list
      'org-src-lang-modes '("plantuml" . plantuml))))
  )
;; (if (package-installed-p 'plantuml-mode)
;;     (my/plantuml-setup)
;;   (message "plantuml-mode not installed"))

todolist [0/7]

facemenu-set-face

super-save

func to toggle auto-save

origami.el for folding

update face of mode / status bar

read a list of people with nice emacs config files

magit

License

My Emacs configurations written in Org mode.

Copyright (c) 2013-2018 Chunfeng Dai

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

About

My .emacs


Languages

Language:Emacs Lisp 97.2%Language:Shell 2.8%