Skip to content

rubensts/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Emacs Configuration

./img/emacs_icon.png[fn:1]

About | Packages Setup | Built-in Capabilities

About

ATTENTION: This is a work in progress

ATTENTION: This configuration has been tested on Emacs 25.

Emacs Configuration using Org-Babel

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.

Dependencies

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.

Source of Ideas

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:

If using it on Mac

For installing Emacs on Mac, check these:

How it works

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.

Installation

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)

Generate the first init.el file

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

Initial Setup

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”.

Debugging

Allow more messages in Messages buffer. A more complete log helps on debugging issues.

(setq message-log-max 10000)

Package management

;; 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)

Initialization

(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)

Garbage collector

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)

Environment fixup

(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)))

Emacs server

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)))

Built-in Capabilities

OS compatibility

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"))

sensible-defaults.el

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)

Better Defaults

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")

Calendar

Location

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")

Holidays

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")
       ))

History

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)

Scrolling

(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)

Useful functions

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)

Custom functions

Customizing the customize

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))

Split window and move

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))

Smarter start of line

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)

Kill the current buffer

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)

Org header IDs

(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)

Main packages

evil

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

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 ;)

KeysCommandResults
C-c C-x C-lShow latex fragments
C-c C-cGet rid of latex fragments

general settings

(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)))
  )

org-clock

(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

org-capture-templates

(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)
          )))

org-bullets

(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

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 " / "))

ox.el

(use-package ox
  :ensure org-plus-contrib
  :config
  (validate-setq org-export-with-smart-quotes t))

ox-pandoc

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)))))
                 )
  )

org-babel

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)
           ))))

hydra

(use-package hydra
  :config
  (setq lv-use-separator t)
  (set-face-attribute 'hydra-face-blue nil :foreground "deep sky blue" :weight 'bold))

ivy

Ivy is a generic completion frontend for Emacs.

Swiper shows an overview during regex searching. It uses the ivy back end for the overview.

KeybindingFunctionsResult
C-M-iivy-display-functiondisplays the function candidate list

ivy

(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)

counsel

(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

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

KeyCommandWhat it does
spersp-switchQuery a perspective to switch or create
kpersp-remove-bufferQuery a buffer to remove from current perspective
cpersp-killQuery a perspective to kill
rpersp-renameRename current perspective
apersp-add-bufferQuery an open buffer to add to current perspective
Apersp-set-bufferAdd buffer to current perspective and remove it from all others
ipersp-importImport a given perspective from another frame.
n, <right>persp-nextSwitch to next perspective
p, <left>persp-prevSwitch 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)

magit

(use-package magit
  :config
  (setq magit-completing-read-function 'ivy-completing-read
        magit-display-buffer-function 'magit-display-buffer-fullframe-status-topleft-v1))

Base packages

ace-window

(use-package ace-window)

alert

(use-package alert
  :demand t)

anzu

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 ""))

async

Simple library for asynchronous processing in Emacs

(use-package async
  :demand t
  :config
  (dired-async-mode t)
  (async-bytecomp-package-mode t))

avy

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))

beacon

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

Bookmarks to files and directories

(use-package bookmark
  :config
  (setq bookmark-completion-ignore-case nil)
  (bookmark-maybe-load-default-file))

company

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

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 (FIXME)

diff-hl-mode highlights uncommitted changes on the left side of the window, allows you to jump between and revert them selectively.

Keybindings

functionKeybinding
diff-hl-diff-goto-hunkC-x v =
diff-hl-revert-hunkC-x v n
diff-hl-previous-hunkC-x v [
diff-hl-next-hunkC-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))

dired

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

easy-kill

Provide commands easy-kill and easy-mark to let users kill or mark things easily.

KeyCommandAction
M-w wsave word at point
M-w ssave sexp at point
M-w lsave list at point (enclosing sexp)
M-w dsave defun at point
M-w Dsave current defun name
M-w fsave file at point
M-w bsave buffer-file-name or default-directory

The following keys modify the selection:

KeyCommandAction
@append selection to previous kill and exit. For example, M-w d @ will append current function to last kill.
C-wkill selection and exit
+, -and 1..9: expand/shrink selection
0shrink the selection to the initial size i.e. before any expansion
C-SPCturn selection into an active region
C-gabort
?help
(use-package easy-kill
  :bind (([remap kill-ring-save] . easy-kill)
         ([remap mark-sexp] . easy-mark)))

ediff (FIXME)

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

Expand region increases the selected region by semantic units. Just keep pressing the key until it selects what you want.

(use-package expand-region)

fill-column-indicator

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

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

KeystrokesFunction
C-c ffixmee-goto-nextmost-urgent
C-c Ffixmee-goto-prevmost-urgent
C-c vfixmee-view-listing
M-nfixmee-goto-next-by-position ; only when the point is
M-pfixmee-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))

flx

Fuzzy matching for Emacs … a la Sublime Text. It is needed for fuzzy matching in swiper + avy.

(use-package flx)

flycheck

(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)))))
  )

Linting prose

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

graphviz-dot-mode is a mode for the DOT language, used by graphviz.

(use-package graphviz-dot-mode)

neotree

(use-package neotree
  :bind (("<f6>" . neotree-toggle))
  :config
  (validate-setq neo-theme (if window-system 'icons 'arrow)))

paradox

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))

pass

(use-package pass)

pcache

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)

pdf-tools

(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

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

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$")))

ripgrep

Use ripgrep in Emacs.

(use-package rg)

uniquify

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

undo-tree

C-x u to undo-tree-visualize C-/ undo S-C-/ redo

(use-package undo-tree
  :init
  (global-undo-tree-mode))

volatile-highlights

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))

window-numbering

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

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:

KeyAction
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))))

which-key

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"                 . ""))))

Keybindings

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
   ))

Tools

IRC (Internet Relay Chat)

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)
  ))

Spell and grammar checking

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.

flyspell

It activates Spell Checking by default. Also uses hunspell instead of ispell as corrector.

Key bindingCommandResult
flyspell-popup-correctC-;spell-check the word on point
flyspell-goto-next-error=C-,=got to the next error
flyspell-auto-correct-wordC-M-iauto-correct the word

hunspell setup

  1. Install Hunspell from your distribution package manager or use Hunspell page
  2. Download the language dictionary extension from Libreoffice or Openoffice
  3. It will download the file <language>.oxt. Rename it to <language>.zip and unzip it into a temporary folder.
  4. 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/
  5. Add that path to shell env variable DICPATH: setenv DICPATH $MYLOCAL/share/hunspell
  6. 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 dictionaries

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-lazy

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

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

LanguageTool is an Open Source proof­reading 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

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)))

Programming

indentation

(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")
  )

parenthesis and delimiters

  • 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))

searching documentation

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"))
       )))

ascii-doc

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))

jinja2

(use-package jinja2-mode
  :mode "\\.j2\\'")

json-mode

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)))

markdown

(use-package markdown-mode)

slime

(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)))

SQL

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)

yaml

(use-package yaml-mode)

Devops

eshell

source

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))

eshell history with counsel

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)))

tramp

(setq tramp-default-method "ssh")

ansible

(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))

puppet

(use-package puppet-mode)

vagrant

(use-package vagrant)

(use-package vagrant-tramp
  :after vagrant
  :config
  (eval-after-load 'tramp '(vagrant-tramp-enable)))

Appearance

Themes

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.

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 ))))
   ))

Fonts

(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)

Modeline

all-the-icons

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

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 . " ⓒ")
             )))

spaceline

(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))

Other details

Better looking break lines.

(use-package page-break-lines
  :init (global-page-break-lines-mode))

About

My Emacs configuration

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published