M-EMACS is a custom GNU Emacs setup and configurations that aims not only to enhance the default Emacs experience, and hopefully be a sample that everyone can easily navigate and reference through a highly detailed README that contains 99% of the entire configuration code.
As a young EMACSer, I have experienced the struggle to find a detailed configuration that is loosely coupled and highly readable. This mostly due to the nature of source codes, sometimes comments are harder to notice or simply not enough. Therefore I decided to construct this README and present any human-readable explanation in a much more human-friendly way. Anyone, particularly Emacs beginners who have no idea where to start with their personal config, is more than welcome to read through this document and copy/paste any part to use it on their own.
This configuration is designed and tested for GNU Emacs 26.1 and above only. However, it is suggested to use emacs27, the latest version currently available.
(when (version< emacs-version "26.1")
(error "M-EMACS requires Emacs 26.1 and above!"))
This README is originated from init.org that is generated using M-x org-gfm-export-to-markdown
. Every block of code is generated through this function - it exports the section of code from the elisp/
directory. You will not see their presence in init.org.
-
Install GNU Emacs. If you are using Ubuntu,
emacs-snapshot
is a great way to get latest version of Emacs.sudo add-apt-repository -y ppa:ubuntu-elisp sudo apt-get update sudo apt-get install emacs-snapshot
-
Clone this repo to
HOME
or~/
path using git and update all the submodules.git clone --recurse-submodules -j8 https://github.com/MatthewZMD/.emacs.d.git cd .emacs.d
-
Ensure a stable connection to Melpa Packages, then open Emacs.
-
Enter
y
when prompted withAuto-update packages now?
, wait for all packages to install. -
In your favorite browser,
Ctrl-F Prerequisite
through this webpage and follow the Prerequisite instructions. -
Restart Emacs.
I will be updating M-EMACS from time to time, it is best to git pull
once a while to stay up to date.
Please also execute git submodule update --recursive --remote
to sync with all the submodules.
You have the permission to use, modify, distribute in any way you want. However, what is free stays free. After all, this is GPL.
Remember you must manually sync this README with all the new changes you made by:
- Please do NOT edit README.md file, edit init.org instead!
- If you add a new mode, create a new
<file-name>.el
file inelisp/
directory. - Put
(require '<file-name>)
in init.el accordingly. - Add
#+INCLUDE: "~/.emacs.d/elisp/<place-holder>.el" src emacs-lisp :range-begin "<start-line-wrapper-exclusive>" :range-end "<end-line-wrapper-exclusive>"
in the appropriate section in init.org. - Enter
C-x C-s
to save and update:lines
. (if you don't see the updated effect, runM-x update-includes
manually) - Call
M-x org-gfm-export-to-markdown
to update this README.
If you spotted a bug or you have any suggestions, please fill in an issue. If you have something to fix, feel free to create a pull request.
Everyone starts somewhere, and I started here.
- M-EMACS
- About
- Startup
- Package Management
- Global Functionalities
- User Interface Enhancements
- General Programming
- Programming
- Web Development
- Miscellaneous
Use lexical-binding. Why?
Until Emacs 24.1 (June 2012), Elisp only had dynamically scoped variables, a feature, mostly by accident, common to old lisp dialects. While dynamic scope has some selective uses, it’s widely regarded as a mistake for local variables, and virtually no other languages have adopted it.
;;; init.el --- -*- lexical-binding: t -*-
Emacs27 introduces early-init.el
, which is run before init.el
, before package and UI initialization happens.
Defer garbage collection further back in the startup process, according to hlissner.
The GC eats up quite a bit of time, easily doubling startup time. The trick is to turn up the memory threshold as early as possible.
(setq gc-cons-threshold 80000000
gc-cons-percentage 0.6)
Package initialize occurs automatically, before user-init-file
is loaded, but after early-init-file
. We handle package initialization, so we must prevent Emacs from doing it early!
(setq package-enable-at-startup nil)
Every file opened and loaded by Emacs will run through this list to check for a proper handler for the file, but during startup, it won’t need any of them.
(setq file-name-handler-alist-original file-name-handler-alist)
(setq file-name-handler-alist nil)
(setq site-run-file nil)
It will be faster to disable them here before they've been initialized.
(unless (and (display-graphic-p) (eq system-type 'darwin))
(push '(menu-bar-lines . 0) default-frame-alist))
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
A large gc-cons-threshold will cause freezing and stuttering during long-term interactive use.
(add-hook 'emacs-startup-hook
(lambda ()
(setq-default gc-cons-threshold better-gc-cons-threshold ;; 16mb
gc-cons-percentage 0.1)
(setq file-name-handler-alist file-name-handler-alist-original)
(makunbound 'file-name-handler-alist-original)))
Note: Since Emacs27.1, focus-out-hook
is obsolete.
(add-hook 'emacs-startup-hook
(lambda ()
(if (boundp 'after-focus-change-function)
(add-function :after after-focus-change-function
(lambda ()
(unless (frame-focus-state)
(garbage-collect))))
(add-hook 'focus-out-hook 'garbage-collect))
(defun gc-minibuffer-setup-hook ()
(setq gc-cons-threshold better-gc-cons-threshold))
(defun gc-minibuffer-exit-hook ()
(garbage-collect)
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook #'gc-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'gc-minibuffer-exit-hook)))
Since all the configuration files are stored in elisp/
folder, they need to be added to load-path
on startup.
(defun update-to-load-path (folder)
"Update FOLDER and its subdirectories to `load-path'."
(let ((base folder))
(add-to-list 'load-path base)
(dolist (f (directory-files base))
(let ((name (concat base "/" f)))
(when (and (file-directory-p name)
(not (equal f ".."))
(not (equal f ".")))
(add-to-list 'load-path name))))))
(update-to-load-path "~/.emacs.d/elisp")
(defconst *sys/gui*
(display-graphic-p)
"Are we running on a GUI Emacs?")
(defconst *sys/win32*
(eq system-type 'windows-nt)
"Are we running on a WinTel system?")
(defconst *sys/linux*
(eq system-type 'gnu/linux)
"Are we running on a GNU/Linux system?")
(defconst *sys/mac*
(eq system-type 'darwin)
"Are we running on a Mac system?")
(defconst *sys/root*
(string-equal "root" (getenv "USER"))
"Are you a ROOT user?")
(defconst *rg*
(executable-find "rg")
"Do we have ripgrep?")
(defconst *tr*
(executable-find "tr")
"Do we have tr?")
(defconst *mvn*
(executable-find "mvn")
"Do we have Maven?")
(defconst *clangd*
(or (executable-find "clangd") ;; usually
(executable-find "/usr/local/opt/llvm/bin/clangd")) ;; macOS
"Do we have clangd?")
(defconst *gcc*
(executable-find "gcc")
"Do we have gcc?")
(defconst *curl*
(executable-find "curl")
"Do we have curl?")
Some packages are disabled with the :disabled
tag, because I don't use them very often. They might not work.
;; Select the folder to store packages
;; Comment / Uncomment to use desired sites
(setq package-user-dir "~/.emacs.d/elpa"
package-archives
'(("gnu" . "http://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("melpa stable" . "http://stable.melpa.org/packages/")
("cselpa" . "https://elpa.thecybershadow.net/packages/")))
Load all Melpa packages in elisp/
to load-path
directly to reduce startup time.
Add packages contained in site-elisp/
to load-path
too.
cd site-elisp/
git submodule add https://github.com/foo/bar.git
Verify /.gitmodules
file that the newly added package exist.
git submodule init
git submodule update
(unless (bound-and-true-p package--initialized) ; To avoid warnings in 27
(setq package-enable-at-startup nil) ; To prevent initializing twice
(package-initialize))
;; set use-package-verbose to t for interpreted .emacs,
;; and to nil for byte-compiled .emacs.elc.
(eval-and-compile
(setq use-package-verbose (not (bound-and-true-p byte-compile-current-file))))
My Emacs configuration is almost entirely dependant on use-package.
The
use-package
macro allows you to isolate package configuration in your .emacs file in a way that is both performance-oriented and, well, tidy. I created it because I have over 80 packages that I use in Emacs, and things were getting difficult to manage. Yet with this utility my total load time is around 2 seconds, with no loss of functionality!
;; Install use-package if not installed yet.
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-and-compile
(setq use-package-always-ensure t)
(setq use-package-expand-minimally t)
(setq use-package-compute-statistics t)
(setq use-package-enable-imenu-support t))
(eval-when-compile
(require 'use-package)
(require 'bind-key))
Auto package update automatically updates installed packages if at least auto-package-update-interval
days have passed since the last update.
(use-package auto-package-update
:config
(setq auto-package-update-interval 7) ;; in days
(setq auto-package-update-prompt-before-update t)
(setq auto-package-update-delete-old-versions t)
(setq auto-package-update-hide-results t)
(auto-package-update-maybe))
Diminish, a feature that removes certain minor modes from mode-line.
(use-package diminish)
GNU Elpa Keyring Update, Update Emacs's GPG keyring for GNU ELPA.
The GPG key used to sign the GNU ELPA archives is nearing retirement: it expires this September. Which means that if you don't get the new key before, you won't be able to check the signature of new packages after that date.
(use-package gnu-elpa-keyring-update)
Prerequisite: Please update this file your personal info.
(setq user-full-name "Mingde (Matthew) Zeng")
(setq user-mail-address "matthewzmd@gmail.com")
;; Unbind C-z to use as prefix and unbind C-x C-z too
(global-set-key (kbd "C-z") nil)
(global-set-key (kbd "C-x C-z") nil)
;; Use iBuffer instead of Buffer List
(global-set-key (kbd "C-x C-b") #'ibuffer)
;; Truncate lines
(global-set-key (kbd "C-x C-!") #'toggle-truncate-lines)
;; Adjust font size like web browsers
(global-set-key (kbd "C-+") #'text-scale-increase)
(global-set-key (kbd"C--") #'text-scale-decrease)
;; Move up/down paragraph
(global-set-key (kbd "M-n") #'forward-paragraph)
(global-set-key (kbd "M-p") #'backward-paragraph)
;; Some local bindings
(define-key emacs-lisp-mode-map (kbd "<f5>") #'eval-buffer)
(add-hook 'c++-mode-hook (lambda () (local-set-key (kbd "<f5>") #'compile)))
(add-hook 'c-mode-hook (lambda () (local-set-key (kbd "<f5>") #'compile)))
Dired, the directory editor.
(use-package dired
:ensure nil
:config
;; Always delete and copy recursively
(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies 'always)
;; Auto refresh Dired, but be quiet about it
(setq global-auto-revert-non-file-buffers t)
(setq auto-revert-verbose nil)
;; Quickly copy/move file in Dired
(setq dired-dwim-target t)
;; Move files to trash when deleting
(setq delete-by-moving-to-trash t)
;; Reuse same dired buffer, so doesn't create new buffer each time
(put 'dired-find-alternate-file 'disabled nil)
(add-hook 'dired-mode-hook (lambda () (local-set-key (kbd "<mouse-2>") #'dired-find-alternate-file)))
(add-hook 'dired-mode-hook (lambda () (local-set-key (kbd "RET") #'dired-find-alternate-file)))
(add-hook 'dired-mode-hook (lambda () (define-key dired-mode-map (kbd "^")
(lambda () (interactive) (find-alternate-file ".."))))))
Set autosave and backup directory.
(make-directory "~/.emacs.d/autosaves" t)
(make-directory "~/.emacs.d/backups" t)
(setq backup-directory-alist '(("." . "~/.emacs.d/backups/"))
auto-save-file-name-transforms '((".*" "~/.emacs.d/autosaves/\\1" t))
delete-old-versions -1
version-control t
vc-make-backup-files t)
;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file
(defun rename-file-and-buffer (new-name)
"Renames both current buffer and file it's visiting to NEW-NAME."
(interactive "sNew name: ")
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not filename)
(message "Buffer '%s' is not visiting a file!" name)
(if (get-buffer new-name)
(message "A buffer named '%s' already exists!" new-name)
(progn
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil))))))
;; Load the newest version of a file
(setq load-prefer-newer t)
;; Detect external file changes and auto refresh file
(global-auto-revert-mode t)
;; Transparently open compressed files
(auto-compression-mode t)
Prerequisite: Please install ripgrep and add rg
to the PATH
.
Color-RG, a search and refactoring tool based on ripgrep that is used to search text.
(when *rg*
(use-package color-rg
:load-path "~/.emacs.d/site-elisp/color-rg"
:bind ("C-z s s" . color-rg-search-input)))
Grep-Dired, a search and refactoring tool based on ripgrep that is used to search files.
(when *rg*
(use-package grep-dired
:load-path "~/.emacs.d/site-elisp/grep-dired"
:bind
(("C-z s f" . grep-dired-dwim)
("C-z s d" . grep-dired))))
Avy, a nice way to move around text.
(use-package avy
:defer t
:bind
(("C-;" . avy-goto-char-timer)
("C-:" . avy-goto-line))
:config
(setq avy-timeout-seconds 0.3)
(setq avy-style 'pre))
Ivy, a generic completion mechanism for Emacs.
(use-package ivy
:diminish ivy-mode
:init (ivy-mode 1)
:config
(setq ivy-use-virtual-buffers t)
(setq ivy-height 10)
(setq ivy-on-del-error-function nil)
(setq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create)
(setq ivy-count-format "【%d/%d】")
(setq ivy-wrap t))
Amx, a M-x enhancement tool forked from Smex.
(use-package amx
:after (:any ivy ido)
:config (amx-mode))
Counsel, a collection of Ivy-enhanced versions of common Emacs commands.
(use-package counsel
:after ivy
:diminish counsel-mode
:init (counsel-mode 1))
Swiper, an Ivy-enhanced alternative to isearch.
(use-package swiper
:bind (("C-M-s" . swiper-isearch)
("C-s" . swiper)))
Shell-here, a tool that opens a shell buffer in (or relative to) default-directory
.
(use-package shell-here
:bind ("C-!" . shell-here))
Term-keys, a lossless keyboard input for Emacs in terminal emulators.
(unless *sys/gui*
(use-package term-keys
:config (term-keys-mode t)))
Winner mode restores old window layout.
(use-package winner
:ensure nil
:config
(setq winner-boring-buffers
'("*Completions*"
"*Compile-Log*"
"*inferior-lisp*"
"*Fuzzy Completions*"
"*Apropos*"
"*Help*"
"*cvs*"
"*Buffer List*"
"*Ibuffer*"
"*esh command on file*"))
(winner-mode 1))
Which Key, a feature that displays the key bindings following the incomplete command.
(use-package which-key
:diminish
:init
(setq which-key-separator " ")
(setq which-key-prefix-prefix "+")
:config
(which-key-mode))
Popup Kill Ring, a feature that provides the ability to browse Emacs kill ring in autocomplete style popup menu.
(use-package popup-kill-ring
:bind ("M-y" . popup-kill-ring))
Undo tree, a feature that provides a visualization of the undos in a file.
(use-package undo-tree
:defer t
:diminish undo-tree-mode
:init (global-undo-tree-mode))
Discover my major, a feature that discovers key bindings and their meaning for the current Emacs major mode.
(use-package discover-my-major
:bind (("C-h C-m" . discover-my-major)))
Ace Window, a package for selecting windows to switch to.
(use-package ace-window
:bind ("C-x C-o" . ace-window))
Some essential configs that make my life a lot easier.
Use UTF-8 as much as possible with unix line endings.
(if (eq system-type 'windows-nt)
(progn
(set-clipboard-coding-system 'utf-16-le)
(set-selection-coding-system 'utf-16-le))
(set-selection-coding-system 'utf-8))
(prefer-coding-system 'utf-8-unix)
(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8-unix)
(set-terminal-coding-system 'utf-8-unix)
(set-keyboard-coding-system 'utf-8-unix)
(setq locale-coding-system 'utf-8-unix)
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
(when (display-graphic-p)
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
;; Remove useless whitespace before saving a file
(add-hook 'before-save-hook 'whitespace-cleanup)
(add-hook 'before-save-hook (lambda() (delete-trailing-whitespace)))
;; Make sentences end with a single space
(setq-default sentence-end-double-space nil)
;; Disable Shift mark
(setq shift-select-mode nil)
;; Replace selection on insert
(delete-selection-mode 1)
;; Merge system clipboard with Emacs
(setq-default select-enable-clipboard t)
(use-package recentf
:ensure nil
:hook (after-init . recentf-mode)
:init
(setq recentf-max-saved-items 200)
(setq recentf-exclude '((expand-file-name package-user-dir)
".cache"
".cask"
".elfeed"
"bookmarks"
"cache"
"ido.*"
"persp-confs"
"recentf"
"undo-tree-hist"
"url"
"COMMIT_EDITMSG\\'")))
;; When buffer is closed, saves the cursor location
(save-place-mode 1)
;; Set history-length longer
(setq-default history-length 500)
(setq ring-bell-function 'ignore)
(setq echo-keystrokes 0.1)
(setq-default create-lockfiles nil)
Better compilation configurations.
(setq-default compilation-always-kill t) ; kill compilation process before starting another
(setq-default compilation-ask-about-save nil) ; save all buffers on `compile'
(setq-default compilation-scroll-output t)
(setq custom-file (concat user-emacs-directory "custom-set-variables.el"))
(load custom-file 'noerror)
Other important, but longer functions.
;; Resizes the window width based on the input
(defun window-resize-width (w)
"Resizes the window width based on W."
(interactive (list (if (> (count-windows) 1)
(read-number "Set the current window width in [1~9]x10%: ")
(error "You need more than 1 window to execute this function!"))))
(message "%s" w)
(window-resize nil (- (truncate (* (/ w 10.0) (frame-width))) (window-total-width)) t))
;; Resizes the window height based on the input
(defun window-resize-height (h)
"Resizes the window height based on H."
(interactive (list (if (> (count-windows) 1)
(read-number "Set the current window height in [1~9]x10%: ")
(error "You need more than 1 window to execute this function!"))))
(message "%s" h)
(window-resize nil (- (truncate (* (/ h 10.0) (frame-height))) (window-total-height)) nil))
;; Setup shorcuts for window resize width and height
(global-set-key (kbd "C-x C-|") #'window-resize-width)
(global-set-key (kbd "C-x C-_") #'window-resize-height)
(defun edit-configs ()
"Opens the README.org file."
(interactive)
(find-file "~/.emacs.d/init.org"))
(global-set-key (kbd "C-z e") #'edit-configs)
Smarter navigation to the beginning of a line by Bozhidar Batsov.
(defun smarter-move-beginning-of-line (arg)
"Move point back to indentation of beginning of line.
Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.
If ARG is not nil or 1, move forward ARG - 1 lines first. If
point reaches the beginning or end of the buffer, stop there."
(interactive "^p")
(setq arg (or arg 1))
;; Move lines first
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line] 'smarter-move-beginning-of-line)
Update Org Mode INCLUDE Statements Automatically from Artur Malabarba.
(defun save-and-update-includes (&rest ignore)
"Update the line numbers of #+INCLUDE:s in current buffer.
Only looks at INCLUDEs that have either :range-begin or :range-end.
This function does nothing if not in org-mode, so you can safely
add it to `before-save-hook'."
(interactive)
(when (derived-mode-p 'org-mode)
(save-excursion
(goto-char (point-min))
(while (search-forward-regexp
"^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)"
nil 'noerror)
(let* ((file (expand-file-name (match-string-no-properties 1)))
lines begin end)
(forward-line 0)
(when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"")
(setq begin (match-string-no-properties 1)))
(when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"")
(setq end (match-string-no-properties 1)))
(setq lines (decide-line-range file begin end))
(when lines
(if (looking-at ".*:lines *\"\\([-0-9]+\\)\"")
(replace-match lines :fixedcase :literal nil 1)
(goto-char (line-end-position))
(insert " :lines \"" lines "\""))))))))
(add-hook 'before-save-hook #'save-and-update-includes)
(defun decide-line-range (file begin end)
"Visit FILE and decide which lines to include.
BEGIN and END are regexps which define the line range to use."
(let (l r)
(save-match-data
(with-temp-buffer
(insert-file-contents file)
(goto-char (point-min))
(if (null begin)
(setq l "")
(search-forward-regexp begin)
(setq l (line-number-at-pos (match-beginning 0))))
(if (null end)
(setq r "")
(search-forward-regexp end)
(setq r (1+ (line-number-at-pos (match-end 0)))))
(format "%s-%s" (+ l 1) (- r 1)))))) ;; Exclude wrapper
(defun abort-minibuffer-using-mouse ()
"Abort the minibuffer when using the mouse."
(when (and (>= (recursion-depth) 1) (active-minibuffer-window))
(abort-recursive-edit)))
(add-hook 'mouse-leave-buffer-hook 'abort-minibuffer-using-mouse)
;; keep the point out of the minibuffer
(setq-default minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt))
(defun duplicate-line ()
"Duplicate the current line."
(interactive)
(move-beginning-of-line 1)
(move-beginning-of-line 1)
(kill-line)
(yank)
(open-line 1)
(forward-line 1)
(yank))
(global-set-key (kbd "C-z l") #'duplicate-line)
(use-package recentf
:ensure nil
:hook (after-init . recentf-mode)
:init
(setq recentf-max-saved-items 200)
(setq recentf-exclude '((expand-file-name package-user-dir)
".cache"
".cask"
".elfeed"
"bookmarks"
"cache"
"ido.*"
"persp-confs"
"recentf"
"undo-tree-hist"
"url"
"COMMIT_EDITMSG\\'")))
;; When buffer is closed, saves the cursor location
(save-place-mode 1)
;; Set history-length longer
(setq-default history-length 500)
(defun display-line-overlay+ (pos str &optional face)
"Display line at POS as STR with FACE.
FACE defaults to inheriting from default and highlight."
(let ((ol (save-excursion
(goto-char pos)
(make-overlay (line-beginning-position)
(line-end-position)))))
(overlay-put ol 'display str)
(overlay-put ol 'face
(or face '(:background null :inherit highlight)))
ol))
All The Icons, a utility package to collect various Icon Fonts. Enable only in GUI Emacs.
Prerequisite: Install all fonts from fonts/all-the-icons-fonts
.
(when *sys/gui*
(use-package all-the-icons))
All The Icons Dired, an icon set for Dired.
(when *sys/gui*
(use-package all-the-icons-dired
:after all-the-icons
:diminish
:custom-face
(all-the-icons-dired-dir-face ((t `(:foreground ,(face-background 'default)))))
:config (add-hook 'dired-mode-hook #'all-the-icons-dired-mode)))
All The Icons Ivy, an icon set for Ivy.
(when *sys/gui*
(use-package all-the-icons-ivy
:after all-the-icons
:config
(all-the-icons-ivy-setup)
(setq all-the-icons-ivy-buffer-commands '())
(setq all-the-icons-ivy-file-commands
'(counsel-find-file counsel-file-jump counsel-recentf counsel-projectile-find-file counsel-projectile-find-dir))))
Doom Themes, an UI plugin and pack of themes.
(when *sys/gui*
(use-package doom-themes
:custom-face
(cursor ((t (:background "BlanchedAlmond"))))
:config
;; flashing mode-line on errors
(doom-themes-visual-bell-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config)
(load-theme 'doom-one t)))
Doom Modeline, a modeline from DOOM Emacs, but more powerful and faster.
(when *sys/gui*
(use-package doom-modeline
:hook (after-init . doom-modeline-mode)
:config
;; Don't compact font caches during GC. Windows Laggy Issue
(setq inhibit-compacting-font-caches t)
(setq doom-modeline-minor-modes t)
;;(setq doom-modeline-github t) ;; requires ghub package
(setq doom-modeline-icon t)
(setq doom-modeline-major-mode-color-icon t)
(setq doom-modeline-height 15)))
Dashboard, an extensible Emacs startup screen.
Use either KEC_Dark_BK.png
or KEC_Light_BK.png
depends on the backgrond theme.
(use-package dashboard
:diminish (dashboard-mode page-break-lines-mode)
:custom-face
(dashboard-banner-logo-title ((t (:family "Love LetterTW" :height 115))))
:config
(dashboard-setup-startup-hook)
(setq dashboard-banner-logo-title "Close the world. Open the nExt.")
(setq dashboard-startup-banner "~/.emacs.d/images/KEC_Dark_BK_Small.png")
(setq dashboard-items '((recents . 7)
(bookmarks . 5)
;; (projects . 5)
(agenda . 5)
))
;; Additional Dashboard widgets.
(defun dashboard-insert-widgets (list-size)
;; (insert (format "%d packages loaded in %s.\n" (length package-activated-list) (emacs-init-time)))
(insert "Navigation: ")
;;(insert (make-string (max 0 (floor (/ (- dashboard-banner-length 25) 2))) ?\ ))
(widget-create 'url-link
:tag (propertize "Github" 'face 'font-lock-keyword-face)
:help-echo "Open M-EMACS Github"
:mouse-face 'highlight
"https://github.com/MatthewZMD/.emacs.d")
(insert " ")
(widget-create 'push-button
:help-echo "Edit M-EMACS configuration"
:action (lambda (&rest _) (edit-configs))
:mouse-face 'highlight
:button-prefix ""
:button-suffix ""
(propertize "Configuration" 'face 'font-lock-keyword-face)))
(add-to-list 'dashboard-item-generators '(buttons . dashboard-insert-widgets))
(add-to-list 'dashboard-items '(buttons)))
Open Dashboard Function
(defun open-dashboard ()
"Open the *dashboard* buffer and jump to the first widget."
(interactive)
(if (get-buffer dashboard-buffer-name)
(kill-buffer dashboard-buffer-name))
(dashboard-insert-startupify-lists)
(switch-to-buffer dashboard-buffer-name)
(goto-char (point-min))
(if (> (length (window-list-1))
;; exclude `treemacs' window
(if (and (fboundp 'treemacs-current-visibility)
(eq (treemacs-current-visibility) 'visible)) 2 1))
(setq dashboard-recover-layout-p t))
(delete-other-windows))
(global-set-key (kbd "C-z d") #'open-dashboard)
Page-break-lines, a feature that displays ugly form feed characters as tidy horizontal rules.
(use-package page-break-lines
:diminish
:init (global-page-break-lines-mode))
Prepares fonts to use.
Prerequisite: Install Input
and Love Letter TW
from fonts/
.
;; Input Mono, Monaco Style, Line Height 1.3 download from http://input.fontbureau.com/
(defvar fonts '(("Input" . 11) ("SF Mono" . 12) ("Consolas" . 12) ("Love LetterTW" . 12.5))
"List of fonts and sizes. The first one available will be used.")
Change Font Function.
(defun change-font ()
"Documentation."
(interactive)
(let* (available-fonts font-name font-size font-setting)
(dolist (font fonts (setq available-fonts (nreverse available-fonts)))
(when (member (car font) (font-family-list))
(push font available-fonts)))
(if (not available-fonts)
(message "No fonts from the chosen set are available")
(if (called-interactively-p 'interactive)
(let* ((chosen (assoc-string (completing-read "What font to use? " available-fonts nil t) available-fonts)))
(setq font-name (car chosen) font-size (read-number "Font size: " (cdr chosen))))
(setq font-name (caar available-fonts) font-size (cdar available-fonts)))
(setq font-setting (format "%s-%d" font-name font-size))
(set-frame-font font-setting nil t)
(add-to-list 'default-frame-alist (cons 'font font-setting)))))
(change-font)
Smoothens Scrolling.
;; Vertical Scroll
(setq scroll-step 1)
(setq scroll-margin 1)
(setq scroll-conservatively 101)
(setq scroll-up-aggressively 0.01)
(setq scroll-down-aggressively 0.01)
(setq auto-window-vscroll nil)
(setq fast-but-imprecise-scrolling nil)
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-progressive-speed nil)
;; Horizontal Scroll
(setq hscroll-step 1)
(setq hscroll-margin 1)
Pretty the Symbols.
(global-prettify-symbols-mode 1)
(defun add-pretty-lambda ()
"Make some word or string show as pretty Unicode symbols. See https://unicodelookup.com for more."
(setq prettify-symbols-alist
'(
("lambda" . 955)
("delta" . 120517)
("epsilon" . 120518)
("->" . 8594)
("<=" . 8804)
(">=" . 8805)
)))
(add-hook 'prog-mode-hook 'add-pretty-lambda)
(add-hook 'org-mode-hook 'add-pretty-lambda)
(setq-default frame-title-format '("M-EMACS - " user-login-name "@" system-name " - %b"))
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(fset 'yes-or-no-p 'y-or-n-p)
(setq inhibit-startup-screen t)
(setq initial-major-mode 'text-mode)
(setq initial-scratch-message "Present Day, Present Time...")
Display line numbers, and column numbers in modeline.
;; Hook line numbers to only when files are opened
(add-hook 'find-file-hook #'display-line-numbers-mode)
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
;; Display column numbers in modeline
(column-number-mode 1)
Magit, an interface to the version control system Git.
(use-package magit
:bind ("C-x g" . magit-status))
Projectile, a Project Interaction Library for Emacs.
Prerequisite: If using Windows OS, install Gow and add to PATH
.
Gow is a lightweight installer that installs useful open source UNIX applications compiled as native win32 binaries. Specifically, tr
is needed for Projectile alien indexing.
(use-package projectile
:bind
("C-c p" . projectile-command-map)
("C-z i" . projectile-switch-project)
("C-z o" . projectile-find-file)
("C-z p" . projectile-add-known-project)
:config
(projectile-mode 1)
(setq projectile-completion-system 'ivy)
(when (and (eq system-type 'windows-nt) *tr*)
(setq projectile-indexing-method 'alien))
(add-to-list 'projectile-globally-ignored-directories "node_modules"))
Treemacs, a tree layout file explorer for Emacs.
(use-package treemacs
:init
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
:config
(progn
(setq treemacs-collapse-dirs
(if (executable-find "python") 3 0)
treemacs-deferred-git-apply-delay 0.5
treemacs-display-in-side-window t
treemacs-file-event-delay 5000
treemacs-file-follow-delay 0.2
treemacs-follow-after-init t
treemacs-follow-recenter-distance 0.1
treemacs-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-no-png-images nil
treemacs-no-delete-other-windows t
treemacs-project-follow-cleanup nil
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
treemacs-recenter-after-file-follow nil
treemacs-recenter-after-tag-follow nil
treemacs-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-desc
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-width 35)
;; The default width and height of the icons is 22 pixels. If you are
;; using a Hi-DPI display, uncomment this to double the icon size.
;;(treemacs-resize-icons 44)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t)
(treemacs-fringe-indicator-mode t)
(pcase (cons (not (null (executable-find "git")))
(not (null (executable-find "python3"))))
(`(t . t) (treemacs-git-mode 'deferred))
(`(t . _) (treemacs-git-mode 'simple))))
:bind
((:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
(:map treemacs-mode-map ("C-p" . treemacs-previous-line)))
(use-package treemacs-magit
:defer t
:after (treemacs magit))
(use-package treemacs-projectile
:defer t
:after (treemacs projectile))
Company, a text completion framework for Emacs.
(use-package company
:diminish company-mode
:defer t
:init (global-company-mode)
:config
(setq company-minimum-prefix-length 1)
(setq company-tooltip-align-annotations 't)
(setq company-idle-delay 0)
(setq company-begin-commands '(self-insert-command))
(setq company-require-match 'never)
(setq company-show-numbers t)
(setq company-global-modes '(not shell-mode))
(define-key company-mode-map [remap indent-for-tab-command] #'company-indent-or-complete-common))
YASnippet, a programming template system for Emacs. It loads YASnippet Snippets, a collection of yasnippet snippets for many languages.
(use-package yasnippet
:diminish yas-minor-mode
:hook (prog-mode . yas-minor-mode)
:bind
(("C-c C-n" . yas-expand-from-trigger-key))
:config
(use-package yasnippet-snippets)
(yas-reload-all))
Flycheck, a syntax checking extension.
(use-package flycheck
:defer t
:hook (prog-mode . flycheck-mode)
:config
(setq flycheck-emacs-lisp-load-path 'inherit)
(flycheck-add-mode 'javascript-eslint 'js-mode)
(flycheck-add-mode 'typescript-tslint 'rjsx-mode))
Dumb jump, an Emacs "jump to definition" package.
(use-package dumb-jump
:bind (("M-g o" . dumb-jump-go-other-window)
("M-g j" . dumb-jump-go)
("M-g i" . dumb-jump-go-prompt)
("M-g x" . dumb-jump-go-prefer-external)
("M-g z" . dumb-jump-go-prefer-external-other-window))
:config (setq dumb-jump-selector 'ivy))
Smartparens, a minor mode for dealing with pairs.
(use-package smartparens
:hook (prog-mode . smartparens-mode)
:diminish smartparens-mode
:bind (:map smartparens-mode-map
("C-M-f" . sp-forward-sexp)
("C-M-b" . sp-backward-sexp)
("C-M-a" . sp-backward-down-sexp)
("C-M-e" . sp-up-sexp)
("C-M-u" . sp-backward-up-sexp)
("C-M-k" . sp-kill-sexp)
("C-M-w" . sp-copy-sexp)
("M-D" . sp-splice-sexp)
("C-M-<backspace>" . sp-splice-sexp-killing-backward)
("C-S-<backspace>" . sp-splice-sexp-killing-around)
("C-]" . sp-select-next-thing-exchange)
("C-M-]" . sp-select-next-thing)
("M-i" . sp-change-enclosing))
:config
;; Stop pairing single quotes in elisp
(sp-local-pair 'emacs-lisp-mode "'" nil :actions nil)
(sp-local-pair 'org-mode "[" nil :actions nil)
(setq sp-escape-quotes-after-insert nil)
;; Smartparens is broken in `cc-mode' as of Emacs 27. See
;; <https://github.com/Fuco1/smartparens/issues/963>.
(unless (version< emacs-version "27")
(dolist (fun '(c-electric-paren c-electric-brace))
(add-to-list 'sp--special-self-insert-commands fun))))
Awesome Pair, a feature that provides grammatical parenthesis completion.
(use-package awesome-pair
:load-path "~/.emacs.d/site-elisp/awesome-pair"
:bind
(("C-c C-k" . awesome-pair-kill)
("SPC" . awesome-pair-space)
("=" . awesome-pair-equal)
("M-F" . awesome-pair-jump-right)
("M-B" . awesome-pair-jump-left))
:config
(add-hook 'prog-mode-hook '(lambda () (awesome-pair-mode 1))))
Delete Block, a feature that deletes block efficiently.
(use-package delete-block
:load-path "~/.emacs.d/site-elisp/delete-block"
:bind
(("M-d" . delete-block-forward)
("C-<backspace>" . delete-block-backward)))
Match and automatically pair parenthesis, and show parenthesis even when it went offscreen from Clemens Radermacher.
;; Show matching parenthesis
(show-paren-mode 1)
;; we will call `blink-matching-open` ourselves...
(remove-hook 'post-self-insert-hook
#'blink-paren-post-self-insert-function)
;; this still needs to be set for `blink-matching-open` to work
(setq blink-matching-paren 'show)
(let ((ov nil)) ; keep track of the overlay
(advice-add
#'show-paren-function
:after
(defun show-paren--off-screen+ (&rest _args)
"Display matching line for off-screen paren."
(when (overlayp ov)
(delete-overlay ov))
;; check if it's appropriate to show match info,
;; see `blink-paren-post-self-insert-function'
(when (and (overlay-buffer show-paren--overlay)
(not (or cursor-in-echo-area
executing-kbd-macro
noninteractive
(minibufferp)
this-command))
(and (not (bobp))
(memq (char-syntax (char-before)) '(?\) ?\$)))
(= 1 (logand 1 (- (point)
(save-excursion
(forward-char -1)
(skip-syntax-backward "/\\")
(point))))))
;; rebind `minibuffer-message' called by
;; `blink-matching-open' to handle the overlay display
(cl-letf (((symbol-function #'minibuffer-message)
(lambda (msg &rest args)
(let ((msg (apply #'format-message msg args)))
(setq ov (display-line-overlay+
(window-start) msg))))))
(blink-matching-open))))))
Highlight Indent Guides, a feature that highlights indentation levels.
(when *sys/gui*
(use-package highlight-indent-guides
:diminish
:hook ((prog-mode web-mode nxml-mode) . highlight-indent-guides-mode)
:config
(setq highlight-indent-guides-method 'character)
(setq highlight-indent-guides-responsive 'top)
(setq highlight-indent-guides-delay 0)
(setq highlight-indent-guides-auto-character-face-perc 7)))
Indentation Configuration
(setq-default indent-tabs-mode nil)
(setq-default indent-line-function 'insert-tab)
(setq-default tab-width 4)
(setq-default c-basic-offset 4)
(c-set-offset 'comment-intro 0)
(c-set-offset 'innamespace 0)
Format all, a feature that lets you auto-format source code.
Prerequisite: Read Supported Languages to see which additional tool you need to install for the specific language.
(use-package format-all
:bind ("C-z f" . format-all-buffer))
Evil Nerd Commenter, a tool that helps you comment code efficiently.
(use-package evil-nerd-commenter
:bind
(("M-;" . evilnc-comment-or-uncomment-lines)
("C-z ; p" . evilnc-comment-or-uncomment-paragraphs)
("C-z ; c" . evilnc-copy-and-comment-lines)))
Iedit, a minor mode that allows editing multiple regions simultaneousy in a buffer or a region.
(use-package iedit
:bind ("C-z ," . iedit-mode)
:diminish)
Header2, a support for creation and update of file headers.
(use-package header2
:load-path "~/.emacs.d/site-elisp/header2"
:config
(autoload 'auto-make-header "header2")
(autoload 'auto-update-file-header "header2")
(add-hook 'write-file-hooks 'auto-update-file-header)
(add-hook 'emacs-lisp-mode-hook 'auto-make-header)
(add-hook 'c-mode-common-hook 'auto-make-header))
Emacs IPython Notebook, a Jupyter (formerly IPython) client in Emacs.
- Execute
M-x ein:run
to launch a local Jupyter session. - Login with
M-x ein:login
to a local or remote session. - Open
.ipynb
file and pressC-c C-o
.
(use-package ein
:disabled
:defer t)
LSP Mode, a client/library for the Language Server Protocol. M-EMACS tries to use lsp-mode whenever possible.
(use-package lsp-mode
:defer t
:commands lsp
:init
(setq lsp-auto-guess-root nil)
(setq lsp-prefer-flymake nil) ; Use flycheck instead of flymake
:bind ("C-z C-f" . lsp-format-buffer)
:hook ((java-mode . lsp)
(python-mode . lsp)
(js2-mode . lsp)
(typescript-mode . lsp)
(web-mode . lsp)
(c-mode . lsp)
(c++-mode . lsp)
(objc-mode . lsp)))
LSP UI, provides all the higher level UI modules of lsp-mode, like flycheck support and code lenses.
(use-package lsp-ui
:after lsp-mode
:diminish
:commands lsp-ui-mode
:custom-face
(lsp-ui-doc-background ((t (:background nil))))
(lsp-ui-doc-header ((t (:inherit (font-lock-string-face italic)))))
:bind (:map lsp-ui-mode-map
([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
([remap xref-find-references] . lsp-ui-peek-find-references)
("C-c u" . lsp-ui-imenu))
:init
(setq lsp-ui-doc-enable t
lsp-ui-doc-header t
lsp-ui-doc-include-signature t
lsp-ui-doc-position 'top
lsp-ui-doc-use-webkit t
lsp-ui-doc-border (face-foreground 'default)
lsp-ui-sideline-enable nil
lsp-ui-sideline-ignore-duplicate t
lsp-ui-sideline-show-code-actions nil)
:config
;; WORKAROUND Hide mode-line of the lsp-ui-imenu buffer
;; https://github.com/emacs-lsp/lsp-ui/issues/243
(defadvice lsp-ui-imenu (after hide-lsp-ui-imenu-mode-line activate)
(setq mode-line-format nil)))
Company LSP, a Company completion backend for lsp-mode.
(use-package company-lsp
:defer t
:config
(setq company-lsp-cache-candidates 'auto))
DAP Mode, a client/library for the Debug Adapter Protocol.
(use-package dap-mode
:disabled
:after lsp-mode
:defer t
:config
(dap-mode 1)
(dap-ui-mode 1))
LSP Java, Emacs Java IDE using Eclipse JDT Language Server. Note that this package is dependant on Request.
Prerequisite: Install Maven and add to PATH
.
(when *mvn*
(use-package lsp-java
:after lsp-mode
:init
(use-package request :defer t)
:config
(setq
lsp-java-server-install-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/server/")
lsp-java-workspace-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/workspace/"))))
Prerequisite: Since all completion features are provided by LSP Mode, it needs to setup.
- Install CMake >= 3.8 for all OS.
- *nix OS:
- Windows OS:
Note: Compile using <f5>
or compile
. The command gcc -o <file>.exe <fileA>.c <fileB>.c ...
is to compile C code into <file>.exe
.
(use-package cc-mode
:ensure nil
:bind (:map c-mode-base-map
("<f5>" . compile)))
Emacs-CCLS, a client for CCLS, a C/C++/Objective-C language server supporting multi-million line C++ code-bases, powered by libclang.
(unless *sys/win32*
(use-package ccls
:defer t
:hook ((c-mode c++-mode objc-mode) .
(lambda () (require 'ccls) (lsp)))
:config
(setq ccls-executable "~/tools/ccls/Release/ccls")))
Modern CPP Font Lock, font-locking for "Modern C++".
(use-package modern-cpp-font-lock
:diminish
:init (modern-c++-font-lock-global-mode t))
(use-package python
:after flycheck
:mode "\\.py\\'"
:config
(setq flycheck-python-pycompile-executable "python3")
(setq python-shell-interpreter "python3"))
LSP Python MS, a lsp-mode client leveraging Microsoft's Python Language Server.
(use-package lsp-python-ms
:after lsp-mode
:config
(setq lsp-python-executable-cmd "python3"))
Arduino mode, a major mode for editing Arduino sketches.
(use-package arduino-mode
:disabled
:defer t
:config
(add-to-list 'auto-mode-alist '("\\.ino\\'" . arduino-mode))
(add-to-list 'auto-mode-alist '("\\.pde\\'" . arduino-mode))
(autoload 'arduino-mode "arduino-mode" "Arduino editing mode." t))
Company Arduino, a set of configuration to let you auto-completion by using irony-mode, company-irony and company-c-headers on arduino-mode.
(use-package company-arduino
:disabled
:defer t
:config
(add-hook 'irony-mode-hook 'company-arduino-turn-on)
;; Activate irony-mode on arduino-mode
(add-hook 'arduino-mode-hook 'irony-mode))
Prerequisite: Install NodeJS and add to path. Execute following commands to enable LSP for JavaScript/TypeScript/HTML:
npm i -g typescript
npm i -g typescript-language-server
npm i -g vscode-html-languageserver-bin
Web mode, a major mode for editing web templates.
(use-package web-mode
:custom-face
(css-selector ((t (:inherit default :foreground "#66CCFF"))))
(font-lock-comment-face ((t (:foreground "#828282"))))
:mode
("\\.phtml\\'" "\\.tpl\\.php\\'" "\\.[agj]sp\\'" "\\.as[cp]x\\'"
"\\.erb\\'" "\\.mustache\\'" "\\.djhtml\\'" "\\.[t]?html?\\'"))
JS2 mode, a feature that offers improved JavsScript editing mode.
(use-package js2-mode
:mode "\\.js\\'"
:interpreter "node")
TypeScript mode, a feature that offers TypeScript support for Emacs.
(use-package typescript-mode
:mode "\\.ts\\'"
:commands (typescript-mode))
Emmet, a feature that allows writing HTML using CSS selectors along with C-j
. See usage for more information.
(use-package emmet-mode
:hook web-mode
:config
(add-hook 'css-mode-hooktype 'emmet-mode)) ;; enable Emmet's css abbreviation
Instant Rename Tag, a plugin that provides ability to rename html tag pairs instantly.
(use-package instant-rename-tag
:load-path "~/.emacs.d/site-elisp/instant-rename-tag"
:bind ("C-z <" . instant-rename-tag))
JSON Mode,major mode for editing JSON files.
(use-package json-mode
:mode "\\.json\\'")
Org, a Emacs built-in tool for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system.
Prerequisite: Modify (setq org-agenda-files (list "~/org/agenda/"))
to your agenda folder.
(use-package org
:ensure nil
:defer t
:bind
("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture)
("C-c b" . org-switch)
:config
(setq org-log-done 'time)
(setq org-export-backends (quote (ascii html icalendar latex md odt)))
(when (file-directory-p "~/org/agenda/")
(setq org-agenda-files (list "~/org/agenda/")))
(setq org-use-speed-commands t)
(setq org-todo-keywords
'((sequence "TODO" "IN-PROGRESS" "REVIEW" "|" "DONE"))))
TOC Org generates table of contents for .org
files
(use-package toc-org
:hook (org-mode . toc-org-mode))
HTMLize, a tool that converts buffer text and decorations to HTML.
(use-package htmlize :defer t)
OX-GFM, a Github Flavored Markdown exporter for Org Mode.
(use-package ox-gfm :defer t)
Emacs Application Framework, a development framework that integrates any PyQt program into Emacs.
Prerequisite: Please install python3 and pip3. Then execute below command:
sudo pip install dbus-python PyMuPDF grip qrcode pyqt5 python-xlib
(when *sys/linux*
(use-package eaf
:load-path "~/.emacs.d/site-elisp/emacs-application-framework"))
EWW, the Emacs Web Wowser.
In Eww, hit & to browse this url system browser
(setq browse-url-browser-function 'eww-browse-url)
(defun xah-rename-eww-hook ()
"Rename eww browser's buffer so sites open in new page."
(rename-buffer "eww" t))
(add-hook 'eww-mode-hook #'xah-rename-eww-hook)
;; C-u M-x eww will force a new eww buffer
(defun force-new-eww-buffer (orig-fun &rest args)
"ORIG-FUN ARGS When prefix argument is used, a new eww buffer will be created,
regardless of whether the current buffer is in `eww-mode'."
(if current-prefix-arg
(with-temp-buffer
(apply orig-fun args))
(apply orig-fun args)))
(advice-add 'eww :around #'force-new-eww-buffer)
PDF Tools, an Emacs support library for PDF files. It works best on non-Windows OS.
(unless *sys/win32*
(use-package pdf-tools
:ensure t
:config
(pdf-loader-install)
(setq TeX-view-program-selection '((output-pdf "pdf-tools")))
(setq TeX-view-program-list '(("pdf-tools" "TeX-pdf-tools-sync-view")))))
LeetCode, an Emacs LeetCode client. Note that this package is dependant on Request-Deferred and GraphQL.
Prerequisite: Ensure cURL
is installed added to PATH
. If you are using Windows, it is suggested to use curl
provided by Git, therefore add <path to Git>\mingw64\bin
to PATH
.
(when *curl*
(use-package leetcode
:load-path "~/.emacs.d/site-elisp/leetcode.el"
:commands (leetcode)
:init
(use-package request-deferred :defer t)
(use-package graphql :defer t)
:config
;; (setq request-message-level 'debug)
;; (setq request-log-level 'debug)
(setq leetcode-prefer-language "python3")))
Pyim, an Emacs Chinese Pinyin Input.
(use-package pyim
:config
(setq default-input-method "pyim")
(setq pyim-default-scheme 'quanpin)
(pyim-isearch-mode 1)
(setq pyim-page-tooltip 'popup)
(setq pyim-page-length 9)
;; 设置 pyim 探针设置,这是 pyim 高级功能设置,可以实现 *无痛* 中英文切换速度 :-)
;; 我自己使用的中英文动态切换规则是:
;; 1. 光标只有在注释里面时,才可以输入中文。
;; 2. 光标前是汉字字符时,才能输入中文。
;; 3. 使用 M-j 快捷键,强制将光标前的拼音字符串转换为中文。
(setq-default pyim-english-input-switch-functions
'(pyim-probe-dynamic-english
pyim-probe-isearch-mode
pyim-probe-program-mode
pyim-probe-org-structure-template))
(setq-default pyim-punctuation-half-width-functions
'(pyim-probe-punctuation-line-beginning
pyim-probe-punctuation-after-punctuation))
:bind
("M-j" . pyim-convert-string-at-point))
Pyim Basedict, the default Chinese-Pyim dictionary.
(use-package pyim-basedict
:after pyim
:config (pyim-basedict-enable))
Although Tetris is part of Emacs, but there still could be some configurations.
(defvar tetris-mode-map
(make-sparse-keymap 'tetris-mode-map))
(define-key tetris-mode-map (kbd "C-p") 'tetris-rotate-prev)
(define-key tetris-mode-map (kbd "C-n") 'tetris-move-down)
(define-key tetris-mode-map (kbd "C-b") 'tetris-move-left)
(define-key tetris-mode-map (kbd "C-f") 'tetris-move-right)
(define-key tetris-mode-map (kbd "C-SPC") 'tetris-move-bottom)
(defadvice tetris-end-game (around zap-scores activate)
(save-window-excursion ad-do-it))
Speed type, a game to practice touch/speed typing in Emacs.
(use-package speed-type
:defer t)
2048 Game, an implementation of 2048 in Emacs.
(use-package 2048-game
:defer t)
Zone, a minor-mode 'zones' Emacs out, choosing one of its random modes to obfuscate the current buffer.
(use-package zone
:ensure nil
:config
;; (zone-when-idle 600) ; in seconds
(defun zone-choose (pgm)
"Choose a PGM to run for `zone'."
(interactive
(list
(completing-read
"Program: "
(mapcar 'symbol-name zone-programs))))
(let ((zone-programs (list (intern pgm))))
(zone))))