Skip to content

anler/.emacs.d-literate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of Contents

About

https://raw.githubusercontent.com/ikame/.emacs.d/master/img/emacs.png

This mi personal Emacs configuration files written in a literate-programming style taught to me by my good friend mgdelacroix.

Emacs

Emacs dependency management

I use Cask for dependency management and Pallet as a package manager (everytime I install a package it adds it as a dependency to my Cask file).

(require 'cask "~/.cask/cask.el")

;; Path to manually installed tramp version (2.2.10) since couldn't use sudo with
;; the default one (2.2.6) in Fedora 20
(add-to-list 'load-path (expand-file-name "/usr/local/share/emacs/site-lisp"))

(cask-initialize)
(require 'pallet)
(pallet-mode t)
(require 'cl)

(load "~/.emacs.d/custom-paths.el" 'noerror)

Custom defined functions

Compose functions

Taken from nullprogram.

(defun compose (&rest funs)
  "Return function composed of FUNS."
  (lexical-let ((lex-funs funs))
    (lambda (&rest args)
      (reduce 'funcall (butlast lex-funs)
              :from-end t
              :initial-value (apply (car (last lex-funs)) args)))))

Create circular lists

(defun cycle (list)
  "Takes a list LIST and converts it into a circular list"
  (let ((cycle (copy-list list)))
    (setf (cdr (last cycle)) cycle)
    cycle))

Comment lines

(defun comment-or-uncomment ()
  "Comment or uncomment current line or region if there's a region active."
  (interactive)
  (let ((start (line-beginning-position))
        (end (line-end-position)))
    (when (region-active-p)
      (setq start (save-excursion
                    (goto-char (region-beginning))
                    (beginning-of-line)
                    (point))
            end (save-excursion
                  (goto-char (region-end))
                  (end-of-line)
                  (point))))
    (comment-or-uncomment-region start end)))

(defun comment-or-uncomment-lisp-form ()
  "Comment or uncomment current lisp form"
  (interactive)
  (save-excursion
    (beginning-of-line)
    (if (search-forward-regexp ";+ " (save-excursion
                                       (end-of-line)
                                       (point))
                               :noerror)
        (call-interactively 'emr-lisp-uncomment-block)
      (call-interactively 'emr-lisp-comment-form))))

Scroll the buffer

The exact same functionality VIM has for C-e and C-y in normal mode:

(defun scroll-up-one-line-command ()
  "Scroll text of selected window upward 1 line."
  (interactive)
  (scroll-up-command 1)
  (next-line))

(defun scroll-down-one-line-command ()
  "Scroll text of selected window downward 1 line."
  (interactive)
  (scroll-down-command 1)
  (previous-line))

And the same but without leaving the current window:

(defun scroll-up-one-line-other-window ()
  "Scroll other window one line up"
  (interactive)
  (scroll-other-window 1))

(defun scroll-down-one-line-other-window ()
  "Scroll other window one line down"
  (interactive)
  (scroll-other-window -1))

Join lines

(defun join-line-below ()
  "Join line bellow current line."
  (interactive)
  (join-line -1))

Kill buffer and delete its file

Modified version of one found in: [[http://tuxicity.se/emacs/elisp

(defun kill-buffer-and-file (buffer-name)
  "Removes file connected to current buffer and kills buffer."
  (interactive "bKill buffer and its file:")
  (let* ((buffer (get-buffer buffer-name))
         (filename (buffer-file-name buffer)))
    (if (not (and filename (file-exists-p filename)))
        (error "Buffer '%s' is not visiting a file!" buffer-name)
      (delete-file filename)
      (kill-buffer buffer))))

Rename buffer and its file

Original command by Steve Yegge: [link].

(defun rename-buffer-and-file (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME."
  (interactive (list (read-string "New name for buffer and file: " (buffer-name))))
  (let ((name (buffer-name))
        (filename (buffer-file-name)))
    (if (not filename)
        (message "Buffer '%s' is not visiting a file!" name)
      (if (get-buffer new-name)
          (message "A buffer named '%s' already exists!" new-name)
        (rename-file filename new-name 1)
        (rename-buffer new-name)
        (set-visited-file-name new-name)
        (set-buffer-modified-p nil)))))

Extend eval-last-sexp extended

(defun ext/eval-last-sexp (arg)
  "Extension over eval-last-sexp that replaces the last sexp with the
result if called with the universal argument twice."
  (interactive "P")
  (if (= 16 (prefix-numeric-value arg))
      (replace-last-sexp)
    (eval-last-sexp arg)))
(defun replace-last-sexp ()
  "Eval last sexp and replaces it in the buffer with its result."
  (interactive)
  (let ((result (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" result))))

Partial functions

(defun partial (function &rest args)
  (lambda (&rest more-args)
    (apply function (append args more-args))))

Create scratch buffers

Command for creating additional scratch buffers.

(defun create-scratch-buffer (mode)
  "Create a brand new scratch buffer."
  (interactive
   (list
    (completing-read
     "Pick a mode for the scratch buffer: "
     (mapcar #'cdr auto-mode-alist))))
  (cl-labels ((get-scratch-buffer-name (index)
                                       (let ((name (format "*scratch<%s>*" index)))
                                         (if (null (get-buffer name))
                                             name
                                           (get-scratch-buffer-name (1+ index))))))
    (switch-to-buffer (get-buffer-create (get-scratch-buffer-name 1)))
    (call-interactively (intern mode))))

Duplicate line

(defun duplicate-line ()
  "Duplicate the line below the cursor and move the cursor 
to the duplicated line."
  (interactive)
  (kill-ring-save (line-beginning-position)
                  (line-end-position))
  (save-excursion
    (end-of-line)
    (open-line 1)
    (next-line 1)
    (yank))
  (next-line 1))

Quit other window

(defun quit-other-window ()
  "Send `quit-window' in the window returned by `other-window'"
  (interactive)
  (other-window 1)
  (quit-window))

Select other window backward

(defun other-window-backward (count)
  "Select another window in anti-cyclic ordering of windows.
COUNT specifies the number of windows to skip, starting with the
selected window, before making the selection."
  (interactive "P")
  (other-window (- (prefix-numeric-value count))))

(global-set-key (kbd "C-x C-o") 'other-window-backward)

Show which function

(autoload 'which-function "which-func")
(defun show-which-function ()
  "Show the function definition the cursor is in the echo area"
  (interactive)
  (message (which-function)))

Electric pairs

(setq skeleton-pair-alist '((?\( _ ?\))
                            (?[  _ ?])
                            (?{  _ ?})
                            (?\" _ ?\")
                            (?\' _ ?\')))

(defun electric-pair ()
  "Insert character pair without surrounding spaces"
  (interactive)
  (let (parens-require-spaces)
    (insert-pair)))

(defun common-electric-pair-string-delimiter ()
  (when (and electric-pair-mode
             (memq last-command-event '(?\" ?\'))
             (let ((count 0))
               (while (eq (char-before (- (point) count)) last-command-event)
                 (setq count (1+ count)))
               (= count 3)))
    (save-excursion (insert (make-string 3 last-command-event)))))

(defun electric-pair-backspace (arg)
  (interactive "p")
  (if (eq (char-after)
          (car (last (assq (char-before) skeleton-pair-alist))))
      (and (char-after) (delete-char 1)))
  (delete-backward-char arg))

(defun set-common-pairs (mode-map)
  (add-hook 'post-self-insert-hook #'common-electric-pair-string-delimiter :append :local)
  (global-set-key [backspace] #'electric-pair-backspace)
  (define-key mode-map "\"" 'electric-pair)
  (define-key mode-map "\'" 'electric-pair)
  (define-key mode-map "(" 'electric-pair)
  (define-key mode-map "[" 'electric-pair)
  (define-key mode-map "{" 'electric-pair))

Projects

(defun in-project-p ()
  (and (fboundp 'projectile-project-p)
       (projectile-project-p)))

General

No bell

(setq ring-bell-function 'ignore)

Debug on error

(setq debug-on-error nil)

Wrap long lines

(global-visual-line-mode)

Display column number in the modeline

(setq column-number-mode t)

Display buffer size in the modeline

(setq size-indication-mode t)

Echo keystrokes earlier

(setq echo-keystrokes 0.2)

Put backups in another place

(setq backup-directory-alist `(("." . "~/.emacs.d/saves")))

Also do the backup by copying the file (slower but safer):

(setq backup-by-copying t)

delete all versions automatically:

(setq delete-old-versions t)

and add version number to backup name:

(setq version-control t)

Replace selected text when start typing

(delete-selection-mode)

Update buffer contents if they are externally changed

(global-auto-revert-mode)
(setq auto-revert-verbose nil)

Never convert spaces to tabs

Emacs likes to do this whenever it can.

(set-default 'indent-tabs-mode nil)

Enable recent files mode (File > Open Recent)

(recentf-mode)

Hungry deletion

Deletes all consecutive white spaces

(require 'hungry-delete)
(global-hungry-delete-mode)

Increase memory threshold for garbage collection

As Magnar Sveen said:

Don’t be so stingy on the memory, we have lots now. It’s the distant future.

(setq gc-cons-threshold 20000000)

Name buffers with same filenames other than buffer<N>

(require 'uniquify)
(setq uniquify-buffer-name-style 'post-forward)

Confirmation when closing Emacs

I do this very often, this is my insurance.

(setq confirm-kill-emacs 'yes-or-no-p)

Start an Emacs server on startup

(require 'server)

(setq server-use-tcp t
      server-socket-dir "~/.emacs.d/server")

(unless (server-running-p)
    (server-start))

Enable ido-mode

ido-mode (Interactively DO things) is a mode that let’s you work with files and buffer more effectively giving you auto-completion for buffer and file names.

(ido-mode)

Use fuzzy-matching by default

(setq ido-enable-flex-matching t)

Use it in all possible places

(ido-everywhere)

img/ido.gif

Use a vertical interface… not at the moment

;; (ido-vertical-mode)

img/ido-vertical-mode.gif

Ido interface when using completion-at-point.

(ido-at-point-mode)

img/ido-at-point.gif

Better help with discover.el and guide-key

See discover.el.

(require 'discover)
(global-discover-mode)

See guide-key-tip.

(require 'guide-key)
(setq guide-key/guide-key-sequence '("C-x" "C-c" "C-x 4" "C-x v"))
(guide-key-mode 1)  ; Enable guide-key-mode

(require 'guide-key-tip)
(setq guide-key-tip/enable t)

Disable transient-mark-mode

Disable transient-mark-mode to use C-x C-x without activating the region:

(transient-mark-mode -1)

Keep abbrev expansion predictable

(setq dabbrev-case-fold-search nil)

Spice info mode

(eval-after-load "info" '(require 'info+))

Open really large files with vlf

(require 'vlf-integrate)

Use mykie for extending keybindings

(require 'mykie)
(setq mykie:use-major-mode-key-override t)
(mykie:initialize)

Diminish the mode line

(when (require 'diminish nil 'noerror)
  (eval-after-load "company"
      '(diminish 'company-mode))
  (eval-after-load "abbrev"
    '(diminish 'abbrev-mode))
  (eval-after-load "projectile"
    '(diminish 'projectile-mode))
  (eval-after-load "whitespace"
    '(diminish 'global-whitespace-mode))
  (eval-after-load "paredit"
    '(diminish 'paredit-mode))
  (eval-after-load "eldoc"
    '(diminish 'eldoc-mode))
  (eval-after-load "rainbow-mode"
    '(diminish 'rainbow-mode))
  (eval-after-load "magit"
    '(diminish 'magit-auto-revert-mode " ±")))

Set default browser

(setq browse-url-browser-function 'browse-url-generic
      browse-url-generic-program "firefox")

Remote sudo access with TRAMP

With the following you can edit remote root files with: C-x C-f /sudo:root@localhost:<path>.

(require 'tramp)
(add-to-list 'tramp-default-proxies-alist
             '(nil "\\`root\\'" "/ssh:%h:"))
(add-to-list 'tramp-default-proxies-alist
             '((regexp-quote (system-name)) nil nil))

Pretty symbols

(pretty-symbols-mode)

Emacs Lisp Sources

(define-key 'help-command (kbd "C-l") 'find-library)
(define-key 'help-command (kbd "C-f") 'find-function)
(define-key 'help-command (kbd "C-k") 'find-function-on-key)
(define-key 'help-command (kbd "C-v") 'find-variable)

(require 'elisp-slime-nav)
(dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook lisp-interaction-mode-hook))
  (add-hook hook 'elisp-slime-nav-mode))

Once this is done you’ll be able to jump to the source of the Emacs Lisp object at point (function or variable) with M-. jump back with M-,=. You can also see the description of the object at point using =C-c C-d or C-c C-d d.

Hunspell hanging my emacs

(setq-default ispell-program-name "aspell")

Allow answer `y` for `yes`

(defalias 'yes-or-no-p 'y-or-n-p)

Centered window mode

(setq cwm/top-padding-factor .12
      cwm/reset-on-splitting-horizontally nil)
;; (centered-window-mode)

Autocompletion

(add-hook 'after-init-hook 'global-company-mode)
(global-set-key (kbd "M-/") 'hippie-expand)

Better window movement

(require 'smart-window)

Appearance

Startup screen

(setq inhibit-startup-message t
      initial-scratch-message nil)

Scrollbars

(if (boundp 'scroll-bar-mode)
    (scroll-bar-mode -1))

Toolbar

(if (boundp 'tool-bar-mode)
    (tool-bar-mode -1))

Menubar

(if (boundp 'menu-bar-mode)
    (menu-bar-mode -1))

Disable cursor blink

(blink-cursor-mode -1)

Buffer file name as frame title

(when window-system
  (setq frame-title-format '(buffer-file-name "%f" ("%b"))))

Cycle through color themes

(load "~/.emacs.d/set-theme.el" 'noerror)
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")

(defvar current-theme nil "Name of the theme being used.")
(defvar themes-list (cycle (custom-available-themes)) "List of themes to cycle through.")
(defvar default-theme nil "Default theme to use.")

(defun my/load-theme (theme)
  "Just like the original `load-theme' but it disables the current theme before 
activating the new one."
  (interactive
   (list
    (intern (completing-read "Load custom theme: "
                             (mapcar 'symbol-name
                                     (custom-available-themes))))))
  (my/disable-theme current-theme)
  (my/enable-theme theme))

(defun use-next-theme ()
  "Use the next theme in themes-list."
  (interactive)
  (if current-theme
      (my/disable-theme current-theme))
  (my/enable-theme (pop themes-list)))

(defun my/disable-theme (theme)
  (unless (eq theme 'default)
    (disable-theme theme)))

(defun my/enable-theme (theme)
  (unless (eq theme 'default)
    (setq current-theme theme)
    (load-theme current-theme t))
  (let* ((font "Fantasque Sans Mono")
         (size 15)
         (font-and-size (format "%s-%s" font size)))
    (when (member font (font-family-list))
      (add-to-list 'initial-frame-alist `(font . ,font-and-size))
      (add-to-list 'default-frame-alist `(font . ,font-and-size))
      (set-frame-font font-and-size)))
  (message "Theme %s enabled" theme))

(if (null default-theme)
    (use-next-theme)
  (my/enable-theme default-theme))

Org mode

Text

(add-hook 'org-mode-hook (lambda ()
                           (set-fill-column 99)
                           (auto-fill-mode)))

Colorize code blocks

(setq org-src-fontify-natively t)

Display inline images

(setq org-html-inline-images t)

Export LaTeX fragments

(setq org-export-with-LaTeX-fragments t)

More headlines to export

(setq org-export-headline-levels 6)

Set org files directory

(setq org-directory "~/org"
      org-agenda-files '("~/org"))

Set notes file

(setq org-default-notes-file (concat org-directory "/notes.org")
      org-capture-templates
      '(("t" "Todo" entry (file+headline (concat org-directory "/gtd.org") "Tasks")
         "* TODO %?\n %i\n %a")
        ("d" "Literate" entry (file+headline (concat org-directory "/literate.org") "Literate")
         "* %?\n %i\n %a")
        ("n" "Note" entry (file+headline (concat org-directory "/notes.org") "Notes")
         "* %?")
        ("j" "Journal" entry (file+datetree (concat org-directory "/journal.org"))
         "* %?" :clock-in t :clock-resume t)
        ("l" "Read it later" checkitem (file+headline (concat org-directory "/readlater.org") "Read it later")
         "[ ] %?")))

Activate babel languages

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (lisp . t)
   (gnuplot . t)
   (dot . t)
   (ditaa . t)
   (R . t)
   (python . t)
   (ruby . t)
   (js . t)
   (clojure . t)
   (sh . t)))

Export code blocks with colors

(require 'ox-latex)
(add-to-list 'org-latex-packages-alist '("" "minted"))
(setq org-latex-listings 'minted)

(setq org-latex-pdf-process
      '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

There are different color-themes you can use with minted, for example you could put this option into your org file to use “monokai”:

#+LaTeX_HEADER: \usemintedstyle{monokai}

To get a list of the supported styles from pygmentize:

pygmentize -L styles

Ditaa executable path

(setq org-ditaa-jar-path "~/.local/bin/ditaa.jar"
      org-babel-ditaa-java-cmd "java")

Encrypting

Options

(require 'epa-file)
(require 'org-crypt )

(setq org-tags-exclude-from-inheritance '("crypt"))

Private

—–BEGIN PGP MESSAGE—– Version: GnuPG v2.0.22 (GNU/Linux)

hQEMAxWSuK3W+kssAQf/Xn/8ehLrOG+9/0N+jX+Ev+w2dRBgKAzTjheHsLhdsuIu iDiK+jSEvBkBtd+dx9Sa1R2DWvKuG6d8/IhSZ3Qf/dyRAnR3muJSyOZDPNIcKIym WyjrGaxycrYamRwu/t5pZar05tPzbyZ5t/X+PZaVdI5w2B0Qb5Pvp0mQvzXxiKC2 LSKCmxpiL3G81lkrIZqvJrqbk8ikUBGyKG1dK31G2e0jqqSoouf5WIQfj7moC0ZA UPLILDpVxde6S8SqepW3hniO+672LqfUGI5RQQcS554hw3PgbF/0Al3jxQw+lzDx dBjPpcFs9Q9iMXlQ+i0gHe87UjOH7f5hLt8ROb4x/dKcARa4EfI7RNGkdKCcv21T gaqJ2QX8ABfIGeo2a7WHWubSLuiB7tSMMBadHDQH6caSXnPKcTXST159aeF15qNY IsLd8YScWuIfXvEQmqjcIKEZ82QHuIKMT6RV8iret7ySXzI/OqVNeJQbV4PZvpxw yziKVRL8P2PtotxNYkfyP3edSpr+ZiD8IVtUI0sqgvYmKcrBBuwsZ2RfD/RB =efPi —–END PGP MESSAGE—–

Helm

KeybindingCommandMeaning
C-c h mhelm-man-womanQuickly jumpp to mana entry using helm prompt or symbol at point
C-c h ihelm-semantic-or-imenuFind major definitions such as function definitions
C-c h /helm-findRun `find` in current directory
C-c h rhelm-regexpPre-configured helm to build regexps
C-c h xhelm-registerPre-configured view of registers
C-c h C-,helm-calcul-expressionCalculate expression
(require 'helm-config)
(require 'helm-descbinds)
(helm-descbinds-mode)

(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))

(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "M-y") 'helm-show-kill-ring)
(global-set-key (kbd "C-x b") 'helm-mini)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
(global-set-key (kbd "C-c h x") 'helm-register)
(global-set-key (kbd "M-:") 'helm-eval-expression-with-eldoc)

(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-z")  'helm-select-action)

(when (executable-find "curl")
  (setq helm-google-suggest-use-curl-p t))

(setq helm-quick-update t
      helm-split-window-in-side-p t
      helm-buffers-fuzzy-matching t
      helm-move-to-line-cycle-in-source t
      helm-ff-search-library-in-sexp t
      helm-scroll-amount 8
      helm-ff-file-name-history-use-recentf t)

(add-to-list 'helm-sources-using-default-as-input 'helm-source-man-pages)

(helm-mode 1)

Dired

General commands

C-M-nnext subdir
C-M-pprevious subdir
M-}next marked file
M-{previous marked file
(toggle details
idisplay subdir listing in current dired buffer
C-u isame as i but you’re able to specify `ls` switches
C-u kdelete a subdir listing
\$hide/show subdirlisting

Commands that act on files

C-u C-uUse all files present, but no directories.
C-u C-u C-uUse all files and dirs except `.’ and `..’.
C-u C-u C-u C-uUse all files and dirs, `.’ and `..’.

Easily copy from one dired split to another

(require 'dired-x)
(setq dired-dwim-target t)

Create a dired file with |

(require 'dired)

(defun dired-create-file (filename)
  "Create FILENAME from Dired in if not exists.
If FILENAME already exists do nothing."
  (interactive "FCreate file: ")
  (shell-command (format "touch %s" filename))
  (when (file-exists-p filename)
    (dired-add-file filename)
    (dired-move-to-filename)))
(define-key dired-mode-map "|" 'dired-create-file)

Activate ggtags on projects

(add-hook 'dired-mode-hook (lambda ()
                             (when (in-project-p)
                               (ggtags-mode))))

Dired imenu

(require 'dired-imenu)

Dired extras

(require 'dired+)

Reuse dired buffer

(toggle-diredp-find-file-reuse-dir 1)

Wrap around commands

(setq diredp-wrap-around-flag t)

Hide details by default

(setq diredp-hide-details-initially-flag t)

Display images

(setq diredp-display-images t)

Find duplicated files

(require 'dired-dups)

Programming

Jump to definition using tags

Code navigation using GNU Global and Exuberant Ctags. See leoliu/ggtags for a complete reference and installation guide.

I already have ggtags-mode listed as a dependency in my Cask file, the only thing left is installing GnuGlobal in the system.

See ggtags usage for a complete list of keybindings.

KeybindingCommandWhat
M-.Find tag.
M-,Continue find tag.
C-c M-?Show definition in minibuffer.
C-M-.Find tag matching regexp.
M-nNext match.
M-pPrevious match.
C-c M-pPrevious mark.
C-c M-nNext mark.
M-*Pop mark.
C-c M-DELDelete tag files.
C-c M-bBrowse as hypertext.
C-c M-jVisit project root.

Treat camel case word as subwords

(global-subword-mode)

Auto-closing and highlighting parens

(show-paren-mode t)
(setq show-paren-style 'mixed)
(autopair-global-mode)

Expand region

expand-region - -demo-

(autoload 'er/expand-region "expand-region")

Wrap region

wrap-region for something like surround in vim:

(require 'wrap-region)
(wrap-region-mode)

Display trailing whitespace

(global-whitespace-mode)
(setq whitespace-style '(face trailing tabs)
      whitespace-line-column nil)

For removing the wrong spaces just call the command whitespace-cleanup. Here I just set it auto for all programming modes:

(add-hook 'prog-mode-hook '(lambda ()
                             (setq whitespace-style '(lines-tail tabs tab-mark trailing empty))
                             (add-hook 'before-save-hook 'whitespace-cleanup nil t)
                             (semantic-mode)))

Snippets

Yasnippet is the best snippets expansion tool for Emacs. It uses the same syntax as TextMate and can even import most TextMate snippets.

(require 'yasnippet)

(setq yas-snippet-dirs '("~/.emacs.d/snippets")
      yas-prompt-functions '(yas/ido-prompt yas/completing-prompt)
      yas/triggers-in-field t
      yas-wrap-around-region t
      yas-verbosity 1)

(yas-global-mode 1)

(define-key yas-keymap (kbd "<return>") 'yas/exit-all-snippets)
(define-key yas-keymap (kbd "C-e") 'yas/goto-end-of-active-field)
(define-key yas-keymap (kbd "C-a") 'yas/goto-start-of-active-field)

(defun yas/goto-end-of-active-field ()
  (interactive)
  (let* ((snippet (car (yas--snippets-at-point)))
         (position (yas--field-end (yas--snippet-active-field snippet))))
    (if (= (point) position)
        (move-end-of-line 1)
      (goto-char position))))

(defun yas/goto-start-of-active-field ()
  (interactive)
  (let* ((snippet (car (yas--snippets-at-point)))
         (position (yas--field-start (yas--snippet-active-field snippet))))
    (if (= (point) position)
        (move-beginning-of-line 1)
      (goto-char position))))

Projects

Projectile is my tool of preference when working on a project and even integrates with ggtags.

(require 'projectile)
(require 'helm-projectile)
(setq projectile-enable-caching t
      projectile-completion-system 'helm)
(projectile-global-mode)
(helm-projectile-on)

Git

Magit is an excellent tool for managing git repositories from Emacs.

(require 'magit)

(require 'git-link)
(setq git-link-remote-alist
  '(("git@github.com" git-link-github)
    ("github.com" git-link-github)
    ("bitbucket.org" git-link-bitbucket)
    ("gitorious.org" git-link-gitorious)))

(setq git-link-commit-remote-alist
  '(("git@github.com" git-link-github)
    ("github.com" git-link-github)
    ("bitbucket.org" git-link-bitbucket)
    ("gitorious.org" git-link-gitorious)))

Searching in files with Ag

ag.el is an Emacs frontend for Ag, aka: the silver searcher.

(require 'ag)

(defun ag-delete-matching-lines ()
  (interactive)
  (read-only-mode -1)
  (call-interactively 'delete-matching-lines)
  (read-only-mode 1))

(defun ag-delete-non-matching-lines ()
  (interactive)
  (read-only-mode -1)
  (call-interactively 'delete-non-matching-lines)
  (read-only-mode 1))

(defun ag-mode-extras ()
  (interactive)
  (local-set-key (kbd "d") 'ag-delete-matching-lines)
  (local-set-key (kbd "f") 'ag-delete-non-matching-lines))

(add-hook 'ag-mode-hook 'ag-mode-extras)

By default everytime you execute ag it creates a new buffer and I prefer to have just one ag buffer openend:

(setq ag-reuse-buffers t
      ag-reuse-window t)

Diffs with ediff

Ignore whitespace

(setq ediff-diff-options "-w")

Display options as a buffer not a frame

(setq ediff-window-setup-function 'ediff-setup-windows-plain)

Common Lisp

(load (expand-file-name "~/quicklisp/slime-helper.el") 'noerror)
(setq inferior-lisp-program "sbcl")

(defun setup-lisp-mode ()
  "Configure lisp mode"
  (interactive)
  (paredit-mode)
  (turn-on-eldoc-mode)
  (rainbow-delimiters-mode))

(add-hook 'lisp-mode-hook 'setup-lisp-mode)

Emacs Lisp

(autoload 'elisp-slime-nav-mode "elisp-slime-nav")

(defun setup-emacs-lisp-mode ()
  "Configure emacs-lisp mode"
  (interactive)
  (paredit-mode)
  (turn-on-eldoc-mode)
  (aggressive-indent-mode)
  (rainbow-delimiters-mode)
  (local-set-key (kbd "C-;") #'comment-or-uncomment-lisp-form))

(add-hook 'emacs-lisp-mode-hook #'setup-emacs-lisp-mode)

Python

Globals

(setq python-shell-interpreter "ipython"
      python-shell-interpreter-args ""
      python-max-column 99
      python-indent-offset 4)

Python mode

(defun python-mode-initialize ()
  (interactive)
  (setq-local whitespace-line-column python-max-column)
  (setq-local whitespace-style (append whitespace-style '(face lines-tail)))
  (setq fill-column python-max-column
        flycheck-flake8-maximum-line-length python-max-column)
  (flycheck-mode)
  (ggtags-mode)
  (anaconda-mode)
  (highlight-lines-matching-regexp "i?pdb.set_trace()"))

(add-hook 'python-mode-hook 'python-mode-initialize)

(defun python-get-buffer-filename-as-module (buffername)
  "Insert the path to the python module represented by BUFFERNAME"
  (interactive "b")
  (unless (string= (f-ext buffername) "py")
    (error "%s is not a python module" buffername))
  (let* ((path (f-short (buffer-file-name (get-buffer buffername))))
         (project-root (f-short (projectile-root-bottom-up path '("manage.py"))))
         (module-unix-path (s-chop-prefix project-root path))
         (module-python-path (s-replace "/" "." (f-no-ext module-unix-path))))
    (insert module-python-path)))

Treat .jinja as html.

(add-to-list 'auto-mode-alist '("\\.jinja\\'" . html-mode))

Pretty symbols

(add-hook 'prog-mode-hook #'pretty-symbols-mode)

Haskell

Key bindings in haskell-mode (with haskell-indent and inf-haskell.el).

Code editing keys:

C-c C-=inserts an = sign and lines up type signatures and other pattern matches nicely.
C-c C-|inserts a guard |
C-c C-oinserts a guard | otherwise = and lines up existing guards
C-c C-winserts a where keyword
C-c C-.aligns code over a region in a “sensible” fashion.

Haskell interpreter keys:

C-c C-lload current buffers file into Haskell interpreter
C-c C-rreload current Haskell interpreter session
C-c C-tgets :type for symbol at point, and remembers it
C-u C-cC-t inserts a type annotation, for symbol at point, on the line above
C-c C-igets :info for symbol at point
C-c M-.find definition of (interpreted) symbol at point
C-c C-bor C-c C-z switch to Haskell interpreter (starts one if needed)
C-c C-dfind haddock documentation about symbol
C-c TABquery the haskell interpreter for the info of the given expression
C-c C-vcheck current buffers file with hlint
(defun setup-haskell-mode ()
  (interactive)
  (turn-on-haskell-doc-mode)
  (turn-on-haskell-indentation)
  (inf-haskell-mode)
  (interactive-haskell-mode)
  ;(add-hook 'before-save-hook #'haskell-mode-stylish-buffer nil t)
  )

(add-hook 'haskell-mode-hook #'setup-haskell-mode)

Scheme

Set the command used to run scheme.

(setq scheme-program-name "guile"
      geiser-default-implementation scheme-program-name)
(autoload 'scheme-smart-comple "scheme-complete" nil t)
(autoload 'scheme-smart-indent-function "scheme-complete" nil t)

(defun setup-scheme-mode ()
    "Configure scheme mode"
    (interactive)
    (paredit-mode)
    (geiser-mode)
    (define-key scheme-mode-map "\e\t" 'scheme-smart-complete)
    (make-local-variable 'eldoc-documentation-function)
    (setq lisp-indent-function 'scheme-smart-indent-function
          eldoc-documentation-function 'scheme-get-current-symbol-info)
    (eldoc-mode))

(add-hook 'scheme-mode-hook 'setup-scheme-mode)

The execute M-x geiser to launch a scheme implementation.

C-x C-eEval sexp before point
C-M-xEval definition
C-c M-eEval definition and go
C-c C-rEval region
C-c M-rEval region and go
C-c C-d C-dSymbol documentation

HTML

(defun html-mode-initialize ()
  (interactive)
  (setq fill-colum nil)
  (local-set-key (kbd "C-<return>") 'html-line)
  (html-autoview-mode -1))

(add-hook 'html-mode-hook 'html-mode-initialize)

SQL

(defun setup-sql-mode ()
  (interactive)
  (setq indent-tabs-mode nil
        tab-stop-list (number-sequence 4 200 4)
        tab-width 4
        indent-line-function 'insert-tab))

(add-hook 'sql-mode-hook #'setup-sql-mode)

Key bindings

Windows

C-x 9Close the other window.
C-M-1Delete other window.
C-M-2Split window horizontally selecting a buffer.
C-M-3Split window vertically selecting a buffer.
C-M-0Delete split.
C-M-oSwitch other window.
C-M-S-oSwitch other window backwards.
s-<up>Enlarge window.
s-<down>Shrink window.
s-M-<up>Enlarge window horizontally.
s-M-<down>Shrink window horizontally.
(defun split-window-other-buffer-below (buffer)
  (interactive "b")
  (split-window-other-buffer 'split-window-below buffer))

(defun split-window-other-buffer-right (buffer)
  (interactive "b")
  (split-window-other-buffer 'split-window-right buffer))

(defun split-window-other-buffer (strategy buffer)
  (select-window (funcall strategy))
  (switch-to-buffer buffer))

(global-set-key (kbd "C-M-1") 'delete-other-windows)
(global-set-key (kbd "C-M-2") 'sw-below)
(global-set-key (kbd "C-M-3") 'sw-right)
(global-set-key (kbd "C-M-0") 'delete-window)
(global-set-key (kbd "C-M-o") 'other-window)
(global-set-key (kbd "C-M-S-o") 'other-window-backward)
(global-set-key (kbd "C-x 9") 'quit-other-window)
(global-set-key (kbd "s-<up>") 'enlarge-window)
(global-set-key (kbd "s-<down>") 'shrink-window)
(global-set-key (kbd "s-M-<up>") 'enlarge-window-horizontally)
(global-set-key (kbd "s-M-<down>") 'shrink-window-horizontally)

(window-numbering-mode)

(global-set-key (kbd "C-c w w") 'smart-window-move)
(global-set-key (kbd "C-c w r") 'smart-window-rotate)
(global-set-key (kbd "C-c w f") 'smart-window-file-split)
(global-set-key (kbd "C-c w b") 'smart-window-buffer-split)

Transpose chars or region

C-tTranspose chars or region if active region
(defun transpose-chars1 (arg)
    "Same as `transpose-chars' but if region is active transpose 
all characters in the region."
  (interactive "*P")
  (if (region-active-p)
      (insert
       (apply #'string
              (reverse
               (string-to-list
                (delete-and-extract-region (region-beginning)
                                           (region-end))))))
    (call-interactively #'transpose-chars)))
(global-set-key (kbd "C-t") 'transpose-chars1)

Change theme

F8Change theme.
(global-set-key [f8] 'use-next-theme)

Evaluating Sexps

C-x C-eShow the result in the minibuffer.
C-u C-x C-eWrite the result after the sexp in the buffer.
C-u C-u C-x C-eReplace sexp with the actual result.
C-M-xEval defun.
M-s-xEval current sexp.
M-s-bEval buffer.
M-s-rEval region.
(global-set-key (kbd "C-x C-e") 'ext/eval-last-sexp)

(global-set-key (kbd "M-s-e") (lambda ()
                                (interactive)
                                (let ((ok (sp-get-enclosing-sexp)))
                                  (when ok
                                    (save-excursion
                                      (let ((beg (sp-get ok :beg))
                                            (end (sp-get ok :end)))
                                        (eval-region beg end t)
                                        (flash-region beg end)))))))

(global-set-key (kbd "M-s-b") (lambda ()
                                (interactive)
                                (eval-buffer)
                                (flash-region (point-min) (point-max))))

(global-set-key (kbd "M-s-r") (lambda (beg end)p
                                (interactive "r")
                                (eval-region beg end)
                                (flash-region beg end)))

Kill Sexp backwards

M-s-kKill sexp backwards.
(global-set-key (kbd "M-s-k") (lambda ()
                                (interactive)
                                (kill-sexp -1)))

Expand region

C-c e eExpand region.
(global-set-key (kbd "C-c e e") 'er/expand-region)

Select inner

M-iChange inner
M-oChange outer
(global-set-key (kbd "M-i") 'change-inner)
(global-set-key (kbd "M-o") 'change-outer)

Comment/Uncomment line/region

C-;comment/uncomment line.
C-M-;comment/uncomment region.
(global-set-key (kbd "C-;") 'comment-or-uncomment)
(global-set-key (kbd "C-M-;") 'comment-or-uncomment-region)

Search

C-sSearch forward using regexp.
C-rSearch backward using regexp.

While searching

C-returnPut cursor at the beginning of the match
(global-set-key (kbd "C-s") 'isearch-forward-regexp)
(global-set-key (kbd "C-r") 'isearch-backward-regexp)

(defvar isearch-done-opposite nil "Wether or not isearch must end at the opposite end.")

(defun isearch-done-opposite (&optional nopush edit)
  (interactive)
  (let ((isearch-done-opposite t))
    (funcall #'isearch-done nopush edit)))

(defadvice isearch-done (after isearch-goto-beginning-of-match activate)
  "After finding a match position put the cursor at the beginning of
the match only if searching forward."
  (when isearch-done-opposite
      (goto-char isearch-other-end)))

(define-key isearch-mode-map (kbd "C-<return>") 'isearch-done-opposite)

(define-key isearch-mode-map (kbd "M-o") #'helm-swoop-from-isearch)

(defadvice isearch-occur (after isearch-occur-switch-to-occur-buffer activate)
  (switch-to-buffer-other-window "*Occur*"))

Search in other

C-M-sSearch forward in other window.
C-M-rSearch backward in other window.
(defun isearch-forward-regexp-other-window ()
  (interactive)
  (save-selected-window
    (other-window 1)
    (isearch-forward-regexp)))

(defun isearch-backward-regexp-other-window ()
  (interactive)
  (save-selected-window
    (other-window 1)
    (isearch-backward-regexp)))

(global-set-key (kbd "C-M-s") 'isearch-forward-regexp-other-window)
(global-set-key (kbd "C-M-r") 'isearch-backward-regexp-other-window)

Multiple cursors

C->Put a cursor in next line.
C-<Put a cursor in previous line.
C-S-c C-S-cPut a cursor in each region line.
C-c C-0Mark all like the current selection.
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "C-M->") 'mc/skip-to-next-like-this)
(global-set-key (kbd "C-M-<") 'mc/skip-to-previous-like-this)
(global-set-key (kbd "C-c C-0") 'mc/mark-all-like-this)
(global-unset-key (kbd "M-<down-mouse-1>"))
(global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)

Jump to places

s-.Jump to starting word character.
s-,Jump to word character.
(autoload 'ace-jump-mode "ace-jump-mode")
(global-set-key (kbd "s-.") 'ace-jump-mode)
(global-set-key (kbd "s-,") 'ace-jump-char-mode)

Query replace using regexps

(global-set-key (kbd "M-%") 'query-replace-regexp)

Scroll with arrows

(global-set-key [down] 'scroll-up-one-line-command)
(global-set-key [up] 'scroll-down-one-line-command)

(global-set-key (kbd "s-S-<up>") 'scroll-down-one-line-other-window)
(global-set-key (kbd "s-S-<down>") 'scroll-up-one-line-other-window)

Join lines a la vim

(global-set-key (kbd "C-S-j") 'join-line-below)

Kill buffer and file

(mykie:set-keys nil
  "C-x k" :default kill-buffer :C-u kill-buffer-and-file)

Rename buffer and file

(mykie:set-keys nil
  "C-c r" :default rename-buffer :C-u rename-buffer-and-file)

Git

(global-set-key (kbd "C-c g m") 'git-messenger:popup-message)
(global-set-key (kbd "C-c g g") 'git-gutter-mode)
(global-set-key (kbd "C-c g n") 'git-gutter:next-hunk)
(global-set-key (kbd "C-c g p") 'git-gutter:previous-hunk)
(global-set-key (kbd "C-c g s") 'git-gutter:stage-hunk)
(global-set-key (kbd "C-c g r") 'git-gutter:revert-hunk)

(global-set-key (kbd "C-c m l") 'git-link)
(global-set-key (kbd "C-c m s") 'magit-status)
(global-set-key (kbd "C-c m b") 'magit-blame-mode)
(global-set-key (kbd "C-c m d") 'magit-diff)

Org

(autoload 'org-toc-insert-toc "org-toc")
(global-set-key (kbd "C-c o t") 'org-toc-insert-toc)

idomenu

(autoload 'idomenu "idomenu")
(global-set-key (kbd "C-.") 'helm-semantic-or-imenu)

Which function

(global-set-key (kbd "C-c C-q") 'show-which-function)

Create scratch buffer

(global-set-key (kbd "C-c s") 'create-scratch-buffer)

Duplicate line

(global-set-key (kbd "C-c P") 'duplicate-line)

Go to beginning/end of buffer

(mykie:set-keys nil
  "C-a" :default (beginning-of-line) :C-u (beginning-of-buffer)
  "C-e" :default (end-of-line) :C-u (end-of-buffer)
  )

Run shell command

(global-set-key (kbd "C-!") 'eshell-here)

Access recent files

(global-set-key (kbd "C-M-r") 'recentf-open-files)

Toggle fullscreen

(global-set-key (kbd "<f11>") 'fullscreen-mode-fullscreen-toggle)

Run last eshell command

(fset 'run-last-eshell-command
   (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([24 52 98 101 115 104 101 108 108 return 134217840 return 134217786 40 115 119 105 116 99 104 45 116 111 45 98 117 102 102 101 114 45 111 116 104 101 114 45 119 105 110 100 111 119 32 40 111 116 104 101 114 45 98 117 102 102 101 114 32 40 99 117 114 114 101 110 116 45 98 117 102 102 101 114 41 32 49 41 41 return] 0 "%d")) arg)))

(global-set-key [f12] 'run-last-eshell-command)

Personal blog

(require 'org-page)
(setq op/repository-directory "~/repos/public/ikame.github.io/"
      op/personal-github-link "https://github.com/ikame"
      op/site-domain "http://ikame.github.io/"
      op/site-main-title "anler.me"
      op/site-sub-title ":: '(thoughts from an outsider)"
      op/personal-disqus-shortname "anler"
      op/personal-google-analytics-id "UA-234"
      op/category-config-alist '(("blog"
                                  :show-meta t
                                  :show-comment t
                                  :uri-generator (op/generate-uri
                                                  :uri-template "/blog/%t/")
                                  :sort-by :date
                                  :category-index t)
                                 ("index"
                                  :show-meta t
                                  :show-comment nil
                                  :uri-generator op/generate-uri
                                  :uri-template "/"
                                  :sort-by :date
                                  :category-index nil)
                                 ("wiki"
                                  :show-meta t
                                  :show-comment nil
                                  :uri-generator op/generate-uri
                                  :uri-template "/wiki/%t/"
                                  :sort-by :mod-date
                                  :category-index t)
                                 ("about"
                                  :show-meta nil
                                  :show-comment nil
                                  :uri-generator op/generate-uri
                                  :uri-template "/about/"
                                  :sort-by :date
                                  :category-index nil)))

Enable some “dangerous” commands

Applications

IRC

(require 'erc)
(load (expand-file-name "~/.emacs.d/erc.el") 'noerror)
(setq erc-auto-query t
      erc-bbdb-auto-create-on-whois-p t
      erc-fill-column (- (window-width) 2)
      erc-pals '("dialelo" "niwibe" "miguel" "alotor")
      erc-notify-list erc-pals
      erc-hide-list '("JOIN" "PART" "NICK" "MODE" "QUIT"))
(add-to-list 'erc-modules 'notifications)

Upcase region

(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)

Emacs’ customize custom file

File used for storing customization information created through Emacs’ customization interface (I don’t keep this file under version control).

(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)

Shells

Eshell (Elisp Shell)

General

M-rSearch backwards for a command by regexp.
M-sSearch forwards for a command by regexp.
M-pPrevious command in history.
M-nNext command in history.
C-c C-pJump to previous command.
C-c C-nJump to next command.
C-c M-rJump to previous instances of current command.
C-c M-sJump to next instances of current command.
C-c M-bInsert printed buffer name at point.
C-c M-iInsert printed process name at point.
C-c M-vInsert and environment variable at point.
C-c M-dToggle between direct/delayed input.

History Interaction

!!Repeat last command.
!lsRepeat last command beginning with ls.
!?lsRepeat last command containing ls.
!ls:nExtrat nth arg from last command beginning with ls.
!lsShow completion results matches ls.
^old^newReplace old with new in last command and run it.
$_Returns last parameter in last command.

Elisp Functions

lispify ARGSParses an argument string into elisp list notation
addpath PATHAdds the argument to the $PATH env variable
unset ENV-VARUnsets an existing env variable
find-file FILEFinds a file
dired DIROpen a dired buffer in a dir
calc-eval EXPRRuns EXPR through the calculator
vc-dir DIRReports status of vcs in dir
ediff-files FILE1 FILE2Diffs files
(require 'eshell)
(require 'em-smart)
(setq eshell-where-to-jump 'begin
      eshell-review-quick-commands nil
      eshell-smart-space-goes-to-end t)

(defun eshell-here ()
  "Opens up a new shell in the directoy associated with the
current buffer's file. The eshell is renamed to match that
directory to make multiple eshell windows easier."
  (interactive)
  (let* ((parent (if (buffer-file-name)
                     (file-name-directory (buffer-file-name))
                   default-directory))
         (height (/ (window-total-height) 3))
         (name (car (last (split-string parent "/" t)))))
    (split-window-vertically (- height))
    (other-window 1)
    (eshell "new")
    (rename-buffer (concat "*eshell: " name "*"))
    (insert (concat "ls"))
    (eshell-send-input)))

(defun eshell/x ()
  (insert "exit")
  (eshell-send-input)
  (delete-window))
## -*- mode: eshell-script -*-
(setenv "PAGER" "cat")
(setenv "TERM" "xterm-256color")

(setq eshell-ask-to-save-history 'always)
## -*- mode: eshell-script -*-
alias ff 'find-file $1'
alias d 'dired $1'

Shell

output group consists of a command and its output.

C-c C-cTerminate command.
C-c C-zStop a job.
C-c C-ocomint-kill-outputGet rid of the prev command output.
C-c C-rcomint-show-outputShow the top of the prev command output.
C-c C-ecomint-show-maximum-outputSame as above but show the end instead.
C-c C-pPrevious output group.
C-c C-nNext output group.
M-pcomint-previous-inputPrevious command.
M-ncomint-next-inputNext command.

Config inside Emacs

Set shell:

(setq shell-file-name "/bin/zsh")

Making passwords invisible:

(add-hook 'comint-output-filter-functions
          'comint-watch-for-password-prompt)
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
(add-hook 'shell-mode-hook (lambda ()
                             (yas-minor-mode -1)
                             (whitespace-mode -1)))

Bash Completion:

(autoload 'bash-completion-dynamic-complete 
  "bash-completion"
  "BASH completion hook")
(add-hook 'shell-dynamic-complete-functions
  'bash-completion-dynamic-complete)
(add-hook 'shell-command-complete-functions
  'bash-completion-dynamic-complete)

Config outside Emacs

prompt walters
unsetopt zle
WITHIN_EMACS=true

Terminal

Terminal emulation inside Emacs.

Disable some conflicting modes when running inside a Terminal buffer.

(defun custom-term-mode ()
  (interactive)
  (yas-minor-mode -1)
  (visual-line-mode -1))

(add-hook 'term-mode-hook 'custom-term-mode)

Executing shell commands

M-!shell-commandRun shell command in background.
M-|shell-command-on-regionRun shell command on region in background.
C-u M-|shell-command-on-regionSame as above but puts command output in the current burrer.

About

Personal Emacs config files described using a literate-programming style.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published