This emacs configuration is mixed together from various configurations, mainly from
- UncleDavesEmacs repository;
- Sacha~Chua’s page;
- Emacs From Scratch;
I highly recommend you to check out these sources.
Run git clone https://github.com/tsipenyuk/.emacs.d ~/.emacs.d .
Don’t forget to back up your own ~/.emacs and your ~/.emacs.d
prior to cloning this configuration. For the first startup, it may be
reasonable to launch emacs in the tty.
Preliminary setup (loading repositories, swap C-x and C-t) is
performed in init.el.
Non-melpa packages are stored in lisp and site-lisp. I load the
file custom.el manually, but I think it is considered bad practice.
I have it because I could not overwrite some settings of the auctex
package otherwise; I intend to remove it in the future.
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
(add-to-list 'load-path (expand-file-name "site-lisp" user-emacs-directory))
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file t)
(setq user-full-name "Arseniy Tsipenyuk"
user-mail-address "arseniy.tsipenyuk@gmail.com")To enable a mode, change -1 to 1.
(setq inhibit-startup-message t)
(scroll-bar-mode -1) ; Disable visible scrollbar
(tool-bar-mode -1) ; Disable the toolbar
(tooltip-mode -1) ; Disable tooltips
(set-fringe-mode 10) ; Give some breathing room
(menu-bar-mode -1) ; Disable the menu bar
;;(setq visible-bell t) ; flashes screen on 'ding'
(setq ring-bell-function 'ignore) ; do nothing on 'ding'
(defalias 'yes-or-no-p 'y-or-n-p)
;; highlight current line in programming modes
(when window-system (add-hook 'prog-mode-hook 'hl-line-mode))(Copied from this superuser thread and tested only on Mac OS.)
;; F12 = Full Screen
(defun toggle-fullscreen (&optional f)
(interactive)
(let ((current-value (frame-parameter nil 'fullscreen)))
(set-frame-parameter nil 'fullscreen
(if (equal 'fullboth current-value)
(if (boundp 'old-fullscreen) old-fullscreen nil)
(progn (setq old-fullscreen current-value)
'fullboth)))))
(global-set-key [f12] 'toggle-fullscreen)I’m a big fan of solarized minus the font-size changes.
(use-package solarized-theme
:init
;; Avoid all font-size changes
(setq solarized-height-minus-1 1.0)
(setq solarized-height-plus-1 1.0)
(setq solarized-height-plus-2 1.0)
(setq solarized-height-plus-3 1.0)
(setq solarized-height-plus-4 1.0)
;; font famili and size; I also like "Ubuntu Mono 19"
(set-face-attribute 'default nil :font "Fira Code 19")
(set-face-attribute 'fixed-pitch nil :font "Fira Code 19" )
(set-face-attribute 'variable-pitch nil :font "Fira Code 19" )
(set-frame-font "Fira Code 19" nil t))
;;
(load-theme 'solarized-light t)These custom functions toggle between the light and the dark theme:
(defun light ()
"Activate a light color theme."
(interactive)
(load-theme 'solarized-light))
(defun dark ()
"Activate a dark color theme."
(interactive)
(load-theme 'solarized-dark));; (use-package fira-code-mode
;; :custom (fira-code-mode-disabled-ligatures '(":"))
;; :hook prog-mode)
;; ligatures you don't want mode to enable fira-code-mode in
;; :custom (fira-code-mode-disabled-ligatures '("[]" "x")) As of yet, they are disabled as in the UncleDavesEmacs. I
recall a post by S.Chua describing how to create a separate
backup folder and intend to implement it in the future.
Change the values below from nil to t to turn on backups.
(setq make-backup-files nil)
(setq auto-save-default nil)(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8) (use-package general
:config
(general-create-definer rune/leader-keys
:keymaps '(normal insert visual emacs)
:prefix "SPC"
:global-prefix "C-SPC")
(rune/leader-keys
"t" '(:ignore t :which-key "toggles")
"tt" '(counsel-load-theme :which-key "choose theme")))
(general-define-key
"C-h C-k" 'free-keys
"C-!" 'rgrep
"C-c m" 'magit
"C-$" 'term-paste)(global-set-key (kbd "<escape>") 'keyboard-escape-quit)Useful to define key binding to some free key
(use-package free-keys)Quickly edit ~/.emacs.d/config.org
(defun config-visit ()
(interactive)
(find-file "~/.emacs.d/config.org"))
(global-set-key (kbd "C-c e") 'config-visit)You can also manually invoke config-reload.
(defun config-reload ()
"Reloads ~/.emacs.d/config.org at runtime"
(interactive)
(org-babel-load-file (expand-file-name "~/.emacs.d/config.org")))
(global-set-key (kbd "C-c d") 'config-reload)(use-package all-the-icons)Recognizes directories with a .git directory as projects and helps
you manage them accordingly.
;; Enable projectile globally
(use-package projectile
:init
(projectile-mode 1))
;; let projectile call make
(global-set-key (kbd "<f5>") 'projectile-compile-project)Startup screen.
(use-package dashboard
:config
(dashboard-setup-startup-hook)
(setq dashboard-startup-banner "~/.emacs.d/img/dashLogo.png")
(setq dashboard-items '((recents . 15)
(projects . 5)))
(setq dashboard-banner-logo-title "Hello there!"))
;; Setup random footer messages
;; http://ergoemacs.org/emacs/elisp_read_file_content.html
(defun read-lines (filePath)
"Return a list of lines of a file at filePath."
(with-temp-buffer
(insert-file-contents filePath)
(split-string (buffer-string) "\n" t)))
;; footer messages are loaded from here
(setq dashboard-footer-messages (read-lines "~/.emacs.d/dashboard-quotes.txt"))Emacs From Scratch / 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.
NOTE: The first time you load your configuration on a new machine, you’ll need to run `M-x all-the-icons-install-fonts` so that mode line icons display correctly.
;; (use-package all-the-icons)
;;
;; (use-package doom-modeline
;; :init (doom-modeline-mode 1)
;; :custom ((doom-modeline-height 15)))UncleDavesEmacs / spaceline
(use-package spaceline
:config
(require 'spaceline-config)
(setq spaceline-buffer-encoding-abbrev-p nil)
(setq spaceline-line-column-p t)
(setq spaceline-line-p t)
(setq powerline-default-separator (quote arrow))
(spaceline-spacemacs-theme))
;; disable separator
(setq powerline-default-separator nil)Hide/abbreviate the mode line displays of minor-modes.
(use-package diminish
:init
(diminish 'which-key-mode)
(diminish 'linum-relative-mode)
(diminish 'hungry-delete-mode)
(diminish 'visual-line-mode)
(diminish 'subword-mode)
(diminish 'beacon-mode)
(diminish 'irony-mode)
(diminish 'page-break-lines-mode)
(diminish 'auto-revert-mode)
(diminish 'rainbow-delimiters-mode)
(diminish 'rainbow-mode)
(diminish 'yas-minor-mode)
(diminish 'flycheck-mode)
(diminish 'helm-mode))(column-number-mode)
;;(global-display-line-numbers-mode nil)
;; Disable line numbers for some modes
(dolist (mode '(org-mode-hook
term-mode-hook
shell-mode-hook
treemacs-mode-hook
eshell-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))A package called fancy-battery will be used if we are in GUI emacs, otherwise the built in battery-mode will be used.
Fancy battery has very odd colors if used in the tty, hence us disabling it.
(use-package fancy-battery
:config
(setq fancy-battery-show-percentage t)
(setq battery-update-interval 15)
(if window-system
(fancy-battery-mode)
(display-battery-mode)))A small system monitor that can be enabled or disabled at runtime,
useful for checking performance with power-hungry processes in
ansi-term.
symon can be toggled on and off with Super + h.
(use-package symon
:bind
("s-h" . symon-mode))After you start the input of a command and stop, pondering what key must follow, it will automatically open a non-intrusive buffer at the bottom of the screen offering you suggestions for completing the command.
(use-package which-key
:config
(which-key-mode))Ivy is an excellent completion framework for Emacs. It provides a minimal yet powerful selection menu that appears when you open files, switch buffers, and for many other tasks in Emacs. Counsel is a customized set of commands to replace `find-file` with `counsel-find-file`, etc which provide useful commands for each of the default completion commands.
ivy-rich adds extra columns to a few of the Counsel commands to provide more information about each item.
(use-package ivy
:diminish
:bind (("C-s" . swiper)
("C-x C-n" . newline)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-j" . ivy-alt-done)
("C-n" . ivy-next-line)
("C-p" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1)
:custom
(company-minimum-prefix-length 3))
(use-package ivy-rich
:init
(ivy-rich-mode 1))
(define-key ivy-mode-map (kbd "C-o") nil)
(use-package counsel
:bind (("C-M-t" . 'counsel-switch-buffer)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history))
:config
(counsel-mode 1))
According to UncleDavesEmacs, this little bit of code makes
scrolling with emacs a lot nicer.
(setq scroll-conservatively 100)Helpful adds a lot of very helpful (get it?) 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.
(use-package helpful
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
This is an example of using Hydra to design a transient key binding for quickly adjusting the scale of the text on screen. We define a hydra that is bound to C-s t s and, once activated, j and k increase and decrease the text scale. You can press any other key (or f specifically) to exit the transient key map.
;;
;; (use-package hydra)
;;
;; (defhydra hydra-text-scale (:timeout 4)
;; "scale text"
;; ("j" text-scale-increase "in")
;; ("k" text-scale-decrease "out")
;; ("f" nil "finished" :exit t))
;;
;; (rune/leader-keys
;; "ts" '(hydra-text-scale/body :which-key "scale text"))
;;By default, after you split a window, your focus remains in the previous one.
The following functions adjust this behaviour.
(defun split-and-follow-horizontally ()
(interactive)
(split-window-below)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 2") 'split-and-follow-horizontally)
(defun split-and-follow-vertically ()
(interactive)
(split-window-right)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 3") 'split-and-follow-vertically)Launch your shell of choice using s-return.
Problem: it is not possible to navigate out of
terminal using switch-window from below.
Maybe I will stick with eshell instead.
(defvar my-term-shell "/bin/zsh")
(defadvice ansi-term (before force-bash)
(interactive (list my-term-shell)))
(ad-activate 'ansi-term)
(global-set-key (kbd "<s-return>") 'ansi-term)(use-package exec-path-from-shell
:defer t)
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize))
;; used to have this instead:
;;(add-to-list 'exec-path "~/.local/bin")Provides easy navigation between multiple panes.
An alternative is ace-window, however by default it also changes the
behaviour of C-x o even if only 2 windows are open.
I have experienced some clashes between ace-window and exwm for
an unknown reason, so I opted for switch-window.
(use-package ace-window
:config
(setq aw-background nil)
(setq aw-keys
'(?h ?t ?n ?s ?a ?o ?e ?u ?i))) ;; programmer dvorak keys
(general-define-key (kbd "C-o") 'ace-window)Doing C-x k should kill the current buffer at all times, we
have ibuffer for more sophisticated thing.
(defun kill-current-buffer ()
"Kills the current buffer."
(interactive)
(kill-buffer (current-buffer)))
(global-set-key (kbd "C-x k") 'kill-current-buffer)Unless you have the muscle memory, UncleDavesEmacs recommends
omitting this bit, as you may lose progress for no reason when
working.
(setq kill-buffer-query-functions (delq 'process-kill-buffer-query-function kill-buffer-query-functions))(global-set-key (kbd "C-x C-b") 'ibuffer)This can be invoked using C-M-s-k. This keybinding makes sure
you don’t hit it unless you really want to.
(defun close-all-buffers ()
"Kill all buffers without regard for their origin."
(interactive)
(mapc 'kill-buffer (buffer-list)))
(global-set-key (kbd "C-M-s-k") 'close-all-buffers)Couldn’t quite get into helm. Maybe some time in the future.
;;(setq ido-enable-flex-matching t)
;;(setq ido-everywhere t)
;;(ido-mode 1)
;;
;;(use-package idomenu)
;;(global-set-key (kbd "C-;") 'idomenu)Efficient navigation in the visible portion of the current buffer.
As you invoke one of avy’s functions, you will be prompted for a character that you’d like to jump to in the visible portion of the current buffer. Afterwards you will notice how all instances of said character have additional letter on top of them. Pressing those letters, that are next to your desired character will move your cursor over there. Admittedly, this sounds overly complicated and complex, but in reality takes a split second and improves your life tremendously.
I like M-s for it, same as C-s is for moving by searching
string, now M-s is moving by searching characters.
(use-package avy
:bind
("M-s" . avy-goto-char))
;;(define-key dired-mode-map (kbd "M-s") 'avy-goto-char)(I use the programmer Dvorak layout.)
(global-set-key (kbd "C-,") 'beginning-of-buffer)
(global-set-key (kbd "C-.") 'end-of-buffer)
(global-set-key (kbd "C-{") 'backward-paragraph)
(global-set-key (kbd "C-}") 'forward-paragraph)Used for text editing in Chrome browser.
(use-package atomic-chrome
:ensure t)
(atomic-chrome-start-server)While changing buffers or workspaces, the first thing you do is look for your cursor. Unless you know its position, you can not move it efficiently. Every time you change buffers, the current position of your cursor will be briefly highlighted now.
(use-package beacon
:config
(beacon-mode 1));; (setq desktop-save-mode true) ;; nil / t(add-to-list 'load-path (expand-file-name "site-lisp/dired+" user-emacs-directory))
(require 'dired+)This site-lisp code from Xah Lee allows you to compile / run
code from the file.
(add-to-list 'load-path (expand-file-name "site-lisp/run-current-file" user-emacs-directory))
(require 'run-current-file)
(global-set-key (kbd "<f8>") 'xah-run-current-file)A pretty simple package, takes your cursor and semantically expands the region, so words, sentences, maybe the contents of some parentheses, it’s awesome, try it out.
(use-package expand-region
:bind ("C-q" . er/expand-region))Fill the line with a character.
(defun fill-to-end (char)
(interactive "cFill Character:")
(save-excursion
(end-of-line)
(while (< (current-column) 80)
(insert-char char))))
(defun fill-short (char)
(interactive "cFill Character:")
(save-excursion
(end-of-line)
(while (< (current-column) 72)
(insert-char char))))(define-key help-mode-map (kbd "b") 'help-go-back)
(define-key help-mode-map (kbd "f") 'help-go-forward)(global-set-key (kbd "C-=") 'other-frame)
;;(global-set-key (kbd "C-o") 'other-window)The default is 60, I personally need more sometimes.
(setq kill-ring-max 100)Backspace or Delete will get rid of all whitespace until the next non-whitespace character is encountered.
(use-package hungry-delete
:config
(global-hungry-delete-mode))Better pdf-browsing than docview.
(use-package pdf-tools
:ensure t)
(pdf-tools-install)Single buffer, narrow view.
;; (require 'prose-mode)Mostly useful if you are into web development or game development. Every time emacs encounters a hexadecimal code that resembles a color, it will automatically highlight it in the appropriate color.
(use-package rainbow-mode
:init
(add-hook 'prog-mode-hook 'rainbow-mode))rainbow-delimiters is useful in programming modes because it colorizes nested parentheses and brackets according to their nesting depth. This makes it a lot easier to visually match parentheses in Emacs Lisp code without having to count them yourself.
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
Sometimes the buffer just isn’t fontified correctly. Here’s how to fix it.
(global-set-key (kbd "C-x C-$") 'font-lock-fontify-buffer)Rearrange split windows: remove previous setting and split horizontally or vertically.
(defun split-window-horizontally-instead ()
"Kill any other windows and re-split such that the current window is on the top half of the frame."
(interactive)
(let ((other-buffer (and (next-window) (window-buffer (next-window)))))
(delete-other-windows)
(split-window-horizontally)
(when other-buffer
(set-window-buffer (next-window) other-buffer))))
(defun split-window-vertically-instead ()
"Kill any other windows and re-split such that the current window is on the left half of the frame."
(interactive)
(let ((other-buffer (and (next-window) (window-buffer (next-window)))))
(delete-other-windows)
(split-window-vertically)
(when other-buffer
(set-window-buffer (next-window) other-buffer))))
(global-set-key (kbd "C-x |") 'split-window-horizontally-instead)
(global-set-key (kbd "C-x _") 'split-window-vertically-instead)Imported from this thread. https://emacs.stackexchange.com/questions/169/how-do-i-reload-a-file-in-a-buffer
(global-set-key (kbd "C-c r")
(lambda ()
(interactive)
(revert-buffer t t t)
(message "buffer is reverted")))Highlights matching parens when the cursor is just behind one of them.
(show-paren-mode 1)Emacs treats camelCase strings as a single word by default, this changes said behaviour.
(global-subword-mode 1)Kills all text between your cursor and a selected character.
If you wish to include the selected character in the killed
region, change zzz-up-to-char into zzz-to-char.
(use-package zzz-to-char
:bind ("M-z" . zzz-up-to-char))