About | Packages Setup | Built-in Capabilities
ATTENTION: This is a work in progress
ATTENTION: This configuration has been tested on Emacs 25.
This repository contains the setup I use to customize Emacs. It is implemented trying to follow the concept of Literate Programming through the use of Org-mode and Org-Babel to manage all the settings in a unique Org mode file.
This is a list of applications that need to be installed previously in order to enjoy all the goodies of this configuration. Of course, you can install only the ones you will really use and/or adapt it to the ones you prefer.
- ripgrep for fast searching
- git for version control, but if you are here you already know what is it ;)
- notmuch for email (also a tool to fetch mail like mbsync or OfflineImap)
- GnuPG for security, always
- pass to manage your passwords
- LaTeX and Pygments to PDF export with syntax highlighting
- MuPDF for DocView, poppler for pdf-tools
- pandoc for ox-pandoc
- proselint a liter for prose
- Zeal (Linux) or Dash (macOS) for browsing software documentation After installing Zeal, you need to download docsets. Go to File->Options->Docsets, select the ones you want, and click the Download button.
- ImageMagick or GraphicsMagick
- gzip
The inspiration for handling the Emacs configuration through Literate Programming came from Eric Schulte’s emacs24-starter-kit. It is a really clever concept that, among other things, keeps your Emacs configuration tidy and well organized.
The first time I saw it being handled by a single org-mode file was on Sacha
Chua’s config. Then I came across joe di castro’s emacs.d on github, where he
automatically generates the ~/.emacs.d/init.el
directly from his readme.org
file. This is the solution I’m using here.
A list of Emacs Jedis, from whon I took most of the solutions applied here.
Their github
pages have many interesting/clever ideas to inspire you. Also
make sure to check their blogs as well…cool stuff:
For installing Emacs on Mac, check these:
The file ~/.emacs.d/init.el
is one of the first standard init files read by
Emacs in order to load all its configuration. The idea here is to create
~/.emacs.d/init.el
exporting all the code blocks contained in this current
readme.org
file to it. This is done by Org-Babel through a process called
tangling. If a code block is marked with :tangle no
it will be skipped.
The cool thing about this setup is that you can export the same file as
documentation to HTML, PDF, or LaTeX quite easily, e.g. to do it from Org mode
directly press C-c C-e
, choose h
or l
and then one of the options to
produce the desired output. At the same time it makes the configuration
management a delight, been pretty easy to find any setting and organize them.
Firstly, rename your current ~/.emacs.d
directory, so you can keep it safe in
case you want to get back to it:
$ mv ~/.emacs.d ~/.emacs.d.disabled
Then clone this repository. It will create your new ~/.emacs.d
directory:
$ git clone https://github.com/rubensts/.emacs.d.git
Code blocks on org mode can be tangled with C-c C-v t
. This is not necessary
on this readme.org
file as the tangling is done automatically.
The code block below is the responsable for creating the hook that will tangle a
new ~/.emacs.d/init.el
every time that this readme.org
is saved. This also
means that alterations on the configuration have to be done on readme.org
. Any
changes made on ~/.emacs.d/init.el
will be overwritten when readme.org
is
saved.
;; originaly seen at
;; https://github.com/larstvei/dot-emacs/blob/master/init.org
(defun tangle-init ()
"If the current buffer is 'readme.org' the code-blocks are
tangled, and the tangled file is compiled."
(when (equal (buffer-file-name)
(expand-file-name (concat user-emacs-directory "readme.org")))
(call-process-shell-command
"emacs ~/.emacs.d/readme.org --batch --eval='(org-babel-tangle)' && notify-send -a 'Emacs' 'init file tangled'" nil 0)))
;;(byte-compile-file (concat user-emacs-directory "init.el")))
(add-hook 'after-save-hook 'tangle-init)
You can notice that there isn’t an init.el
file present in this
repository. To generate it the first time you just have to run the
following command:
$ /usr/bin/emacs ~/.emacs.d/readme.org --batch --eval='(org-babel-tangle)'
This will generate a ~/.emacs.d/init.el
file from this current
readme.org
file. Remember that you just have to run the above
command once right after you have cloned this repo. After that the
~/.emacs.d/init.el
will be recreated every time this readme.org
file is saved.
Because of that, there is no reason to track the ~/.emacs.d/init.el
that is generated; by running the following command git
will not
bother tracking it:
git update-index --assume-unchanged init.el
To automatized package intallation I’ve started using use-package
, which gives a
concise and powerful way to organize Emacs configuration avoiding the terrible
“config bankrupcy”.
Allow more messages in Messages buffer. A more complete log helps on debugging issues.
(setq message-log-max 10000)
;; Avoid accidentally using outdated compiled files
(setq load-prefer-newer t)
;; Load package here allows to add the new repositories listed below
(require 'package)
;; Assures package-initialize is not called again after init.el.
(setq package-enable-at-startup nil)
;; Sets the ELPA repositories from where packages are fetched
(setq package-archives '(("org" . "http://orgmode.org/elpa/")
("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
;; By default package-initialize is called after init.el.
;; Calling it here because some packages listed depend on it.
(package-initialize)
;; Automatically compile Emacs Lisp libraries
;;(require 'auto-compile)
;;(auto-compile-on-load-mode)
;;(auto-compile-on-save-mode)
;; Bootstrap `use-package'
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package)
(setq-default use-package-always-defer t
use-package-always-ensure t))
(require 'subr-x)
(require 'time-date)
;; Help keeping ~/.emacs.d clean
(use-package no-littering :demand t)
(use-package validate :demand t)
;; load libraries
(use-package s)
(use-package f)
(when (version< emacs-version "25")
(warn "This configuration needs Emacs 25, but this is %s!" emacs-version))
;; Disables calling default.el (default settings) after init.el
(setq inhibit-default-init t)
Optimizing the Emacs’s garbage collector only for when the minibuffer is opened. I’m using the block below after reading about it here.
(defun my-minibuffer-setup-hook ()
(setq gc-cons-threshold most-positive-fixnum))
(defun my-minibuffer-exit-hook ()
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook)
(use-package exec-path-from-shell
:if (display-graphic-p)
:config
(progn
(when (string-match-p "/zsh$" (getenv "SHELL"))
;; Use a non-interactive login shell. A login shell, because my
;; environment variables are mostly set in `.zprofile'.
(setq exec-path-from-shell-arguments '("-l")))
;; Import additional environment variables beyond just $PATH
(dolist (var '("PYTHONPATH" ; Python modules
"INFOPATH" ; Info directories
))
(add-to-list 'exec-path-from-shell-variables var))
;; Initialize Emacs' environment from the shell
(exec-path-from-shell-initialize)))
Loads Emacs as a server, allowing it to answer to client calls coming from
emacsclient
.
(use-package server
:config
(unless (server-running-p) (server-start)))
Check which OS for keeping compatibility.
The functions system-is-mac
and system-is-linux
is called throughout this org
file.
(defun system-is-mac ()
(interactive)
(string-equal system-type "darwin"))
(defun system-is-linux ()
(interactive)
(string-equal system-type "gnu/linux"))
Use sensible-defaults.el for some basic settings.
(load-file "~/git/sensible-defaults.el/sensible-defaults.el")
(sensible-defaults/use-all-settings)
(sensible-defaults/use-all-keybindings)
Other personal preferences not covered by sensible-defaults.el.
;; Fullscreen
(cond ((system-is-mac) (toggle-frame-fullscreen))
((system-is-linux) (add-to-list 'default-frame-alist
'(fullscreen . maximized))))
;; disable menu, tool-bar and scroll-bar
(when (window-system)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1))
(setq apropos-do-all t ; apropos commands perform more extensive searches than default
x-select-enable-clipboard t ; allows pasting selection outside of Emacs
echo-keystrokes 0.1 ; shows keystrokes in progress
use-dialog-box nil ; don't use dialog when using mouse click
line-spacing '0.10 ; line height
)
(blink-cursor-mode -1) ; turn of the blinking cursor
;;(fringe-mode '(1 . 1)) ; thinner window divisions
(defalias 'list-buffers 'ibuffer) ; use ibuffer by default
(global-hl-line-mode 1) ; highlight the current line
(global-visual-line-mode t) ; break long line of text
(global-prettify-symbols-mode 1) ; prettify symbols (lambdas, etc)
(save-place-mode 1) ; save cursor position for opened files
(setq-default indicate-empty-lines t) ; show empty lines at bottom of buffer
(when (not indicate-empty-lines)
(toggle-indicate-empty-lines))
(setq-default indent-tabs-mode nil ; always indent with spaces
default-tab-width 4
c-basic-offset 4)
(set-terminal-coding-system 'utf-8) ; make sure that UTF-8 is used everywhere
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
(set-selection-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(set-input-method nil)
;; settings for the modeline
(column-number-mode t) ; shows column number on the modeline
(setq size-indication-mode t)
;;(which-function-mode 1)
;; silence the beep sound, and shows the alarm bell visually on the modeline
(setq ring-bell-function (lambda ()
(invert-face 'mode-line)
(run-with-timer 0.1 nil
'invert-face 'mode-line)))
;; text wrapping at 80 columns by default (only text)
;; (add-hook 'text-mode-hook 'turn-on-auto-fill)
;; (add-hook 'text-mode-hook
;; '(lambda() (set-fill-column 80)))
;; browser settings
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "firefox")
Set the calendar to current location.
(setq calendar-week-start-day 1
calendar-latitude 43.8
calendar-longitude 11.0
calendar-location-name "Prato, Italy")
Let Emacs know about holidays of the location.
(setq holiday-general-holidays
'((holiday-fixed 1 1 "Capodanno")
(holiday-fixed 5 1 "1 Maggio")
(holiday-fixed 4 25 "Liberazione")
(holiday-fixed 6 2 "Festa Repubblica")
))
(setq holiday-christian-holidays
'((holiday-fixed 12 8 "Immacolata Concezione")
(holiday-fixed 12 25 "Natale")
(holiday-fixed 12 26 "Santo Stefano")
(holiday-fixed 1 6 "Epifania")
(holiday-easter-etc -52 "Giovedì grasso")
(holiday-easter-etc -47 "Martedì grasso")
(holiday-easter-etc -2 "Venerdì Santo")
(holiday-easter-etc 0 "Pasqua")
(holiday-easter-etc +1 "Lunedì Pasqua")
(holiday-fixed 8 15 "Assunzione di Maria")
(holiday-fixed 11 1 "Ognissanti")
))
Maintain a history of past actions and a reasonable number of lists.
(setq-default history-length 1000)
;;(setq savehist-file (concat
;; tmp-directory "history")
(setq-default history-delete-duplicates t
savehist-save-minibuffer-history 1
savehist-additional-variables '(kill-ring
search-ring
regexp-search-ring))
(savehist-mode t)
(setq scroll-margin 0
scroll-conservatively 100000
scroll-preserve-screen-position 1
mouse-wheel-scroll-amount '(1 ((shift) . 1))
mouse-wheel-progressive-speed nil
mouse-wheel-follow-mouse 't)
These functions are useful. Activate them.
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'dired-find-alternate-file 'disabled nil)
Oremacs source - This function is used in some point of this init.el
file for
setting custom variables. Basically it is a setq
that is aware of the
custom-set property of a variable.
(defmacro csetq (variable value)
`(funcall (or (get ',variable 'custom-set)
'set-default)
',variable ,value))
This improves the default Emacs behavior of split windows. The cursor automatically moves to the new splited window.
(defun split-below-and-move ()
(interactive)
(split-window-below)
(other-window 1))
(defun split-right-and-move ()
(interactive)
(split-window-right)
(other-window 1))
(bind-keys ("C-x 2" . split-below-and-move)
("C-x 3" . split-right-and-move))
This function, from emacsredux blog, defines a better start of line and remaps
C-a
for it.
(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)
(global-set-key (kbd "C-a") 'smarter-move-beginning-of-line)
Change the key-binding to kill the current buffer instead of asking which one to kill. Very good tip taken from Pragmaticemacs.
(global-set-key (kbd "C-x k") 'kill-this-buffer)
(defun my/copy-id-to-clipboard()
"Copy the ID property value to killring,
if no ID is there then create a new unique ID.
This function works only in org-mode buffers.
The purpose of this function is to easily construct id:-links to
org-mode items. If its assigned to a key it saves you marking the
text and copying to the killring."
(interactive)
(when (eq major-mode 'org-mode) ; do this only in org-mode buffers
(setq mytmpid (funcall 'org-id-get-create))
(kill-new mytmpid)
(message "Copied %s to killring (clipboard)" mytmpid)
))
(global-set-key (kbd "<f5>") 'my/copy-id-to-clipboard)
Why use vim modal editing on Emacs?
Simple: the editing paradigm of Vim is the best way, by far, of editing text. Emacs is the best for everything else ;) Evil configuration taken from https://ilikewhenit.works/blog/6
(use-package evil
:demand t
:config
(evil-mode 1)
(with-eval-after-load 'evil-maps
;;(define-key evil-motion-state-map (kbd "SPC") nil)
(define-key evil-motion-state-map (kbd "RET") nil)
(define-key evil-motion-state-map (kbd "TAB") nil))
(validate-setq evil-emacs-state-cursor '("red" box)
evil-motion-state-cursor '("orange" box)
evil-normal-state-cursor '("green" box)
evil-visual-state-cursor '("orange" box)
evil-insert-state-cursor '("red" bar)
evil-replace-state-cursor '("red" bar)
evil-operator-state-cursor '("red" hollow))
(add-hook 'after-init-hook
(lambda ()
(evil-put-property 'evil-state-properties 'normal :tag " NORMAL ")
(evil-put-property 'evil-state-properties 'insert :tag " INSERT ")
(evil-put-property 'evil-state-properties 'visual :tag " VISUAL ")
(evil-put-property 'evil-state-properties 'motion :tag " MOTION ")
(evil-put-property 'evil-state-properties 'emacs :tag " EMACS ")
(evil-put-property 'evil-state-properties 'replace :tag " REPLACE ")
(evil-put-property 'evil-state-properties 'operator :tag " OPERATOR ")))
)
(use-package evil-surround
:after evil
:config
(global-evil-surround-mode))
(use-package evil-indent-plus
:after evil
:config
(evil-indent-plus-default-bindings))
(use-package evil-commentary
:after evil
:config
(evil-commentary-mode))
(use-package evil-snipe
:after evil
:demand t
:init
(setq evil-snipe-scope 'whole-buffer
evil-snipe-enable-highlight t
evil-snipe-enable-incremental-highlight t
evil-snipe-auto-disable-substitute t
evil-snipe-show-prompt nil
evil-snipe-smart-case t)
:config
(progn
(evil-snipe-override-mode 1)
(evil-snipe-mode 1)))
(use-package evil-anzu
:after evil)
(use-package evil-matchit
:after evil
:config
(global-evil-matchit-mode 1))
(use-package evil-numbers
:after evil)
Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system…bu not only :)
Actually, org-mode is the solely reason why many people recently have decided to try Emacs, then they are hooked ;)
Keys | Command | Results |
---|---|---|
C-c C-x C-l | Show latex fragments | |
C-c C-c | Get rid of latex fragments |
(use-package org
:ensure org-plus-contrib
:bind (("C-c a" . org-agenda-list)
("C-c c" . org-capture)
("C-c l" . org-store-link)
;;("C-c f" . org-cycle-agenda-files)
;;("C-c s" . org-search-view)
("C-c t" . org-todo-list))
:config
(validate-setq
org-tags-column 90 ; column to which the tags have to be indented
org-ellipsis "⤵" ; ⬎, ⤷, ⤵, ⚡
org-fontify-whole-heading-line t ; fontify the whole line for headings
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-startup-indented t
org-hide-emphasis-markers t ; hide markup elements, e.g. * *, / /, _ _
org-cycle-include-plain-lists t
org-list-allow-alphabetical t
org-latex-create-formula-image-program 'imagemagick ; preview latex fragments
;; Code blocks to play nicelly on org-babel
org-edit-src-content-indentation 0 ; number of whitespaces added to the code block indentation (after #begin)
org-src-tab-acts-natively t ; TAB acts natively as it was in the language major mode
org-src-preserve-indentation t ; preserve indentation when exporting blocks
org-src-fontify-natively t ; highlights code-blocks natively
org-src-window-setup 'current-window ; open code-blocks in the current window
org-confirm-babel-evaluate nil ; don't ask for confirmation when compiling code-blocks
;; Files location
org-directory "~/org"
org-default-notes-file (concat org-directory "/notes.org")
org-agenda-files (list "~/org/todo.org"
"~/org/clockin.org"))
;; TODO workflow states
org-todo-keywords
'("☛ TODO(t)" "⚑ WAIT(w@)" "|" "✔ DONE(d)" "✘ CANCEL(c@)")
;; TODO fontification
org-todo-keyword-faces
'(("☛ TODO" . (:foreground "#ff4500" :weight bold))
("✔ DONE" . (:foreground "#00ff7f" :weight bold))
("⚑ WAIT" . (:foreground "#ffff00" :weight bold))
("✘ CANCEL" . (:foreground "#00bfff" :weight bold)))
)
(use-package org-clock
:ensure org-plus-contrib
:demand t
:config
(org-clock-persistence-insinuate) ; resume clocking task when emacs is restarted
(validate-setq
org-clock-persist t ; save all clock history when exiting Emacs, load it on startup
org-clock-persist-query-resume nil ; do not prompt to resume an active clock
org-clock-history-length 10 ; show lot of clocking history from where choose items
org-clock-in-resume t ; resume clocking task on clock-in if the clock is open
org-clock-into-drawer "CLOCKING" ; clocking goes into specfic drawer
org-clock-report-include-clocking-task t)) ; include current clocking task in clock reports
(use-package org-protocol
:ensure org-plus-contrib
:demand t
:config
;; Define capture templates
(setq org-capture-templates
'(("w" "Web bookmarks" entry
(file+headline (concat org-directory "/www.org") "Bookmarks")
"* %?%c %^g\n:PROPERTIES:\n:CREATED: %U\n:END:\n%i\n"
:empty-lines 1
:immediate-finish)
("t" "Tasks" entry
(file+headline (concat org-directory "/tasks.org") "Tasks")
"* ☛ TODO %^{Task} %^g\n:PROPERTIES:\n:CREATED: %U\n:END:\n%?%i"
:empty-lines 1)
("n" "Notes" entry
(file+headline (concat org-directory "/notes.org") "Notes")
"* %^{Header} %^G\n %u\n %?")
("j" "Journal" entry
(file+datetree (concat org-directory "/journal.org"))
"* %U %^{Title}\n %?%i\n %a")
("a" "Articles" entry
(file+headline (concat org-directory "/articles.org") "Articles")
"* %^{Title} %^g\n:PROPERTIES:\n:CREATED: %U\n:END:\n%?%i\n"
:empty-lines 1
:immediate-finish)
("r" "Redmine" entry
(file+datetree (concat org-directory "/clockin.org"))
"* [[https://redmine.2ndquadrant.it/issues/%^{Ticket}][%^{Description}]] :redmine:%^g\n%?"
:clock-in t
:clock-keep t
:empty-lines 1)
("s" "RT - Support" entry
(file+datetree (concat org-directory "/clockin.org"))
"* [[https://support.2ndquadrant.com/rt/Ticket/Display.html?id=%^{Ticket}][%^{Description}]] :support:%^g\n%?"
:clock-in t
:clock-keep t
:empty-lines 1)
("b" "RT - RDBA" entry
(file+datetree (concat org-directory "/clockin.org"))
"* [[https://support.2ndquadrant.com/rt/Ticket/Display.html?id=%^{Ticket}][%^{Description}]] :rdba:%^g\n%?"
:clock-in t
:clock-keep t
:empty-lines 1)
)))
(use-package org-bullets
:demand t
:after org-plug-contrib
:config
;;(setq org-bullets-bullet-list '("☯" "☰" "☱" "☲" "☳" "☴" "☵" "☶" "☷"))
;;(setq org-bullets-bullet-list '("♣" "♥" "♠" "♦" "♧" "♡" "♤" "♢"))
(validate-setq org-bullets-bullet-list '("☯" "☉" "∞" "◉" "⊚" "☀" "☾" "☥"))
(add-hook 'org-mode-hook (lambda () (org-bullets-mode t)))
;; make available "org-bullet-face" such that I can control the font size individually
(validate-setq org-bullets-face-name (quote org-bullet-face))
(custom-set-faces '(org-bullet-face
((t (:foreground "burlywood"
:weight normal
:height 1.6))))
))
org-sticky-header shows off-screen Org heading at top of window.
(use-package org-sticky-header
:after org
:demand t
:config
(setq-default org-sticky-header-full-path 'full
org-sticky-header-outline-path-separator " / "))
(use-package ox
:ensure org-plus-contrib
:config
(validate-setq org-export-with-smart-quotes t))
I’m using ox-pandoc to export org files to all formats Pandoc works with. It only exports org files, in opposite of pandoc-mode, which exports from any source format. The problem is that ox-pandoc needs considerably less configuration and as I usually write everything in org-mode, no need to worry. https://github.com/kawabata/ox-pandoc http://www.rousette.org.uk/blog/archives/org-mode-and-pandoc/ Keeping a lab book with org-mode http://informatica.boccaperta.com/m-x-emacs-ox-pandoc/
(use-package ox-pandoc
:after org-plus-contrib
:demand t
:config
(validate-setq org-pandoc-options '((standalone . t)) ; default options for all output formats
org-pandoc-options-for-docx '((standalone . nil)) ; cancel above settings only for 'docx' format
org-pandoc-options-for-beamer-pdf '((latex-engine . "lualatex"))
org-pandoc-options-for-latex-pdf '((latex-engine . "lualatex"))
;;org-pandoc-options-for-latex-pdf '((latex-engine . "xelatex")
;; (template . "~/.pandoc/templates/memoir2.latex" ))
;;org-pandoc-options-for-latex '((latex-engine . "xelatex")
;; (template . "~/.pandoc/templates/memoir2.latex" ))
;; Use external css for html5
;; (let ((stylesheet (expand-file-name
;; (locate-user-emacs-file "etc/pandoc.css"))))
;; (setq org-pandoc-options-for-html5
;; `((css . ,(concat "file://" stylesheet)))))
)
)
Babel is Org-mode’s ability to execute source code within Org-mode documents.
(use-package ob
:ensure org-plus-contrib
:config
(org-babel-do-load-languages
(quote org-babel-load-languages)
(quote ((calc . t)
(clojure . t)
(ditaa . t)
(dot . t)
(emacs-lisp . t)
(gnuplot . t)
(latex . t)
(ledger . t)
(octave . t)
(org . t)
(makefile . t)
(plantuml . t)
(python . t)
(R . t)
(ruby . t)
(sh . t)
(sqlite . t)
(sql . t)
))))
(use-package hydra
:config
(setq lv-use-separator t)
(set-face-attribute 'hydra-face-blue nil :foreground "deep sky blue" :weight 'bold))
Ivy is a generic completion frontend for Emacs.
Swiper shows an overview during regex searching. It uses the ivy back end for the overview.
Keybinding | Functions | Result |
---|---|---|
C-M-i | ivy-display-function | displays the function candidate list |
(use-package swiper
:demand t
:bind (("C-c C-r" . ivy-resume)
("C-s" . swiper)
:map ivy-minibuffer-map
("<return>" . ivy-alt-done)
("C-M-h" . ivy-previous-line-and-call)
("C-:" . ivy-dired)
("C-c o" . ivy-occur)
:map read-expression-map
("C-r" . counsel-expression-history)
)
:config
(ivy-mode 1)
(validate-setq ivy-use-virtual-buffers t ; list `recentf' and bookmarks as well
ivy-height 10
ivy-count-format "(%d/%d) " ; counter
ivy-extra-directories nil ; Do not show "./" and "../"
ivy-virtual-abbreviate 'full ; Show full file path
ivy-re-builders-alist '((t . ivy--regex-plus))
ivy-use-ignore-default 'always ; ignore buffers set in `ivy-ignore-buffers'
ivy-ignore-buffers ; ignore some buffers in `ivy-switch-buffer'
'("company-statistics-cache.el"
".elfeed/index")
swiper-action-recenter t ; always recenter when leaving swiper
)
(defun ivy-dired ()
(interactive)
(if ivy--directory
(ivy-quit-and-run
(dired ivy--directory)
(when (re-search-forward
(regexp-quote
(substring ivy--current 0 -1)) nil t)
(goto-char (match-beginning 0))))
(user-error
"Not completing files currently")))
;; Customize faces per mode
(validate-setq ivy-switch-buffer-faces-alist
'((emacs-lisp-mode . swiper-match-face-1)
(dired-mode . ivy-subdir)
(org-mode . org-level-4)))
)
;; Speed up my workflow with prearranged windows
;; (setq ivy-views '(("boccaperta + ba-server [–]"
;; (vert
;; (sexp (bookmark-jump "boccaperta"))
;; (sexp (bookmark-jump "ba-server"))))
;; ("desktop + ba-server [–]"
;; (vert
;; (sexp (bookmark-jump "desktop"))
;; (sexp (bookmark-jump "ba-server"))))))
;; Hydra bindings for ivy buffer
(use-package ivy-hydra
:after ivy)
;; smex order selections accordingly to the most used ones
(use-package smex :after swiper)
(use-package counsel
:after swiper
:bind (("M-x" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("<f1> f" . counsel-describe-function)
("<f1> v" . counsel-describe-variable)
("<f1> l" . counsel-load-library)
("<f2> i" . counsel-info-lookup-symbol)
("<f2> u" . counsel-unicode-char)
("C-r" . counsel-grep-or-swiper)
("C-c g" . counsel-git)
("C-c j" . counsel-git-grep)
("C-c k" . counsel-rg)
("C-x l" . counsel-locate)
("C-c r" . counsel-linux-app)
("C-x i" . counsel-imenu)
("M-y" . counsel-yank-pop))
:config
(validate-setq counsel-mode-override-describe-bindings t
counsel-find-file-at-point t
counsel-find-file-ignore-regexp
(concat
"\\(?:\\`[#.]\\)" ; file names beginning with # or .
"\\|\\(?:\\`.+?[#~]\\'\\)" ; file names ending with # or ~
)))
Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies (when feasible). For instance - finding project files has a portable implementation written in pure Emacs Lisp without the use of GNU find (but for performance sake an indexing mechanism backed by external commands exists as well).
Perspective provides tagged workspaces in Emacs, similar to workspaces in windows managers such as Awesome and XMonad (and somewhat similar to multiple desktops in Gnome or Spaces in OS X).
Commands are all prefixed by C-x x
Key | Command | What it does |
---|---|---|
s | persp-switch | Query a perspective to switch or create |
k | persp-remove-buffer | Query a buffer to remove from current perspective |
c | persp-kill | Query a perspective to kill |
r | persp-rename | Rename current perspective |
a | persp-add-buffer | Query an open buffer to add to current perspective |
A | persp-set-buffer | Add buffer to current perspective and remove it from all others |
i | persp-import | Import a given perspective from another frame. |
n, <right> | persp-next | Switch to next perspective |
p, <left> | persp-prev | Switch to previous perspective |
(use-package projectile
:config
(validate-setq projectile-enable-caching t
projectile-completion-system 'ivy
projectile-switch-project-action 'projectile-dired
projectile-mode-line '(:eval (format
" :%s:" (projectile-project-name))))
(projectile-global-mode))
(use-package perspective
:config
(persp-mode))
(use-package persp-projectile
:config
(define-key projectile-mode-map (kbd "s-s")
'projectile-persp-switch-project))
(use-package counsel-projectile
:config
(counsel-projectile-on))
(use-package ibuffer-projectile)
(use-package magit
:config
(setq magit-completing-read-function 'ivy-completing-read
magit-display-buffer-function 'magit-display-buffer-fullframe-status-topleft-v1))
(use-package ace-window)
(use-package alert
:demand t)
anzu provides a minor mode which displays current match and total matches information in the mode-line in various search modes.
(use-package anzu
:bind (("M-%" . anzu-query-replace)
("C-M-%" . anzu-query-replace-regexp))
:config
(global-anzu-mode +1)
(setq-default anzu-cons-mode-line-p nil
anzu-replace-to-string-separator " "))
Simple library for asynchronous processing in Emacs
(use-package async
:demand t
:config
(dired-async-mode t)
(async-bytecomp-package-mode t))
avy is a GNU Emacs package for jumping to visible text using a char-based decision tree. See also ace-jump-mode and vim-easymotion - avy uses the same idea.
(use-package avy
:bind (("C-:" . avy-goto-char)
("C-'" . avy-goto-char-2)
("M-g f" . avy-goto-line)
("M-g w" . avy-goto-word-1)
("M-g e" . avy-goto-word-0))
:config
(setq avy-background t
avy-all-windows t
avy-style 'at-full
avy-case-fold-search nil)
(set-face-attribute 'avy-lead-face nil
:foreground "gold"
:weight 'bold
:background nil)
(set-face-attribute 'avy-lead-face-0 nil
:foreground "deep sky blue"
:weight 'bold
:background nil))
Never lose your cursor again. Whenever the window scrolls a light will shine on top of your cursor so you know where it is.
(use-package beacon
:demand t
:config
(beacon-mode t)
(setq beacon-push-mark 35
beacon-color "#666600"))
Bookmarks to files and directories
(use-package bookmark
:config
(setq bookmark-completion-ignore-case nil)
(bookmark-maybe-load-default-file))
Company is a text completion framework for Emacs. The name stands for “complete anything”. It uses pluggable back-ends and front-ends to retrieve and display completion candidates.
It comes with several back-ends such as Elisp, Clang, Semantic, Eclim, Ropemacs, Ispell, CMake, BBDB, Yasnippet, dabbrev, etags, gtags, files, keywords and a few others.
The CAPF back-end provides a bridge to the standard completion-at-point-functions facility, and thus works with any major mode that defines a proper completion function.
(use-package company
:bind (("C-c /" . company-files)) ; force complete file names on "C-c /" key
:config
(add-hook 'after-init-hook 'global-company-mode)
(setq company-tooltip-limit 20 ; bigger popup window
company-tooltip-align-annotations 't ; align annotations to the right tooltip border
company-idle-delay .3 ; decrease delay before autocompletion popup shows
company-begin-commands '(self-insert-command)) ; start autocompletion only after typing
)
(use-package company-statistics
:after company
:config
;;(setq company-statistics-file
;; (concat tmp-directory "company-statistics-cache.el"))
(add-hook 'after-init-hook 'company-statistics-mode))
(use-package slime-company
:after company
:config
(slime-setup '(slime-fancy slime-company)))
(use-package company-ansible
:after company
:config
(add-to-list 'company-backends 'company-ansible))
(use-package company-math
:after company
:config
(add-to-list 'company-backends '((company-math-symbols-unicode)
(company-math-symbols-latex)
(company-latex-commands)))
(setq company-tooltip-align-annotations t))
crux is a Collection of Ridiculously Useful eXtensions for Emacs. crux bundles a few useful interactive commands to enhance your overall Emacs experience.
(use-package crux)
diff-hl-mode highlights uncommitted changes on the left side of the window, allows you to jump between and revert them selectively.
Keybindings
function | Keybinding |
---|---|
diff-hl-diff-goto-hunk | C-x v = |
diff-hl-revert-hunk | C-x v n |
diff-hl-previous-hunk | C-x v [ |
diff-hl-next-hunk | C-x v ] |
(use-package diff-hl
:disabled t
:config
(global-diff-hl-mode)
(diff-hl-flydiff-mode)
(add-hook 'dired-mode-hook 'diff-hl-dired-mode)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
Load up the assorted dired extensions.
(use-package dired-x
:ensure nil)
(use-package dired+
:config
(setq diredp-hide-details-initially-flag t
diredp-hide-details-propagate-flag t)
(toggle-diredp-find-file-reuse-dir 1) ; use single buffer for all dired navigation
;;(diredp-make-find-file-keys-reuse-dirs)
)
(use-package dired-open)
;; Dired configuration
(setq dired-clean-up-buffers-too t ; kill buffer of files/dir that are deleted in dired
dired-recursive-copies 'always ; always copy directories recursively
dired-recursive-deletes 'top ; ask before recursively deleting a directory
dired-open-extensions ; open files with appropriate programs
'(("pdf" . "evince")
("mkv" . "vlc")
("mp4" . "vlc")
("avi" . "vlc")))
(setq-default dired-listing-switches "-lhvA") ; ls switches when dired gets list of files
Provide commands easy-kill
and easy-mark
to let users kill or mark things
easily.
Key | Command | Action |
---|---|---|
M-w w | save word at point | |
M-w s | save sexp at point | |
M-w l | save list at point (enclosing sexp) | |
M-w d | save defun at point | |
M-w D | save current defun name | |
M-w f | save file at point | |
M-w b | save buffer-file-name or default-directory | |
The following keys modify the selection:
Key | Command | Action |
---|---|---|
@ | append selection to previous kill and exit. For example, M-w d @ will append current function to last kill. | |
C-w | kill selection and exit | |
+, - | and 1..9: expand/shrink selection | |
0 | shrink the selection to the initial size i.e. before any expansion | |
C-SPC | turn selection into an active region | |
C-g | abort | |
? | help |
(use-package easy-kill
:bind (([remap kill-ring-save] . easy-kill)
([remap mark-sexp] . easy-mark)))
The default ediff-mode
isn’t quite optimized. The following settings are taken
from Oremacs.
Just a note about the --text
in the ediff-diff-options
: it will force the
GNU utility diff
, which is called by ediff
, to treat the input files as text
files. This is necessary as the utility diff
doesn’t understand unicode, and
sees unicode encoded files as binary files (stackoverflow).
(use-package ediff
:ensure nil
:config
(csetq ediff-window-setup-function 'ediff-setup-windows-plain)
(csetq ediff-split-window-function 'split-window-horizontally)
(csetq ediff-diff-options "-w --text")
(defun ora-ediff-prepare-buffer ()
(when (memq major-mode '(org-mode emacs-lisp-mode))
(outline-show-all)))
(add-hook 'ediff-prepare-buffer-hook 'ora-ediff-prepare-buffer)
(defun ora-ediff-jk ()
(define-key ediff-mode-map "j" 'ediff-next-difference)
(define-key ediff-mode-map "k" 'ediff-previous-difference))
(add-hook 'ediff-keymap-setup-hook #'ora-ediff-jk)
;;;###autoload
(defun ora-ediff-hook ())
;;;###autoload
(defun ora-diff-hook ())
(mapc
(lambda (k)
(define-key diff-mode-map k
`(lambda () (interactive)
(if (region-active-p)
(replace-regexp "^." ,k nil
(region-beginning)
(region-end))
(insert ,k)))))
(list " " "-" "+"))
)
Expand region increases the selected region by semantic units. Just keep pressing the key until it selects what you want.
(use-package expand-region)
Toggle the vertical column that indicates the fill threshold.
(use-package fill-column-indicator
:config
(fci-mode t)
(setq fci-rule-width 1
fci-rule-color "#5d478b"
fci-rule-column 80))
Fixmee-mode tracks fixme notices in code comments, highlights them, ranks them by urgency, and lets you navigate to them quickly.
It requires button-lock.el, which is installed by wiki-nav
.
Patterns - The following fixme patterns are supported by default:
@@@ XXX ; only this one is case-sensitive todo fixme
Key bindings
Keystrokes | Function |
---|---|
C-c f | fixmee-goto-nextmost-urgent |
C-c F | fixmee-goto-prevmost-urgent |
C-c v | fixmee-view-listing |
M-n | fixmee-goto-next-by-position ; only when the point is |
M-p | fixmee-goto-previous-by-position ; inside a fixme notice |
(use-package wiki-nav
:config
(global-wiki-nav-mode 1))
(use-package fixmee
:after wiki-nav
:config
(global-fixmee-mode 1))
Fuzzy matching for Emacs … a la Sublime Text. It is needed for fuzzy matching in swiper + avy.
(use-package flx)
(use-package flycheck
:init (global-flycheck-mode)
:config
(setq flycheck-mode-line
'(:eval
(pcase flycheck-last-status-change
(`not-checked nil)
(`no-checker (propertize " -" 'face 'warning))
(`running (propertize " ✷" 'face 'success))
(`errored (propertize " ☠" 'face 'error))
(`finished
(let* ((error-counts (flycheck-count-errors flycheck-current-errors))
(no-errors (cdr (assq 'error error-counts)))
(no-warnings (cdr (assq 'warning error-counts)))
(face (cond (no-errors 'error)
(no-warnings 'warning)
(t 'success))))
(propertize (format " %s/%s" (or no-errors 0) (or no-warnings 0))
'face face)))
(`interrupted " -")
(`suspicious '(propertize " ?" 'face 'warning)))))
)
Proselint checks the text for common errors. This creates a flycheck checker that runs proselint in texty buffers and displays the errors.
(flycheck-define-checker proselint
"A linter for prose."
:command ("proselint" source-inplace)
:error-patterns
((warning line-start (file-name) ":" line ":" column ": "
(id (one-or-more (not (any " "))))
(message (one-or-more not-newline)
(zero-or-more "\n" (any " ") (one-or-more not-newline)))
line-end))
:modes (text-mode markdown-mode gfm-mode org-mode))
(add-to-list 'flycheck-checkers 'proselint)
graphviz-dot-mode is a mode for the DOT language, used by graphviz
.
(use-package graphviz-dot-mode)
(use-package neotree
:bind (("<f6>" . neotree-toggle))
:config
(validate-setq neo-theme (if window-system 'icons 'arrow)))
Project for modernizing Emacs’ Package Menu. With package ratings, usage statistics, customizability, and more.
(use-package paradox
:config
(setq-default paradox-column-width-package 27
paradox-column-width-version 13
paradox-execute-asynchronously t
paradox-github-token t
paradox-hide-wiki-packages t)
(set-face-attribute 'paradox-homepage-button-face nil :italic nil)
(remove-hook 'paradox--report-buffer-print 'paradox-after-execute-functions))
(use-package pass)
pcache provides a persistent way of caching data, in a hashtable-like structure. It relies on `eieio-persistent’ in the backend, so that any object that can be serialized by EIEIO can be stored with pcache.
persistent-soft is a wrapper around pcache.el, providing “soft” fetch and store routines which never throw an error, but instead return nil on failure.
(use-package pcache
:demand t)
(use-package persistent-soft
:demand t
:after pcache)
(use-package pdf-tools
:config
(pdf-tools-install)
(setq-default pdf-view-display-size 'fit-page)
(bind-keys :map pdf-view-mode-map
("<s-spc>" . pdf-view-scroll-down-or-next-page)
("g" . pdf-view-first-page)
("G" . pdf-view-last-page)
("l" . image-forward-hscroll)
("h" . image-backward-hscroll)
("j" . pdf-view-next-page)
("k" . pdf-view-previous-page)
("e" . pdf-view-goto-page)
("u" . pdf-view-revert-buffer)
("al" . pdf-annot-list-annotations)
("ad" . pdf-annot-delete)
("aa" . pdf-annot-attachment-dired)
("am" . pdf-annot-add-markup-annotation)
("at" . pdf-annot-add-text-annotation)
("y" . pdf-view-kill-ring-save)
("i" . pdf-misc-display-metadata)
("s" . pdf-occur)
("b" . pdf-view-set-slice-from-bounding-box)
("r" . pdf-view-reset-slice)))
(use-package org-pdfview
:after pdf-tools)
persistent-scratch preserves the state of scratch buffers accross Emacs sessions by saving the state to and restoring it from a file.
(use-package persistent-scratch
:config
(persistent-scratch-setup-default))
Recentf is a minor mode that builds a list of recently opened files. This list is automatically saved across Emacs sessions. You can access the list through a menu. Here it’s set to work together with ivy-switch-buffer.
source 1 - source 2 - source 3
(use-package recentf
:config
(recentf-mode t)
(validate-setq recentf-max-saved-items 10
recentf-exclude '("COMMIT_MSG"
"COMMIT_EDITMSG"
"github.*txt$"
".*png$")))
Use ripgrep in Emacs.
(use-package rg)
Nicer naming of buffers for files with identical names. source
(use-package uniquify
:ensure nil
:config
(setq uniquify-buffer-name-style 'reverse
uniquify-separator " • "
uniquify-after-kill-buffer-p t ; rename after killing uniquified
uniquify-ignore-buffers-re "^\\*")) ; don't muck with special buffers
C-x u
to undo-tree-visualize
C-/ undo
S-C-/ redo
(use-package undo-tree
:init
(global-undo-tree-mode))
It provides minor mode volatile-highlights-mode, which brings visual feedback to some operations (eg. pasting, etc) by highlighting portions relating to the operations.
(use-package volatile-highlights
:config
(volatile-highlights-mode t))
Numbered window shortcuts for Emacs Enable window-numbering-mode and use M-1 through M-0 to navigate.
The defun window-numbering-install-mode-line set below is to make window-numbering work together with spaceline, overriding its own modeline display function.
(use-package window-numbering
:init
(window-numbering-mode)
:config
(defun window-numbering-install-mode-line (&optional position)
"Do nothing."))
wgrep is a writable grep buffer and apply the changes to files
You can edit the text in the grep buffer after typing C-c C-p
. After that the
changed text is highlighted. The following keybindings are defined:
Key | Action |
---|---|
C-c C-e: | Apply the changes to file buffers. |
C-c C-u: | All changes are unmarked and ignored. |
C-c C-d: | Mark as delete to current line (including newline). |
C-c C-r: | Remove the changes in the regiond |
C-c C-p: | Toggle read-only area. |
C-c C-k: | Discard all changes and exit. |
C-x C-q: | Exit wgrep mode. |
(use-package wgrep
:config
(progn
(with-eval-after-load 'grep
(bind-key "C-x C-q" #'wgrep-change-to-wgrep-mode grep-mode-map))
(with-eval-after-load 'wgrep
(bind-key "C-c C-c" #'wgrep-finish-edit grep-mode-map))))
Displays the key bindings following your currently entered incomplete command (a prefix) in a popup.
(use-package which-key
:init (which-key-mode)
:config (setq which-key-idle-delay 0.5
which-key-key-replacement-alist
'(("<\\([[:alnum:]-]+\\)>" . "\\1")
("up" . "↑")
("right" . "→")
("down" . "↓")
("left" . "←")
("DEL" . "⌫")
("deletechar" . "⌦")
("RET" . "⏎"))))
I’m start managing my keybindins through General.
(use-package general
:demand t
:after evil
:config
(general-define-key
:states '(normal visual insert emacs)
:prefix "SPC"
:non-normal-prefix "C-SPC"
;; simple command
;;"'" '(iterm-focus :which-key "iterm")
;;"?" '(iterm-goto-filedir-or-home :which-key "iterm - goto dir")
;;"/" 'counsel-ag
"SPC" '(avy-goto-word-or-subword-1 :which-key "go to char")
"iu" 'insert-char
"ne" 'flycheck-next-error
"pe" 'flycheck-previous-error
"qq" 'save-buffers-kill-emacs
"zp" 'zeal-at-point
"cy" 'clipboard-kill-ring-save
;;"cp" 'clipboard-yank
;; buffers
"TAB" '(switch-to-other-buffer :which-key "prev buffer")
"b" '(:ignore t :which-key "Buffers")
"bb" 'switch-to-buffer
"bd" 'kill-this-buffer
"by" 'copy-whole-buffer
;; windows
"w1" 'delete-other-windows
"w2" 'split-below-and-move
"w3" 'split-right-and-move
"wk" 'windmove-left
"wj" 'windmove-right
;; files
"f" '(:ignore t :which-key "Files")
"ff" 'find-file
"fl" 'load-file
"fs" 'save-buffer
;; modes
"m" '(:ignore t :which-key "Modes")
"ml" 'linum-mode
"mw" 'whitespace-mode
;; applications
"a" '(:ignore t :which-key "Applications")
"ad" 'dired
"am" 'notmuch
;; git
"g" '(:ignore t :which-key "GIT")
"gs" 'magit-status
;; spelling
"s" '(:ignore t :which-key "Spelling")
"sd" 'switch-dictionary
"sn" 'flyspell-goto-next-error
"sp" 'flyspell-popup-correct
"sw" 'flyspell-auto-correct-word
;; evil-nerd-commenter
;; "ci" 'evilnc-comment-or-uncomment-lines
;; "cl" 'evilnc-quick-comment-or-uncomment-to-the-line
;; "cc" 'evilnc-copy-and-comment-lines
;; "cp" 'evilnc-comment-or-uncomment-paragraphs
;; "cr" 'comment-or-uncomment-region
;; "cv" 'evilnc-toggle-invert-comment-line-by-line
;; "." 'evilnc-copy-and-comment-operator
))
IRC is a great way to hang out with other Emacs geeks. I use ERC for that and the configuration here is adapted from Prelude.
(use-package erc
:config
(progn
(erc-track-mode t) ; track activities on chats
(erc-truncate-mode +1) ; truncate long irc buffers
(erc-spelling-mode 1) ; enable spell checking
(setq erc-interpret-mirc-color t ; interpret mIRC-style color commands in IRC chats
erc-kill-buffer-on-part t ; kill buffer for channels after /part
erc-kill-queries-on-quit t ; kill buffer for private queries after quitting the server
erc-kill-server-buffer-on-quit t ; kill buffer for server messages after quitting the server
erc-query-display 'buffer ; open query buffers in the current window
erc-save-buffer-on-part t ; logging
;; autoaway setup
erc-auto-discard-away t
erc-autoaway-idle-seconds 600
erc-autoaway-use-emacs-idle t
erc-server-coding-system '(utf-8 . utf-8) ; utf-8 always and forever
erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
"324" "329" "332" "333" "353" "477") ; exclude these from tracking
erc-hide-list '("JOIN" "PART" "QUIT" "NICK") ; doesn't show any of these
)
;; logging
;; (setq erc-log-channels-directory "~/.erc/logs/")
;; (if (not (file-exists-p erc-log-channels-directory))
;; (mkdir erc-log-channels-directory t))
(defvar erc-notify-nick-alist nil
"Alist of nicks and the last time they tried to trigger a
notification")
(defvar erc-notify-timeout 10
"Number of seconds that must elapse between notifications from
the same person.")
(defun erc-notify-allowed-p (nick &optional delay)
"Return non-nil if a notification should be made for NICK.
If DELAY is specified, it will be the minimum time in seconds
that can occur between two notifications. The default is
`erc-notify-timeout'."
(unless delay (setq delay erc-notify-timeout))
(let ((cur-time (time-to-seconds (current-time)))
(cur-assoc (assoc nick erc-notify-nick-alist))
(last-time nil))
(if cur-assoc
(progn
(setq last-time (cdr cur-assoc))
(setcdr cur-assoc cur-time)
(> (abs (- cur-time last-time)) delay))
(push (cons nick cur-time) erc-notify-nick-alist)
t)))
(defun start-irc ()
"Connect to IRC."
(interactive)
(when (y-or-n-p "Do you want to start IRC? ")
(erc :server "irc.freenode.net"
:port 6667
:nick rubens)))
;; (defun erc-start-or-switch ()
;; "Connect to ERC, or switch to last active buffer"
;; (interactive)
;; (if (get-buffer "irc.freenode.net:6667") ; ERC already active?
;; (erc-track-switch-buffer 1) ; yes: switch to last active
;; (when (y-or-n-p "Start ERC? ") ; no: maybe start ERC
;; (erc :server "irc.freenode.net"
;; :port 6667
;; :nick "rsouza"))))
(defun filter-server-buffers ()
(delq nil
(mapcar
(lambda (x) (and (erc-server-buffer-p x) x))
(buffer-list))))
(defun stop-irc ()
"Disconnects from all irc servers"
(interactive)
(dolist (buffer (filter-server-buffers))
(message "Server buffer: %s" (buffer-name buffer))
(with-current-buffer buffer
(erc-quit-server "Asta la vista"))))
(setq erc-autojoin-channels-alist '(("freenode.net"
"#org-mode"
"#hacklabto"
"#emacs"
"#itpug-soci")))
(require 'erc-log)
(require 'erc-notify)
(require 'erc-spelling)
(require 'erc-autoaway)
))
Emacs can help you writing better…I know, I know, this is relative, but the tools here will try to help you with the language, at least ;)
Reading these articles will better explain the idea: Joel Kuiper’s spellcheck emacs and Matt Might’s weasel words.
It activates Spell Checking by default. Also uses hunspell instead of ispell as corrector.
Key binding | Command | Result |
---|---|---|
flyspell-popup-correct | C-; | spell-check the word on point |
flyspell-goto-next-error | =C-,= | got to the next error |
flyspell-auto-correct-word | C-M-i | auto-correct the word |
- Install Hunspell from your distribution package manager or use Hunspell page
- Download the language dictionary extension from Libreoffice or Openoffice
- It will download the file
<language>.oxt
. Rename it to<language>.zip
and unzip it into a temporary folder. - Copy the
<language>.dic
and<language>.aff
files from there to a folder where you save dictionary files, usually to~/usr/local/share/hunspell/
or~/usr/share/hunspell/
- Add that path to shell env variable
DICPATH
:setenv DICPATH $MYLOCAL/share/hunspell
- Restart emacs so that when hunspell is run by ispell/flyspell, that env variable is effective.
Hunspell will search for a dictionary called en_US
in the path specified by $DICPATH
.
(use-package flyspell
:demand t
:config
(progn
(validate-setq ispell-program-name "hunspell"
ispell-dictionary "en_GB"
ispell-dictionary-alist '(("en_GB"
"[[:alpha:]]"
"[^[:alpha:]]"
"[']" nil ("-d" "en_GB") nil utf-8)
'("it_IT"
"[[:alpha:]]"
"[^[:alpha:]]"
"[']" nil ("-d" "it_IT") nil utf-8)
)))
(validate-setq flyspell-issue-welcome-flag nil ; turn off flyspell welcome message
flyspell-issue-message-flag nil) ; turn off flyspell messages when checking words
(add-hook 'prog-mode-hook 'flyspell-prog-mode) ; spell check in program comments
(add-hook 'org-mode-hook 'flyspell-mode) ; spell check in md/plain text/org-mode
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'markdown-mode-hook 'flyspell-mode))
Switch between the most used dictionaries in my case.
(defun switch-dictionary ()
(interactive)
(let* ((dic ispell-current-dictionary)
(change (if (string= dic "en_GB") "it_IT" "en_GB")))
(ispell-change-dictionary change)
(message "Dictionary switched from %s to %s" dic change)))
(global-set-key (kbd "<f8>") 'switch-dictionary)
Flyspell usually slows down the responsiveness when writing texts. flyspell-lazy is used to improve Flyspell responsiveness using idle timers.
(use-package flyspell-lazy
:demand t
:after flyspell
:config
(flyspell-lazy-mode 1))
Flyspell-popup is used to correct words with Flyspell in popup menus.
(use-package flyspell-popup
:after flyspell
:bind (:map flyspell-mode-map
("C-;" . flyspell-popup-correct)))
LanguageTool is an Open Source proofreading program for English, French, German, Polish, and more than 20 other languages.
(use-package langtool
:bind (("C-x 4 w" . langtool-check) ; check buffer and show warnings
("C-x 4 W" . langtool-check-done) ; finish checking and remove markers
("C-x 4 l" . langtool-switch-default-language) ; swicth languages
("C-x 4 n" . langtool-goto-next-error) ; go to the next error
("C-x 4 4" . langtool-show-message-at-point) ; show the warning at point
("C-x 4 c" . langtool-correct-buffer) ; correct markers
)
:config
(validate-setq langtool-language-tool-jar "/usr/share/java/languagetool/languagetool-commandline.jar"
langtool-java-bin "/usr/bin/java"
langtool-mother-tongue "en")
(setq langtool-disabled-rules '("WHITESPACE_RULE"
"EN_UNPAIRED_BRACKETS"
"COMMA_PARENTHESIS_WHITESPACE"
"EN_QUOTES"))
;; show suggestions in a popup
(defun langtool-autoshow-detail-popup (overlays)
(when (require 'popup nil t)
;; Do not interrupt current popup
(unless (or popup-instances
;; suppress popup after type `C-g` .
(memq last-command '(keyboard-quit)))
(let ((msg (langtool-details-error-message overlays)))
(popup-tip msg)))))
(validate-setq langtool-autoshow-message-function
'langtool-autoshow-detail-popup))
Writegood is a minor mode to aid in finding common writing problems. It highlights text based on a set of weasel-words, passive-voice and duplicate words. Matt Might’s weaselwords scripts inspired this mode.
(use-package writegood-mode
:disabled t
:config
(progn
(add-hook 'org-mode-hook 'writegood-mode)
(add-hook 'text-mode-hook 'writegood-mode)
(add-hook 'markdown-mode-hook 'writegood-mode)))
- agressive-indent-mode keeps the code always indented.
- highligh-indent-guides minor mode to highlight indentation. I prefer it over indent-guide (too slow when I tested it)
(use-package aggressive-indent
:demand t
:config
(global-aggressive-indent-mode 1)
(add-to-list 'aggressive-indent-excluded-modes 'html-mode)
)
;; Leaving disabled for now. It does
(use-package highlight-indent-guides
:disabled t
:config
(add-hook 'prog-mode-hook 'highlight-indent-guides-mode)
(setq highlight-indent-guides-method 'column)
;;(set-face-background 'highlight-indent-guides-odd-face "#3f3f39")
;;(set-face-background 'highlight-indent-guides-even-face "#32322d")
)
- smartparens is a minor mode that deals with parens pairs and tries to be smart about it. There are good tips here.
- rainbow-delimiters puts different colours on parenthesis depending on their depth.
(use-package smartparens-config
:ensure smartparens
:config
(show-smartparens-global-mode t))
(add-hook 'prog-mode-hook 'turn-on-smartparens-strict-mode)
(add-hook 'markdown-mode-hook 'turn-on-smartparens-strict-mode)
(use-package rainbow-delimiters
:demand t
:config
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
These are 2 options for searching software documentation from within Emacs: Zeal (if you are on Linux) or Dash (if on macOS).
Remember: Install the docsets after installing Zeal or Dash
(cond ((system-is-linux)
(use-package zeal-at-point
:config
(add-to-list 'zeal-at-point-mode-alist '(python-mode . "python"))
(add-to-list 'zeal-at-point-mode-alist '(sql-mode . "postgresql"))
))
((system-is-mac)
(use-package dash-at-point
:config
(add-to-list 'zeal-at-point-mode-alist '(python-mode . "python"))
(add-to-list 'zeal-at-point-mode-alist '(sql-mode . "postgresql"))
)))
AsciiDoc is a text document format for writing short documents, articles, books and UNIX man pages. AsciiDoc files can be translated to HTML and DocBook markups.
adoc-mode is an Emacs major mode for editing AsciiDoc files. It emphasizes on the idea that the document is highlighted so it pretty much looks like the final output. What must be bold is bold, what must be italic is italic etc. Meta characters are naturally still visible, but in a faint way, so they can be easily ignored.
(use-package adoc-mode
:config
(autoload 'adoc-mode "adoc-mode" nil t))
(use-package jinja2-mode
:mode "\\.j2\\'")
Installs json-mode and make its reformat keybinding match the global default.
(use-package json-mode
:commands json-mode
:config
(bind-keys :map json-mode-map
("C-c <tab>" . json-mode-beautify)))
(use-package markdown-mode)
(use-package slime
:config
(setq inferior-lisp-program "sbcl")
(load (expand-file-name "~/quicklisp/slime-helper.el")))
(use-package elisp-slime-nav
:after slime
:config
(dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook))
(add-hook hook 'turn-on-elisp-slime-nav-mode)))
Emacs has SQLi mode buitin, which work pretty well to connect to databases. Here I am configuring it for PostgreSQL, of course.
sqlup-mode is a minor mode to upcase SQL keyword and functions.
;; Make SQLi default to PostgreSQL syntax highlighting
;; https://blogs.gentoo.org/titanofold/2011/05/17/postgresql-syntax-highlighting-in-emacs/
(eval-after-load "sql"
'(progn (sql-set-product 'postgres)))
;; Set default config for login
;; https://truongtx.me/2014/08/23/setup-emacs-as-an-sql-database-client/
(setq sql-postgres-login-params
'((user :default "postgres")
(database :default "postgres")
(server :default "localhost")
(port :default 5432)))
;; Truncate lines to better visualize many columns tables
(add-hook 'sql-interactive-mode-hook
(lambda ()
(toggle-truncate-lines t)))
(use-package sqlup-mode
:bind (("C-c u" . sqlup-capitalize-keywords-in-region))
:config
(add-hook 'sql-mode-hook
'sqlup-mode) ; capitalize keywords in SQL mode
(add-hook 'sql-interactive-mode-hook
'sqlup-mode)) ; and in an interactive session (e.g. psql)
(use-package yaml-mode)
My frustration with shells makes me enjoy Emacs Shell, but there are some significant differences to address. To this end, I documented most features.
The keychain-environmet
is to be used together with keychain. It loads the
file “$HOME/.keychain/$HOSTNAME-sh” and parses it for the SSH_AUTH_SOCK and
SSH_AUTH_PID variables.
(use-package keychain-environment
:config
(keychain-refresh-environment))
(setenv "PAGER" "cat")
(setq eshell-scroll-to-bottom-on-input t)
;; Define a keybinding to get to your eshell quickly.
(global-set-key (kbd "C-c e") 'eshell)
;; Visual commands are commands which require a proper terminal.
;; eshell will run them in a term buffer when you invoke them.
(setq eshell-visual-commands
'("less" "tmux" "htop" "top" "bash" "zsh" "fish"))
(setq eshell-visual-subcommands
'(("git" "log" "l" "diff" "show")))
(setq eshell-cmpl-cycle-completions t) ;TAB for suggestion
(add-hook 'eshell-mode-hook (lambda ()
(setq-local show-trailing-whitespace nil)
(semantic-mode -1)
(hl-line-mode -1)
(global-hl-line-mode -1)))
;; Define a pretty prompt.
(use-package eshell-git-prompt
:config
(eshell-git-prompt-use-theme 'powerline))
;; Like Plan-9 shell
(use-package em-smart
:ensure nil
:init
(add-hook 'eshell-mode-hook 'eshell-smart-initialize)
:config
(setq eshell-where-to-jump 'begin
eshell-review-quick-commands nil
eshell-smart-space-goes-to-end t))
Navigate eshell history using counsel. Keybinding to `C-c C-l` - Boccaperta
FIXME: There’s a bug on Eshell that forces the key-binding to be include using the `add-hook` below (not nice!). As soon as the bug is fixed, add the key-binding using `bind` from use-package:
:bind (:map eshell-mode-map (“C-c C-l” . mu-counsel-esh-history))
(defun mu-counsel-esh-history ()
"Browse Eshell history."
(interactive)
(setq ivy-completion-beg (point))
(setq ivy-completion-end (point))
(ivy-read "Symbol name: "
(delete-dups
(ring-elements eshell-history-ring))
:action #'ivy-completion-in-region-action))
(add-hook 'eshell-mode-hook
#'(lambda ()
(bind-key "C-c C-l" #'mu-counsel-esh-history
eshell-mode-map)))
(setq tramp-default-method "ssh")
(use-package ansible
:init
(add-hook 'yaml-mode-hook '(lambda () (ansible 1))))
(use-package ansible-doc
:after ansible
:init
(add-hook 'yaml-mode-hook #'ansible-doc-mode))
(use-package puppet-mode)
(use-package vagrant)
(use-package vagrant-tramp
:after vagrant
:config
(eval-after-load 'tramp '(vagrant-tramp-enable)))
Here is a list of some themes I like. Just enable it on the configuration below; don’t forget the disable the one that is active.
- ample-themes
- apropospriate-theme
- doom-theme
- leuven-theme
- material-theme
- monokai-theme
- sanityinc-tomorrow
- solarized-theme
- spacemacs-theme
- zenburn-theme
- zerodark-theme
Some themes, as solarized and material, change the pitch size of org-headers,
leaving them a little too big for my taste, so I adjust them. I’m adjusting the
material-theme
here. If you want to makes changes to the solarized-theme
instead, check here.
(use-package material-theme
:demand t
:init
(load-theme 'material t)
:config
(custom-theme-set-faces
'material
`(org-level-1 ((t (:inherit outline-1
:background ,"#455A64"
:weight bold
:box (:style released-button)
:height 1.1))))
`(org-level-2 ((t (:inherit outline-2
:background ,"#35575b"
:box (:style released-button)
:height 1.0))))
`(org-level-3 ((t (:inherit outline-3 :height 1.0))))
`(org-level-4 ((t (:inherit outline-4 :height 1.0))))
`(org-level-5 ((t (:inherit outline-5 ))))
`(org-level-6 ((t (:inherit outline-6 ))))
`(org-level-7 ((t (:inherit outline-7 ))))
`(org-level-8 ((t (:inherit outline-8 ))))
`(org-level-9 ((t (:inherit outline-9 ))))
))
(cond ((system-is-linux)
(set-face-attribute 'default nil
;;:family "Iosevka"
:family "Source Code Pro"
:height 90))
((system-is-mac)
(set-face-attribute 'default nil
:family "Source Code Pro"
:height 100)))
;; Set a smaller font for the mode line
(set-face-attribute 'mode-line nil
:family "Source Code Pro"
:height 90)
;; Set a font with great support for Unicode Symbols to fallback in those case
;; where certain Unicode glyphs are missing in the current font.
;; Test range: 🐷 ❤ ⊄ ∫ 𝛼 α 🜚 Ⓚ
(set-fontset-font "fontset-default" nil
(font-spec :size 100 :name "Fontawesome"))
;;(font-spec :size 20 :name "Symbola"))
;; Insert fontawesome icons.
(use-package fontawesome)
all-the-icons is a utility package to collect various Icon Fonts and propertize them within Emacs.
(use-package all-the-icons :demand t)
Delight enables you to easily customise how major and minor modes appear in the ModeLine.
It is similar in purpose to DiminishedModes but it accounts for major modes as well as minor modes, and also incorporates the necessary ‘eval-after-load’ call for minor modes, which makes the configuration simpler.
(use-package delight
:demand t
:config
(delight '((company-mode " Ⓐ" company)
(hs-minor-mode " ⓗ" hideshow)
(outline-minor-mode " Ⓞ" outline)
(outline-mode " Ⓞ" :major)
(git-gutter-mode " Ⓖ" git-gutter)
(flyspell-mode " Ⓕ" flyspell)
(smartparens-mode " Ⓢ" smartparens)
(elisp-slime-nav-mode nil elisp-slime-nav)
(emacs-lisp-mode "Elisp" :major)
(lisp-interaction-mode "LispI" :major)
(ess-noweb-font-lock-mode nil ess)
(reftex-mode " Ⓡ" reftex)
(visual-line-mode " Ⓦ" simple)
(ess-noweb-mode " Ⓝ" ess)
(anzu-mode " Ⓩ" anzu)
(abbrev-mode " ⓐ" abbrev)
(helm-mode " Ⓗ" helm)
(rainbow-mode)
(org-indent-mode nil org-indent)
(which-key-mode nil which-key)
(counsel-mode nil counsel)
(ivy-mode nil ivy)
(fixmee-mode nil fixmee)
(button-lock-mode nil button-lock)
(beacon-mode nil beacon)
(page-break-lines-mode nil page-break-lines)
(auto-revert-mode nil autorevert)
(undo-tree-mode nil undo-tree)
;;(server-buffer-clients . " ⓒ")
)))
(use-package spaceline
:demand t
:config
(setq powerline-default-separator 'wave
spaceline-window-numbers-unicode t
spaceline-workspace-numbers-unicode t))
(use-package spaceline-config
:demand t
:ensure nil
:config
(spaceline-spacemacs-theme))
Better looking break lines.
(use-package page-break-lines
:init (global-page-break-lines-mode))