Add lexical-binding cookie to early-init.el
;; -*- lexical-binding: t; -*-Add lexical-binding cookie to init.el
;; -*- lexical-binding: t; -*-Make startup faster by reducing the frequency of garbage collection.
(setq gc-cons-threshold-original gc-cons-threshold
gc-cons-percentage-original gc-cons-percentage)
(setq gc-cons-threshold most-positive-fixnum
gc-cons-percentage 1.0)After Emacs startup has been completed, set `gc-cons-threshold’ and `gc-cons-percentage’ to their original values.
(add-hook
'emacs-startup-hook
#'(lambda ()
(setq gc-cons-threshold gc-cons-threshold-original
gc-cons-percentage gc-cons-percentage-original)
(makunbound 'gc-cons-threshold-original)
(makunbound 'gc-cons-percentage-original)))Increase the amount of data which Emacs reads from a sub-process in one read operation.
(setq read-process-output-max (* 1024 1024))(dolist (mode
'(menu-bar-mode
tool-bar-mode
scroll-bar-mode
tooltip-mode))
(when (fboundp mode)
(funcall mode -1)))(setq default-frame-alist
'((fullscreen . maximized)
(vertical-scroll-bars . nil)
(horizontal-scroll-bars . nil)))(setq-default inhibit-startup-screen t)(setq ring-bell-function 'ignore)(load-theme 'modus-operandi t)(add-to-list
'default-frame-alist
'(font . "Monaco 12"))Add melpo to the list of package archives.
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize);; Enable it for all programming major modes
(add-hook 'prog-mode-hook #'hl-line-mode)
;; and for all modes derived from text-mode
(add-hook 'text-mode-hook #'hl-line-mode)(add-hook 'before-save-hook 'delete-trailing-whitespace)(electric-pair-mode 1)(global-set-key (kbd "C-c d") 'duplicate-dwim)(show-paren-mode 1)(setq-default require-final-newline t)Remap ‘comment-line key to ‘C-x C-' because the default ‘C-;’ is not recognized by some terminals.
(global-unset-key (kbd "C-x C-;"))
(global-set-key (kbd "C-x C-\\") 'comment-line)(setq scroll-margin 0 ;; Default
scroll-step 1
scroll-conservatively 10000
scroll-preserve-screen-position 1)(global-set-key
(kbd "C-c s")
(lambda ()
"Open Emacs configuration"
(interactive)
(find-file
(expand-file-name
"readme.org"
user-emacs-directory))))(global-auto-revert-mode t)(setopt use-short-answers t)(save-place-mode 1)(global-set-key (kbd "C-x C-b") 'ibuffer)Bind the keyboard shortcut ‘M-o’ to the `other-window` function for easier switching between windows.
(global-set-key (kbd "M-o") 'other-window)Enable windmove default keybindings so you can use the ‘S-<arrow>’ keyboard shortcuts to switch between windows.
(windmove-default-keybindings)Display the key bindings following your currently entered incomplete command (a prefix) in a popup.
(which-key-mode)(savehist-mode 1)(recentf-mode 1)`completion-at-point’ is often bound to M-TAB.
(setq tab-always-indent 'complete)(setopt text-mode-ispell-word-completion nil)Hide commands in M-x which do not apply to the current mode. Corfu commands are hidden, since they are not used via M-x. This setting is useful beyond Corfu.
(setq read-extended-command-predicate #'command-completion-default-include-p)When running in compilation-mode:
- Scroll the output
- Jump to the first error
- Don’t hide output of long lines
- Display ANSI colors
(use-package compile
:custom
(compilation-scroll-output t)
(compilation-max-output-line-length nil)
:hook
(compilation-filter . ansi-color-compilation-filter))Store all backup and autosave files in the ‘backups’ dir.
(setq auto-save-list-file-prefix nil)
(setq backup-directory-alist
`(("." . ,(expand-file-name
"backups"
user-emacs-directory))))Use version contral and keep multiple backup files.
(setq backup-by-copying t
delete-old-versions t
kept-new-versions 10
kept-old-versions 0
version-control t
vc-make-backup-files t)Move lines added by the customize system to a seperate file. Config changes made through the customize UI will be stored here.
(setq custom-file
(expand-file-name
"custom.el"
user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file))Decode the headers and payload of a JWT token.
(use-package jwt-content
:vc (:url "https://github.com/igroen/jwt-content"
:rev :newest))(use-package dired
:config
;; Require dired-x for `dired-omit-mode'
(use-package dired-x)
;; Omit files starting with a dot
(setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))
;; Default omit files
(setq-default dired-omit-mode t)
;; Make dired open in the same window when using RET or ^
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
(define-key dired-mode-map (kbd "^")
(lambda () (interactive) (find-alternate-file "..")))
(put 'dired-find-alternate-file 'disabled nil))(use-package drag-stuff
:ensure t
:bind (("M-p" . drag-stuff-up)
("M-n" . drag-stuff-down))
:config (drag-stuff-global-mode 1))(use-package eat
:ensure t
:hook
(eshell-load . eat-eshell-mode)
:custom
(eat-kill-buffer-on-exit t))Make GUI Emacs use the proper $PATH and avoid a common setup issue on MacOS. Without this package packages such as flycheck and EPA are not working correctly.
(use-package exec-path-from-shell
:ensure t
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))(use-package expand-region
:ensure t
:bind ("C-=" . er/expand-region))(use-package magit
:ensure t
:bind ("C-x g" . magit-status)
:hook (after-save-hook . magit-after-save-refresh-status))
(use-package git-timemachine
:ensure t
:commands git-timemachine)
(use-package diff-hl
:ensure t
:hook ((magit-post-refresh . diff-hl-magit-post-refresh)
(dired-mode . diff-hl-dired-mode-unless-remote))
:init
(global-diff-hl-mode)
:config
(diff-hl-margin-mode)
(diff-hl-flydiff-mode))(use-package epa
:config
;; Prefer armored ASCII (.asc)
(setq epa-armor t)
;; Open .asc files in the same way as .gpg files
(setq epa-file-name-regexp "\\.\\(gpg\\|asc\\)$")
(epa-file-name-regexp-update)
;; Prompt for the password in the minibuffer
(setq epg-pinentry-mode 'loopback))Edit multiple occurrences of some text simultaneously.
(use-package iedit
:ensure t
:bind
("C-;" . iedit-mode))Minibuffer completion UI.
(use-package vertico
:ensure t
:custom
(file-name-shadow-properties
'(invisible t intangible t))
(file-name-shadow-tty-properties
'(invisible t intangible t))
(vertico-cycle t)
(vertico-resize nil)
:config
(file-name-shadow-mode 1)
(vertico-mode 1))Completion style for matching regexps in any order.
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles partial-completion)))))Consult provides search and navigation commands centered around completion.
(use-package consult
:ensure t
:custom
(xref-show-xrefs-function #'consult-xref)
(xref-show-definitions-function #'consult-xref)
:bind (("M-s M-g" . consult-grep)
("M-s M-r" . consult-ripgrep)
("M-s M-f" . consult-find)
("M-s M-d" . consult-fd)
("M-s M-o" . consult-outline)
([remap isearch-forward] . consult-line)
([remap isearch-backward] . consult-line)
([remap switch-to-buffer] . consult-buffer)
([remap yank-pop] . consult-yank-pop)))Marginalia provides annotations for completion candidates, which can be seen in the minibuffer or the completions buffer.
(use-package marginalia
:ensure t
:config
(marginalia-mode 1))Conveniently act on minibuffer completions.
(use-package embark
:ensure t
:bind (("C-." . embark-act)
:map minibuffer-local-map
("C-c C-c" . embark-collect)
("C-c C-e" . embark-export)))This package is the glue that ties together `embark’ and `consult’.
(use-package embark-consult
:ensure t)Edit a grep buffer and apply those changes to the file buffer.
(use-package wgrep
:ensure t
:bind (:map grep-mode-map
("e" . wgrep-change-to-wgrep-mode)
("C-x C-q" . wgrep-change-to-wgrep-mode)
("C-c C-c" . wgrep-finish-edit)))Corfu is an in-buffer completion popup UI built on child frames.
(use-package corfu
:ensure t
:custom
(corfu-auto t)
(corfu-auto-prefix 2)
(corfu-cycle t)
(corfu-quit-at-boundary nil)
(corfu-quit-no-match t)
(corfu-on-exact-match 'quit)
:config
(global-corfu-mode))Make Corfu work in the terminal.
(use-package corfu-terminal
:ensure t
:config
(unless (display-graphic-p)
(corfu-terminal-mode +1)))Cape is a collection of completion-at-point functions (Capfs), which serve as completion sources for Corfu or the Emacs in-buffer completion system.
(use-package cape
:ensure t
:bind ("C-c p" . cape-prefix-map)
:init
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-elisp-block))(use-package mood-line
:ensure t
:config
(mood-line-mode)
:custom
(mood-line-glyph-alist mood-line-glyphs-fira-code))(use-package org
:hook ((org-mode . visual-line-mode)
(org-mode . org-indent-mode))
:config
(setq org-babel-python-command "python3")
;; Add languages for `SRC` code blocks in org-mode
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(python . t))))Enable xclip-mode to use the system clipboard when killing/yanking. Install xclip on Linux for this to work. On OSX pbcopy/pbpaste will be used.
(use-package xclip
:ensure t
:config (xclip-mode t))Enable Eglot Language Server Protocol support.
The eglot configuration format can be found here: https://joaotavora.github.io/eglot/#Project_002dspecific-configuration-1
The pylsp configuration to setup flake8 here: https://github.com/python-lsp/python-lsp-server#configuration
(use-package eglot
:hook ((python-mode . eglot-ensure)
(c-mode . eglot-ensure)
(c++-mode . eglot-ensure))
:bind (:map eglot-mode-map
("C-c l f" . eglot-format)
("C-c l r" . eglot-reconnect)))(use-package pyvenv
:ensure t
:commands pyvenv-activate
:config
(pyvenv-mode t))The treesitter YAML language grammar can be installed from https://github.com/tree-sitter-grammars/tree-sitter-yaml by doing “M-x treesit-install-language-grammar”.
(add-to-list 'auto-mode-alist '("\\.ya?ml\\'" . yaml-ts-mode))(defun my/delete-current-file-copy-to-kill-ring ()
"Delete current buffer/file and close the buffer, push content to `kill-ring'."
(interactive)
(progn
(kill-new (buffer-string))
(message "Buffer content copied to kill-ring.")
(when (buffer-file-name)
(when (file-exists-p (buffer-file-name))
(progn
(delete-file (buffer-file-name))
(message "Deleted file: 「%s」." (buffer-file-name)))))
(let ((buffer-offer-save nil))
(set-buffer-modified-p nil)
(kill-buffer (current-buffer)))))
(global-set-key (kbd "C-c k") 'my/delete-current-file-copy-to-kill-ring)Move point back to indentation or 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.
(defun my/move-beginning-of-line (arg)
(interactive "^p")
(setq arg (or arg 1))
(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 `my/move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
'my/move-beginning-of-line)Load local configuration from local.el or local.elc in `user-emacs-directory`.
(load
(expand-file-name
"local"
user-emacs-directory)
'noerror)When opening this file for the first time the following warning is shown: “The local variables list in init.org contains values that may not be safe (*)”.
- Press ‘y’ to continue.
- Run `org-babel-tangle’ (C-c C-v t) to generate an early-init.el and init.el file.
- Restart emacs or load the generated files.
- The next time this warning is shown press ‘!’ to prevent future warnings.