A7R7 / EmaxBound

Let's explore the bound of emacs :D

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

EmaxBound Configuration


GNU Emacs Package Manager Linux

assets/dashboard.png

Introduction

How to deploy this config

This config file is still in its early stages of development, Everything is unstable! To play around with my config files, clone this repo anywhere you like on your system.
git clone --depth=1 https://github.com/A7R7/EmaxBound.git

Then, simply execute these make rules inside the repo directory.

make bootstrap-borg  # bootstrap borg itself
make bootstrap       # bootstrap collective or new drones

Last, run emacs --init-directory=<path-of-the-repo> (replace the path).

How I built this config from the seed

The whole config structure is built upon emacscollective/emacs.g. It is a starter-kit using borg as the package manager, which utilizes git submodules to maintain all its packages. Check Bootstrapping-using-a-seed from Borg’s manual to see how to build the config structure.

  • First, I generated the structure from the seed.
  • Then, I copied and pasted all the original code from init.el and early-init.el to this org file.
  • Last, most further config does not go beyond the following 3 steps:
    • Run M-x borg-assimilate and input the name of the package to install this package.
    • Write config codes into this org file, then run M-x org-babel-tangle so that emacs writes the codes into the corresponding file. (the org-auto-tangle package that I installed enables auto tangling on saving org file)
    • For some packages, specify its load path or build method in .borgconfig for them to be load or built as expected. This is auto tangled as well.

Why it’s called EmaxBound

The name “EmaxBound” is inspired by “Starbound”, a game I used to play and I love it. Why it is “EmaxBound” but not “EmacsBound” ?

  • “Emax” has the same number of characters of “Star”
  • So that the logo I drawed (mimicing the style of starbound) looks balanced
  • “Emaxbound” means “Explore the maxium bound of emacs”

Why not other popular emacs distros

  • Doom emacs, spacemacs and other emacs “distros”, are pretty good. They did a good job in “working out of the box”. However, their complexities is blocking me from gaining a further understanding of emacs and elisp.
  • Meanwhile, it’s much harder to do customizations on those complex systems, especially when you do not know what it already have. However, self-configured emacs does not have this problem.
  • Those distros get updates from time to time. What if one update breaks your workflow?

Why a literate config

Using literate configuration in org-mode has many benefits.

  • You know what you code does, because there’re descriptions in various styles around the code. Code comments cannot achieve 100% of this.
  • Easy jumping to the target code block among those foldable outlines.
  • Hot reload code blocks: after editing a src block, C-c C-c to apply changes on the fly.
  • The org file can be used as readme in github/gitlab, which shows all your codes. It can be published as blogs. For example, I use ox-hugo to generate markdown files, and later hugo renders it to html files. This is where this blog comes from.

References

Credits goes to the authors of those emacs configs that I referenced during the build-up of my emacs config file.

NOTE: the year number after link equals to min (last time the config get’s updated, last time I refered to the config)

Early Init

Transparency

NOTE: elisp codes under this headline are tangled to early-init.el.

Emacs load early-init.el before the initalization of GUI, which is before init.el.

Enable lexical-binding. Disable byte-compile for early-init.el.

According to the emacs manual, byte-compiling the init does not startup very much, and often leads to problems when you forget to recompile the file. Also, from my experience, it may lead to bugs that do not happen when not using byte-compile.

;;; -*- lexical-binding: t; no-byte-compile: t -*-

Defer garbage collection in the startup process.

(setq gc-cons-threshold most-positive-fixnum)
;; copied from lazycat
(setq gc-cons-percentage 0.6)

Prevent unwanted runtime compilation for native-comp.

(setq native-comp-deferred-compilation nil ;; obsolete since 29.1
      native-comp-jit-compilation nil)

Disable tool-bar, menu-bar and scroll-bar before they’re loaded.

(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
;; Prevent flashing of unstyled modeline at startup
(setq-default mode-line-format nil)

Smooth window on startup

(setq frame-inhibit-implied-resize t)

Config use-package before loading use-package. When start emacs with --debug-init, the init-file-debug condition is meet, and use-package will print out more info.

;; (if init-file-debug
  (setq use-package-verbose t
        use-package-expand-minimally nil
        use-package-compute-statistics t
        use-package-minimum-reported-time 0.001
        ;;debug-on-error t
  )
  ;; (setq use-package-verbose nil
  ;;       use-package-expand-minimally t))

Make emacs startup with background Transparency.

(set-frame-parameter nil 'alpha-background 85)
(add-to-list 'default-frame-alist '(alpha-background . 85))
(add-to-list 'default-frame-alist '(background-color . "#11142c"))

Disable fcitx5 on linux, because I use emacs rime, an internal input method of emacs, which is setuped here,

(setq pgtk-use-im-context-on-new-connection nil)

Below codes belongs to the original Borg seed.

(setq load-prefer-newer t)

(let ((dir (file-name-directory (or load-file-name buffer-file-name))))
  (add-to-list 'load-path (expand-file-name "lib/compat" dir))
  (add-to-list 'load-path (expand-file-name "lib/packed" dir))
  (add-to-list 'load-path (expand-file-name "lib/auto-compile" dir))
  (add-to-list 'load-path (expand-file-name "lib/org" dir))
  )

(require 'auto-compile)
(auto-compile-on-load-mode)
(auto-compile-on-save-mode)

(setq package-enable-at-startup nil)

(with-eval-after-load 'package
  (add-to-list 'package-archives (cons "melpa" "https://melpa.org/packages/") t))

Init

NOTE: Starting from here, elisp codes are tangled to init.el

Begin of init

After loading early-init.el, emacs begin to load init.el.

Disable byte compile for init.el, same reason of early-init.el.

;;; -*- lexical-binding: t; no-byte-compile: t -*-

Calculating time used loading emacs excutable, as well as setting some variables.

(progn ;     startup
  (defvar before-user-init-time (current-time)
    "Value of `current-time' when Emacs begins loading `user-init-file'.")
  ;; (switch-to-buffer "*Messages*")
  (message "Loading Emacs...done (%fs)"
           (float-time (time-subtract before-user-init-time
                                      before-init-time)))
  (setq user-init-file (or load-file-name buffer-file-name))
  (setq user-emacs-directory (file-name-directory user-init-file))
  (message "Loading %s..." user-init-file)
)

Set some defaults of emacs

(progn
  (setq inhibit-startup-buffer-menu t)
  (setq inhibit-startup-screen t)
  (setq inhibit-startup-echo-area-message "locutus")
  (setq initial-buffer-choice t)
  ;; (setq initial-scratch-message "")
  ;; This improves performance for some fonts
  (setq inhibit-compacting-font-cache t)
  ;; emacs.stackexchange/how-to-disable-emacs-bidi
  (setq-default bidi-paragraph-direction 'left-to-right)
  (setq bidi-inhibit-bpa t
        long-line-threshold 1000
        large-hscroll-threshold 1000
        syntax-wholeline-max 1000)
  (setq use-dialog-box nil)
  (setq confirm-kill-emacs 'y-or-n-p)
  (put 'downcase-region 'disabled nil)
  (put 'upcase-region 'disabled nil)
  )
(global-auto-revert-mode)

Borg

Borg is the package manager that I use for my configuration. It assimilate Emacs packages as git submodules, which are called ”drones” in borg’s specific.

Borg clones all drones into borg-drones-directory (by default user-emacs-directory/lib). The drones are not added to the load path until borg-initialize is called. In a nut shell borg-initialize is a loop of borg-activate on all assimilated (and not disabled) drones, which adds the drone to the load path and eval its autoloads.

Here we add lib/borg to the load-path before borg is loaded, and then call borg-initialize to add all packages to the load path and eval their autoloads.

And then we switch to the message buffer in an attempt to make the loading process not that boring.

(use-package borg
:init
  (add-to-list 'load-path
    (expand-file-name "lib/borg" user-emacs-directory))
:config
  (borg-initialize)
  (switch-to-buffer "*Messages*")
)

Auto-Compile

Auto-Compile automatically compile Emacs Lisp libraries. But comp warnings are always boring. Suppress comp warnings.
(use-package auto-compile
:config
  (setq auto-compile-display-buffer             nil
        auto-compile-mode-line-counter            t
        auto-compile-source-recreate-deletes-dest t
        auto-compile-toggle-deletes-nonlib-dest   t
        auto-compile-update-autoloads             t
        warning-suppress-log-types        '((comp))
  )
)

Epkg

Epkg allows you browse the Emacsmirror package database. It also provides a command epkg-describe-package that looks nicer than the built-in describe-package.
(use-package epkg
:defer t
:bind
  ([remap describe-package] . epkg-describe-package)
:init
  (setq epkg-repository
        (expand-file-name "var/epkgs/" user-emacs-directory))
  (setq epkg-database-connector 'sqlite-builtin ) ; requires emacs >=29
)

Custom

Custom is a built-in package, provides the customize system of emacs. We set the custom-file to custom.el and then load it.

It’s not a good idea to put too many customizations in the custom file, especially for a declarative configuration. If one wants to make something permanent, he should write them down in the user configuration file (like here).

On the other hand, some unimportant customizations that change over time based on user’s likes are better suited to be placed in the custom file, a good example is the theme.

(use-package custom
:no-require t
:config
  (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
  (setf custom-safe-themes t) ;Treat all themes as safe
  (when (file-exists-p custom-file)
    (load custom-file))
)

Server

Server allows Emacs to operate as a server for other processes. Built in.
(use-package server
:commands (server-running-p)
:config (or (server-running-p) (server-mode)))

GCMH

Pulse-Cursor

The Garbage Collector Magic Hack enforce a sneaky Garbage Collection strategy to minimize GC interference with user activity.

(use-package gcmh
:init
  (setq gcmh-high-cons-threshold 536870912) ;; 512mb
:config
  (gcmh-mode 1)
  )

No-littering

(use-package no-littering)

Libraries

S

S is the long lost Emacs string manipulation library.

F

F is a modern API for working with files and directories in Emacs.

Dash

Dash is a modern list library for Emacs. See its overview at dash.el - functions. Dash-Fontify mode is a buffer-local minor mode intended for Emacs Lisp buffers. Enabling it causes the special variables bound in anaphoric Dash macros to be fontified. These anaphoras include ‘it’, ‘it-index’, ‘acc’, and ‘other’. In older Emacs versions which do not dynamically detect macros, Dash-Fontify mode additionally fontifies Dash macro calls.
(use-package dash
  :config (global-dash-fontify-mode))

Dash needs some tweaks to be built

[submodule "dash"]
  no-byte-compile = dash-functional.el
  no-makeinfo = dash-template.texi

EIEIO

EIEIO is a series of Lisp routines which implements a subset of CLOS, the Common Lisp Object System. In addition, EIEIO also adds a few new features which help it integrate more strongly with the Emacs running environment.
(use-package eieio)

Annalist

annalist.el is a library that can be used to record information and later print that information using org-mode headings and tables. It allows defining different types of things that can be recorded (e.g. keybindings, settings, hooks, and advice) and supports custom filtering, sorting, and formatting. annalist is primarily intended for use in other packages like general and evil-collection, but it can also be used directly in a user’s configuration.

Sqlite3

[submodule "sqlite3"]
  build-step = make

Emacsql

tweaks to buiild emacsql
[submodule "emacsql"]
no-byte-compile = emacsql-pg.el

Emacs Async

Builtins

DIff mode

(use-package diff-mode
  :defer t
  :config
  (when (>= emacs-major-version 27)
    (set-face-attribute 'diff-refine-changed nil :extend t)
    (set-face-attribute 'diff-refine-removed nil :extend t)
    (set-face-attribute 'diff-refine-added   nil :extend t)))

Dired

(use-package dired
  :defer t
  :config (setq dired-listing-switches "-alh"))

ELdoc

a MinorMode which shows you, in the echo area, the argument list of the function call you are currently writing.
(use-package eldoc
  :when (version< "25" emacs-version)
  :config (global-eldoc-mode))

Help

(use-package help
  :defer t
  :config (temp-buffer-resize-mode))

Helpful

Helpful adds a lot of very helpful information to Emacs’ describe- command buffers. For example, if you use describe-function, you will not only get the documentation about the function, you will also see the source code of the function and where it gets used in other places in the Emacs configuration. It is very useful for figuring out how things work in Emacs.

It’s not a built in package. I put it here simply because it’s near help.

(use-package helpful
:bind
  ([remap describe-key]      . helpful-key)
  ([remap describe-command]  . helpful-command)
  ([remap describe-variable] . helpful-variable)
  ([remap describe-function] . helpful-callable)
  ("C-h F" . describe-face)
  ("C-h K" . describe-keymap)
:config
  ;; (defun my/helpful--syntax-highlight (string)
  ;;   (propertize string 'family 'fixed-pitch))
  ;; (advice-add 'helpful--syntax-highlight :filter-return #'my/helpful--syntax-highlight)
)

Info+

(use-package info+
:defer t
:config
)
(use-package info-colors
:config
  (add-hook 'Info-selection-hook 'info-colors-fontify-node)
  (add-hook 'Info-mode-hook 'olivetti-mode)
  (add-hook 'Info-mode-hook 'mixed-pitch-mode)
)

Isearch

(progn ;    `isearch'
  (setq isearch-allow-scroll t))

Lisp-mode

(use-package lisp-mode
  :config
  (add-hook 'emacs-lisp-mode-hook 'outline-minor-mode)
  (add-hook 'emacs-lisp-mode-hook 'reveal-mode)
  (defun indent-spaces-mode ()
    (setq indent-tabs-mode nil))
  (add-hook 'lisp-interaction-mode-hook 'indent-spaces-mode))

Man

(use-package man
  :defer t
  :config (setq Man-width 80))

Prog-mode

(use-package prog-mode
  :config
  (global-prettify-symbols-mode)
  (defun indicate-buffer-boundaries-left ()
    (setq indicate-buffer-boundaries 'left))
  (add-hook 'prog-mode-hook 'indicate-buffer-boundaries-left)
)

Recentf

(use-package recentf
  :demand t
  :config (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?x?:"))

Savehist

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

Saveplace

;; A few more useful configurations...
  (use-package emacs
      :init
      ;; Add prompt indicator to `completing-read-multiple'.
      ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
      (defun crm-indicator (args)
      (cons (format "[CRM%s] %s"
          (replace-regexp-in-string
          "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
          crm-separator)
          (car args))
        (cdr args)))
      (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

      ;; Do not allow the cursor in the minibuffer prompt
      (setq minibuffer-prompt-properties
    '(read-only t cursor-intangible t face minibuffer-prompt))
      (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

      ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
      ;; Vertico commands are hidden in normal buffers.
      ;; (setq read-extended-command-predicate
      ;;       #'command-completion-default-include-p)
      ;; Enable recursive minibuffers
      (setq enable-recursive-minibuffers t))

Simple

(use-package simple
  :config (column-number-mode))

Smerge

(use-package smerge-mode
  :defer t
  :config
  (when (>= emacs-major-version 27)
    (set-face-attribute 'smerge-refined-removed nil :extend t)
    (set-face-attribute 'smerge-refined-added   nil :extend t)))

Text

(progn ;    `text-mode'
  (add-hook 'text-mode-hook 'indicate-buffer-boundaries-left))

Tramp

(use-package tramp
:config
  (add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:"))
  (add-to-list 'tramp-default-proxies-alist '("localhost" nil nil))
  (add-to-list 'tramp-default-proxies-alist
         (list (regexp-quote (system-name)) nil nil))
  (setq vc-ignore-dir-regexp
  (format "\\(%s\\)\\|\\(%s\\)"
    vc-ignore-dir-regexp
    tramp-file-name-regexp)))

(use-package tramp-sh
  :config (cl-pushnew 'tramp-own-remote-path tramp-remote-path))

Pixel-scroll

(use-package pixel-scroll
:config
  (setq scroll-conservatively 97)
  (setq scroll-preserve-screen-position 1)
  (setq mouse-wheel-progressive-speed nil)
  ;; The following piece of code is stolen from
  ;; https://emacs-china.org/t/topic/25114/5
  (pixel-scroll-precision-mode 1)
  (setq pixel-scroll-precision-interpolate-page t)
  (defun +pixel-scroll-interpolate-down (&optional lines)
      (interactive)
      (if lines
          (pixel-scroll-precision-interpolate (* -1 lines (pixel-line-height)))
      (pixel-scroll-interpolate-down)))

  (defun +pixel-scroll-interpolate-up (&optional lines)
      (interactive)
      (if lines
          (pixel-scroll-precision-interpolate (* lines
          (pixel-line-height))))
      (pixel-scroll-interpolate-up))

  (defalias 'scroll-up-command '+pixel-scroll-interpolate-down)
  (defalias 'scroll-down-command '+pixel-scroll-interpolate-up)
)

End of core units

Calculate loading time of core units.
(progn ;     startup
  (message "Loading core units...done (%fs)"
     (float-time (time-subtract (current-time) before-user-init-time))))

Debug init

<<debug-init>>

Keybindings

An overview of this outline: In General.el and Meow.el, we setup the keybinding framework. Then in Keybindings, define keybindings.

General.el

General provides a more convenient method for binding keys in emacs (for both evil and non-evil users).

Note: byte compile init.el will lead to function created by general-create-definer failed to work.

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

(use-package general)

Meow.el

Meow is yet another modal editing.
(use-package meow
:custom-face
  (meow-cheatsheet-command ((t (:height 180 :inherit fixed-pitch))))
:config
  ;cate the behavior of vi's
  (defun my-meow-append ()
    "Move to the end of selection, switch to INSERT state."
    (interactive)
    (if meow--temp-normal
           (progn
             (message "Quit temporary normal mode")
             (meow--switch-state 'motion))
    (if (not (region-active-p))
             (when (and (not (use-region-p))
                        (< (point) (point-max)))
               (forward-char 1))
     (meow--direction-forward)
     (meow--cancel-selection))
     (meow--switch-state 'insert)))

   (advice-add 'meow-append :override #'my-meow-append)

  (defun my-meow-open-below ()
    "Open a newline below and switch to INSERT state."
    (interactive)
    (if meow--temp-normal
        (progn
          (message "Quit temporary normal mode")
          (meow--switch-state 'motion))
      (meow--switch-state 'insert)
      ;(goto-char (line-end-position))
      (move-end-of-line 1)
      (meow--execute-kbd-macro "RET")))
   (advice-add 'meow-open-below :override #'my-meow-open-below)

 (setq meow-keypad-self-insert-undefined nil)
 (setq meow-selection-command-fallback '(
    (meow-grab . meow-right-expand)
    (meow-change . meow-change-char)
    (meow-kill . meow-delete)
    (meow-cancel-selection . keyboard-quit)
    (meow-pop-selection . meow-pop-grab)
    (meow-beacon-change . meow-beacon-change-char)
    (meow-replace . meow-yank)
    (meow-reverse . negative-argument)
  ))

 (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
 (meow-global-mode)
)

Mode-map

Keybindings defined somewhere else…

Mode leader

Generally, I define my local leader as follows:
  • Let C-<escape> be the local leader. The convention is to use C-c, but I make C-c save to system clipboard ;)
  • I do not directly press C-<escape>. Instead, I translate \ to C-<escape> in meow’s normal mode.
  • The keybindings are bind to those major mode maps.
(defvar my/mode-leader "C-<escape>")

(defmacro my/key (&optional key)
  `(general-key
       (if ,key
           (concat ,my/mode-leader " " ,key)
         ,my/mode-leader)))

(general-create-definer my/mode-leader-def
  :prefix my/mode-leader
  :wk-full-keys nil
)

Global-map

Meow-normal

(meow-normal-define-key
  '("<escape>" . meow-cancel-selection)
  '("SPC" . my/leader-prefix-cmd) ;; defined latter
  '("1" . meow-expand-1) '("2" . meow-expand-2)
  '("3" . meow-expand-3) '("4" . meow-expand-4)
  '("5" . meow-expand-5) '("6" . meow-expand-6)
  '("7" . meow-expand-7) '("8" . meow-expand-8)
  '("9" . meow-expand-9) '("0" . meow-expand-0)
  '("*" . tempel-insert) '("+" . tempel-expand)

  '("q" . meow-quit) '("Q" . meow-quit)
     ;'("w" . meow-window) '("W" . meow-window)
  '("e" . embark-dwim) '("E" . embark-act)
     ;'("r" . meow-) '("R" . meow-e)
  '("t" . meow-till) '("T" . meow-till-expand)

  '("a" . begin-of-line) '("a" . meow-beginning-of-thing)
  '("s" . meow) '("s" . meow-bounds-of-thing)
  '("d" . meow) '("d" . meow-inner-of-thing)
  '("f" . end-of-line) '("f" . meow-end-of-thing)
  '("g" . meow-right-expand) '("G" . meow-grab)

  '("z" . meow-undo) '("Z" . meow-undo-in-selection)
  '("x" . meow-kill) '("X" . meow-clipboard-kill)
  '("c" . meow-clipboard-save)
  '("v" . meow-replace) '("V" . meow-yank-pop)
  '("C-v" . meow-clipboard-yank)
  '("b". meow-block) '("B" . meow-to-block)

  '("y" . meow-visit)
  '("u" . meow-change) '("U" . meow-reverse)
  '("i" . meow-insert) '("I" . meow-open-above)
  '("o" . meow-append) '("O" . meow-open-below)
  '("p" . meow-pop-selection)
  '("[" . meow-beginning-of-thing) '("]" . meow-end-of-thing)

  '("h" . meow-join)  '("H" . meow-join)
  '("j" . meow-left)  '("J" . meow-left-expand)
  '("k" . meow-prev)  '("K" . meow-prev-expand)
  '("l" . meow-next)  '("L" . meow-next-expand)
  '(";" . meow-right) '(":" . meow-right-expand)
  '("'" . meow-line) '("\"" . meow-line)

  '("C-j" . "C-<escape> C-j")
  '("C-k" . "C-<escape> C-k")
  '("C-l" . "C-<escape> C-l")
  '("C-;" . "C-<escape> C-;")

  '("n" . meow-search)      '("N" . meow-pop-search)
  '("m" . meow-mark-word)   '("M" . meow-mark-symbol)
  '("," . meow-back-word)   '("<" . meow-back-symbol)
  '("." . meow-next-word)   '(">" . meow-next-symbol)
  '("/" . meow-reverse)

  '("\"" . fingertip-wrap-double-quote)
  '("(" . fingertip-wrap-round)
  '("[" . fingertip-wrap-bracket)
  '("{" . fingertip-wrap-curly)
  )

Meow-motion

(meow-motion-overwrite-define-key
 '("j" . meow-left)
 '("k" . meow-prev)
 '("l" . meow-next)
 '(";" . meow-right)
 '("SPC" . my/leader-prefix-cmd) ;; defined latter
 '("<escape>" . ignore)
)

Meow-keypad

I generally do not use meow’s keypad, because meow’s keypad highly relies on vanilla emacs’s keybindings, which is what I do not prefer.
(meow-leader-define-key
;; Use SPC (0-9) for digit arguments.
 '("1" . meow-digit-argument) '("2" . meow-digit-argument)
 '("3" . meow-digit-argument) '("4" . meow-digit-argument)
 '("5" . meow-digit-argument) '("6" . meow-digit-argument)
 '("7" . meow-digit-argument) '("8" . meow-digit-argument)
 '("9" . meow-digit-argument) '("0" . meow-digit-argument)
 '("/" . meow-keypad-describe-key) '("?" . meow-cheatsheet)
 ;;'("SPC" . config/leader-prefix-cmd)
)

Meow-insert

(general-def
:keymaps '(global-map)
  "C-v"       '(clipboard-yank              :wk "paste")
  "C-SPC"     '(toggle-input-method         :wk "input method")
  "<f12>"       'org-capture
  "C-j"       (my/key "C-j")
  "C-;"       (my/key "C-;")
  "C-k"       (my/key "C-k")
  "C-l"       (my/key "C-l")
  ;"C-/"      '(yank                        :wk "comment-dwim")
)
(general-def
:keymaps '(meow-normal-state-keymap meow-motion-state-keymap)
  "\\"         (my/key)
  "M-j"       '(windmove-left               :wk " Win")
  "M-k"       '(windmove-up                 :wk " Win")
  "M-l"       '(windmove-down               :wk " Win")
  "M-;"       '(windmove-right              :wk " Win")
  "M-\'"      '(delete-window               :wk " Win")
  "M-,"       '(sort-tab-select-prev-tab    :wk " Tab")
  "M-."       '(sort-tab-select-next-tab    :wk " Tab")
  "M-/"       '(sort-tab-close-current-tab  :wk " Tab")
)

Global leader

(general-create-definer my/leader
:prefix-command 'my/leader-prefix-cmd
:prefix-map 'my/leader-prefix-map
:wk-full-keys nil
  "DEL"     '(which-key-undo                 :wk "undo-key")
)
(my/leader
  "SPC"     (my/key)
  "/"       '(comment-dwim                   :wk "comment")
  "c"       '(nil                            :wk "consult")
  "d"       '(dirvish-side                   :wk "dirvish-side ")
  "D"       '(dirvish                        :wk "dirvish")
  "r"       '(nil                            :wk "run")
  "s"       '(save-buffer                    :wk "save")
  "t"       '(nil                            :wk "toggle")
  "w"       '(nil                            :wk "workspace")
  "x"       '(consult-mode-command           :wk "execute")
  "z"       '(vundo                          :wk "visual undo")
)
(my/leader :infix "r"
  "b"      '(nil                             :wk "borg")
  "e"      '(elfeed                          :wk " elfeed")
  "t"      '(telega                          :wk " telega")
  "p"      '(profiler-start                  :wk " profiler")
  "P"      '(profiler-stop                   :wk " profiler stop")
)
;; Borg
(my/leader :infix "rb"
  "a"       '(borg-assimilate                :wk "󱧕 assimilate ")
  "b"       '(borg-build                     :wk "󱇝 build")
  "c"       '(borg-clone                     :wk " clone")
  "d"       '(borg-remove                    :wk "󱧖 delete")
  "r"       '(borg-activate                  :wk " run")
  )
(my/leader :infix "c"
  "l"       '(consult-line                   :wk "line")
  "L"       '(consult-line-multi             :wk "line multi")
  "o"       '(consult-outline                :wk "outline")
  "i"       '(consult-imenu                  :wk "imenu")
  "I"       '(consult-imenu-multi            :wk "imenu multi")
  "r"       '(consult-ripgrep                :wk "ripgrep")
  "m"       '(consult-mark                   :wk "mark")
  "x"       '(consult-mode-command           :wk "execute")
  )
(my/leader :infix "w" ;; workspaces
  "\\"      '(tab-new                        :wk "tab 󰏌")
  "|"       '(tab-close                      :wk "tab 󰅖")
  "["       '(tab-previous                   :wk "tab ")
  "]"       '(tab-next                       :wk "tab ")

  "/"       '(consult-buffer                 :wk "buffer 󰏌")
  "f"       '(find-file                      :wk "file 󰏌")
  "r"       '(revert-buffer-quick            :wk "revert")

  "J"       '(split-window-right             :wk "split ")
  "K"       '(split-window-below             :wk "split ")
  "L"       '(split-window-above             :wk "split ")
  ":"       '(split-window-left              :wk "split ")
  )
;; toggle
(my/leader :infix "t"
  "o"       '(olivetti-mode                  :wk "󰼭 olivetti")
  "l"       '(nil                            :wk " line Number ")
  )

(my/leader :infix "tl"
  "DEL" '(which-key-undo                     :wk "󰕍 Undo key   ")
  "n"   '(config/toggle-line-number-nil      :wk "󰅖 Nil        ")
  "a"   '(config/toggle-line-number-absolute :wk "󰱇 Absolute   ")
  "r"   '(config/toggle-line-number-relative :wk "󰰠 Relative   ")
  "v"   '(config/toggle-line-number-visual   :wk " Visual     ")
  "h"   '(hl-line-mode                       :wk "󰸱 Hl-line")
  )
;; Git
(my/leader :infix "g"
  ""        '(nil                            :wk "git")
  "g"       '(magit                          :wk " magit")
  )
;; windows, buffers and tabs(workspaces)
;; these are copied from emacs source code
(defun split-window-left (&optional size window-to-split)
  (interactive `(,(when current-prefix-arg
                    (prefix-numeric-value current-prefix-arg))
                 ,(selected-window)))
  (let (new-window)
    (when (and size (< size 0) (< (- size) window-min-width))
      ;; `split-window' would not signal an error here.
      (error "Size of new window too small"))
    (setq new-window (split-window window-to-split size 'left))
    ;; Always copy quit-restore parameter in interactive use.
    (let ((quit-restore (window-parameter window-to-split 'quit-restore)))
      (when quit-restore
        (set-window-parameter new-window 'quit-restore quit-restore)))
    new-window))

(defun split-window-above (&optional size window-to-split)
  (interactive `(,(when current-prefix-arg
                    (prefix-numeric-value current-prefix-arg))
                 ,(selected-window)))
  (let ((old-point (window-point))
        moved-by-window-height moved new-window bottom)
    (when (and size (< size 0) (< (- size) window-min-height))
      ;; `split-window' would not signal an error here.
      (error "Size of new window too small"))
    (setq new-window (split-window window-to-split size 'above))
    (when (and (null split-window-keep-point)
               (or (null window-to-split)
                   (eq window-to-split (selected-window))))
      (with-current-buffer (window-buffer window-to-split)
        (save-excursion
          (goto-char (window-start))
          (setq moved (vertical-motion (window-height)))
          (set-window-start new-window (point))
          (when (> (point) (window-point new-window))
            (set-window-point new-window (point)))
          (when (= moved (window-height))
            (setq moved-by-window-height t)
            (vertical-motion -1))
          (setq bottom (point)))
        (and moved-by-window-height
             (<= bottom (point))
             (set-window-point window-to-split (1- bottom)))
        (and moved-by-window-height
             (<= (window-start new-window) old-point)
             (set-window-point new-window old-point)
             (select-window new-window))))
    ;; Always copy quit-restore parameter in interactive use.
    (let ((quit-restore (window-parameter window-to-split 'quit-restore)))
      (when quit-restore
        (set-window-parameter new-window 'quit-restore quit-restore)))
    new-window))

Transient

Transient-posframe display transient popups using a posframe.
(use-package transient-posframe
:config
  (setq transient-posframe-min-height 1)
  (setq transient-posframe-poshandler
        'posframe-poshandler-frame-bottom-right-corner)
  (transient-posframe-mode)
)

Which-key.el

Which-key is a minor mode for Emacs that displays the key bindings following your currently entered incomplete command (a prefix) in a popup.

Magit and meow all use transient maps, therefore we let which-key show transient maps.

(use-package which-key
:init
  ;; contents
  (setq which-key-sort-order 'which-key-key-order)
  (setq which-key-sort-uppercase-first nil)
  ;; delays
  (setq which-key-idle-delay 0.01) ; the first idle
  (setq which-key-idle-secondary-delay 0.01) ; set to 0 will cause some problems
  (setq which-key-show-early-on-C-h t)
  ;; arrangements
  (setq which-key-max-display-columns nil)
  (setq which-key-max-description-length 25) ;
  (setq which-key-allow-imprecise-window-fit t) ; reduce delay
  (setq which-key-show-transient-maps t)
  (setq which-key-frame-max-height 60)
  ;; window
  (setq which-key-popup-type 'side-window)
  (setq which-key-side-window-location 'right)
  ;; characters
  (setq which-key-prefix-prefix "󰜄 ")
  (setq which-key-separator " ") ; yeah I don't like the arrow
  ;; (dolist (replace
  ;;          '((("SPC" . nil) . ("󱁐" . nil))
  ;;            (("TAB" . nil) . ("󰌒" . nil))
  ;;            (("RET" . nil) . ("󰌑" . nil))
  ;;            (("DEL" . nil) . ("󰭜" . nil))
  ;;            ))
  ;;   (add-to-list 'which-key-replacement-alist replace))
:config
  (set-face-attribute 'which-key-key-face nil :inherit 'fixed-pitch)
  (which-key-mode 1)
)

Which-key-posframe use posframe to show which-key popup.

Here I tried to make which-key act like the one in helix editor. It pops up instantly at the right bottom of the editor, and displays one column vertically.

(use-package which-key-posframe
:after which-key
:config
  (setq which-key-posframe-poshandler
        'posframe-poshandler-frame-bottom-right-corner)
  (setq which-key-max-display-columns 1)
  (setq which-key-min-display-lines 1)
  (which-key-posframe-mode)
)

Rime.el

Early Init
(use-package rime
:custom
  (rime-emacs-module-header-root "~/.nix-profile/include")
  (rime-librime-root "~/.nix-profile")
  (rime-share-data-dir "~/.config/fcitx/rime")
:config
  (setq default-input-method "rime"
        rime-show-candidate 'posframe)
  (setq rime-disable-predicates
    '(meow-normal-mode-p
      meow-motion-mode-p
      rime-predicate-after-alphabet-char-p
      rime-predicate-prog-in-code-p))
  (setq pgtk-use-im-context-on-new-connection nil)
)

Displays

We try to decide what emacs would look like beneath this outline. However, many packages affect how emacs looks. To make it simplier, we’ll just define things that only changes how emacs looks, but do not provides extra functionalities or stuffs, meanning that deleting them will not affect how emacs works (hopefully).

Fonts

Fonts in emacs is really a complex system. If you don’t treat it with care, you’ll definitedly encounter some bugs.

One essential thing about font is pitch. In general, pitch control’s whether a font is fixed-widthed or non-fixed-widthed. Currently there’re 2 helpful packages that controls font pitch: mixed-pitch-mode and fixed-pitch-mode.

I recommend stick to only one of these modes and does all the font settings based on that mode.

Mixed-pitch-mode

(use-package mixed-pitch
:custom
'(mixed-pitch-fixed-pitch-faces
  '(diff-added diff-context diff-file-header diff-function diff-header diff-hunk-header diff-removed
               font-latex-math-face font-latex-sedate-face font-latex-warning-face font-latex-sectioning-5-face font-lock-builtin-face font-lock-comment-delimiter-face font-lock-constant-face font-lock-doc-face font-lock-function-name-face font-lock-keyword-face font-lock-negation-char-face font-lock-preprocessor-face font-lock-regexp-grouping-backslash font-lock-regexp-grouping-construct font-lock-string-face font-lock-type-face font-lock-variable-name-face line-number line-number-current-line line-number-major-tick line-number-minor-tick markdown-code-face markdown-gfm-checkbox-face markdown-inline-code-face markdown-language-info-face markdown-language-keyword-face markdown-math-face message-header-name message-header-to message-header-cc message-header-newsgroups message-header-xheader message-header-subject message-header-other mu4e-header-key-face mu4e-header-value-face mu4e-link-face mu4e-contact-face mu4e-compose-separator-face mu4e-compose-header-face
               org-document-info-keyword org-code org-indent org-latex-and-related org-checkbox org-formula org-special-keyword org-table org-verbatim widget-field org-modern-label))
  '(mixed-pitch-set-height nil)

:config
  (setq mixed-pitch-set-height nil)
  (set-face-attribute
   'default nil
   :family "IBM Plex Mono Text"
   ;; :family "Sarasa Gothic SC Nerd Font"
   ;; :family "IBM Plex Serif"
   :height 150)
  (set-face-attribute
   'fixed-pitch nil
   :family "IBM Plex Mono Text"
   ;; :family "RobotoMono Nerd Font Mono"
   ;; :family "CommitMono Nerd Font Mono"
   ;; :family "Sarasa Fixed SC"
   ;; :family "Monaspace Neon"
   :height 1.0)
  (set-face-attribute 'fixed-pitch-serif nil
    ;; :family "Sarasa Gothic SC Nerd Font"
    :family "IBM Plex Mono Text"
    ;; :family "IBM Plex Serif"
    :height 1.0)
  (set-face-attribute 'variable-pitch nil
    ;; :family "Sarasa Gothic SC Nerd Font"
    :family "IBM Plex Serif"
    :height 1.0)

  (set-face-attribute 'link nil :underline t :bold nil)

  ;; patches nerd font
  (set-fontset-font t 'han "Source Han Serif SC")
  (set-fontset-font t 'symbol "Noto Sans Symbols")
  (set-fontset-font t 'nil "Noto Emoji")
  (set-fontset-font t 'nil "Weather Icons")
  (set-fontset-font t 'nil "Material Icons")
  (set-fontset-font t 'nil "github-octicons")
  (set-fontset-font t 'nil "file-icons")
  (set-fontset-font t 'nil "FontAwesome")
  (set-fontset-font t 'nil "Symbols Nerd Font Mono")

  )

Zooming In/Out

You can use the bindings CTRL plus =/- for zooming in/out. You can also use CTRL plus the mouse wheel for zooming in/out.

(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-down>") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)

Line Space

(defun my/toggle-line-spacing ()
  "Toggle line spacing between no extra space to extra half line height.
URL `http://xahlee.info/emacs/emacs/emacs_toggle_line_spacing.html'
Version 2017-06-02"
  (interactive)
  (if line-spacing
      (setq line-spacing nil)
    (setq line-spacing 0.5))
  (redraw-frame (selected-frame)))

Icons

All-the-icons

All-the-icons is an icon set that can be used with dashboard, dired, ibuffer and other Emacs programs.

(use-package all-the-icons
  :if (display-graphic-p))

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

NOTE: In order for the icons to work it is very important that you install the Resource Fonts included in this package. Run M-x all-the-icons-install-fonts to install necessary icons.

All-the-icons-completion

All-the-icons-completion makes icons appear in the minibuffer. Cool.
(use-package all-the-icons-completion
  :after (marginalia all-the-icons)
  :hook (marginalia-mode . all-the-icons-completion-marginalia-setup)
  :init
  (all-the-icons-completion-mode))

Nerd-icons

Nerd-icons is a library for easily using Nerd Font icons inside Emacs, an alternative to all-the-icons. Run M-x nerd-icons-install-fonts to install Symbols Nerd Fonts Mono for you.
(use-package nerd-icons
  ;; :custom
  ;; The Nerd Font you want to use in GUI
  ;; "Symbols Nerd Font Mono" is the default and is recommended
  ;; but you can use any other Nerd Font if you want
  ;; (nerd-icons-font-family "Symbols Nerd Font Mono")
)

Themes

Doom-themes

Doom-themes is a great set of themes with a lot of variety and support for many different Emacs modes. Taking a look at the screenshots might help you decide which one you like best. Run M-x counsel-load-theme to choose between them easily.

Solaire mode

Solaire-mode makes certain buffers grossly incandescent. Useful to distinguish the main buffers from others.
(use-package solaire-mode
:defer t
:init (solaire-global-mode)
:config
  (add-hook 'org-src-mode-hook 'turn-off-solaire-mode)
)

Frames

Posframe

Posframe can pop up a frame at point, this posframe is a child-frame connected to its root window’s buffer, in which some texts are showed. It’s more pretty and tidy than showing everything in the minibuffer. Posframe can be used by many useful and important package, such as vertico, consult, emacs-rime, lsp-bridge.

Note that a ‘frame’ is a window on the desktop, a ‘window’ is a subwindow of emacs.

(use-package posframe
:config
  (defun posframe-poshandler-frame-upper-center! (info)
  "Posframe's position handler.

   This poshandler function let center of posframe align to
   vertically upper 1/6, horizontally center
   of frame."
  (cons (/ (max 0 (- (plist-get info :parent-frame-width)
               (plist-get info :posframe-width))) 2)
        (/ (plist-get info :parent-frame-height) 6)))

  (defun posframe-poshandler-window-upper-center! (info)
   "Posframe's position handler.

     This poshandler function let center of posframe align to
     vertically upper 1/6, horizontally center
     of window."
  (let* ((window-left    (plist-get info :parent-window-left))
         (window-top     (plist-get info :parent-window-top))
         (window-width   (plist-get info :parent-window-width))
         (window-height  (plist-get info :parent-window-height))
         (posframe-width (plist-get info :posframe-width)))
    (cons (max 0 (+ window-left (/ (- window-width posframe-width) 2)))
          (+ window-top (/ window-height 6))))
  )
)

Transparency

We have already set transparency in Early Init Here lets define a function to interactively set transparency value.
(defun my/set-transparency (value)
  "Sets the transparency of the frame window. 0=transparent/100=opaque"
  (interactive "nTransparency Value 0 - 100 opaque:")
  (set-frame-parameter nil 'alpha-background value))

Margin

Horizontal

We have 3 modes that can help centering text in a window. But currently we only use olivetti mode.

Olivetti

Olibetti is a simple Emacs minor mode for a nice writing environment. Set olivetti-style to both margins and fringes for a fancy “page” look.

Note that for pages with variable-pitch fonts, olivetti-body-width should be set smaller for it to look good.

(use-package olivetti
:defer nil
:hook (org-mode . olivetti-mode)
      (Custom-mode . olivetti-mode)
      (help-mode . olivetti-mode)
      ;(dashboard-mode . olivetti-mode)
      (dashboard-mode . variable-pitch-mode)
      (olivetti-mode . visual-line-mode)
:init
      (setq-default fill-column 100)
:config
      ;If nil (the default), use the value of fill-column + 2.
      (setq olivetti-body-width nil olivetti-style 'fancy)
      ;; (set-face-attribute 'olivetti-fringe nil :background "#171B24")
      (defun config/window-center (width)
          (interactive)
          (setq fill-column width)
          (olivetti-mode)
      )
      ;; (config/leader
      ;;  "tc"  '(olivetti-mode     :wk "󰉠 Center")
      ;; )
)

Visual-fill-column

visual-fill-column
(setq-default visual-fill-column-center-text t)

Writeroom-mode

The Four

These four things are basically what you’re gonna to see anywhere, anytime in emacs. Therefore I grouped them together.

Minibuffer

Vertico

Mode mapVertico provides a performant and minimalistic vertical completion UI based on the default completion system.
(use-package vertico
:init
  ;; Different scroll margin
  (setq vertico-scroll-margin 1)
  ;; Show more candidates
  (setq vertico-count 20)
  ;; Grow the Vertico minibuffer
  ;; (setq vertico-resize 'grow-only)
  ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
  (setq vertico-cycle t)
  ;; use Vertico as an in-buffer completion UI
  (setq completion-in-region-function 'consult-completion-in-region)
  (vertico-mode 1)
:config
  (general-def
    :keymaps '(vertico-map)
    "C-l"       'vertico-next
    "C-k"       'vertico-previous
    "C-j"       'vertico-directory-delete-word
    "C-;"       'vertico-directory-enter
    "C-,"       'vertico-previous-group
    "C-."       'vertico-next-group
    "A-l"       'vertico-next
    "A-k"       'vertico-previous
    "A-j"       'vertico-directory-delete-word
    "A-;"       'vertico-directory-enter
    "A-,"       'vertico-previous-group
    "A-."       'vertico-next-group
    "RET"       'vertico-directory-enter
    "DEL"       'vertico-directory-delete-char
    "M-DEL"     'vertico-directory-delete-word
  )
)

tweaks to build vertico

[submodule "vertico"]
  load-path = .
  load-path = extensions

Vertico-directory

(use-package vertico-directory
    :after vertico
    ;; More convenient directory navigation commands
    :bind (:map vertico-map
)
    ;; Tidy shadowed file names
    :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))

Vertico-multiform

Vertico-multiform configures Vertico modes per command or completion category.

(use-package vertico-multiform
  :after vertico
  :config (vertico-multiform-mode)
)

Vertico-posframe

Vertico-posframe is an vertico extension, which lets vertico use posframe to show its candidate menu. See Posframe for function defintion.

(use-package vertico-posframe
;:disabled
:after vertico-multiform
:init
  (setq vertico-posframe-poshandler
        'posframe-poshandler-frame-top-center)
  (setq vertico-count 15
        vertico-posframe-border-width 3
        vertico-posframe-width 140
        )
  (setq vertico-posframe-parameters
        '((left-fringe . 20)
          (right-fringe . 20)))
  (setq vertico-multiform-commands
        '(
          (execute-extended-command ; M-x
           (vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
           (vertico-posframe-width . 120))

          (meow-visit
           (vertico-posframe-poshandler . posframe-poshandler-window-top-right-corner)
           (vertico-posframe-width . 50))

          (meow-yank-pop; M-x
           (vertico-posframe-poshandler . posframe-poshandler-point-window-center)
           (vertico-posframe-width . 50))

          (find-file
           (vertico-count . 25)
           (vertico-posframe-width . 100)
           (vertico-posframe-poshandler . posframe-poshandler-window-upper-center!))

          (consult-buffer
           (vertico-count . 25)
           (vertico-posframe-width . 100)
           (vertico-posframe-poshandler . posframe-poshandler-window-upper-center!))

          (switch-to-buffer
           (vertico-count . 25)
           (vertico-posframe-width . 100)
           (vertico-posframe-poshandler . posframe-poshandler-window-upper-center!))

          (org-insert-link; C-c C-l
           (vertico-posframe-poshandler . posframe-poshandler-point-top-left-corner)
           (vertico-posframe-width . 70))

          (tempel-insert
           (vertico-posframe-poshandler . posframe-poshandler-point-top-left-corner)
           (vertico-posframe-width . 70))

          (consult-imenu
           (vertico-count . 40)
           (vertico-posframe-poshandler . posframe-poshandler-window-top-right-corner)
           (vertico-posframe-width . 80))

          (consult-outline
           (vertico-count . 30)
           (vertico-posframe-poshandler . posframe-poshandler-window-top-right-corner)
           (vertico-posframe-width . 40))

          (consult-line
           (vertico-count . 30)
           (vertico-posframe-poshandler . posframe-poshandler-frame-top-right-corner)
           (vertico-posframe-width . 60))

          (t
           (vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
           (vertico-posframe-width . 120))
      ))

:config
      (vertico-multiform-mode 1)
      (vertico-posframe-mode 1)
)

Completion

Orderless

Orderless provides a completion style that divides the pattern into space-separated components, and matches candidates that match all of the components in any order. Each component can match in any one of several ways: literally, as a regexp, as an initialism, in the flex style, or as multiple word prefixes. By default, regexp and literal matches are enabled.
(use-package orderless
  :init
  (setq completion-styles '(orderless))
  (setq orderless-component-separator
          #'orderless-escapable-split-on-space)
  (setq orderless-matching-styles
          '(orderless-initialism orderless-prefixes orderless-regexp))
  )

Savehist

;; Persist history over Emacs restarts. Vertico sorts by history position.
  (use-package savehist
      :init
      (savehist-mode))
;; A few more useful configurations...
  (use-package emacs
      :init
      ;; Add prompt indicator to `completing-read-multiple'.
      ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
      (defun crm-indicator (args)
      (cons (format "[CRM%s] %s"
          (replace-regexp-in-string
          "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
          crm-separator)
          (car args))
        (cdr args)))
      (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

      ;; Do not allow the cursor in the minibuffer prompt
      (setq minibuffer-prompt-properties
    '(read-only t cursor-intangible t face minibuffer-prompt))
      (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

      ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
      ;; Vertico commands are hidden in normal buffers.
      ;; (setq read-extended-command-predicate
      ;;       #'command-completion-default-include-p)
      ;; Enable recursive minibuffers
      (setq enable-recursive-minibuffers t))

Consult

Consult provides search and navigation commands based on the Emacs completion function completing-read.

(use-package consult
      ;; Replace bindings. Lazily loaded due by `use-package'.
:bind (;; C-c bindings in `mode-specific-map'
       ("C-c M-x" . consult-mode-command)
       ("C-c h" . consult-history)
       ;("C-c k" . consult-kmacro)
       ("C-c m" . consult-man)
       ;("C-c i" . consult-info)
       ([remap Info-search] . consult-info)
       ;; C-x bindings in `ctl-x-map'
       ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
       ([remap list-buffers] . consult-buffer)   ;; orig. switch-to-buffer
       ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
       ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
       ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
       ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
       ;; Custom M-# bindings for fast register access
       ("M-#" . consult-register-load)
       ("M-'" . consult-register-store)  ;; orig. abbrev-prefix-mark (unrelated)
       ("C-M-#" . consult-register)
       ;; Other custom bindings
       ("M-y" . consult-yank-pop)           ;; orig. yank-pop
       ;; M-g bindings in `goto-map'
       ("M-g e" . consult-compile-error)
       ("M-g f" . consult-flymake)          ;; Alternative: consult-flycheck
       ("M-g g" . consult-goto-line)        ;; orig. goto-line
       ("M-g M-g" . consult-goto-line)      ;; orig. goto-line
       ("M-g o" . consult-outline)          ;; Alternative: consult-org-heading
       ("M-g m" . consult-mark)
       ("M-g k" . consult-global-mark)
       ("M-g i" . consult-imenu)
       ("M-g I" . consult-imenu-multi)
       ;; M-s bindings in `search-map'
       ("M-s d" . consult-find)
       ("M-s D" . consult-locate)
       ("M-s g" . consult-grep)
       ("M-s G" . consult-git-grep)
       ("M-s r" . consult-ripgrep)
       ("M-s l" . consult-line)
       ("M-s L" . consult-line-multi)
       ("M-s k" . consult-keep-lines)
       ("M-s u" . consult-focus-lines)
       ;; Isearch integration
       ("M-s e" . consult-isearch-history)
       :map isearch-mode-map
       ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
       ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
       ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
       ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
       ;; Minibuffer history
       :map minibuffer-local-map
       ("M-s" . consult-history)                 ;; orig. next-matching-history-element
       ("M-r" . consult-history))                ;; orig. previous-matching-history-element

      ;; 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)

: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)

: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 "M-.")
      ;; (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-bookmark consult-recent-file consult-xref
       consult--source-bookmark consult--source-file-register
       consult--source-recent-file consult--source-project-recent-file
       ;;  :preview-key "M-."
       :preview-key '(:debounce 0.4 any)
  )

      ;; Optionally configure the narrowing key.
      (setq consult-narrow-key "<") ;; "C-+"
  (setq consult-buffer-filter "\\*")
      ;; 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)
)

Marginalia

Marginalia enriches existing commands with completion annotations
(use-package marginalia
:general
  (:keymaps 'minibuffer-local-map
   "M-A" 'marginalia-cycle)
:custom
  (marginalia-max-relative-age 0)
  (marginalia-align 'right)
:init
  (marginalia-mode)
)

Tabs

Tab-bar-mode

Sort-tab

(use-package sort-tab
:if (not (daemonp))
:init (sort-tab-mode)
:config
  (defun my/sort-tab-filter (buffer)
    "a filter functioni for sort-tab. return t hides the buffer"
    (let ((major-mode (buffer-local-value 'major-mode buffer)))
      (cond ((eq major-mode 'dired-mode) t)
            (t nil)))
    )
  (setq sort-tab-hide-function 'my/sort-tab-filter)
)

Windows

Popper

Toggle-one-window

Toggle-one-window provides only one function, toggle-one-window, to toggle between one window to multiple window. When you have a multiple windows, it remembers the window layout and deletes all other windows. The next call restores them.
(use-package toggle-one-window)

Modeline

Doom-modeline

Doom-modeline is a very attractive and rich (yet still minimal) mode line configuration for Emacs. The default configuration is quite good but you can check out the configuration options for more things you can enable or disable.
(use-package doom-modeline
:init
      (setq
          ;; doom-modeline-height 37
          doom-modeline-enable-word-count t
          doom-modeline-modal nil
          )
      (doom-modeline-mode 1)
:config
      (set-face-attribute 'doom-modeline t
          :inherit 'variable-pitch)
  ;; let modeline show on the header, not bottom
  (defun move-up-modeline ()
    (interactive)
    (progn
      (setq-default header-line-format mode-line-format)
      (setq-default mode-line-format nil)
    ))
  (move-up-modeline)
)

NOTE1: Nerd-icons are necessary. Run M-x nerd-icons-install-fonts to install the resource fonts.

NOTE2: All-the-icons hasn’t been supported since 4.0.0. If prefer all-the-icons, use release 3.4.0, then run M-x all-the-icons-install-fonts to install necessary icons.

Diminish

This package implements hiding or abbreviation of the modeline displays (lighters) of minor-modes. With this package installed, you can add ‘:diminish’ to any use-package block to hide that particular mode in the modeline.
(use-package diminish)

Awesome-tray

(use-package awesome-tray
:defer t
:init
  ;(awesome-tray-mode)
:config
  (setq awesome-tray-hide-mode-line nil)
)

Interface

Packages beneath this outline implements some functionalities by creating new buffers or windows. Packages that serves for a specific mode is not configured here.

Dashboard

Emacs Dashboard

Dashboard is an extensible startup screen showing you recent files, bookmarks, agenda items and an Emacs banner.

Emacs currently cannot display correpng or svg with alpha channels, when emacs’s background is transparent. A workaround is to use xpm or webp format image.

(use-package dashboard
:if (not (daemonp))
:init
  (setq initial-buffer-choice 'dashboard-open
      dashboard-image-banner-max-width 1100
      dashboard-set-heading-icons t
      dashboard-center-content t ;; set to 't' for centered content
      dashboard-set-file-icons t
      initial-buffer-choice (lambda () (get-buffer-create "*scratch*"))
      dashboard-startup-banner ;; use custom image as banner
      (concat user-emacs-directory "assets/EmaxBound.xpm")
      dashboard-items
      '((recents . 5)
        (agenda . 5 )
        (bookmarks . 3)
        (projects . 3)
        (registers . 3)
        )
  )
:config
  (dashboard-setup-startup-hook)
  (setq-default header-line-format mode-line-format)
  (setq-default mode-line-format nil)
  (set-face-attribute 'dashboard-items-face nil)

:bind (:map dashboard-mode-map
  ("k" . 'dashboard-previous-line)
  ("l" . 'dashboard-next-line)
  (";" . 'dashboard-next-section)
  ("j" . 'dashboard-previous-section)
  )
)

Visual Undo

Vundo (visual undo) displays the undo history as a tree and lets you move in the tree to go back to previous buffer states.
(use-package vundo
:config
  (general-def vundo-mode-map
    "j"  'vundo-backward
    ";"  'vundo-forward
    "k"  'vundo-previous
    "l"  'vundo-next
    "q"  'vundo-quit
    "s"  'vundo-save
    )
)

Version Control

Magit

Magit is a VERY powerful git client.
(use-package magit
:defer t
:commands (magit-add-section-hook)
;; :hook (magit-mode . olivetti-mode)
:config
  (magit-add-section-hook 'magit-status-sections-hook
                          'magit-insert-modules
                          'magit-insert-stashes
                          'append
                          )
  (setq magit-show-long-lines-warning nil)
  (set-face-attribute 'magit-hash nil :inherit 'fixed-pitch)
  (set-face-attribute 'magit-diff-removed-highlight nil :inherit 'fixed-pitch)
  (set-face-attribute 'magit-diff-context-highlight nil :inherit 'fixed-pitch)
  (set-face-attribute 'magit-diff-added-highlight nil :inherit 'fixed-pitch)

  (general-def
  :keymaps '(magit-mode-map)
    "n"   'magit-gitignore
    "p"   'magit-push
    "P"   'magit-pull
    "DEL" 'magit-discard
  )
)
  • tweaks to build magit
[submodule "magit"]
  no-byte-compile = lisp/magit-libgit.el

Diff-hl

Diff highlight highlights the fringe of lines that have been edited.

(use-package diff-hl
:custom-face
  (diff-hl-change ((t (:background "#2c5f72" :foreground "#77a8d9"))))
  (diff-hl-delete ((t (:background "#844953" :foreground "#f27983"))))
  (diff-hl-insert ((t (:background "#5E734A" :foreground "#a6cc70"))))
:init
  (setq diff-hl-draw-borders nil)
:config
  ;(global-diff-hl-mode)
  (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh t)
  (add-hook 'prog-mode-hook #'diff-hl-mode)
  (add-hook 'conf-mode-hook #'diff-hl-mode)
  (add-hook 'dired-mode-hook #'diff-hl-dired-mode)


  (add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
  (add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
  ;; Highlight on-the-fly
  (diff-hl-flydiff-mode 1)
  (unless (display-graphic-p)
    ;; Fall back to the display margin since the fringe is unavailable in tty
    (diff-hl-margin-mode 1)
    ;; Avoid restoring `diff-hl-margin-mode'
    (with-eval-after-load 'desktop
      (add-to-list 'desktop-minor-mode-table
                   '(diff-hl-margin-mode nil))))
)

Dired

Dired

Diredfl

Diredfl defines extra font lock rules to make dired more colorful.
(use-package diredfl
:after dired
:hook
  ((dired-mode . diredfl-mode)
   ;; highlight parent and directory preview as well
   (dirvish-directory-view-mode . diredfl-mode))
:config
  (set-face-attribute 'diredfl-dir-name nil :bold t)
)

Tweaks to build dirvish. Load dirvish and its extensions.

[submodule "dirvish"]
  load-path = .
  load-path = extensions

Dirvish

Dirvish is a dropin replacement for dired. It looks and feels like ranger.
(use-package dirvish
:after dired
:custom
  (dirvish-quick-access-entries ;`setq' won't work for custom
    '(("h" "~/"                          "Home")
      ("d" "~/Downloads/"                "Downloads")
      ("m" "/mnt/"                       "Drives")
      ("t" "~/.local/share/Trash/files/" "TrashCan"))
  )
:config
  (dirvish-define-preview exa (file)
  "Use `exa' to generate directory preview."
  :require ("exa") ; tell Dirvish to check if we have the executable
  (when (file-directory-p file) ; we only interest in directories here
      `(shell . ("exa" "-al" "--color=always" "--icons"
          "--group-directories-first" ,file))))

  (add-to-list 'dirvish-preview-dispatchers 'exa)
  ;; (dirvish-peek-mode) ; Preview files in minibuffer
  ;; (dirvish-side-follow-mode) ; similar to `treemacs-follow-mode'
  (setq dirvish-path-separators (list "" "" ""))
  (setq dirvish-mode-line-format
      '(:left (sort symlink) :right (omit yank index)))
  (setq dirvish-attributes
      '(all-the-icons file-time file-size collapse subtree-state vc-state git-msg))
  (setq delete-by-moving-to-trash t)
  (setq dired-listing-switches
      "-l --almost-all --human-readable --group-directories-first --no-group")

  (general-def dirvish-mode-map
    "q"      '(dirvish-quit              :wk "quit")
    "TAB"    '(dirvish-toggle-subtree    :wk "subtree toggle")
    "j"      '(dired-up-directory        :wk "up-dir")
    ";"      '(dired-find-file           :wk "open/toggle")
    "C-b"    '(dired-up-directory        :wk "up-dir")
    "C-f"    '(dired-find-file           :wk "open/toggle")
    "a"      '(dirvish-quick-access      :wk "access")
    "c"      '(dired-do-copy             :wk "copy")
    "u"      '(dired-do-rename           :wk "rename")
    )
  ;; (nmap dirvish-mode-map
  ;;    "?"      '(dirvish-dispatch          :wk "Dispatch")
  ;;    "TAB"    '(dirvish-subtree-toggle    :wk "Subtre-toggle")
  ;;    "q"      '(dirvish-quit              :wk "Quit")
  ;;    "h"      '(dired-up-directory        :wk "Up-dir")
  ;;    "l"      '(dired-find-file           :wk "Open/Toggle")
  ;;    "a"      '(dirvish-quick-access      :wk "Access")
  ;;    "f"      '(dirvish-file-info-menu    :wk "File Info Menu")
  ;;    "y"      '(dirvish-yank-menu         :wk "Yank Menu")
  ;;    "N"      '(dirvish-narrow            :wk "Narrow")
  ;;    ;         `dired-view-file'
  ;;    "v"      '(dirvish-vc-menu           :wk "View-file")
  ;;    ;         `dired-sort-toggle-or-edit'
  ;;    "s"      '(dirvish-quicksort         :wk "Quick-sort")

  ;;    "M-f"    '(dirvish-history-go-forward  :wk "History-forward")
  ;;    "M-b"    '(dirvish-history-go-backward :wk "History-back")
  ;;    "M-l"    '(dirvish-ls-switches-menu    :wk "ls Switch Menu")
  ;;    "M-m"    '(dirvish-mark-menu           :wk "Mark Menu")
  ;;    "M-t"    '(dirvish-layout-toggle       :wk "Layout-toggle")
  ;;    "M-s"    '(dirvish-setup-menu          :wk "Setup-Menu")
  ;;    "M-e"    '(dirvish-emerge-menu         :wk "Emerge-Menu")
  ;;    "M-j"    '(dirvish-fd-jump             :wk "fd-jump")
  ;; )
  (dirvish-override-dired-mode)
)

Embark

(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)

  ;; 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)))))
(use-package embark-consult
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Blink search

Blink-search is the fastest multi-source search framework for Emacs.

(use-package blink-search
:defer t
:config
  (setq blink-search-enable-posframe t)
)

Color-rg

Color-rg is a search and refactoring tool based on ripgrep.

(use-package color-rg
:config
  (general-def isearch-mode-map
    "M-s M-s" 'isearch-toggle-color-rg
  )
)

Voyager

Voyager is an Emacs debugging plugin based on the DAP protocol.

(use-package voyager)

Holo-layer

Holo-layer is developed based on PyQt, aiming to significantly enhance the visual experience of Emacs.
(use-package holo-layer
:commands holo-layer-enable
:if (memq window-system '(pgtk mac ns))
:config
  (setq holo-layer-enable-cursor-animation 1
        holo-layer-enable-window-border 1
        holo-layer-sort-tab-ui 1
        ;;holo-layer-cursor-animation-type "arrow easing"
        )
  (holo-layer-enable)
)

Coding

Keybindings

(general-def
:keymaps '(prog-mode-map)
:wk-full-keys nil
  "C-<escape>" '(my/prog-cmd :wk "Prog")
)

(general-def
:prefix-command 'my/prog-cmd
:prefix-map 'my/prog-map
:wk-full-keys nil
  "C-j" '()
  "C-k" '(backward-paragraph  :wk " para")
  "C-l" '(forward-paragraph :wk " para")
  "C-;" '()
  )

Displays

Pulse

Beacon

Beacon makes the cursor shine when scrolling window or jumping. Somewhat buggy.
(use-package beacon
:defer t
:config
      (beacon-mode)
)

Pulse-Cursor

Makes the cursor to blink with fade out animation when idle. Cool.

Be careful that it’s possible to consume a horrible amount of memory with pulsing-cursor-blinks set to 0 (means infinite blinks) and without proper gc configuration (can be done with GCMH).

(use-package pulsing-cursor
:config
  (setq pulse-delay 0.02
        pulse-iterations 10)
  (setq pulsing-cursor-interval 0.7)
  (setq pulsing-cursor-blinks 20)
  (set-face-attribute 'pulsing-cursor-overlay-face1 nil
                      :background (face-background 'cursor))
  ;; (setq blink-cursor-alist '((box . hollow)))
  (advice-add 'describe-face :around
              (lambda (func FACE &optional FRAME)
                (pulsing-cursor-mode -1)
                (unwind-protect
                    (funcall-interactively func FACE FRAME)
                  (pulsing-cursor-mode 1))))
  (pulsing-cursor-mode)
)

Goggles

Goggles highlights the modified region using pulse. Currently the commands undo, yank, kill and delete are supported.
(use-package goggles
:hook ((prog-mode text-mode org-mode) . goggles-mode)
:config
  (setq-default goggles-pulse t)) ;; set to nil to disable pulsing

Hl-line

Highlights the line that the cursor locates.

(use-package hl-line
:config
  (defun my/read-face-advice (orig-fun &rest args)
    "Advice function to turn off hl-line-mode before calling describe-face."
    (if hl-line-mode
        (progn
          (hl-line-mode -1)
          (apply orig-fun args)
          (hl-line-mode 1)
          )
      (apply orig-fun args)))
  ;; (advice-add 'read-face-name :around #'my/read-face-advice)
  ;; (global-hl-line-mode)
)

Whitespace mode

Whitespace mode is a built in mode of emacs that visualizes whitespaces, tab symbols, indentations and related stuffs.

(use-package whitespace
:config
  (setq whitespace-line-column 1000) ;; do not want line to be highlighted
)
  ;; (config/leader :infix "t"
  ;;   "SPC"  '(whitespace-mode  :wk "󰡭 Show Space")
  ;; )

Line Number

(use-package emacs
:hook (prog-mode . config/toggle-line-number-absolute)
:init (setq display-line-numbers-width 4)
:config
      (defun config/toggle-line-number-nil ()
          (interactive)
          (setq display-line-numbers nil)
      )
      (defun config/toggle-line-number-absolute ()
          (interactive)
          (setq display-line-numbers t)
      )
      (defun config/toggle-line-number-relative ()
          (interactive)
          (setq display-line-numbers 'relative)
      )
      (defun config/toggle-line-number-visual ()
          (interactive)
          (setq display-line-numbers 'visual)
      )
)

Rainbow-mode

This minor mode sets background color to strings that match color names, useful for UI and theme design.

Simple-call-tree

(use-package simple-call-tree :defer t)

Indent

Electric-Indent

(use-package electric
:config
  (setq-default indent-tabs-mode nil) ;; always indent with spaces
  (setq electric-pair-mode t) ;; global-minor mode
)

Aggressive-Indent

Aggressive-indent-mode is a minor mode that keeps your code always indented. It reindents after every change, making it more reliable than `electric-indent-mode’.
(use-package aggressive-indent
:disabled
:config
  (global-aggressive-indent-mode 1)
)

Highlight-Indent-Guides

Highlight-Indent-Guides is a minor mode that highlights indentation levels via font-lock.
(use-package highlight-indent-guides
:hook (prog-mode . highlight-indent-guides-mode)
:config
  (setq highlight-indent-guides-method 'character
        highlight-indent-guides-character 9474
        highlight-indent-guides-auto-enabled nil
        highlight-indent-guides-responsive nil
  )

  (set-face-attribute 'highlight-indent-guides-character-face nil
    :foreground "#3b445f")
  (set-face-attribute 'highlight-indent-guides-top-character-face nil
    :foreground "#ffcc66")

)

Dtrt-indent

Dtrt-indent is a minor mode that guesses the indentation offset originally used for creating source code files and transparently adjusts the corresponding settings in Emacs, making it more convenient to edit foreign files.

(use-package dtrt-indent
:config
  (dtrt-indent-global-mode)
)

Parens

Smartparens

Smartparens is minor mode for Emacs that deals with parens pairs and tries to be smart about it. It insert pair of parens.
(use-package smartparens
:config
  (smartparens-global-mode)
)

Highlight-parentheses

(use-package highlight-parentheses
:init
  (show-paren-mode 0)
:config
  (setq highlight-parentheses-highlight-adjacent 1
        highlight-parentheses-attributes '((:box (:line-width (-1 . -1))))
        highlight-parentheses-colors nil
        highlight-parentheses-delay 0.03)
  (global-highlight-parentheses-mode)
  )

Rainbow-Delimiters

Rainbow-delimiters is a “rainbow parentheses”-like mode which highlights parentheses, brackets, and braces according to their depth.
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode)
)

Snippets

Tempel

Mode map
(use-package tempel
  ;; Require trigger prefix before template name when completing.
  ;; :custom
  ;; (tempel-trigger-prefix "<")

  :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
         ("M-*" . tempel-insert))
  :init

  ;; Setup completion at point
  (defun tempel-setup-capf ()
    ;; Add the Tempel Capf to `completion-at-point-functions'.
    ;; `tempel-expand' only triggers on exact matches. Alternatively use
    ;; `tempel-complete' if you want to see all matches, but then you
    ;; should also configure `tempel-trigger-prefix', such that Tempel
    ;; does not trigger too often when you don't expect it. NOTE: We add
    ;; `tempel-expand' *before* the main programming mode Capf, such
    ;; that it will be tried first.
    (setq-local completion-at-point-functions
                (cons #'tempel-expand
                      completion-at-point-functions)))

  (add-hook 'conf-mode-hook 'tempel-setup-capf)
  (add-hook 'prog-mode-hook 'tempel-setup-capf)
  (add-hook 'text-mode-hook 'tempel-setup-capf)

  ;; Optionally make the Tempel templates available to Abbrev,
  ;; either locally or globally. `expand-abbrev' is bound to C-x '.
  ;; (add-hook 'prog-mode-hook #'tempel-abbrev-mode)
  (global-tempel-abbrev-mode)

  (my/mode-leader-def
  :keymaps '(tempel-map)
    "C-j"  'tempel-previous
    "C-;"  'tempel-next
    "TAB"  'tempel-next
  )
)
;; Optional: Add tempel-collection.
;; The package is young and doesn't have comprehensive coverage.
(use-package tempel-collection
:after tempel
)

LSP-bridge

lsp-bridge builds a high-speed cache between Emacs and the LSP server.
(use-package lsp-bridge
:config
  (setq lsp-bridge-java-lsp-server "jdt-language-server")
  (setq lsp-bridge-nix-lsp-server "nil")
  (global-lsp-bridge-mode)
  ;(set-face-attributes 'lsp-bridge-alive-mode-line nil
  ;  :inherit 'variable-pitch
  ;)
)

tweaks to build lsp-bridge

[submodule "lsp-bridge"]
  load-path = .
  load-path = acm

Fingertip

Treesit-auto

fingertip.el is a plugin that provides grammatical edit base on treesit

(use-package fingertip
:config
  (dolist (hook (list
        'c-mode-common-hook 'c-mode-hook 'c++-mode-hook
        'c-ts-mode-hook 'c++-ts-mode-hook
        'cmake-ts-mode-hook
        'java-mode-hook
        'haskell-mode-hook
        'emacs-lisp-mode-hook
        'lisp-interaction-mode-hook 'lisp-mode-hook
        'maxima-mode-hook
        'ielm-mode-hook
        'bash-ts-mode-hook 'sh-mode-hook
        'makefile-gmake-mode-hook
        'php-mode-hook
        'python-mode-hook 'python-ts-mode-hook
        'js-mode-hook
        'go-mode-hook
        'qml-mode-hook
        'jade-mode-hook
        'css-mode-hook 'css-ts-mode-hook
        'ruby-mode-hook
        'coffee-mode-hook
        'rust-mode-hook 'rust-ts-mode-hook
        'qmake-mode-hook
        'lua-mode-hook
        'swift-mode-hook
        'web-mode-hook
        'markdown-mode-hook
        'llvm-mode-hook
        'conf-conf-mode-hook 'conf-ts-mode-hook
        'nim-mode-hook
        'typescript-mode-hook 'typescript-ts-mode-hook
        'js-ts-mode-hook 'json-ts-mode-hook
        ))
  (add-hook hook #'(lambda () (fingertip-mode 1))))
  ;; (general-def
  ;;   :keymaps 'fingertip-mode-map
  ;;     "(" 'fingertip-open-round
  ;;     "[" 'fingertip-open-bracket
  ;;     "{" 'fingertip-open-curly
  ;;     ")" 'fingertip-close-round
  ;;     "]" 'fingertip-close-bracket
  ;;     "}" 'fingertip-close-curly
  ;;     "=" 'fingertip-equal

  ;;     "%" 'fingertip-match-paren
  ;;     "\"" 'fingertip-double-quote
  ;;     "'" 'fingertip-single-quote

  ;;     "SPC" 'fingertip-space
  ;;     "RET" 'fingertip-newline

  ;;     "M-o" 'fingertip-backward-delete
  ;;     "C-d" 'fingertip-forward-delete
  ;;     "C-k" 'fingertip-kill

  ;;     "M-\"" 'fingertip-wrap-double-quote
  ;;     "M-'" 'fingertip-wrap-single-quote
  ;;     "M-[" 'fingertip-wrap-bracket
  ;;     "M-{" 'fingertip-wrap-curly
  ;;     "M-(" 'fingertip-wrap-round
  ;;     "M-)" 'fingertip-unwrap

  ;;     "M-p" 'fingertip-jump-right
  ;;     "M-n" 'fingertip-jump-left
  ;;     ;"M-:" 'fingertip-jump-out-pair-and-newline

  ;;     "C-j" 'fingertip-jump-up )
)

Treesit

Treesitter-context

Treesitter-context utilize emacs built-in treesit to show code context.

(use-package treesitter-context
:config
  (add-hook 'python-ts-mode-hook #'treesitter-context-mode)
  )

Lazycat’s method

You can find the addresses of language parsers at treesitter’s official doc. To enable treesit support for a language, you need to run M-x treesit-install-language-grammar and select the language. This will clone the language’s tree-sitter repo and build it (requires system cc).
(use-package treesit
:commands (treesit-install-language-grammar
           config/treesit-install-all-languages)
:init
  (setq treesit-language-source-alist
    '((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
      (c . ("https://github.com/tree-sitter/tree-sitter-c"))
      (cpp . ("https://github.com/tree-sitter/tree-sitter-cpp"))
      (css . ("https://github.com/tree-sitter/tree-sitter-css"))
      (cmake . ("https://github.com/uyha/tree-sitter-cmake"))
      (common-lisp . ("https://github.com/theHamsta/tree-sitter-commonlisp"))
      (csharp . ("https://github.com/tree-sitter/tree-sitter-c-sharp.git"))
      (dockerfile . ("https://github.com/camdencheek/tree-sitter-dockerfile"))
      (elisp . ("https://github.com/Wilfred/tree-sitter-elisp"))
      (go . ("https://github.com/tree-sitter/tree-sitter-go"))
      (gomod . ("https://github.com/camdencheek/tree-sitter-go-mod.git"))
      (html . ("https://github.com/tree-sitter/tree-sitter-html"))
      (java . ("https://github.com/tree-sitter/tree-sitter-java.git"))
      (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript"))
      (json . ("https://github.com/tree-sitter/tree-sitter-json"))
      (lua . ("https://github.com/Azganoth/tree-sitter-lua"))
      (make . ("https://github.com/alemuller/tree-sitter-make"))
      (markdown . ("https://github.com/MDeiml/tree-sitter-markdown" nil
        "tree-sitter-markdown/src"))
      (nix . ("https://github.com/nix-community/tree-sitter-nix.git"))
      (ocaml . ("https://github.com/tree-sitter/tree-sitter-ocaml" nil "ocaml/src"))
      (org . ("https://github.com/milisims/tree-sitter-org"))
      (python . ("https://github.com/tree-sitter/tree-sitter-python"))
      (php . ("https://github.com/tree-sitter/tree-sitter-php"))
      (typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" nil
          "typescript/src"))
      (tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" nil
          "tsx/src"))
      (ruby . ("https://github.com/tree-sitter/tree-sitter-ruby"))
      (rust . ("https://github.com/tree-sitter/tree-sitter-rust"))
      (sql . ("https://github.com/m-novikov/tree-sitter-sql"))
      (vue . ("https://github.com/merico-dev/tree-sitter-vue"))
      (yaml . ("https://github.com/ikatyang/tree-sitter-yaml"))
      (toml . ("https://github.com/tree-sitter/tree-sitter-toml"))
      (zig . ("https://github.com/GrayJack/tree-sitter-zig"))))
:config
(defun config/treesit-install-all-languages ()
  "Install all languages specified by `treesit-language-source-alist'."
  (interactive)
  (let ((languages (mapcar 'car treesit-language-source-alist)))
    (dolist (lang languages)
      (treesit-install-language-grammar lang)
      (message "`%s' parser was installed." lang)
      (sit-for 0.75)))))
;; stolen from lazycat
(setq major-mode-remap-alist
      '((c-mode          . c-ts-mode)
        (c++-mode        . c++-ts-mode)
        (cmake-mode      . cmake-ts-mode)
        (conf-toml-mode  . toml-ts-mode)
        (css-mode        . css-ts-mode)
        (js-mode         . js-ts-mode)
        (js-json-mode    . json-ts-mode)
        (nix-mode        . nix-ts-mode)
        (python-mode     . python-ts-mode)
        (sh-mode         . bash-ts-mode)
        (typescript-mode . typescript-ts-mode)
        (rust-mode       . rust-ts-mode)
        ))
  ;; (advice-add 'org-src-get-lang-mode :filter-return #'my/remap-mode)

(add-hook 'markdown-mode-hook #'(lambda ()
          (treesit-parser-create 'markdown)))

(add-hook 'web-mode-hook #'(lambda ()
           (let ((file-name (buffer-file-name)))
             (when file-name
               (treesit-parser-create
          (pcase (file-name-extension file-name)
            ("vue" 'vue)
            ("html" 'html)
            ("php" 'php))))
             )))

(add-hook 'emacs-lisp-mode-hook #'(lambda () (treesit-parser-create 'elisp)))
(add-hook 'ielm-mode-hook #'(lambda () (treesit-parser-create 'elisp)))
(add-hook 'json-mode-hook #'(lambda () (treesit-parser-create 'json)))
(add-hook 'go-mode-hook #'(lambda () (treesit-parser-create 'go)))
(add-hook 'java-mode-hook #'(lambda () (treesit-parser-create 'java)))
(add-hook 'java-ts-mode-hook #'(lambda () (treesit-parser-create 'java)))
(add-hook 'php-mode-hook #'(lambda () (treesit-parser-create 'php)))
(add-hook 'php-ts-mode-hook #'(lambda () (treesit-parser-create 'php)))

Copilot

https://github.com/zerolfx/copilot.el

Auto-save

Auto save saves your buffer after entering idle state.
(use-package auto-save
:after lsp-bridge
:config
  (auto-save-enable)
  (setq auto-save-silent t)   ; quietly save
  (setq auto-save-delete-trailing-whitespace t)
)

Vlf

(use-package vlf-setup
:config
  (setq-default vlf-application 'dont-ask)
)

Outli

(use-package outli
  :hook ((prog-mode text-mode) . outli-mode))

Direnv

Envrc provides support for direnv that is buffer-local.

(use-package envrc
:config
  (envrc-global-mode)
)

Languages

Elisp

  • buttercup
  • elisp-def
  • elisp-demos
  • highlight-quoted
  • macrostep
  • oversee
(setq-default lexical-binding t)
(use-package highlight-quoted)

Lisp

(use-package lisp-mode
:mode "\\.yuck\\'"
)

LaTeX

AUCTeX

(use-package auctex)

AucTex needs some tweaks to be built. To build auctex, autoconf should be avaliable on your system.

[submodule "auctex"]
  load-path = .
  build-step = ./autogen.sh
  build-step = ./configure --with-lispdir="$HOME"/.emacs.d/lib/auctex --with-texmf-dir="$HOME"/texmf
  build-step = make
  build-step = make doc
  build-step = borg-maketexi
  build-step = borg-makeinfo
  build-step = borg-update-autoloads

CDTeX

(use-package cdlatex)

LAAS

LASS (LaTeX Auto Activating Snippets) is a chunky set of LaTeX snippets for the auto-activating-snippets engine.

(use-package laas
:after ass
:hook (LaTeX-mode . laas-mode))

Markdown

(use-package markdown-mode
:config
  (dotimes (i 6)
    (set-face-attribute (intern (format "markdown-header-face-%d" (1+ i)))
                        nil
                        :inherit
                        (intern (format "outline-%d" (1+ i)))))
)

Nix

(use-package nix-mode
:mode "\\.nix\\'"
:config
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((nix . t))
   )
)
(use-package nix-ts-mode
:mode "\\.nix\\'"
)

PlantUML

(use-package plantuml-mode
:mode "\\.plantuml\\'"
)

Python

Jupyter

(use-package jupyter
;; :defer t
:config
(org-babel-do-load-languages
 'org-babel-load-languages
 (append org-babel-load-languages
         '((jupyter . t)))))

Rust

(use-package rust-ts-mode
:mode "\\.rs\\'"
)

Rusty object notation mode

(use-package ron-mode
:mode "\\.ron\\'"
)

Verilog

(use-package verilog-mode
:mode "\\.v\\'"
)

YAML

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

Org

Org mode is a reason to use emacs.

Init

Org-9.7 did some overhaul to org-latex-preview in org mode. Load External org before the built in org is loaded.
(use-package org
:after emacs
:init
  (setq org-element-cache-persistent nil)
  (setq org-element-use-cache nil)
  (setq org-latex-preview-numbered t)
:config
  (add-hook 'org-mode-hook #'olivetti-mode)
  ;(add-hook 'org-mode-hook #'org-visual-indent-mode)
  (add-hook 'org-mode-hook #'turn-on-org-cdlatex)
)

All the .el files are placed in the ./lisp/ folder. According to the installation manual of org, we need to make autoloads before compile.

[submodule "org"]
  load-path = lisp
  build-step = make autoloads
  build-step = borg-update-autoloads
  build-step = borg-compile
  build-step = borg-maketexi
  build-step = borg-makeinfo

UI

Fonts

Change the font size of different org-levels.

(use-package org
:custom-face
  ;; (org-latex-and-related ((t (:foreground "LightSteelBlue4" :weight bold))))
  ;; (org-meta-line ((t (:foreground "LightSteelBlue4"))))
  ;; (org-special-keyword ((t (:foreground "LightSteelBlue4"))))
  ;; (org-tag ((t (:foreground "LightSteelBlue4" :weight normal))))
:hook (org-mode . (lambda () (face-remap-add-relative 'default 'variable-pitch)))
:config
  (set-face-attribute 'outline-1 nil :height 1.8 )
  (set-face-attribute 'outline-2 nil :height 1.6 )
  (set-face-attribute 'outline-3 nil :height 1.4 )
  (set-face-attribute 'outline-4 nil :height 1.3 )
  (set-face-attribute 'outline-5 nil :height 1.2 )
  (set-face-attribute 'outline-6 nil :height 1.1 )
  (set-face-attribute 'org-document-title nil :height 2.5 :bold t)
  (set-face-attribute 'org-document-info nil :height 1.8 :bold t)
  (set-face-attribute 'org-document-info-keyword nil
     :inherit 'org-document-info)
  (set-face-attribute 'org-block nil
    :extend t :inherit 'fixed-pitch)
  (set-face-attribute 'org-block-begin-line nil
                      :background (face-background 'default) :height 0.9 :inherit nil)
)

Org-modern

Org-modern implements a modern style for Org buffers using font locking and text properties. The package styles headlines, keywords, tables and source blocks.

(use-package org-modern
;;:hook (org-mode . org-modern-mode)
:config
  (setq org-modern-keyword
     '(("author" . "")
      ("title" . "")
      ("subtitle" . "")
      ("html" . "󰅱 ")
      ("results" . "results")
      (t . t)))
  (setq org-modern-star
        nil
   ;; '("󱅊" "󱅋" "󱅌" "󱅍" "󱅎" "󱅏")
   ;; '("󰇊" "󰇋" "󰇌" "󰇍" "󰇎" "󰇏")
  )
  ;; (set-face-attribute 'org-modern-symbol nil :family "Noto Sans Symbols 2")
  (setq org-modern-list ;; for '+' '-' '*' respectively
      '((43 . "") (45 . "") (42 . "")))
  (setq org-modern-block-fringe nil)
  (setq org-modern-todo nil)
  (setq org-modern-timestamp nil)
  (setq org-modern-priority nil)
  ;; (setq org-modern-block-name )
  (setq org-modern-block-name
        '("" . "")
        ;; '("󰼀 " . "󰼀 ")
        ;; '("󰨔" . "󰨔")
        ;; '("󰨓" . "󰨓")
        ;; '("󰝤 " . "󰝤 ") ; nf-md-square
        )
  (set-face-attribute 'org-modern-block-name nil
     :inherit 'variable-pitch)
  (set-face-attribute 'org-meta-line nil
     :height 0.9)
  (set-face-attribute 'org-modern-horizontal-rule nil
      :strike-through (face-foreground 'org-meta-line) :inherit 'org-hide)

  (setq org-modern-table nil)
  (global-org-modern-mode)
)

Org-superstar replaces the asterisk before every org-level with ascii symbols. Disabled because org-morden is a drop-in replacement.

(use-package org-superstar
:defer t
;:hook (org-mode . org-superstar-mode)
:init
  (setq
    ;;org-superstar-headline-bullets-list '("󰇊" "󰇋" "󰇌" "󰇍" "󰇎" "󰇏")
    org-superstar-special-todo-items t
    ;;org-ellipsis "  "
  )
)

Svg-tag-mode

global svg tag mode will not work will dashboard image banner.

(use-package svg-tag-mode
;; :hook (org-mode . svg-tag-mode)
:config
(setq svg-tag-tags
      (append svg-tag-tags
              '(;; (":\\([A-Za-z0-9]+\\)" .
                ;;  ((lambda (tag)
                ;;     (if (not (or (org-at-table-p) (org-in-src-block-p)))
                ;;         (svg-tag-make tag)))))
                ("\\[#A\\]" .
                 ((lambda (tag)
                    (svg-tag-make tag
                                  :face '(:foreground "IndianRed" :weight bold)
                                  :inverse t))))
	        ("\\[#B\\]" .
                 ((lambda (tag)
                    (svg-tag-make tag
                                  :face '(:foreground "DarkOrange" :weight bold)
                                  :inverse t))))
	        ("\\[#C\\]" .
                 ((lambda (tag)
                    (svg-tag-make tag
                                  :face '(:foreground "Grey" :weight bold)
                                  :inverse t)))))))
)

Org-visual-outline

Org-visual-outline does the same as Org-bars-mode. It has two independent packages:
Org-dynamic-bullets
handles the dynamic bullets.
Org-visual-indent
adds vertical lines to org-indent. Does better than Org-bars-mode, as it do not need to set bar’s height.
(use-package org-visual-outline
;; :custom-face
  ;;  (org-visual-indent-blank-pipe-face ((t
  ;;        (:background "#1f2430" :foreground "#1f2430"
  ;;     :height 0.1 :width extra-expanded))))
  ;; (org-visual-indent-pipe-face ((t
  ;;       (:background "#454d6d" :foreground "#454d6d"
  ;;    :height 0.1 :width extra-expanded))))
:hook (org-mode . org-visual-indent-mode)
      (org-mode . org-dynamic-bullets-mode)
:after org
)

valign

This package provides visual alignment for Org Mode, Markdown and table.el tables on GUI Emacs. It can properly align tables containing variable-pitch font, CJK characters and images. Meanwhile, the text-based alignment generated by Org mode (or Markdown mode) is left untouched.

(use-package valign
:hook (org-mode . valign-mode)
:config
  (setq valign-fancy-bar t)
)

Highlight TODO

(use-package hl-todo
  :init
  (hl-todo-mode)
)

Org-appear

Org-appear disaply emphasis markers and links when the cursor is on them.
(use-package org-appear
  :hook (org-mode . org-appear-mode)
  :init
  (setq org-appear-autoemphasis  t
        ;; org-appear-autolinks t
        org-appear-autosubmarkers t
        org-appear-autoentities t
        org-appear-autokeywords t
        ;; org-appear-inside-latex t
        org-hide-emphasis-markers t
  )

)

Org-popup-posframe

(use-package org-popup-posframe
:config
  (setq org-popup-posframe-border-width 3)
  (setq org-popup-posframe-font "IBM Plex Mono-15")
  (setq org-popup-posframe-parameters
        '((left-fringe . 20)
          (right-fringe . 20)))
  (setq org-popup-posframe-org-todo-poshandler
        'posframe-poshandler-point-1)
  (org-popup-posframe-mode)
)

Keybindings

Local Keybindings
(setq org-return-follows-link t)
(my/mode-leader-def
  :prefix-command 'my/org-cmd
  :prefix-map 'my/org-map
  :keymaps '(org-mode-map)
  ""    '(nil                              :wk "org-mode")
  "a"   '(org-attach                       :wk "attach")
  "b"   '(nil                              :wk "Babel")
  "c"   '(org-ctrl-c-ctrl-c                :wk "execute")
  "d"   '(org-deadline                     :wk "deadline")
  "e"   '(org-edit-special                 :wk "edit")
  "f"   '(org-fold-reveal                  :wk "reveal")
  "g"   '(org-goto                         :wk "goto")
  ;; "h"   '(                                 :wk "")
  ;; "i"   '(                                 :wk "")
  "i"   '(org-insert-structure-template    :wk "structure")
  ;; "j"   '(                                 :wk "")
  ;; "k"   '(                                 :wk "")
  "l"   '(org-insert-link                  :wk "link")
  "m"   '(org-toggle-inline-images         :wk "toggle image")
  ;; "n"   '(                                 :wk "")
  "o"   '(org-export-dispatch              :wk "export")
  "p"   '(org-priority                     :wk "priority")
  ;; "q"   '(                                 :wk "")
  "r"   '(org-refile                       :wk "refile")
  "s"   '(org-schedule                     :wk "schedule")
  "t"   '(org-todo                         :wk "todo")
  ;; "u"   '(nil                              :wk "")
  "v"   '(org-download-clipboard           :wk "paste image")
  "w"   '(org-refile                       :wk "refile")
  "x"   '(nil                              :wk "latex")
  "y"   '(org-evaluate-time-range          :wk "time range")
  ;; "z"   '(nil                              :wk "")
  "C-j" '(my/outline-left                  :wk "dwim ")
  "C-k" '(my/outline-up                    :wk "dwim ")
  "C-l" '(my/outline-down                  :wk "dwim ")
  "C-;" '(my/outline-right                 :wk "dwim ")
  )
(my/mode-leader-def
  :keymaps '(org-mode-map)
  :infix "b"
  "t" '(org-babel-tangle                   :wk "tangle")
  "d" '(org-babel-demarcate-block          :wk "demarcate")
  )
(my/mode-leader-def
  :keymaps '(org-mode-map)
  :infix "x"
  "c" '(org-latex-preview-clear-cache      :wk "clear")
  "p" '(org-latex-preview                  :wk "preview")
  "a" '(org-latex-preview-auto-mode        :wk "auto")
  "r" '(my/org-latex-preview-reload        :wk "reload")
  )
(my/mode-leader-def
  :keymaps '(org-src-mode-map)
  "e"   'org-edit-src-exit
  "k"   'org-edit-src-abort
  )
(my/mode-leader-def
  :keymaps '(org-capture-mode-map)
  "c"   'org-capture-finalize
  "w"   'org-capture-refile
  "k"   'org-capture-kill
  )

outline functions

(defvar my/recenter 6)
(defun my/outline-left ()
  (interactive)
  (cond ((outline-on-heading-p)
         (hide-subtree)
         (outline-up-heading 1)
         (hide-subtree)
         (outline-show-children)
         (outline-show-entry))
        (t
         (outline-back-to-heading)
         ))
  (recenter my/recenter)
)

(defun my/outline-up ()
  (interactive)
  (cond ((outline-on-heading-p)
         (hide-subtree)
         (outline-backward-same-level 1)
         (outline-show-children)
         (outline-show-entry)
         )
        (t
         (org-previous-block 1)))
  (recenter my/recenter)
)

(defun my/outline-down ()
  (interactive)
  (cond ((outline-on-heading-p)
         (hide-subtree)
         (outline-forward-same-level 1)
         (outline-show-children)
         (outline-show-entry)
         )
        (t
         (org-next-block 1)))
  (recenter my/recenter))

(defun my/outline-right ()
  (interactive)
  (outline-show-children)
  (outline-show-entry)
  (if (outline-has-subheading-p)
      (progn (outline-next-heading)
             (outline-show-children)
             (outline-show-entry)))
  (recenter my/recenter))

Objects

Src block

Treesit-auto
(use-package org
:init
  (setq org-babel-load-languages
        '((awk . t)
          (shell . t)
          (eshell . t)

          (emacs-lisp . t)
          (lisp . t)
          (haskell . t)
          (clojure . t)
          (scheme . t)
          (org . t)

          (C . t)
          (sql . t)
          ;; (jupyter . t)
          (java . t)
          (lua . t)
          (js . t)

          (dot . t)
          (plantuml . t)

          (R . t)
          (python . t)
          (octave . t)
          (matlab . t)
          (julia . t)))
:config
  (setq org-edit-src-content-indentation 0
        org-src-tab-acts-natively t
        org-src-preserve-indentation nil
        org-src-ask-before-returning-to-edit-buffer nil
        org-confirm-babel-evaluate nil
        org-confirm-elisp-link-function nil
        org-link-elisp-confirm-function nil
        )
  (general-define-key :keymap 'org-src-mode-map
     "C-c C-c" 'eval-buffer)
)

Org-auto-tangle Automatically and Asynchronously tangles org files on save. Adding the option #+auto_tangle: t in an org file to auto-tangle. Or setting org-auto-tangle-default to t to configure auto-tangle as the default behavior for all org buffers. In this case, it can be disabled for some buffers by adding #+auto_tangle: nil.

(use-package org-auto-tangle
:hook (org-mode . org-auto-tangle-mode)
)

Ob-async enables asynchronous execution of org-babel src blocks. Simply add the keyword :async to the header-args of any org-babel src block and invoke ob-async-org-babel-execute-src-block.

(use-package ob-async
:after org
:config
  ;; below languages may have independent implementation of async
  (setq ob-async-no-async-languages-alist '("jupyter-python" "jupyter-julia"))
  )

Table

Valign provides visual alignment for Org Mode, Markdown and table.el tables on GUI Emacs. It can properly align tables containing variable-pitch font, CJK characters and images. Meanwhile, the text-based alignment generated by Org mode (or Markdown mode) is left untouched.

Orgtbl-aggregate can creat a new table by computing sums, averages, and so on, out of material from the first table.

LaTeX

Disable hiding of {}, _ and ^, from this post in emacs china.
(use-package org
:config
  (defconst org-match-substring-regexp
    (concat
     "\\(\\S-\\)\\([_^]\\)\\("
     "\\(?:" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)"
     "\\|"
     "\\(?:" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)"
     "\\|"
     "\\(?:.\\)"
     "\\|"
     "\\(?:\\\\[[:alnum:].,\\]*[[:alnum:]]\\)"
     "\\)")
    "The regular expression matching a sub- or superscript.")

  (defun +org-raise-scripts (limit)
    "Add raise properties to sub/superscripts."
    (when (and org-pretty-entities org-pretty-entities-include-sub-superscripts
               (re-search-forward org-match-substring-regexp limit t))
      (let* ((pos (point)) table-p comment-p
             (mpos (match-beginning 3))
             (emph-p (get-text-property mpos 'org-emphasis))
             (link-p (get-text-property mpos 'mouse-face))
             (keyw-p (eq 'org-special-keyword (get-text-property mpos 'face)))
             (tex-p (eq 'org-latex-and-related (get-text-property mpos 'face))))
        (goto-char (line-beginning-position))
        (setq table-p (looking-at-p org-table-dataline-regexp)
              comment-p (looking-at-p "^[ \t]*#[ +]"))
        (goto-char pos)
        ;; Handle a_b^c
        (when (member (char-after) '(?_ ?^)) (goto-char (1- pos)))
        (if (not (or comment-p emph-p link-p keyw-p))
            (put-text-property (match-beginning 3) (match-end 0)
                               'display
                               (if (equal (char-after (match-beginning 2)) ?^)
                                   (nth (if table-p 3 1) org-script-display)
                                 (nth (if table-p 2 0) org-script-display)))
          (put-text-property (match-beginning 2) (match-end 3) 'org-emphasis t))
        t)))

  (advice-add #'org-raise-scripts :override #'+org-raise-scripts)
)

Prettify symbols mode

(use-package org
  :hook
  (org-mode . (lambda ()
    (push '("\\operatorname{\\mathrm{" . (?  (Bc . Bl) ?{ (Bc . Br) ?{)) prettify-symbols-alist)
    (push '("\\mathcal{" . (?  (Bc . Bl) ?{ (Bc . Br) ?𝒞)) prettify-symbols-alist)
    (push '("\\mathbb{" . (?  (Bc . Bl) ?{ (Bc . Br) ?𝔹)) prettify-symbols-alist)
    (push '("\\\\{" . ?{) prettify-symbols-alist)
    (push '("\\\\}" . ?}) prettify-symbols-alist)
    (push '("\\(" . ?⟨) prettify-symbols-alist)
    (push '("\\)" . ?⟩) prettify-symbols-alist)
    (push '("\\)," . (?  (Bc . Bl) ?, (Bc . Br) ?⟩)) prettify-symbols-alist)
    (push '("\\)。" . (?  (Bc . Bl) ?。 (Bc . Br) ?⟩)) prettify-symbols-alist)
    (push '("\\);" . (?  (Bc . Bl) ?; (Bc . Br) ?⟩)) prettify-symbols-alist)
  ))
)

Org-entities-user

(use-package org
:config
  (setq org-entities-user '(
          ("frac" "\\frac" t "÷" "÷" "÷" "÷")
          ("sqrt" "\\sqrt" t "" "" "" "")
          ("vdash" "\\vdash" t "" "" "" "")
          ("vDash" "\\vDash" t "" "" "" "")
          ("Vdash" "\\Vdash" t "" "" "" "")
          ("Vvdash" "\\Vvdash" t "" "" "" "")
          ("nvdash" "\\nvdash" t "" "" "" "")
          ("nvDash" "\\nvDash" t "" "" "" "")
          ("nVdash" "\\nVdash" t "" "" "" "")
          ("nVDash" "\\nVDash" t "" "" "" "")
          ("subseteq" "\\subseteq" t "" "" "" "")
          ("supseteq" "\\supseteq" t "" "" "" "")
          ("subsetneq" "\\subsetneq" t "" "" "" "")
          ("supsetneq" "\\supsetneq" t "" "" "" "")
          ("nsubseteq" "\\nsubseteq" t "" "" "" "")
          ("nsupseteq" "\\nsupseteq" t "" "" "" "")
          ("nsubseteqq" "\\nsubseteqq" t "" "" "" "")
          ("nsupseteqq" "\\nsupseteqq" t "" "" "" "")
          ("subsetneqq" "\\subsetneqq" t "" "" "" "")
          ("supsetneqq" "\\supsetneqq" t "" "" "" "")
          ("nsubset" "\\nsubset" t "" "" "" "")
          ("nsupset" "\\nsupset" t "" "" "" "")
          ("nsubseteq" "\\nsubseteq" t "" "" "" "")
          ("nsupseteq" "\\nsupseteq" t "" "" "" "")
          ))
  )

Org Latex Preview configs. This makes the preview looks nicer.

(use-package org
:config
  (setq org-latex-preview-numbered t)
  (plist-put org-latex-preview-options :zoom 1.25)
  (let ((pos (assoc 'dvisvgm org-latex-preview-process-alist)))
    (plist-put (cdr pos) :image-converter '("dvisvgm --page=1- --optimize --clipjoin --relative --no-fonts --bbox=preview -o %B-%%9p.svg %f")))

  (defun my/org-latex-preview-reload ()
    (interactive)
    (call-interactively 'org-latex-preview-clear-cache)
    (org-latex-preview)
    )
)

Images

Org-download

(use-package org-download
:after org
)

PlantUML

(use-package plantuml-mode
  :defer t
  :mode ("\\.plantuml\\'" . plantuml-mode)
  :init
  ;; enable plantuml babel support
  (add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
  (org-babel-do-load-languages 'org-babel-load-languages
                               (append org-babel-load-languages
                                       '((plantuml . t))))
  :config
  (setq org-plantuml-exec-mode 'plantuml)
  (setq org-plantuml-executable-path "plantuml")
  (setq plantuml-executable-path "plantuml")
  (setq plantuml-default-exec-mode 'executable)
  ;; set default babel header arguments
  (setq org-babel-default-header-args:plantuml
        '((:exports . "results")
          (:results . "file")
          ))
)

Org-capture

Check capture-templates for more info.
(use-package org-capture
:after org
:init
  (setq org-directory "~/org")
:config
  ;; if file path is not absolute
  ;; it is treated as relative path to org-directory
  (defun org-hugo-new-subtree-post-capture-template ()
    "Returns `org-capture' template string for new Hugo post.
     See `org-capture-templates' for more information."
    (let* ((title (read-from-minibuffer "Post Title: "))
       (fname (org-hugo-slug title)))
    (mapconcat #'identity
        `(,(concat "* TODO " title) ":PROPERTIES:"
          ,(concat ":EXPORT_FILE_NAME: " fname) ":END:" "%?\n")
          ;Place the cursor here finally
        "\n")))
  (setq org-capture-templates
        (append org-capture-templates
                '(("i" "Inbox" entry (file+olp "gtd.org" "Inbox")
                   "* TODO %?\n:ENTERED: %U\n")
                  ("j" "Journal" entry (file+olp+datetree "journal.org")
                   "* [%<%R>] %?\n")
                  ("l" "Link" entry (file+olp "org-linkz/Linkz.org" "INBOX")
                   "* %a %U"
                   :immediate-finish t)
                  ("h" "Hugo post" entry (file+olp "capture.org" "Notes")
                   (function org-hugo-new-subtree-post-capture-template)))))
  (require 'org-protocol)
  (setq org-protocol-default-template-key "l")
)

Links

What is a backlink? If there’s a link at A pointing to B, and in the same time if there’s also a link at B pointing to A, then the link at B can be called the backlink of the link at A.

I’m using two plugins that handles backlink. Org-super-links handles inserting backlinks in current buffer. Org-roam inserts links and backlinks between different org files.

Custom-ID

(use-package org
:config
  (defun my/org-add-custom-id ()
    "Add CUSTOM_ID property to current heading, skip if already have"
    (interactive)
    (let ((custom-id (org-entry-get nil "CUSTOM_ID")))
      (unless custom-id
        (org-set-property "CUSTOM_ID" (org-id-new))))
    )

  (defun my/org-add-custom-id-to-all-headings ()
    "Add CUSTOM_ID properties to headings without a CUSTOM_ID property in current Org buffer."
    (interactive)
    (org-map-entries
     (lambda ()
       (let ((custom-id (org-entry-get nil "CUSTOM_ID")))
         (unless custom-id
           (org-set-property "CUSTOM_ID" (org-id-new)))))
     nil 'file)
    )
)

Org-super-links

Org super links handles backlink inside the current file. When inserting link to a target using org-super-links-link, it automatically inserts a backlink at the target.

I think this is what makes Org’s tree-style structure more complete. A tree style structure is efficient in dividing a big object into many smaller ones. But it’s possible that two children share something in common, but do not belong to the same parent. In this case backlinks does the job.

(use-package org-super-links
:after org
:config

  (defun my/org-insert-backlink ()
    "insert backlink using consult-org-heading in current org file"
    (interactive)
    (let ((target-position
           (save-excursion (consult-org-heading) (point) )))
      (org-super-links--insert-link
       (set-marker (make-marker) target-position)))
    (recenter)
    )
  (setq org-super-links-search-function 'my/org-insert-backlink)
  (setq org-super-links-backlink-prefix nil)
)

Org-roam

(use-package org-roam
:after org
:init
  (setq org-roam-directory (file-truename "~/roam"))
  (org-roam-db-autosync-mode)
  (setq org-roam-v2-ack t)
  (setq org-roam-capture-templates '(
     ("d" "default" plain "%?"
       :target (file+head
         "%<%Y%m%d%H>-${slug}.org"
         "#+title: ${title}\n#+filetags: \n")
       :unnarrowed t)
     ("b" "book notes" plain "%?"
       :target (file+head
         "book/book%<%Y%m%d%H>-${slug}.org"
         "#+title: ${title}\n#+filetags: :bookreading: \n\n")
       :unnarrowed t)
     ("c" "coMpany" plain "%?"
       :target (file+head
         "company/company%<%Y%m%d%H>-${slug}.org"
         "#+title: ${title}\n#filetags: :compnay: \n\n")
       :unnarrowed t)
     ("i" "industry" plain "%?"
       :target (file+head
         "industry/industry%<%Y%m%d%H>-${slug}.org"
         "#+title:${slug}\n#+filetags: :industry: \n\n")
       :unnarrowed t)
     ("m" "marketing" plain "%?"
       :target (file+head
         "marketing/marketing%<%Y%m%d%H%M%S>-${slug}.org"
         "#+title: ${title}\n#+filetags: :marketing: \n\n")
       :unnarrowed t)
     ("p" "project" plain "%?"
       :target (file+head
         "project/project%<%Y%m%d%H>-${slug}.org"
         "#+title: ${title}\n#+filetags: :project: \n\n - tag ::")
       :unnarrowed t)
     ("r" "reference" plain "%?"
       :target (file+head
         "<%Y%m%d%H>-${slug}.org"
         "#+title: {$title}\n%filetags: reference \n\n -tag ::")
       :unarrowed t)))
)

Scheduling

TODOs

(use-package org
:config
(setq org-todo-keywords '(
     (sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
     (sequence "WAIT(w@/!)" "HOLD(h@/!)" "|" "CNCL(c@/!)")
     (sequence "SOMEDAY")
))
(setq org-todo-state-tags-triggers
   '(("CNCL" ("CNCL" . t))
     ("WAIT" ("WAIT" . t))
     ("HOLD" ("WAIT") ("HOLD" . t))
     (done ("WAIT") ("HOLD"))
     ("TODO" ("WAIT") ("CNCL") ("HOLD"))
     ("NEXT" ("WAIT") ("CNCL") ("HOLD"))
     ("DONE" ("WAIT") ("CNCL") ("HOLD"))))
)

;;selecting keys from the fast todo selection key menu
(setq org-use-fast-todo-selection t
      org-enforce-todo-dependencies t
      org-log-done 'time
)

Org-agenda

(use-package org-agenda
:after org
:hook
  (org-agenda-mode . solaire-mode)
  (org-agenda-mode . olivetti-mode)
:bind
  ("<f12>" . org-agenda)
:config
  (setq org-agenda-span 'day)
  (setq org-agenda-files '("~/Org"))
  (let ((org-agenda-custom-commands '(
    ("u" "Super view" (
      (agenda "" (
        (org-agenda-span 1)
        (org-super-agenda-groups '(
          (:name "Today"
           :tag ("bday" "ann" "hols" "cal" "today")
           :time-grid t
           :todo ("WIP")
           :deadline today)
          (:name "Perso"
           :tag "perso")
          (:name "Overdue"
           :deadline past)
          (:name "Reschedule"
           :scheduled past)
          (:name "Due Soon"
           :deadline future)
          )))
      )
      (tags (concat "w" (format-time-string "%V"))
        ( (org-agenda-overriding-header
            (concat "ToDos Week " (format-time-string "%V")))
          (org-super-agenda-groups '(
             (:discard (:deadline t))
             (:name "Perso" :tag "perso")
             (:name "Loka"  :tag "loka")
             (:name "Ping"  :tag "ping")
          ))
        )
      )
   )))))
  (org-agenda nil "u"))

)

Org-super-agenda

(use-package org-super-agenda
:after org-agenda
:config
  (org-super-agenda-mode)
  (setq org-super-agenda-groups '(
    (:name "Today"
     :time-grid t
     :scheduled today)
    (:name "Due today"
           :deadline today)
    (:name "Important"
     :priority "A")
    (:name "Overdue"
     :deadline past)
    (:name "Due soon"
     :deadline future)
    (:name "Waiting"
     :todo "WAIT")
    (:name "Someday"
     :todo "SOMEDAY")
  ))
)

Calendar

(use-package calendar
:hook
  (calendar-mode . olivetti-mode)
  (calendar-mode . solaire-mode)
:config
  (setq calendar-date-style 'iso)
)

Archive repeated task

Copied from https://lists.gnu.org/archive/html/emacs-orgmode/2020-11/msg00361.html

(use-package org
:config
  (defun my/org-archive-without-delete ()
    "Archive item at point, but do not actually delete it."
    (cl-letf (((symbol-function 'org-cut-subtree) (lambda () nil)))
      (org-archive-subtree)))

  (defun org-archive-repeated-task (arg)
    "Add a copy of the recurring task marked DONE to archive."
    (when (and (eq (plist-get arg :type) 'todo-state-change)
               (string= (plist-get arg :to) "DONE")) ;; The state is changed to DONE
      (let* ((pos (plist-get arg :position))
             (repeater (org-with-point-at pos (org-get-repeat))))
        (when repeater ;; Only consider tasks with repeater timestamp anywhere in the task body
          (my/org-archive-without-delete)))))

  (add-hook 'org-trigger-hook #'org-archive-repeated-task)
)

Export

Ox

(use-package ox
:after org
:defer t
:config
  (setq
    org-export-with-toc t
          org-export-with-tags 'not-in-toc
          org-export-with-drawers nil
          org-export-with-priority t
          org-export-with-footnotes t
          org-export-with-smart-quotes t
          org-export-with-section-numbers t
          org-export-with-sub-superscripts '{}
    org-export-use-babel t
          org-export-headline-levels 9
          org-export-coding-system 'utf-8
          org-export-with-broken-links 'mark
  )
)

HTML

(use-package ox-html
  :defer t
  :after ox
  :config
  (setq org-html-doctype "html5"
          org-html-html5-fancy t
          org-html-checkbox-type 'unicode
          org-html-validation-link nil))
(use-package htmlize
  :defer t
  :config
  (setq htmlize-pre-style t
          htmlize-output-type 'inline-css))

grip-mode

(use-package grip-mode
:after org
)

PDF

There’re 3 common ways to export org into PDF.
  • ox-html, then export to pdf via browser.
  • ox-latex
  • ox-pandoc

LaTeX

(use-package ox-latex
:defer t
:after ox
:config
  ;; use xelatex
  (setq org-latex-pdf-process '("xelatex -file-line-error -interaction nonstopmode %f"
                                "bibtex %b"
                                "xelatex -file-line-error -interaction nonstopmode %f"
                                "xelatex -file-line-error -interaction nonstopmode %f"))

  ;; clear files after generating PDF
  ;; https://answer-id.com/53623039
  (setq org-latex-logfiles-extensions
    (quote ("lof" "lot" "tex~" "tex" "aux"
      "idx" "log" "out" "toc" "nav"
      "snm" "vrb" "dvi" "fdb_latexmk"
      "blg" "brf" "fls" "entoc" "ps"
      "spl" "bbl" "xdv")))
  (setq org-image-actual-width nil)

  (setq org-export-with-sub-superscripts nil)

  ;;
  (setq make-backup-files nil)
  (setq org-latex-listings t)
  (add-to-list
   'org-latex-classes
   '("elegantpaper"
     "\\documentclass[lang=cn]{elegantpaper}
[NO-DEFAULT-PACKAGES]
[PACKAGES]
[EXTRA]"
     ("\\section{%s}" . "\\section*{%s}")
     ("\\subsection{%s}" . "\\subsection*{%s}")
     ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
     ("\\paragraph{%s}" . "\\paragraph*{%s}")
     ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
  )

Ipynb

(use-package ox-ipynb
:defer t
:after ox
  )

Slides

Use reveal.js to generate beautiful presentations. This requires reveal.js installed on your machine.
git clone https://github.com/hakimel/reveal.js.git
cd reveal.js && npm install
(use-package ox-reveal
:defer t
:after ox
:config
  (setq org-reveal-hlevel 1
          org-reveal-theme "moon"
          org-reveal-mathjax t
          org-reveal-ignore-speaker-notes t
          org-reveal-title-slide "<h1><font size=\"8\">%t</font></h1><h2><font size=\"6\">%s</font></h2><p><font size=\"5\">%a</font><br/><font size=\"5\">%d</font></p>"
          org-reveal-plugins '(markdown zoom notes search)
          org-reveal-klipsify-src 'on))

Markdown

Use ox-gfm to generate github-style markdown file.
(use-package ox-gfm
:defer t
:after ox
)

MS-Office

Use ox-pandoc to generate MS-Office files like word and ppt.
(use-package ox-pandoc
:defer t
:after ox
:config
  (setq org-pandoc-format-extensions
        '(markdown_github+pipe_tables+raw_html)
  )
)

Static HTML

(use-package ox-publish
:defer t
)

Hugo

General steps to publish a blog using hugo in emacs includes:
  • create a org mode heading
  • write your blog
  • use ox-hugo to export to a markdown file (Because hugo doesn’t support org very well)
  • use easy-hugo to preview
  • publish

ox-hugo is an Org exporter backend that exports Org to Hugo-compatible Markdown and also generates the front-matter (in TOML or YAML format).

(use-package ox-hugo
:after ox
:commands (org-hugo-export-as-md org-hugo-export-to-md)
:init
  (setq org-hugo-base-dir "~/Blog"
        org-hugo-front-matter-format "yaml"
  )
)

Easy-hugo

(use-package easy-hugo
:defer t
)

Org-transclusion

Emacs OS

Telega

Telegram inside emacs!
(use-package telega
  :defer t
  :hook (telega-chat-mode .
                          (lambda ()
                            (visual-fill-column-mode 0)
                            (config/window-center 102)
                            (solaire-mode -1)
                            ))
  :init
  (setq telega-server-libs-prefix "~/.nix-profile")
  (setq telega-avatar-workaround-gaps-for '(return t)) ;; solves broken avatar
  (setq telega-emoji-use-images nil) ;; or emoji will look monochrome and broken
  (setq ;; telega-root
   ;; telega-root-default-view-function 'telega-view-folders
   telega-root-keep-cursor 'track
   telega-root-buffer-name "*Telega Root*"
   telega-root-fill-column 70 ; fill-column
   telega-symbol-folder "  ")
  (setq telega-symbol-forum (nerd-icons-mdicon "nf-md-format_list_text"))
  (setq telega-brackets
        `(((chat (type private))
           ,(concat " "
             (nerd-icons-mdicon "nf-md-account"
                                :face '(:foreground "#86dffd" :height 0.7))
             " ") " ")
          ((chat (type bot))
           ,(concat " "
             (nerd-icons-mdicon "nf-md-robot"
                                :face '(:foreground "#86dffd" :height 0.7))
             " ") " ")
          ((chat (type basicgroup))
           ,(concat " "
             (nerd-icons-mdicon "nf-md-account_multiple"
                                :face '(:foreground "#70bcff" :height 0.7))
             " ") " ")
          ((chat (type supergroup))
           ,(concat " "
             (nerd-icons-mdicon "nf-md-account_multiple"
                                :face '(:foreground "#70bcff" :height 0.7))
             " ") " ")
          ((chat (type channel))
           ,(concat " "
             (nerd-icons-faicon "nf-fa-feed"
                                :face '(:foreground "#ffa95f" :height 0.7))
             " ") " ")
          ((user (return t))
           ,(concat " "
             (nerd-icons-mdicon "nf-md-account"
                                :face '(:foreground "#86dffd" :height 0.7))
             " ") " ")
          ((return t)
           ,(concat " "
             (nerd-icons-faicon "nf-fa-question_circle"
                                :face '(:foreground "#ff0000" :height 0.7))
             " ") " "))
        )
  (general-def
    :keymaps '(telega-msg-button-map)
    "SPC" nil
    "l"   nil
    "C"   'telega-msg-copy-link
    )

  )
[submodule "telega"]
  ;; build-nix-shell-packages = tdlib
  build-step = make server
  build-step = make autoloads
  build-step = borg-update-autoloads
  build-step = borg-compile
  build-step = borg-maketexi
  build-step = borg-makeinfo

Elfeed

Elfeed is emacs’s built-in rss reader.

The following config adds nerd icons, copied from Emacs China.

(use-package elfeed
:defer t
:hook
  (elfeed-search-mode .
    (lambda () (config/window-center 110) (solaire-mode -1)))
  (elfeed-show-mode .
    (lambda () (config/window-center 114) (solaire-mode -1)))
:config
  (defun nerd-icon-for-tags (tags)
    "Generate Nerd Font icon based on tags.
  Returns default if no match."
    (cond
     ((member "youtube" tags)
      (nerd-icons-faicon "nf-fa-youtube_play" :face '(:foreground "#FF0200")))
     ((member "instagram" tags)
      (nerd-icons-faicon "nf-fa-instagram" :face '(:foreground "#FF00B9")))
     ((member "emacs" tags)
      (nerd-icons-sucicon "nf-custom-emacs" :face '(:foreground "#9A5BBE")))
     ((member "github" tags)
      (nerd-icons-faicon "nf-fa-github"))
     ((member "zhihu" tags)
      (nerd-icons-mdicon "nf-md-alpha_z_box" :face '(:foreground "#1772F6")))
     ((member "bilibili" tags)
      (nerd-icons-mdicon "nf-md-alpha_b_box" :face '(:foreground "#FB7299")))
     (t
      (nerd-icons-faicon "nf-fae-feedly" :face '(:foreground "#2AB24C")))))

  (defun my/elfeed-search-print-entry--better-default (entry)
    "Print ENTRY to the buffer."
    (let* ((date (elfeed-search-format-date (elfeed-entry-date entry)))
           (date-width (car (cdr elfeed-search-date-format)))
           (title (concat (or (elfeed-meta entry :title)
                              (elfeed-entry-title entry) "")
                          ;; NOTE: insert " " for overlay to swallow
                          " "))
           (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
           (feed (elfeed-entry-feed entry))
           (feed-title (when feed (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
           (tags (mapcar #'symbol-name (delq 'unread (elfeed-entry-tags entry))))
           (tags-str (mapconcat (lambda (s) (propertize s 'face 'elfeed-search-tag-face)) tags ","))
           (title-width (- (frame-width)
                           ;; (window-width (get-buffer-window (elfeed-search-buffer) t))
                           date-width elfeed-search-trailing-width))
           (title-column (elfeed-format-column
                          title (elfeed-clamp
                                 elfeed-search-title-min-width
                                 title-width
                                 elfeed-search-title-max-width) :left))


           ;; Title/Feed ALIGNMENT
           (align-to-feed-pixel (+ 2 date-width
                                   (max elfeed-search-title-min-width
                                        (min title-width elfeed-search-title-max-width)))))
      (insert (propertize date 'face 'elfeed-search-date-face) "  ")
      (insert (propertize title-column 'face title-faces 'kbd-help title))
      (put-text-property (1- (point)) (point) 'display `(space :align-to ,align-to-feed-pixel))
      ;; (when feed-title (insert " " (propertize feed-title 'face 'elfeed-search-feed-face) " "))
      (when feed-title
        (insert " " (concat (nerd-icon-for-tags tags) " ")
                (propertize feed-title 'face 'elfeed-search-feed-face) " "))
      (when tags (insert "(" tags-str ")"))))

  (setq  elfeed-search-print-entry-function
         #'my/elfeed-search-print-entry--better-default)
)

Elfeed-org

(use-package elfeed-org
:after elfeed
:init
  (setq rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))
  (elfeed-org)
)

Calc

PDF-Tools

PDF-tools is a replacement for DocView for PDF files. The rendering is performed by poppler. Run M-x pdf-tools-install to install libraries needed.

pdf-view-midnight-colors are set by doom-themes

(use-package pdf-tools
  ;; manually update
  ;; after each update we have to call:
  ;; Install pdf-tools but don't ask or raise error (otherwise daemon mode will wait for input)
  ;; (pdf-tools-install t t t)
:magic ("%PDF" . pdf-view-mode)
:mode (("\\.pdf\\'" . pdf-view-mode))
:hook ((pdf-view-mode . pdf-view-init))
:bind (:map pdf-view-mode-map
            ("C-s" . isearch-forward)
            ("M-w" . pdf-view-kill-ring-save)
            ("M-p" . print-pdf))
:config
  (defun pdf-view-init ()
    "Initialize pdf-tools view like enabline TOC functions or use dark theme at night."

    ;; Use dark theme when opening PDFs at night time
    (let ((hour (string-to-number (format-time-string "%H"))))
      (when (or (< hour 5) (< 20 hour))
        (pdf-view-midnight-minor-mode)))

    ;; Enable pdf-tools minor mode to have features like TOC extraction by pressing `o'.
    (pdf-tools-enable-minor-modes)

    ;; Disable while-line-or-region to free keybindings.
    (whole-line-or-region-local-mode -1))

  ;; Use `gtklp' or `hp-print' to print as it has better cups support
  (setq print-pdf-command "hp-print")
  (defun print-pdf (&optional pdf)
    "Print PDF using external program defined in `print-pdf-command'."
    (interactive "P")
    (start-process-shell-command
     print-pdf-command nil (concat print-pdf-command " " (shell-quote-argument (or pdf (buffer-file-name))))))

  ;; more fine-grained zooming; +/- 10% instead of default 25%
  (setq pdf-view-resize-factor 1.1)
  )

Nov

nov.el provides a major mode for reading EPUB documents.

(use-package nov
:defer t)

Mu4e

[submodule "mu4e"]
  build-step = ./autogen.sh
  build-step = make -C mu4e > /dev/null
  build-step = borg-update-autoloads
  load-path = build/mu4e

Eaf

EAF is an extensible framework that revolutionizes the graphical capabilities of Emacs.

(use-package eaf
:disabled
:custom
  ; See https://github.com/emacs-eaf/emacs-application-framework/wiki/Customization
  (eaf-browser-continue-where-left-off t)
  (eaf-browser-enable-adblocker t)
  (browse-url-browser-function 'eaf-open-browser)
:config
  (defalias 'browse-web #'eaf-open-browser)
  ;; (eaf-bind-key scroll_up "C-n" eaf-pdf-viewer-keybinding)
  ;; (eaf-bind-key scroll_down "C-p" eaf-pdf-viewer-keybinding)
  ;; (eaf-bind-key take_photo "p" eaf-camera-keybinding)
  ;; (eaf-bind-key nil "M-q" eaf-browser-keybinding)
  (setq confirm-kill-processes nil)
) ;; unbind, see more in the Wiki

;(use-package eaf-browser)
;(use-package eaf-pdf-viewer)

tweaks to build eaf

[submodule "eaf"]
  load-path = .
  load-path = core
  load-path = extension

Games

Tetris

(add-hook 'tetris-mode-hook (lambda () (config/window-center 76)))

2048

(add-hook '2048-mode-hook (lambda () (config/window-center 35)))

Emacs-Everywhere

Takes emacs-everywhere with you, all over your system

End

(progn ;     startup
  (message "Loading %s...done (%fs)" user-init-file
           (float-time (time-subtract (current-time)
                                      before-user-init-time)))
  (add-hook 'after-init-hook
            (lambda ()
              (message
               "Loading %s...done (%fs) [after-init]" user-init-file
               (float-time (time-subtract (current-time)
                                          before-user-init-time))))
            t))

(progn ;     personalize
  (let ((file (expand-file-name (concat (user-real-login-name) ".el")
                                user-emacs-directory)))
    (when (file-exists-p file)
      (load file))))
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; init.el ends here

*

COMMENT

Org-denote

Completion

flx-rs + fussy

hotfuzz

Align variable pitch

Transient maps

Dired

Elfeed add filter group

Dired guess shell alist user

Svg libs/tabs

copy from nano emacs

Try setup.el

Memacs

https://github.com/novoid/Memacs

About

Let's explore the bound of emacs :D

License:ISC License


Languages

Language:Emacs Lisp 98.8%Language:Makefile 1.2%