- screenshot
- usage
- basic configuration
- user interface
- key bindings
- visual
- navigation
- editing
- programming
- operating system
- org mode
- menu keys
# backup
$ mv ~/.emacs.d ~/.emacs.d.bak
# install
$ git clone https://github.com/MasterCsquare/.emacs.d.git ~/.emacs.d
$ cd ~/.emacs.d
$ git submodule init
$ git submodule update
# start
$ emacs
A bigger garbage collect threshold can make emacs boot faster, mostly prevent it to become a weakness.
(setq gc-cons-threshold 100000000)
Turnoff all of these things to make emacs become pretty and cool. Lacking of theses have none affect on a pure keyboard driven user.
(tool-bar-mode -1)
(menu-bar-mode -1)
(blink-cursor-mode -1)
(scroll-bar-mode -1)
The initial startup screen will be replace by dashboard.
(setq inhibit-startup-screen t)
If not config this, you will get native emacs scrolling, which scrolls per 50 lines.
(setq scroll-margin 0
scroll-conservatively 100000
scroll-preserve-screen-position 1)
Connect emacs with X11 clipboard. Without this, it will be messy.
(setq x-select-enable-clipboard t)
Turnoff backup and auto save, which is useless after VC take over the jobs.
(setq make-backup-files nil)
(setq auto-save-default nil)
Set the custom file path. The file is annoying if you not move it to somewhere.
(setq custom-file
(expand-file-name "custom.el" user-emacs-directory))
Now you can see it’s tab or space by the cursor.
(setq x-stretch-cursor t)
Basic setups for modeline.
(line-number-mode t)
(column-number-mode t)
(size-indication-mode t)
Input character When selection is active to delete the selection.
(delete-selection-mode 1)
A general and basic support for pair.
(electric-pair-mode 1)
(show-paren-mode 1)
(setq show-paren-style 'parenthesis)
Delete trailing whitespaces when save the file.
(add-hook 'before-save-hook 'delete-trailing-whitespace)
On the fly spell checking.
(use-package jinx
:config
(dolist (hook '(text-mode-hook prog-mode-hook conf-mode-hook))
(add-hook hook #'jinx-mode))
(let ((st jinx--base-syntax-table))
(modify-syntax-entry '(#x4E00 . #x9FFF) "_" st) ; CJK Unified Ideographs
(modify-syntax-entry '(#x3400 . #x4DBF) "_" st) ; CJK Unified Ideographs Extension A
(modify-syntax-entry '(#x20000 . #x2A6DF) "_" st) ; CJK Unified Ideographs Extension B
(modify-syntax-entry '(#x2A700 . #x2B73F) "_" st) ; CJK Unified Ideographs Extension C
(modify-syntax-entry '(#x2B740 . #x2B81F) "_" st) ; CJK Unified Ideographs Extension D
(modify-syntax-entry '(#x2B820 . #x2CEAF) "_" st) ; CJK Unified Ideographs Extension E
(modify-syntax-entry '(#x2CEB0 . #x2EBEF) "_" st) ; CJK Unified Ideographs Extension F
(modify-syntax-entry '(#x30000 . #x3134F) "_" st) ; CJK Unified Ideographs Extension G
(modify-syntax-entry '(#x31350 . #x323AF) "_" st) ; CJK Unified Ideographs Extension H
(modify-syntax-entry '(#x2EBF0 . #x2EE5F) "_" st) ; CJK Unified Ideographs Extension I
))
Subword-mode makes moving actions obey camel case rules.
(add-hook 'java-mode-hook 'subword-mode)
(add-hook 'go-mode-hook 'subword-mode)
(add-hook 'haskell-mode-hook 'subword-mode)
Require final newline when save.
(setq require-final-newline t)
Set c as linux style.
(setq c-basic-offset 8)
Answer the exit question by one letter.
(fset 'yes-or-no-p 'y-or-n-p)
Emacs disable some features by default, you have to enable the disable.
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
Add a path to emacs theme load path for loading my custom theme.
(add-to-list 'custom-theme-load-path
(expand-file-name user-emacs-directory))
Add paths to load extra elisp codes.
(let ((default-directory "~/.emacs.d/lisp/"))
(normal-top-level-add-subdirs-to-load-path))
Activate the winner mode. Winner mode can undo and redo the windows layout.
(when (fboundp 'winner-mode)
(winner-mode 1))
Set the default font to inconsolata, default CJK font to Wenquanyi Zen hei.
(set-face-attribute 'default nil :font "inconsolata 13")
(dolist (charset '(kana han symbol cjk-misc bopomofo))
(set-fontset-font (frame-parameter nil 'font)
charset
(font-spec :family "WenQuanYi Zen Hei" :size 15)))
Enable package manager and install use-package.
(package-initialize)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(unless package-archive-contents
(package-refresh-contents))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-verbose t)
(setq use-package-always-ensure t)
A modern emacs always have a completion framework. There are many choices of these, such as ido, ivy, helm. Ido is include in emacs as default, but it’s not great enough to compare with helm and ivy. Helm used to be a great framework, but it’s not maintain anymore. Ivy is another popular choice, but it’s grow from a text-based search tool called swiper, which means ivy is a framework grows from specific to general and these makes it messy.
Selectrum, which is mature enough as a replacement of ivy, is made as a general framework at first. So selectrum is my final choice.
After days, selectrum was deprecated by the author, who switched to vertico. That’s why it is vertico now.
(use-package vertico
:init
(vertico-mode)
:config
(setq vertico-count 15))
(use-package consult
:bind
(("C-s" . consult-line)
("C-c o" . consult-outline)
("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x 5 b" . consult-buffer-other-frame)
("C-x r x" . consult-register)
("C-x r b" . consult-bookmark)
("M-y" . consult-yank-pop))
:config
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref))
(use-package marginalia
:init
(marginalia-mode))
(use-package embark
:bind
("C-S-a" . embark-act))
(use-package embark-consult
:hook
(embark-collect-mode . embark-consult-preview-minor-mode))
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
Doom themes provide a lot of popular themes. Ayu-dark is implemented by myself based on doom-themes.
(use-package doom-themes
:config
(load-theme 'doom-ayu-darkp t)
(doom-themes-org-config))
(use-package doom-modeline
:init (doom-modeline-mode 1))
Helpful provide more information than the native one.
(use-package helpful
:bind (("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)))
Which key popups hints for keys and commands after invoke a key prefix.
(use-package which-key
:config (which-key-mode))
The things you see after emacs boot.
(use-package dashboard
:config
(setq dashboard-startup-banner (expand-file-name "banner.png" user-emacs-directory))
(dashboard-setup-startup-hook))
Rainbow mode can make you see the color of a rgb markup string. It’s useful when you adjust the color theme.
(use-package rainbow-mode :commands rainbow-mode)
The native emacs undo modal is linear. Undo tree now is almost the
official replacement. C-x u
shows you the visualize undo tree.
(use-package undo-tree
:config
(global-undo-tree-mode)
(setq undo-tree-auto-save-history nil)
:bind ("M-/" . undo-tree-redo))
Diff hl highlights the diffs under the VC.
(use-package diff-hl
:config
(global-diff-hl-mode)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
Eyebrowse is similar to the X11 workspace.
(use-package eyebrowse
:config (eyebrowse-mode t))
Highlight the volatile objects.
(use-package volatile-highlights
:config (volatile-highlights-mode t))
Customize the headings signs of org mode.
(use-package org-bullets
:config (setq org-bullets-bullet-list '("λ" "μ" "ν" "ξ" ))
:hook (org-mode . (lambda () (org-bullets-mode 1))))
Dired+ provides plenty of extensions of dired mode. Dired is a great file manager. When combine with editing based on buffer, dired is like a magic tool.
Dired-sort can sort the dired buffer.
(use-package dired+
:ensure nil
:init
(setq diredp-hide-details-initially-flag nil)
:config
(setq dired-listing-switches "-alh"))
(use-package dired-sort
:ensure nil
:bind
(:map dired-mode-map
(", s" . dired-sort-size)
(", t" . dired-sort-time)
(", n" . dired-sort-name)
(", c" . dired-sort-ctime)
(", u" . dired-sort-utime)
(", e" . dired-sort-extension)))
Many people think info is a gnu version man pages, but exactly they are totally different. The unix man pages is single page about a command, but info is a fully documentation about a software. Info+ makes info pages colorful.
(use-package info+ :ensure nil)
A tab plugin.
(use-package centaur-tabs
:demand
:config
(centaur-tabs-mode t)
:bind
("C-<prior>" . centaur-tabs-backward)
("C-<next>" . centaur-tabs-forward))
A tree-style view plugin.
(use-package treemacs
:defer t
:init
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
:config
(progn
(setq treemacs-collapse-dirs (if treemacs-python-executable 3 0)
treemacs-deferred-git-apply-delay 0.5
treemacs-directory-name-transformer #'identity
treemacs-display-in-side-window t
treemacs-eldoc-display 'simple
treemacs-file-event-delay 2000
treemacs-file-extension-regex treemacs-last-period-regex-value
treemacs-file-follow-delay 0.2
treemacs-file-name-transformer #'identity
treemacs-follow-after-init t
treemacs-expand-after-init t
treemacs-find-workspace-method 'find-for-file-or-pick-first
treemacs-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-header-scroll-indicators '(nil . "^^^^^^")
treemacs-hide-dot-git-directory t
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-missing-project-action 'ask
treemacs-move-files-by-mouse-dragging t
treemacs-move-forward-on-expand nil
treemacs-no-png-images nil
treemacs-no-delete-other-windows t
treemacs-project-follow-cleanup nil
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
treemacs-position 'left
treemacs-read-string-input 'from-child-frame
treemacs-recenter-distance 0.1
treemacs-recenter-after-file-follow nil
treemacs-recenter-after-tag-follow nil
treemacs-recenter-after-project-jump 'always
treemacs-recenter-after-project-expand 'on-distance
treemacs-litter-directories '("/node_modules" "/.venv" "/.cask")
treemacs-project-follow-into-home nil
treemacs-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-asc
treemacs-select-when-already-in-treemacs 'move-back
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-text-scale nil
treemacs-user-mode-line-format nil
treemacs-user-header-line-format nil
treemacs-wide-toggle-width 70
treemacs-width 35
treemacs-width-increment 1
treemacs-width-is-initially-locked t
treemacs-workspace-switch-cleanup nil)
;; The default width and height of the icons is 22 pixels. If you are
;; using a Hi-DPI display, uncomment this to double the icon size.
;;(treemacs-resize-icons 44)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t)
(treemacs-fringe-indicator-mode 'always)
(when treemacs-python-executable
(treemacs-git-commit-diff-mode t))
(pcase (cons (not (null (executable-find "git")))
(not (null treemacs-python-executable)))
(`(t . t)
(treemacs-git-mode 'deferred))
(`(t . _)
(treemacs-git-mode 'simple)))
(treemacs-hide-gitignored-files-mode nil))
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t d" . treemacs-select-directory)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
Hydra can group commands, also provide a helpful interface.
(use-package hydra)
God mode likes sticky keys.
(use-package god-mode :bind ("<escape>" . god-local-mode))
Pangu spacing add spaces between English and CJK characters.
(use-package pangu-spacing
:hook (org-mode . pangu-spacing-mode))
Hide the namespace of elisp codes.
(use-package nameless
:commands nameless-mode)
Jump to windows faster. Also can swap windows.
(use-package ace-window :commands ace-window)
Jump to any positions of the text viewing.
(use-package avy :commands avy-goto-char-timer)
Jump to links faster.
(use-package ace-link :config (ace-link-setup-default))
Preview when goto-line
.
(use-package goto-line-preview
:config
(global-set-key [remap goto-line] 'goto-line-preview))
Add multiple cursors and edit things at the same time.
(use-package multiple-cursors
:bind (("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)))
Select text increasingly based on syntax blocks.
(use-package expand-region
:bind ("C-=" . er/expand-region))
Move current line up or down.
(use-package move-text
:bind
(("M-p" . move-text-up)
("M-n" . move-text-down)))
A writable grep buffer.
(use-package wgrep :defer t)
Project Managements. The projects are auto recognized.
(use-package projectile
:config
(projectile-mode +1)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
Highlight the todo keywords.
(use-package hl-todo :hook (prog-mode . hl-todo-mode))
Code completions.
(use-package company
:config
(add-hook 'after-init-hook 'global-company-mode)
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 1))
A snippets system.
(use-package yasnippet
:hook
(after-init . yas-global-mode))
(use-package yasnippet-snippets
:after yasnippet)
Create snippet on the fly.
(use-package auto-yasnippet
:bind (("C-c [" . aya-create)
("C-c ]" . aya-expand)))
A lsp client. The language server protocol can provide many IDE features by a language server, which makes emacs more powerful.
(use-package eglot :commands eglot
:config
(defun vue-eglot-init-options ()
(let ((tsdk-path (expand-file-name
"lib"
(string-trim-right (shell-command-to-string "npm list --global --parseable typescript | head -n1")))))
`(:typescript (:tsdk ,tsdk-path
:languageFeatures (:completion
(:defaultTagNameCase "both"
:defaultAttrNameCase "kebabCase"
:getDocumentNameCasesRequest nil
:getDocumentSelectionRequest nil)
:diagnostics
(:getDocumentVersionRequest nil))
:documentFeatures (:documentFormatting
(:defaultPrintWidth 100
:getDocumentPrintWidthRequest nil)
:documentSymbol t
:documentColor t))
:vue (:hybridMode :json-false))))
(add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))
(add-to-list 'eglot-server-programs
`(vue-mode . ("vue-language-server" "--stdio" :initializationOptions ,(vue-eglot-init-options))))
:hook
((go-mode c-mode c++-mode python-mode rust-mode java-mode js-mode haskell-mode vue-mode html-mode css-mode typescript-mode) . eglot-ensure))
On the fly syntax check.
(use-package flycheck
:hook (after-init . global-flycheck-mode))
Show different color of delimiters based on nested depth.
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
A face for highlight numbers.
(use-package highlight-numbers
:hook (prog-mode . highlight-numbers-mode))
Lispy is one of the Parenthesis edit plugins family, such as pareidt, smartparens. Works on parenthesis makes it totally different and more convenient.
(use-package lispy
:hook
(emacs-lisp-mode . lispy-mode)
(lisp-mode . lispy-mode)
(scheme-mode . lispy-mode))
A front end of git. Magit is magic.
(use-package magit
:bind ("C-x g" . magit))
(use-package forge
:after magit)
Go to any git commits on the fly.
(use-package git-timemachine
:commands git-timemachine)
Show messages about a commit on the fly.
(use-package git-messenger
:commands git-messenger:popup-message)
Modes for git related files.
(use-package git-modes
:commands gitconfig-mode gitattributes-mode gitignore-mode)
A common lisp IDE.
(use-package sly :commands sly
:config (setq inferior-lisp-program "/usr/bin/sbcl"))
A scheme IDE.
(use-package geiser :commands geiser)
(use-package geiser-chez :commands run-chez)
Modes for languages.
(use-package haskell-mode :mode "\\.hs\\'")
(use-package go-mode :mode "\\.go\\'"
:hook (before-save . gofmt-before-save))
(use-package rust-mode :mode "\\.rs\\'")
(use-package php-mode :mode "\\.php\\'")
(use-package lua-mode :mode "\\.lua\\'")
(use-package json-mode :mode "\\.json\\'")
(use-package markdown-mode :mode "\\.md\\'")
(use-package typescript-mode :mode "\\.ts\\'"
:config
(setq typescript-indent-level 2))
(use-package vue-mode :mode "\\.vue\\'"
:config
(setq mmm-submode-decoration-level 2)
(add-hook 'mmm-mode-hook
(lambda ()
(set-face-background 'mmm-default-submode-face nil))))
A mpd client.
(use-package mingus :commands mingus)
Input method based on rime.
(use-package rime
:custom
(default-input-method "rime")
(rime-show-candidate 'posframe))
Fish-like auto suggestions for eshell.
(use-package esh-autosuggest
:hook (eshell-mode . esh-autosuggest-mode))
Restart emacs.
(use-package restart-emacs
:commands restart-emacs)
Google somethings.
(use-package google-this
:config
(google-this-mode 1))
Latex editing.
(use-package tex
:defer t
:ensure auctex
:config
(setq TeX-auto-save t))
A boot profile tool.
(use-package esup
:commands esup)
Calendar for chinese.
(use-package cal-china-x
:config
(setq mark-holidays-in-calendar t)
(setq cal-china-x-important-holidays cal-china-x-chinese-holidays)
(setq cal-china-x-general-holidays '((holiday-lunar 1 15 "元宵节")))
(setq calendar-holidays
(append cal-china-x-important-holidays
cal-china-x-general-holidays
holiday-other-holidays)))
View epub files.
(use-package nov-mode
:ensure nov
:mode "\\.epub\\'")
indent text to align with the headline.
(setq org-adapt-indentation t)
Open pdf file with emacs after export from org-mode.
(add-to-list 'org-file-apps '("\\.pdf\\'" . emacs))
Insert toc in org-mode.
(use-package toc-org
:config
(if (require 'toc-org nil t)
(add-hook 'org-mode-hook 'toc-org-mode)))
Visual alignment for Org Mode, Markdown and table.el tables.
(use-package valign
:hook
(org-mode . valign-mode))
A modern style for org mode.
(use-package org-modern
:config
(add-hook 'org-mode-hook #'org-modern-mode)
(add-hook 'org-agenda-finalize-hook #'org-modern-agenda))
The menu key is very useful. I bind it with so many commands, which are very frequently used.
(define-prefix-command 'menu-key-map)
(define-key menu-key-map (kbd "h") 'beginning-of-buffer)
(define-key menu-key-map (kbd "n") 'end-of-buffer)
(define-key menu-key-map (kbd "o") 'mode-line-other-buffer)
(define-key menu-key-map (kbd "f") 'consult-buffer)
(define-key menu-key-map (kbd ";") 'save-buffer)
(define-key menu-key-map (kbd "k") 'kill-buffer)
(define-key menu-key-map (kbd "b") 'mark-whole-buffer)
(define-key menu-key-map (kbd "g") 'revert-buffer)
(define-key menu-key-map (kbd "w") 'ace-window)
(define-key menu-key-map (kbd "d") 'ace-swap-window)
(define-key menu-key-map (kbd "e") 'find-file)
(define-key menu-key-map (kbd "r") 'consult-recent-file)
(define-key menu-key-map (kbd "0") 'delete-window)
(define-key menu-key-map (kbd "1") 'delete-other-windows)
(define-key menu-key-map (kbd "2") 'split-window-below)
(define-key menu-key-map (kbd "3") 'split-window-right)
(define-key menu-key-map (kbd "8") 'org-edit-special)
(define-key menu-key-map (kbd "9") 'org-edit-src-exit)
(define-key menu-key-map (kbd "[") 'winner-undo)
(define-key menu-key-map (kbd "]") 'winner-redo)
(define-key menu-key-map (kbd "m") 'consult-bookmark)
(define-key menu-key-map (kbd "i") 'consult-imenu)
(define-key menu-key-map (kbd "s") 'jinx-correct)
(define-key menu-key-map (kbd "j") 'avy-goto-char-timer)
(define-key menu-key-map (kbd "a") 'consult-ripgrep)
(define-key menu-key-map (kbd "<menu>") 'execute-extended-command)
(define-key menu-key-map (kbd "SPC") 'magit)
(define-key menu-key-map (kbd "p") 'projectile-command-map)
(global-set-key (kbd "<menu>") 'menu-key-map)