My previous Emacs configuration
Table of Contents
Below are fragments from my previous package.el
based Emacs
configuration file (~/.emacs.d/init.el
).
The newest version of this config is available from a github repo.
I recommend watching the following video by BuildFunThings called My GNU Emacs configuration for programming.
If you put this config on a new machine with no Emacs packages installed then you will be asked if you want automatically install all packages used below.
Later, if you add new packages you can temporary set
use-package-always-ensure
below to t
start Emacs and then set
it back to nil
(or always have it set to t
, if you prefer).
Note that for Emacs 25 you first need to install new ELPA signing key as described here.
Basic settings
Directory with local Emacs lisp files
I add a directory to the lisp search path where I can add my own lisp code and (now less often) downloaded lisp code which is not available through MELPA. Then I initialize secure downloading from GNU and MELPA archives of Emacs packages.
(let ((path (expand-file-name "~/.emacs.d/lisp"))) (if (file-accessible-directory-p path) (add-to-list 'load-path path t)))
Add MELPA package list
You can install many Emacs packages from MELPA
repository. To add MELPA to the package list add the following to your
~/.emacs.d/init.el
file
(require 'package) (setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") ("melpa-stb" . "https://stable.melpa.org/packages/") ("melpa" . "https://melpa.org/packages/")) tls-checktrust t tls-program '("gnutls-cli --x509cafile %t -p %p %h") gnutls-verify-error t)
This also turns on checking TLS certificates (in both possible
modes) with tls-program
set to only the first value from the
default value (for more info see Your Text Editor Is
Malware).
We use major version specific package directory (but only if the directory already exists, meaning you may be switching between more than one version of Emacs).
(let ((path (format "~/.emacs.d/elpa-%s" emacs-major-version))) (if (file-accessible-directory-p path) (setq package-user-dir path)))
Now we are ready to initialize package system.
(package-initialize) (setq use-package-always-ensure nil)
Now you can list available packages by running M-x list-packages
.
Mark packages you want to install by pressing i
and later press x
to install all marked packages (the necessary dependencies will be
installed automatically).
Now, load use-package package or propose automatic installation if it is not yet installed.
(unless (require 'use-package nil t) (if (not (yes-or-no-p (concat "Refresh packages, install use-package and" " other packages used by init file? "))) (error "you need to install use-package first") (package-refresh-contents) (package-install 'use-package) (require 'use-package) (setq use-package-always-ensure t)))
After loading use-package
we can use it to configure other
packages.
Workaround for security vulnerability in Emacs >= 21.1 and < 25.3
(eval-after-load "enriched" '(defun enriched-decode-display-prop (start end &optional param) (list start end)))
Productivity
Key discoverability
If you type a prefix key (such as C-x r
) and wait some time then
display window with keys that can follow.
(use-package which-key :config (which-key-mode))
List of personal key bindings
(global-set-key (kbd "C-c h b") 'describe-personal-keybindings) (use-package remind-bindings :bind ("H-?" . remind-bindings-togglebuffer))
More efficient buffer/file selection
(setq recentf-max-saved-items 100) (global-set-key "\C-cq" #'bury-buffer) (use-package flx :after ivy) (use-package counsel :demand :init (setq ivy-use-virtual-buffers t ivy-re-builders-alist '((counsel-git-grep . ivy--regex-plus) (counsel-rg . ivy--regex-plus) (swiper . ivy--regex-plus) (swiper-all . ivy--regex-plus) (t . ivy--regex-fuzzy))) :config (add-to-list 'ivy-ignore-buffers "\\`\\*remind-bindings\\*") (ivy-mode 1) (counsel-mode 1) :bind (("C-c E" . counsel-flycheck) ("C-c f" . counsel-fzf) ("C-c g" . counsel-git) ("C-c j" . counsel-git-grep) ("C-c L" . counsel-locate) ("C-c o" . counsel-outline) ("C-c r" . counsel-rg) ("C-c R" . counsel-register) ("C-c T" . counsel-load-theme))) (use-package ivy-rich :config (setq ivy-rich-display-transformers-list (plist-put ivy-rich-display-transformers-list 'ivy-switch-buffer '(:columns ((ivy-switch-buffer-transformer (:width 40)) (ivy-rich-switch-buffer-project (:width 15 :face success)) (ivy-rich-switch-buffer-path (:width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3)))))) :predicate (lambda (cand) (get-buffer cand))))) (ivy-rich-mode 1))
For counsel-fzf
install fzf and for
counsel-rg
install ripgrep (rg).
File explorer sidebar
(use-package treemacs :bind (("C-c t" . treemacs) ("s-a" . treemacs)))
Cycle through buffers’ history
(use-package buffer-flip :bind (("H-f" . buffer-flip) :map buffer-flip-map ("H-f" . buffer-flip-forward) ("H-F" . buffer-flip-backward) ("C-g" . buffer-flip-abort)))
Window selection enhancements
(use-package ace-window :init (setq aw-scope 'frame ; limit to single frame aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) :bind ("C-x o" . ace-window)) (use-package windmove :demand :bind (("H-w j" . windmove-down) ("H-w k" . windmove-up) ("H-w h" . windmove-left) ("H-w l" . windmove-right)) :config (windmove-default-keybindings)) (use-package windswap :demand :bind (("H-w J" . windswap-down) ("H-w K" . windswap-up) ("H-w H" . windswap-left) ("H-w L" . windswap-right)) :config (windswap-default-keybindings))
Allow for Undo/Redo of window manipulations (such as C-x 1
)
(winner-mode 1)
In buffer movement enhancements
Improved in buffer search
(use-package ctrlf :config (ctrlf-mode 1))
Type substring and wait to select one of its visible occurrences (even in other windows) with a single or two letters.
(use-package avy :bind (("H-." . avy-goto-char-timer) ("H-," . avy-goto-line)))
Bind key o
to selection of a link in help or info buffers by a
single or two letters.
(use-package ace-link :config (ace-link-setup-default))
Select from visible errors by a single letter
(use-package avy-flycheck :bind ("C-c '" . avy-flycheck-goto-error))
Go to last change in the current buffer
(use-package goto-chg :bind ("C-c G" . goto-last-change))
Editing enhancements
Context aware insertion of pairs of parenthesis
(use-package smartparens :defer)
Edit with multiple cursors
(use-package multiple-cursors :bind (("C-c n" . mc/mark-next-like-this) ("C-c p" . mc/mark-previous-like-this)))
Fix trailing spaces but only in modified lines
(use-package ws-butler :hook (prog-mode . ws-butler-mode))
Expand region
(use-package expand-region :bind ("H-e" . er/expand-region))
Spell checking
(setq ispell-dictionary "american") (defun my-american-dict () "Change dictionary to american." (interactive) (setq ispell-local-dictionary "american") (flyspell-mode 1) (flyspell-buffer)) (defun my-polish-dict () "Change dictionary to polish." (interactive) (setq ispell-local-dictionary "polish") (flyspell-mode 1) (flyspell-buffer)) (defalias 'ir #'ispell-region)
Shell and terminal
(use-package shell-pop :init (setq shell-pop-full-span t) :bind (("C-c s" . shell-pop))) (use-package vterm :defer) (use-package vterm-toggle :bind (("H-z" . vterm-toggle) ("H-F" . vterm-toggle-forward) ("H-B" . vterm-toggle-backward)))
Git
(use-package magit :bind (("C-x g" . magit-status) ("C-x M-g" . magit-dispatch))) (use-package git-commit :hook (git-commit-mode . my-american-dict)) (use-package git-messenger :bind ("C-x G" . git-messenger:popup-message) :config (setq git-messenger:show-detail t git-messenger:use-magit-popup t))
Switching buffers
Bind keys from H-r a
to H-r z
to switch to buffers from a
register from a
to z
.
(defalias 'pr #'point-to-register) (defun my-switch-to-register () "Switch to buffer given by a register named by last character of the key binding used to execute this command." (interactive) (let* ((v (this-command-keys-vector)) (c (aref v (1- (length v)))) (r (get-register c))) (if (and (markerp r) (marker-buffer r)) (switch-to-buffer (marker-buffer r)) (jump-to-register c)))) (setq my-switch-to-register-map (make-sparse-keymap)) (dolist (character (number-sequence ?a ?z)) (define-key my-switch-to-register-map (char-to-string character) #'my-switch-to-register)) (global-set-key (kbd "H-r") my-switch-to-register-map)
Yasnippet and abbrev mode
(setq-default abbrev-mode 1) (use-package yasnippet :hook (after-init . yas-global-mode) :bind (:map yas-minor-mode-map ("C-c & t" . yas-describe-tables) ("C-c & &" . org-mark-ring-goto))) (use-package yasnippet-snippets :defer) (use-package ivy-yasnippet :bind (("C-c y" . ivy-yasnippet)))
Programming languages
Common settings for programming modes
For modes using company for tab completion add
(use-package company :init (setq company-idle-delay nil ; avoid auto completion popup, use TAB ; to show it company-async-timeout 15 ; completion may be slow company-tooltip-align-annotations t) :hook (after-init . global-company-mode) :bind (:map prog-mode-map ("C-i" . company-indent-or-complete-common) ("C-M-i" . counsel-company)))
For modes that also use Language Server Protocol from lsp-mode add
(defun my-lsp-format-buffer () (if (eq major-mode 'go-mode) (lsp-format-buffer))) (defun my-lsp-organize-imports () (if (eq major-mode 'go-mode) (lsp-organize-imports))) (use-package lsp-mode :commands lsp :init (setq lsp-keymap-prefix "H-l") :config (lsp-enable-which-key-integration t) ;; reformat Go code and add missing (or remove old) imports :hook ((before-save . my-lsp-format-buffer) (before-save . my-lsp-organize-imports)) :bind (("C-c e n" . flymake-goto-next-error) ("C-c e p" . flymake-goto-prev-error) ("C-c e r" . lsp-find-references) ("C-c e R" . lsp-rename) ("C-c e i" . lsp-find-implementation) ("C-c e t" . lsp-find-type-definition))) (use-package lsp-ui :init (setq lsp-ui-doc-enable nil lsp-ui-sideline-delay 5.0) :bind (("C-c d" . lsp-ui-doc-show) ("C-c i" . lsp-ui-imenu)))
Compilation
(global-set-key "\C-ck" #'compile)
C and C++
The following needs clangd to be in
you PATH. You also need to provide compiler
flags. You may
also look at available
keybindings
(I use H-l
instead of s-l
as the prefix).
For tab completion and lsp support also add my common settings for programming modes.
(setq-default c-basic-offset 8) (defun my-c-c++-mode-hook-fn () (lsp) (lsp-headerline-breadcrumb-mode) (smartparens-mode) (local-set-key (kbd "<tab>") #'company-indent-or-complete-common)) (add-hook 'c-mode-hook #'my-c-c++-mode-hook-fn) (add-hook 'c++-mode-hook #'my-c-c++-mode-hook-fn)
Lisp and Emacs lisp
;; in emacs 25.1: M-. runs xref-find-definitions, M-, jumps back (global-set-key (kbd "C-c e l") #'find-library) (setq slime-lisp-implementations '((sbcl ("sbcl"))) slime-default-lisp 'sbcl slime-contribs '(slime-fancy)) (let ((path "/usr/local/share/doc/HyperSpec/")) (if (file-accessible-directory-p path) (setq common-lisp-hyperspec-root (concat "file://" path)))) (use-package lispy :hook (eval-expression-minibuffer-setup . lispy-mode)) (use-package paren-face :defer) (defun my-emacs-lisp-mode-hook-fn () (set (make-local-variable 'lisp-indent-function) #'lisp-indent-function) (lispy-mode 1) (local-set-key (kbd "C-c S") (global-key-binding (kbd "M-s"))) (local-set-key (kbd "C-c C-z") (lambda () (interactive) (switch-to-buffer "*scratch*"))) (local-set-key (kbd "C-M-i") #'counsel-company) (show-paren-mode 1) (paren-face-mode)) (use-package slime-company :defer) (use-package slime :demand :config (slime-setup '(slime-fancy slime-company slime-cl-indent))) (defun my-lisp-mode-hook-fn () (set (make-local-variable 'lisp-indent-function) #'common-lisp-indent-function) (lispy-mode 1) (local-set-key (kbd "C-c S") (global-key-binding (kbd "M-s"))) (show-paren-mode 1) (paren-face-mode) (set (make-local-variable 'company-backends) '(company-slime)) (company-mode) (local-set-key "\C-i" #'company-indent-or-complete-common)) (add-hook 'emacs-lisp-mode-hook #'my-emacs-lisp-mode-hook-fn) (add-hook 'lisp-mode-hook #'my-lisp-mode-hook-fn)
JavaScript
See also TypeScript section below where tide is enabled for javascript files.
(setq js-indent-level 4)
Go (golang)
gopls
supports Go modules outside of
GOPATH
(some Go tools, for example guru
does not).
I use the following setup for the go-mode in my
~/.emacs.d/init.el
. This adds syntax highlighting but without
fontifing names of called functions, autocompletion and info on
called function in mode line, auto formatting of the code on save
with adding of missing imports.
It is quite long as I define two interactive functions:
-
my-go-electric-brace
which is bind to{
key and inserts an indented pair of braces (if previous character is a space, otherwise it inserts single opening brace), -
my-godoc-package
which is bind toC-c P
key and display documentation for a package choosen from a list of installed packages.
For tab completion and lsp support also add my common settings for programming modes.
(defun my-go-electric-brace () "Insert an opening brace may be with the closing one. If there is a space before the brace also adds new line with properly indented closing brace and moves cursor to another line inserted between the braces between the braces." (interactive) (insert "{") (when (looking-back " {") (newline) (indent-according-to-mode) (save-excursion (newline) (insert "}") (indent-according-to-mode)))) (defun my-godoc-package () "Display godoc for given package (with completion)." (interactive) (godoc (ivy-read "Package: " (go-packages) :require-match t))) (use-package go-guru :after go-mode) (use-package go-mode :init (setq go-fontify-function-calls nil) ; fontifing names of called ; functions is too much for me :bind (:map go-mode-map ("C-c e g" . godoc) ("C-c P" . my-godoc-package) ("{" . my-go-electric-brace)) :hook ((go-mode . lsp) (go-mode . smartparens-mode))) ;; Go/speedbar integration (eval-after-load 'speedbar '(speedbar-add-supported-extension ".go"))
Now, in go buffers you can use M-.
to jump to the definition of
the identifier at point (use M-,
to jump back as for normal tags
in Emacs 25.1) and you can also use C-c C-d
for a short
description of the identifier at point (actually it is constantly
displayed in the mode line by enabled lsp support). You can
use C-c d
for a longer description of the identifier at point.
For this to work you have to
-
After adding above to your emacs config file see how to install from MELPA all required packages. Or just install go-mode, go-guru.
-
Install Go compiler. Under Debian you may install
golang
package (but in Debian 10 Buster it is 1.11 compared to the current 1.14, so you may consider downloading the current version of Go). Otherwise search for the package for your system or see Getting started. -
Install gopls with (but in your home directory, not inside some Go module)
$ go install golang.org/x/tools/gopls@latest
-
Install guru with
$ go get -u golang.org/x/tools/cmd/guru
-
Add your
$GOPATH/bin
to yourPATH
environment variable (or copy thegopls
andguru
executables from$GOPATH/bin
to some directory which is in yourPATH
).
See also Go, pls stop breaking my editor - GopherCon SG 2019 and Writing Go in Emacs for more info.
Old Go setup
I used the following setup for the go-mode in my ~/.emacs.d/init.el
. This
adds syntax highlighting but without fontifing names of called
functions, autocompletion and eldoc support, auto formatting of the
code on save with adding of missing imports (goimports).
It is quite long as I define two interactive functions:
-
my-go-electric-brace
which is bind to{
key and inserts an indented pair of braces (if previous character is a space, otherwise it inserts single opening brace), -
my-godoc-package
which is bind toC-c P
key and display documentation for a package choosen from a list of installed packages.
(defun my-go-electric-brace () "Insert an opening brace may be with the closing one. If there is a space before the brace also adds new line with properly indented closing brace and moves cursor to another line inserted between the braces between the braces." (interactive) (insert "{") (when (looking-back " {") (newline) (indent-according-to-mode) (save-excursion (newline) (insert "}") (indent-according-to-mode)))) (defun my-godoc-package () "Display godoc for given package (with completion)." (interactive) (godoc (ivy-read "Package: " (go-packages) :require-match t))) (use-package flycheck :defer) (use-package go-eldoc :defer) (use-package company-go :defer) (use-package go-guru :after go-mode) (use-package go-mode :init (setq gofmt-command "goimports" ; use goimports instead of gofmt go-fontify-function-calls nil ; fontifing names of called ; functions is too much for me company-idle-delay nil) ; avoid auto completion popup, use TAB ; to show it :bind (:map go-mode-map ("M-." . go-guru-definition) ("C-c d" . godoc-at-point) ("C-c g" . godoc) ("C-c h" . go-guru-hl-identifier) ("C-c P" . my-godoc-package) ("{" . my-go-electric-brace) ("C-i" . company-indent-or-complete-common) ("C-M-i" . company-indent-or-complete-common)) :config ;; run gofmt/goimports when saving the file (add-hook 'before-save-hook #'gofmt-before-save) (defun my-go-mode-hook-fn () (go-eldoc-setup) (set (make-local-variable 'company-backends) '(company-go)) (company-mode) (smartparens-mode 1) (flycheck-mode 1) (setq imenu-generic-expression '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) ("func" "^func *\\(.*\\) {" 1)))) (add-hook 'go-mode-hook #'my-go-mode-hook-fn)) ;; Go/speedbar integration (eval-after-load 'speedbar '(speedbar-add-supported-extension ".go"))
Now, in go buffers you can use M-.
to jump to the definition of
the identifier at point (use M-,
to jump back as for normal tags
in Emacs 25.1) and you can also use C-c C-d
for a short
description of the identifier at point (actually it is constantly
displayed in the mode line by enabled Go eldoc support). You can
use C-c d
for a longer description of the identifier at point.
For this to work you have to
-
Install from MELPA the following Emacs packages: go-mode, company-go, go-eldoc, and go-guru.
-
Install Go compiler. Under Debian you may install
golang
package (but in Debian 10 Buster it is 1.11 compared to the current 1.14, so you may consider downloading the current version of Go). Otherwise search for the package for your system or see Getting started. -
Install godef with
$ go get github.com/rogpeppe/godef
-
Install goimports which can be installed from Debian package
golang-go.tools
or with$ go get golang.org/x/tools/cmd/goimports
-
Install gocode (a fork with Go modules support) which can be installed with
$ go get -u github.com/stamblerre/gocode
-
Install guru with
$ go get golang.org/x/tools/cmd/guru
-
Add your
$GOPATH/bin
to yourPATH
environment variable (or copy thegodef
,goimports
,gocode
, andguru
executables from$GOPATH/bin
to some directory which is in yourPATH
).
See also Writing Go in Emacs for more info.
D (Dlang)
Install dcd and
dtools (for rdmd
)
either by following instructions on previous two links or on Arch
Linux you can also run
$ sudo pacman -S dcd dtools
And install serve-d (but check the link for newer version) with
$ dub fetch serve-d@0.7.0-beta.5 $ dub run serve-d --build=release
For tab completion and lsp support also add my common settings for programming modes.
(use-package lsp-mode :commands lsp :config (add-to-list 'lsp-language-id-configuration '(vala-mode . "D")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("serve-d")) :major-modes '(d-mode) :server-id 'serve-d))) (defun my-d-mode-hook-fn () (setq c-basic-offset 4 indent-tabs-mode nil) (company-mode 1) (local-set-key "\C-i" #'company-indent-or-complete-common) (lsp 1)) (use-package d-mode :hook (d-mode . my-d-mode-hook-fn))
Python
Install pylsp.
(use-package python :hook (python-mode . lsp))
Rust
If you have Emacs 26 than you need Rustup and using Rustup you
should install components rls
and rust-src
with the command
$ rustup component add rls rust-src
For tab completion and lsp support add my common settings for programming modes and then add
(when (>= emacs-major-version 26) (defun my-rustic-mode-hook-fn () "needed for lsp-format-buffer to indent with 4 spaces" (setq tab-width 4 indent-tabs-mode nil)) (use-package rustic :init ;; to use rustic-mode even if rust-mode also installed (setq auto-mode-alist (delete '("\\.rs\\'" . rust-mode) auto-mode-alist)) :hook (rustic-mode . my-rustic-mode-hook-fn)))
But if you have Emacs older than 26 than you should install
Rustup and racer and with
Rustup install component rust-src
with the command
$ rustup component add rust-src
for tab completion add my common settings for programming modes and then add
(when (< emacs-major-version 26) (use-package cargo :defer) (use-package racer :defer) (use-package rust-mode :init (setq rust-format-on-save t) :hook ((rust-mode . company-mode) (rust-mode . cargo-minor-mode) (rust-mode . racer-mode) (rust-mode . eldoc-mode))))
Meson build system
(use-package meson-mode :defer :init (setq meson-indent-basic 4))
To use cmake-ide
with Meson build system
see.
Vala
You need to install vala-language-server.
For tab completion and lsp support also add my common settings for programming modes.
(use-package lsp-mode :commands lsp :config (add-to-list 'lsp-language-id-configuration '(vala-mode . "vala")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("vala-language-server")) :major-modes '(vala-mode) :server-id 'vala-ls))) (defun my-vala-mode-hook-fn () (setq c-basic-offset 4 tab-width 8 indent-tabs-mode nil) (company-mode 1) (local-set-key "\C-i" #'company-indent-or-complete-common) (lsp 1)) (use-package vala-mode :hook (vala-mode . my-vala-mode-hook-fn))
Dart
NOTE: pub
and dart
must be in PATH
for lsp to start in
dart-mode.
For tab completion and lsp support also add my common settings for programming modes.
(use-package dart-mode :init (setq lsp-dart-analysis-sdk-dir "~/local/flutter/bin/cache/dart-sdk/") :hook ((dart-mode . smartparens-mode) (dart-mode . lsp))) (use-package flutter :after dart-mode :init (setq flutter-sdk-path "~/local/flutter/") :bind (:map dart-mode-map ("C-M-x" . #'flutter-run-or-hot-reload)))
PHP
For fully functional PHP support apart from below code block you also need the content of web-mode section below.
(use-package php-mode :defer) (use-package company-php :defer) (defun my-php-mode-hook-fn() (when (require 'company-php nil t) (set (make-local-variable 'company-backends) '(company-ac-php-backend)) (company-mode t) (local-set-key (kbd "M-.") #'ac-php-find-symbol-at-point))) (add-hook 'php-mode-hook #'my-php-mode-hook-fn)
TypeScript
For fully functional TypeScript support apart from below code block you also need the content of web-mode section below.
Your should have tsconfig.json file in the root of your project.
(defun my-setup-tide-mode () (interactive) (tide-setup) (flycheck-mode 1) (setq flycheck-check-syntax-automatically '(save mode-enabled)) (eldoc-mode 1) (tide-hl-identifier-mode +1) (company-mode 1)) (defun my-tide-jump-to-type-definiton () (interactive) (tide-jump-to-definition 1)) (use-package tide :after (:any js typescript-mode) :bind (:map tide-mode-map ("C-c e n" . flycheck-next-error) ("C-c e p" . flycheck-prev-error) ("C-c e L" . tide-project-errors) ("C-c e r" . tide-references) ("C-c e R" . tide-rename-symbol) ("C-c e i" . tide-jump-to-implementation) ("C-c e t" . my-tide-jump-to-type-definiton)) :hook ((before-save . tide-format-before-save) (typescript-mode . my-setup-tide-mode) (js-mode . my-setup-tide-mode))) (use-package ng2-mode :defer)
Other modes
Web mode
For tab completion support also add first code block with
use-package company
from my common settings for programming
modes (the second code block with use-package lsp
is not
required for Web mode).
(defun my-web-mode-hook-fn () (cond ((string= web-mode-engine "php") (my-php-mode-hook-fn)) ((string-match-p "^[jt]sx$" (file-name-extension (or (buffer-file-name) ""))) (my-setup-tide-mode)))) (use-package web-mode :mode "\\.\\(jsx\\|php\\|tsx\\)\\'" :init (add-hook 'web-mode-hook #'my-web-mode-hook-fn))
CSS
(use-package rainbow-mode :hook (css-mode . rainbow-mode))
Org mode
(use-package org :init (setq org-default-notes-file "~/org/notes.org" org-highlight-latex-and-related '(latex) org-hide-leading-stars t org-ellipsis "…" org-catch-invisible-edits 'smart gnuplot-program "pyxplot") (defun my-org-timer-done () (shell-command "echo Timer timed out; date &")) :bind (("C-c A" . org-agenda) ("C-c B" . org-switchb) ("C-c c" . org-capture) ("C-c l" . org-store-link)) :hook ((org-timer-done . my-org-timer-done)) :config (require 'ox-beamer))
Search engines
(use-package engine-mode :config (engine-mode t) (defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "d") (defengine google "http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s" :keybinding "g"))
WWW browsers
(setq my-browsers '(("Firefox" . browse-url-firefox) ("Chromium" . browse-url-chromium) ("EWW" . eww-browse-url))) (defun my-browse-url (&rest args) "Select the prefered browser from a menu before opening the URL." (interactive) (let ((browser (ivy-read "WWW browser: " my-browsers :require-match t))) (apply (cdr (assoc browser my-browsers)) args))) (setq browse-url-browser-function #'my-browse-url) (defun my-eww-scale-adjust () "Slightly bigger font but text shorter than text." (interactive) (text-scale-adjust 0) (text-scale-adjust 1) (eww-toggle-fonts) (split-window-right) (eww-toggle-fonts) (other-window 1) (sleep-for 1) (delete-window))
(use-package notmuch :defer :init (setq notmuch-search-oldest-first nil))
API documentation
(when (require 'devdocs-lookup nil t) (devdocs-setup))
Appearance and custom file
Minimalistic look
(setq inhibit-startup-screen t frame-title-format "%b" ediff-window-setup-function #'ediff-setup-windows-plain) (add-to-list 'global-mode-string `(t (,(user-login-name) "@" system-name " ")) t) (set-scroll-bar-mode 'right) (menu-bar-mode 0) (tool-bar-mode 0) (scroll-bar-mode 0)
Easy switching between some fonts
(setq my-font-list '("Fantasque Sans Mono" "Fira Code Light" "Go mono" "IBM 3270" "Inconsolata" "Iosevka Light" "Iosevka Slab Light" "Monofur" "Monoid" "mononoki")) (defun my-set-frame-font (font-name size &optional frames) "Set font to one of the fonts from `my-font-list' Argument FRAMES has the same meaning as for `set-frame-font'" (interactive (list (ivy-read "Font name: " my-font-list) (read-number "Font size: "))) (set-frame-font (format "%s:pixelsize=%d:antialias=true:autohint=true" font-name size) nil frames)) (global-set-key (kbd "C-c F") #'my-set-frame-font)
Toggle between dark and light themes with a key
Toggle between my own dark and light
themes if available in
~/.emacs.d/lupan-themes
otherwise falls back to another themes.
(let ((path (expand-file-name "~/.emacs.d/lupan-themes"))) (when (file-accessible-directory-p path) (add-to-list 'load-path path t))) (defun my-preferred-theme (themes) (let ((theme (car themes))) (cond ((symbolp theme) theme) ((require (car theme) nil t) (cdr theme)) ((cdr themes) (my-select-theme (cdr themes)))))) (setq my-dark-theme (my-preferred-theme '((undersea-theme . undersea) (lupan-themes . lupan-dark) (apropospriate-theme . apropospriate-dark) deeper-blue)) my-light-theme (my-preferred-theme '((cloud-theme . cloud) (lupan-themes . lupan-light) (apropospriate-theme . apropospriate-light) adwaita))) (defun my-select-theme (theme) (mapc #'disable-theme custom-enabled-themes) (load-theme (cond ((eq theme 'dark) my-dark-theme) ((eq theme 'light) my-light-theme) (t theme)) t)) (defun my-toggle-theme () "Toggle between dark and light themes" (interactive) (my-select-theme (if (custom-theme-enabled-p my-dark-theme) my-light-theme my-dark-theme))) (global-set-key (kbd "C-S-<f6>") #'my-toggle-theme) (use-package apropospriate-theme :defer) (if (or (require 'lupan-themes nil t) (require 'apropospriate-theme nil t)) (my-toggle-theme)) (defun my-frame-setup-fn (&optional frame) (unless (display-graphic-p frame) (set-face-background 'default "unspecified-bg" (or frame (selected-frame))))) (add-hook 'after-make-frame-functions #'my-frame-setup-fn) (add-hook 'window-setup-hook #'my-frame-setup-fn)
Hyper bindings
(dolist (k '(("H-1" . "C-x 1") ("H-2" . "C-x 2") ("H-3" . "C-x 3") ("H-0" . "C-x 0") ("H-b" . "C-x b") ("H-g" . "C-x g") ("H-k" . "C-x k") ("H-o" . "C-x o"))) (global-set-key (kbd (car k)) (lookup-key (current-global-map) (kbd (cdr k)))))
Use separate custom file
(setq custom-file "~/.emacs.d/custom.el") (if (file-exists-p custom-file) (load custom-file))