Skip to content

Latest commit

 

History

History
1192 lines (1085 loc) · 40.1 KB

config.org

File metadata and controls

1192 lines (1085 loc) · 40.1 KB

Package Manager

Lexical Binding

In order to enable lexical binding in the config, this must be the first line of Emacs Lisp.

;;; config.el -*- lexical-binding: t -*-

Straight

straight.el is a better replacement of the default package.el.

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

Shadow clone git repo to improve the speed.

(setq straight-vc-git-default-clone-depth 1)

Use Package

Use Package allows you to isolate package configuration in your emacs config file in a way that is both performance-oriented and, well, tidy.

(straight-use-package 'use-package)
(setq straight-use-package-by-default t)

Basic UI

Color Theme

Modus Themes

modus-themes is a highly accessible themes for GNU Emacs.

(use-package modus-themes
  :init
  (setq modus-themes-italic-constructs t
        modus-themes-bold-constructs t
        modus-themes-mode-line '(borderless)
        modus-themes-markup '(background italic)
        modus-themes-paren-match '(bold intense)
        modus-themes-links '(neutral-underline background)
        modus-themes-prompts '(intense bold)
        modus-themes-org-blocks 'gray-background
        modus-themes-region '(bg-only no-extend)
        modus-themes-headings '((1 . (1.15))
                                (2 . (1.05))
                                (t . (semibold))))
  :config
  (load-theme 'modus-operandi :no-confim))

Default Face

(set-face-foreground 'link "#0168da")
(set-face-background 'isearch "#feff00")
(set-face-foreground 'isearch nil)
(set-face-background 'lazy-highlight "#feff00")

Programming Face

(set-face-foreground 'font-lock-function-name-face "#0168da")
;; (set-face-foreground 'font-lock-variable-name-face "orange red")
(set-face-foreground 'font-lock-keyword-face "#874bf8")
(set-face-foreground 'font-lock-comment-face "DarkGray")
;; (set-face-foreground 'font-lock-type-face "#1E90FF")
(set-face-foreground 'font-lock-constant-face "dark cyan")
;; (set-face-foreground 'font-lock-builtin-face "#1E90FF")
(set-face-foreground 'font-lock-string-face "chocolate")

Emacs Lisp

highlight-defined is an Emacs minor mode that highlights defined Emacs Lisp symbols in source code.

Currently it recognizes Lisp function, built-in function, macro, face and variable names.

(use-package highlight-defined
  :hook
  (emacs-lisp-mode . highlight-defined-mode)
  :custom-face
  (highlight-defined-face-name-face  ((t :inherit org-block))))

Markup Face

Org Mode

(set-face-foreground 'org-meta-line "Gray")
(set-face-foreground 'org-drawer "Gray")
(set-face-foreground 'org-document-info-keyword "Gray")
(set-face-foreground 'org-date "Gray")
(set-face-foreground 'org-link "#0168da")

(set-face-attribute 'org-level-1 nil :foreground "#0168da")
(set-face-attribute 'org-level-2 nil :foreground "#874bf8")
(set-face-attribute 'org-level-3 nil :foreground "dark cyan")
(set-face-attribute 'org-level-4 nil :foreground "violet red")
(set-face-attribute 'org-level-5 nil :foreground "SpringGreen4")
(set-face-attribute 'org-level-6 nil :foreground "orange red")
(set-face-attribute 'org-level-7 nil :foreground "light sea green")
(set-face-attribute 'org-level-8 nil :foreground "chocolate")

(set-face-attribute 'org-headline-done nil :foreground "gray")
(set-face-attribute 'org-done nil :foreground "gray"
                                  :weight 'normal)

Markdown

Terminal Face

Modeline

Use a single line as modeline.

(use-package emacs
  :custom-face
  (header-line ((t (:background "grey90" :foreground "grey20" :box nil))))
  (mode-line ((t (:foreground "dim gray" :height 0.1))))
  (mode-line-inactive ((t (:inherit mode-line))))
  (mode-line-inactive ((t (:inherit mode-line))))
  :config
  (setq-default mode-line-format '("")))

Title Bar

Show icon and abbreviated full path for file and directory in title bar.

(setq frame-title-format
      '(buffer-file-name (:eval (abbreviate-file-name buffer-file-name))
         (dired-directory dired-directory "%b")))

Cursor

(use-package emacs
  ;; TODO: disable highlight face or make it inherit current face, like region
  :custom-face
  (highlight ((t (:foreground nil :background nil))))
  :config
  ;; Set default cursor type to bar.
  (setq-default cursor-type 'bar)
  ;; Disable cursor in inactive window.
  (setq-default cursor-in-non-selected-windows nil))

Fringe

https://stackoverflow.com/a/27854648/9984029 Disable ugly fringe bitmaps.

(use-package fringe
  :straight (:type built-in)
  :custom-face
  (fringe ((t (:foreground nil :background nil))))
  :config
  (setf (cdr (assq 'continuation fringe-indicator-alist))
        '(nil nil)))

Basic UX

Messages

Disable these messages by setting command-error-function to a function that ignores unused signals. https://emacs.stackexchange.com/a/20039/19518

(defun filter-command-error-function (data context caller)
  "Ignore the buffer-read-only, beginning-of-line, end-of-line, beginning-of-buffer, end-of-buffer signals; pass the rest to the default handler."
  (when (not (memq (car data) '(buffer-read-only
                                mark-inactive
                                beginning-of-line
                                end-of-line
                                beginning-of-buffer
                                end-of-buffer)))
    (command-error-default-function data context caller)))

(setq command-error-function #'filter-command-error-function)

Disable unhelpful mesages in minibuffer.

(defun suppress-messages (func &rest args)
  (cl-letf (((symbol-function 'message)
              (lambda (&rest args) nil)))
     (apply func args)))

Use Return to act Yes

(setq use-short-answers t)
(define-key y-or-n-p-map (kbd "<return>") 'y-or-n-p-insert-y)

Visit a symbolic link pointing to a version-controlled file without asking.

(setq vc-follow-symlinks t)

Disable mouse command on y-or-n-p.

(setq use-dialog-box nil)

Scroll

Enable pixel scroll mode to improve scroll experience.

(use-package pixel-scroll
  :straight (:type built-in)
  :config
  (pixel-scroll-precision-mode))

File Manager

Dired

Hide all the information about files and folders except their names.

(use-package dired
  :straight (:type built-in)
  :hook
  (auto-revert-mode . dired-mode)
  :custom
  (dired-use-ls-dired nil)
  (dired-kill-when-opening-new-dired-buffer t)
  :config
  (add-hook 'dired-mode-hook (lambda () (dired-hide-details-mode))))

Dired Subtree

Dired Subtree can list subdirectories with Tab.

(use-package dired-subtree
  :after dired
  :bind
  (:map  dired-mode-map
   ("<tab>"     . dired-subtree-toggle)
   ("<backtab>" . dired-subtree-cycle)))

All The Icon Dired

All the icon dired adds dired support to all-the-icons.

(use-package all-the-icons-dired
 :hook
 (dired-mode . all-the-icons-dired-mode))

Completion

Vertico

(use-package vertico
  :init
  (vertico-mode)
  ;; Persist history over Emacs restarts. Vertico sorts by history position.
  (savehist-mode))

Marginalia

Marginalia adds marginalia to the minibuffer completions.

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

Orderless

Orderless is a completion style that matches multiple regexps in any order.

;; Optionally use the `orderless' completion style.
(use-package orderless
  :init
  (setq completion-styles '(orderless basic)
        completion-category-defaults nil
        completion-category-overrides '((file (styles partial-completion)))))

Search

Consult

consult allows you to quickly select an item from a list of candidates that you’re searching for.

(use-package consult
  :bind
  ("s-f"   . consult-line)
  ("s-F"   . consult-ripgrep)
  ("s-b"   . consult-project-buffer)
  ("s-B"   . consult-buffer)
  :config
  ;; Record recent files, call consult-recent-file.
  (recentf-mode))

Prompt

Embark

Embark is a Emacs Mini-Buffer Actions Rooted in Keymaps.

(use-package embark
  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
  :init
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  :config
  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :after (embark consult)
  :demand t ; only necessary if you have the hook below
  ;; if you want to have consult previews as you move around an
  ;; auto-updating embark collect buffer
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Window Management

Session

restart-emacs offers a command restart-emacs.

(use-package restart-emacs)

Associate alfred-open-in-editor to open folder in a new frame by emacsclient.

(server-start)

Window

No popup windows.

(setq pop-up-windows nil)

Frame

Keybindings

KeybindingsFeatures
Command + QQuit Emacs
Command + NCreate new frame
Command + `Change to other frame
Shift + Command + WClose current window
Ctrl + Command + FSet/Unset window full screen

Buffer

Keybindings

KeybindingsFeatures
Command + PFind File in Project
Command + WClose Current Buffer
Command + [Go to previous Buffer
Command + ]Go to next Buffer
Command + TCreate New Buffer
Command + SSave Buffer
Command + ,Open config file
Command + .Reload init file

Behaviors

Save files automatically.

(auto-save-visited-mode 1)

Save file silently.

(setq save-silently t)

Ensure files end with newline.

(setq require-final-newline t)

Revert (update) buffers automatically when underlying files are changed externally.

(global-auto-revert-mode t)

Set initial buffer mode to org-mode.

(setq-default initial-major-mode 'org-mode)

Save cursor position for each file.

(save-place-mode t)

Disable the ring bell when scroll beyond the document.

(setq ring-bell-function 'ignore)

Disable automatic backup~ file.

(setq make-backup-files nil)

Delete trailing whitespace on save.

(add-hook 'write-file-hooks 'delete-trailing-whitespace nil t)

Word Processing

Basic Features

Displaying Text

Font

English font refer to early-init.el default-frame-alist.

Keybindings

KeybindingsFeatures
Command + +Increase text scale
Command + =Increase text scale
Command + -Decrease text scale
Command + 0Reset text scale

Behaviors

Improve the readability by increasing line spacing.

(setq-default line-spacing 0.1)

Highlight urls and make them clickable.

(global-goto-address-mode 1)

Highlight paired brackets, includes (), [], {} and so on…

(use-package paren
  :config
  (show-paren-mode 1))

Moving Cursor

Keybindings

Make Command/Option + ArrowKey behaves like MacOS app.

KeybindingsFeatures
Command + ↑Move to the top of the file
Command + ↓Move to the bottom of the file
Command + ←Move to the beginning of the line
Command + →Move to the end of the line

Searching Text

Keybindings

KeybindingsFeatures
Command + FSearch text in Buffer
Shift + Command + FSearch text in current folder

Selecting Text

Keybindings

KeybindingsFeatures
Command + ASelect all the content in current file
Shift + ↑Select one line up
Shift + ↓Select one line down
Shift + ←Select one character left
Shift + →Select one character right
Shift + Option + ←Select one word left
Shift + Option + →Select one word right
Shift + Command + ↑Select to ttop of the file
Shift + Command + ↓Select to bottom of the file
Shift + Command + ←Select to the beginning of the line
Shift + Command + →Select to the end of the line

Behaviors

Highlight selection with system accent color.

(set-face-attribute 'region nil :background "#fccae2")

Editing Text

Keybindings

KeybindingsFeatures
Command + CCopy text
Command + XCut text
Command + VPaste text
Command + ReturnForce newline
Command + BackspaceDelete current line from cursor to the beginning
Command + Shift + BackspaceDelete whole line entirely
Command + /Comment/Uncomment line(s)

Behaviors

Only cut text with selection.

(setq mark-even-if-inactive nil)

Auto pair brackets, quotes etc.

(electric-pair-mode 1)

Do not indent on newlines.

(electric-indent-mode -1)

Overwrite selection on pasting.

(delete-selection-mode 1)

Indent with 2 space.

(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)
(setq indent-line-function 'insert-tab)

Undo

Increase undo limit.

;; default is 160000
(setq undo-limit 800000)
;; default is 240000
(setq undo-strong-limit 12000000)
;; default is 24000000
(setq undo-outer-limit 120000000)

Vim Emulator

Evil

Evil is an extensible vi layer for Emacs. It emulates the main features of Vim, and provides facilities for writing custom extensions.

(use-package evil
  :bind
  (:map evil-normal-state-map
        ("j"   . evil-next-visual-line)
        ("k"   . evil-previous-visual-line)
   :map evil-motion-state-map
        ;; Make Return open link in org-mode.
        ("RET" . nil))
  :init
  (setq evil-want-keybinding nil)
  ;; Make Tab in org mode works normally.
  (setq evil-want-C-i-jump nil)
  ;; Disable o to add indent below org mode heading.
  (setq evil-auto-indent nil)
  ;; Set Evil cursor color and styles in different situations.
  (setq evil-emacs-state-cursor 'bar)
  (setq evil-normal-state-cursor '(box "deep pink"))
  (setq evil-insert-state-cursor '(bar "deep pink"))
  (setq evil-visual-state-cursor '(hollow "deep pink"))
  (setq evil-operator-state-cursor '(evil-half-cursor "deep pink"))
  (setq evil-replace-state-cursor '(hbar "deep pink"))
  :config
  (evil-mode 1)
  ;; https://stackoverflow.com/a/10166400/9984029
  ;; Make ESC cancel selection in insert mode.
  (defun evil-escape-cancel-selection-first ()
    "In evil insert state, make ESC to cancel selection first, then press ESC to go to normal state."
    (interactive)
    (if (and delete-selection-mode transient-mark-mode mark-active)
        (setq deactivate-mark  t)
      (evil-normal-state)))
  (define-key evil-insert-state-map [escape] 'evil-escape-cancel-selection-first)
  ;; Consist keybinding for text movements.
  (define-key evil-normal-state-map "\C-a" 'beginning-of-line)
  (define-key evil-insert-state-map "\C-a" 'beginning-of-line)
  (define-key evil-visual-state-map "\C-a" 'beginning-of-line)
  (define-key evil-motion-state-map "\C-a" 'beginning-of-line)
  (define-key evil-normal-state-map "\C-e" 'end-of-line)
  (define-key evil-insert-state-map "\C-e" 'end-of-line)
  (define-key evil-visual-state-map "\C-e" 'end-of-line)
  (define-key evil-motion-state-map "\C-e" 'end-of-line)
  (define-key evil-normal-state-map "\C-f" 'forward-char)
  (define-key evil-insert-state-map "\C-f" 'forward-char)
  (define-key evil-insert-state-map "\C-f" 'forward-char)
  (define-key evil-normal-state-map "\C-b" 'backward-char)
  (define-key evil-insert-state-map "\C-b" 'backward-char)
  (define-key evil-visual-state-map "\C-b" 'backward-char)
  (define-key evil-normal-state-map "\C-n" 'next-line)
  (define-key evil-insert-state-map "\C-n" 'next-line)
  (define-key evil-visual-state-map "\C-n" 'next-line)
  (define-key evil-normal-state-map "\C-p" 'previous-line)
  (define-key evil-insert-state-map "\C-p" 'previous-line)
  (define-key evil-visual-state-map "\C-p" 'previous-line)
  :custom
  ;; Do not echo the state in minibuffer.
  (evil-echo-state nil)
  ;; Use native keybindings on insert state.
  (evil-disable-insert-state-bindings t)
  ;; Records changes to separate undo instead of a big one in insert state.
  (evil-want-fine-undo t))

Evil Collection

evil-collection provides evil-friendly bindings for many modes.

(use-package evil-collection
  :after evil
  :config
  (setq evil-collection-mode-list '(dired magit which-key diff-hl))
  (evil-collection-init))

Evil Surround

evil-surround makes surround text with paired symbols easily.

(use-package evil-surround
  :after evil
  :config
  (global-evil-surround-mode 1)
  (dolist (pair '((?\( . ("(" . ")"))
                  (?\[ . ("[" . "]"))
                  (?\{ . ("{" . "}"))
                  (?\* . ("*" . "*"))
                  (?\+ . ("+" . "+"))
                  (?\/ . ("/" . "/"))
                  (?\~ . ("~" . "~"))
                  (?\= . ("=" . "="))
                  (?\$ . ("$" . "$"))
                  (?\_ . ("_" . "_"))))
    (push pair evil-surround-pairs-alist)))

Evil Snip

Evil Snip enables incremental highlighting, repeat searches with ​~f~​, F, t and T.

(use-package evil-snipe
  :custom-face
  (evil-snipe-matches-face ((t (:inherit region :background "#feff00"))))
  :config
  (evil-snipe-override-mode t))

Evil Goggles

Evil Goggles displays visual hint on evil edit operations.

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

  ;; optionally use diff-mode's faces; as a result, deleted text
  ;; optionally use diff-mode's faces; as a result, deleted text
  ;; will be highlighed with `diff-removed` face which is typically
  ;; some red color (as defined by the color theme)
  ;; other faces such as `diff-added` will be used for other actions
  (evil-goggles-use-diff-faces))

Evil Nerd Commenter

evil-nerd-commenter (un)comments lines efficiently.

(use-package evil-nerd-commenter
  :bind
   (("s-/" . evilnc-comment-or-uncomment-lines)))

Avy

Avy is for jumping to visible text using a char-based decision tree.

(use-package avy
  :bind
  (("s-l" . avy-goto-line)
   :map evil-normal-state-map
        ("gt" . avy-goto-char)
        ("gf" . avy-goto-char)
        ("gs" . avy-goto-char-2)
        ("gl" . avy-goto-line)))

Undo

Undo Fu

Undo Fu is a simple, stable linear undo with redo.

(use-package undo-fu
  :bind
  (("s-z" . undo-fu-only-undo)
   ("s-Z" . undo-fu-only-redo)
   :map evil-normal-state-map
    ("u"   . undo-fu-only-undo)
    ("C-r" . undo-fu-only-redo))
  :custom
  (undo-fu-allow-undo-in-region t))

Undo fu Session

Undo fu session writes undo/redo information upon file save which is restored where possible when the file is loaded again.

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

Undo Highlight

undo hl highlights undo operations, like evil-goggles.

(use-package undo-hl
  :straight (undo-hl :type git :host github :repo "casouri/undo-hl")
  :hook
  (text-mode . undo-hl-mode))

Highlight Parens

rainbow-delimiters is a “rainbow parentheses”-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth.

(use-package rainbow-delimiters
  :hook
  ((prog-mode . rainbow-delimiters-mode)
   (latex-mode . rainbow-delimiters-mode))
  :config
  (set-face-attribute 'rainbow-delimiters-unmatched-face nil
                      :foreground 'unspecified
                      :inherit 'error
                      :strike-through t))

Super Save

Super Save auto-saves your buffers, when certain events happen.

(use-package super-save
  :config
  (super-save-mode 1))

Sudo Edit

Sudo Edit can edit read only file.

(use-package sudo-edit)

Large File

vlf can make you view large files in Emacs.

(use-package vlf
  :custom
  (vlf-application 'dont-ask))

Multiple Cursors

multiple-cursors for emacs.

(use-package multiple-cursors
  :bind
   (("s-d" . mc/mark-next-like-this)
    ("s-D" . mc/mark-all-like-this)
    :map mc/keymap
     ("<return>" . nil))
  :custom
  ;; Make mc slicent instead of asking almost every action.
  (mc/always-run-for-all t))

Yasnippet

Markup Languages

Org Mode

Config

Org is a highly flexible structured plain text file format.

(use-package org
  :straight (:type built-in)
  :hook
  (org-mode . org-indent-mode)
  :bind
  (:map org-mode-map
        ("<M-S-left>"  . nil)
        ("<M-S-right>" . nil)
        ("<M-left>"    . left-word)
        ("<M-right>"   . right-word)
        ("<C-S-right>" . org-shiftmetaright)
        ("<C-S-left>"  . org-shiftmetaleft)
        ("<C-right>"   . org-metaright)
        ("<C-left>"    . org-metaleft))
  :init
  ;; FIX: not working sometimes.
  ;; Enable shift selection in insert and visual mode.
  (add-hook 'evil-insert-state-entry-hook
            (lambda()
              (setq org-support-shift-select 'always)))
  (add-hook 'evil-normal-state-entry-hook
            (lambda()
              (setq org-support-shift-select nil)))
  (add-hook 'evil-visual-state-entry-hook
            (lambda()
              (setq org-support-shift-select 'always)))

  :custom
  ;; Fold all contents on opening a org file.
  (org-startup-folded t)
  ;; Disable reindent on every time editing code block.
  (org-src-preserve-indentation nil)
  (org-edit-src-content-indentation 0)
  ;; Use return to open link.
  (org-return-follows-link t)
  ;; Always display images.
  (org-startup-with-inline-images t)
  ;; Do not display image actual width, set to 500px by default.
  (org-image-actual-width 500)
  ;; Always download and display remote images.
  (org-display-remote-inline-image 'download)
  ;; Turncate lines
  (org-startup-truncated nil)
  ;; Export org to pdf through latex, support Chinese.
  (org-latex-pdf-process '("xelatex -interaction nonstopmode %f" "xelatex -interaction nonstopmode %f"))
  :config
  (advice-add 'org-cycle :around #'suppress-messages)
  ;; Add REVIEW to org todo keywords.
  (setq org-todo-keywords '((sequence "TODO" "REVIEW" "DONE")))
  ;; Make verbatim with highlight text background.
  (add-to-list 'org-emphasis-alist
             '("=" (:background "#fef7ca")))
  ;; Make deletion(obsolote) text foreground with dark gray.
  (add-to-list 'org-emphasis-alist
             '("+" (:foreground "dark gray"
                    :strike-through t)))
  ;; Make code style around with box.
  ;; TODO: try https://gist.github.com/rougier/f0f291f681cb5b95aef5ad51a83166fdhttps://github.com/rougier/svg-tag-mode
  (add-to-list 'org-emphasis-alist
             '("~" (:background "#f0f0f0"))))

Org Appear

Org Appear toggles visibility of hidden org-mode element parts upon entering and leaving an element.

(use-package org-appear
  :hook
  (org-mode . org-appear-mode)
  :config
  ;; Instant toggle raw format on insert mode
  (setq org-appear-trigger 'manual)
  (add-hook 'org-mode-hook (lambda ()
            (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)))
  ;; Hide emphasis makers.
  (setq org-hide-emphasis-markers t)
  ;; Prettify things like \pi, sub/super script.
  ;; (setq org-pretty-entities t)
  ;; Hide keywords like #+TITLE:
  (setq org-hidden-keywords '(title email date author))
  :custom
  (org-appear-delay 0)
  (org-appear-autolinks t)
  (org-appear-autoentities t)
  (org-appear-autokeywords t)
  (org-appear-autosubmarkers t))

Xenops

$rxx = \frac{Σ(X - \bar{X})(Y - \bar{Y})}{NSxSy}$

xenops is an editing environment for LaTeX mathematical documents with async rendering.

(use-package xenops
  ;; :hook
  ;; (org-mode . xenops-mode)
  :bind
  (:map xenops-mode-map
   ;; FIX: xenops overrides the default paste behavior with xenops-handle-paste through xenops-util-define-key-with-fallback in xenops-define-key which breaks the delete-selection-mode
   ("s-v" . yank))
  :custom
  (setq xenops-reveal-on-entry t)
  :config
  ;; Suppress xenops startup messages.
  (advice-add 'xenops-mode :around #'suppress-messages)
  (setq xenops-math-image-scale-factor 1.8))

Org Surround Markup

Surround selection with org mode markup. https://github.com/alphapapa/unpackaged.el#surround-region-with-emphasis-or-syntax-characters

;;;###autoload
(defmacro org-surround-markup (&rest keys)
  "Define and bind interactive commands for each of KEYS that surround the region or insert text.
Commands are bound in `org-mode-map' to each of KEYS.  If the
region is active, commands surround it with the key character,
otherwise call `org-self-insert-command'."
  `(progn
     ,@(cl-loop for key in keys
                for name = (intern (concat "unpackaged/org-maybe-surround-" key))
                for docstring = (format "If region is active, surround it with \"%s\", otherwise call `org-self-insert-command'." key)
                collect `(defun ,name ()
                           ,docstring
                           (interactive)
                           (if (region-active-p)
                               (let ((beg (region-beginning))
                                     (end (region-end)))
                                 (save-excursion
                                   (goto-char end)
                                   (insert ,key)
                                   (goto-char beg)
                                   (insert ,key)))
                             (call-interactively #'org-self-insert-command)))
                collect `(define-key org-mode-map (kbd ,key) #',name))))

(org-surround-markup "~" "=" "*" "/" "_" "+" "$")

Org Mouse

Support mouse click.

(use-package org-mouse
  :straight (:type built-in))

Org Modern

org-modern styles headlines, keywords, tables and source blocks by using font locking and text properties.

(use-package org-modern
  :hook
  (org-mode . org-modern-mode)
  :custom
  (org-modern-star [""] )
  (org-modern-hide-stars nil)
  ;; Enable this will break code block indentation.
  (org-modern-block-fringe nil)
  ;; Use valign instead
  (org-modern-table nil))

Markdown Mode

Markdown allows you to write using an easy-to-read, easy-to-write plain text format.

(use-package markdown-mode
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))

Script Languages

Apple Script

https://github.com/emacsorphanage/applescript-mode

(use-package applescript-mode)

Data Format

YAML

YAML is a human friendly data serialization language for all programming languages.

(use-package yaml-mode
  :mode
  (("\\.yaml\\'" . yaml-mode)
   ("\\.yml\\'" . yaml-mode)))

JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format.

(use-package json-mode
  :defer t)

Version Control

Magit

Magit is an interface for Git inside Emacs.

(use-package magit
  :bind
  (("s-k" . magit)
   :map transient-base-map
   ("<escape>" . transient-quit-one))
  :custom
  (magit-diff-refine-hunk t)
  (magit-save-repository-buffers 'dontask)
  ;; Disable ulgy bitmap in fringe in magit mode.
  (magit-section-visibility-indicator nil)
  :config
  ;; https://manuel-uberti.github.io/emacs/2018/02/17/magit-bury-buffer/
  (evil-define-key 'normal magit-status-mode-map (kbd "q") 'magit-kill-buffers)

  (defun magit-kill-buffers ()
    "Restore window configuration and kill all Magit buffers."
    (interactive)
    (let ((buffers (magit-mode-get-buffers)))
      (magit-restore-window-configuration)
      (mapc #'kill-buffer buffers))))

Git Modes

git-modes is Emacs major modes for Git configuration files.

(use-package git-modes
  :defer t)

Diff HL

diff-hl highlights uncommitted changes in the left fringe.

(use-package diff-hl
  :init
  (add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
  (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
  :config
  (global-diff-hl-mode)
  ;; Highlight changes on editing.
  (diff-hl-flydiff-mode)
  ;; Makes fringe and margin react to mouse clicks to show the curresponding hunk.
  (global-diff-hl-show-hunk-mouse-mode)
  :custom
  (diff-hl-draw-borders nil)
  :custom-face
  (diff-hl-change ((t (:background "#8fe9e3"))))
  (diff-hl-insert ((t (:background "#80f1a4"))))
  (diff-hl-delete ((t (:background "#f5cce1")))))

Terminal Emulator

Exec Path From Shell

exec-path-from-shell ensures environment variables inside Emacs look the same as in the user’s shell.

(use-package exec-path-from-shell
  :custom
  ;; No warnings, please! I don't care!
  (exec-path-from-shell-warn-duration-millis 99999)
  :config
  (exec-path-from-shell-initialize))

Vterm

Vterm is fully capable, fast, and it can seamlessly handle large outputs.

(use-package vterm
  :bind
  (:map vterm-mode-map
   ("s-k"           . vterm-clear)
   ("<s-left>"      . vterm-send-C-a)
   ("<s-right>"     . vterm-send-C-e)
   ("<s-backspace>" . vterm-send-C-u)
   ("C-c"           . vterm-send-C-c))
  :custom
  (vterm-always-compile-module t)
  :config
  ;; Disable evil mode for vterm.
  (evil-set-initial-state 'vterm-mode 'emacs)
  ;; FIX: Close vterm buffer without confriming.
  (setq kill-buffer-query-functions nil))

Vterm Toggle

vterm-toggle toggles between the vterm buffer and whatever buffer you are editing.

(use-package vterm-toggle
  :bind
  (("C-`"        . vterm-toggle)
   :map vterm-mode-map
   ("<C-return>" . vterm-toggle-insert-cd))
  :config
  ;; Display vterm at bottom.
  (setq vterm-toggle-fullscreen-p nil)
  (add-to-list 'display-buffer-alist
               '((lambda (buffer-or-name _)
                     (let ((buffer (get-buffer buffer-or-name)))
                       (with-current-buffer buffer
                         (or (equal major-mode 'vterm-mode)
                             (string-prefix-p vterm-buffer-name (buffer-name buffer))))))
                  (display-buffer-reuse-window display-buffer-in-direction)
                  (direction . bottom)
                  (dedicated . t)
                  (reusable-frames . visible)
                  (window-height . 0.3))))

Chinese Optimization

Display

valign can properly align tables containing variable-pitch font, CJK characters and images.

(use-package valign
  :hook
  ;; FIX: Performance is lack, cause slow movement.
  ;; Waiting for the author to rewrite the package https://github.com/casouri/valign/issues/29
  ((markdown-mode org-mode) . valign-mode)
  :config
  (setq valign-fancy-bar 1))

Search

Pinyinlib is a elisp library for converting first letter of Pinyin to Simplified/Traditional Chinese characters.

(use-package pinyinlib
  :config
  ;; https://emacs-china.org/t/vertico/17913/3
  (defun completion--regex-pinyin (str)
    (orderless-regexp (pinyinlib-build-regexp-string str)))
  (add-to-list 'orderless-matching-styles 'completion--regex-pinyin))

evil-pinyin: Search Chinese characters with the first letter of Pinyin.

(use-package evil-pinyin
  :config
  (evil-select-search-module 'evil-search-module 'evil-search)
  (global-evil-pinyin-mode))

ace-pinyin make you jump to Chinese character by pinyin with avy.

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

Input Method

sis can auto switch to English input method and save the previous input method when entering Evil normal mode, restore the saved input method when switching back to Evil insert mode.

(use-package sis
  :config
  (sis-ism-lazyman-config
   "com.apple.keylayout.ABC"
   "com.apple.inputmethod.SCIM.ITABC")
  (sis-global-respect-mode t)
  (sis-global-context-mode t)
  ;; Improve typing fluency experience.
  (set-language-environment "UTF-8"))

Keybindings

Make keybindings work under Chinese input method.

KeybindingsChinese KeybindingsFeatures
Command + [Command + 】Go to previous Buffer
Command + ]Command + 【Go to next Buffer
Command + ,Command + ,Open config file
Command + ,Command + 。Reload init file
Control + ·Control + `Toggle vterm

Font

Set Chinese Font.

(dolist (charset '(kana han symbol cjk-misc bopomofo))
    (set-fontset-font "fontset-default" charset
                      '("PingFang SC" . "iso10646-1") nil 'prepend))