Emacs configuration
Emacs Lisp
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
README.md
config.org
init.el

README.md

Table of Contents

About

After using Emacs for a while, I decided to create my own config to simplify my daily life by adding scripts, useful functions, etc.

To manage package configurations, I use the use-package package from John Wiegley, that I recommend.

This config is inspired of the Sacha Chua config which I thank her for all the work she has done.

Starting up

Here's how we start

(package-initialize)
(setq custom-file "~/.emacs.d/custom-settings.el")
(load custom-file t)

Personal informations

For more informations about myself, you can visit my website (http://terencio-agozzino.com/).

(setq user-full-name "Terencio Agozzino"
      user-mail-address "terencio.agozzino@gmail.com")

Emacs initialization

Add packages sources

(unless (assoc-default "melpa" package-archives)
  (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t))
(unless (assoc-default "org" package-archives)
  (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t))

Use M-x package-refresh-contents to reload the list of packages after adding these for the first time.

Add elisp directory and others files

(add-to-list 'load-path "~/elisp")
(unless (package-installed-p 'use-package)
  (package-install 'use-package))
(setq use-package-verbose t)
(setq use-package-always-ensure t)
(require 'use-package)
(use-package auto-compile
  :config (auto-compile-on-load-mode))
(setq loda-prefer-newer t)

General configuration

Backups

By default, Emacs saves backup files ending by ~ in ~/.emacs.d directory. Following line allows to put them to ~/.emacs.d/backups folder.

(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))

Don't hesitate to save a lot.

(setq delete-old-versions -1)
(setq version-control t)
(setq vc-make-backup-files t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))

Clean white spaces after saving

It's often annoying to see useless white spaces.

(require 'whitespace-cleanup-mode)
(setq whitespace-style '(face empty tabs lines-tail trailing))
(global-whitespace-cleanup-mode 1)

Highlight the current line

More easier to find ourself.

(global-hl-line-mode)

History

Give the possibility to have commands and their history saved so that every time you get back to work, you can re-run stuff as you need it. It isn't a radical feature, it is part of a good user experience.

(setq savehist-file "~/.emacs.d/savehist")
(savehist-mode 1)
(setq history-length t)
(setq history-delete-duplicates t)
(setq savehist-save-minibuffer-history 1)
(setq savehist-additional-variables
      '(kill-ring
	search-ring
	regexp-search-ring))

Killing text

From https://github.com/itsjeyd/emacs-config/blob/emacs24/init.el

I find that useful, I can delete a line and a region with only C-w

(defadvice kill-region (before slick-cut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
    (if mark-active (list (region-beginning) (region-end))
      (list (line-beginning-position)
	(line-beginning-position 2)))))

Replaces "yes or no" with "y or n"

I'm too lazy…

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

Set UTF-8

These commands permit to set UTF-8 everywhere.

(prefer-coding-system 'utf-8)
(when (display-graphic-p)
  (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))

Show the column number and the parent

Useful for programming.

(column-number-mode 1)
(show-paren-mode 1)

Theme

I like the light on dark because I find it to be more restful.

(defadvice color-theme-alist (around sacha activate)
  (if (ad-get-arg 0)
      ad-do-it
    nil))
(use-package color-theme)
(use-package color-theme-solarized)
(defun my/setup-color-theme ()
  (interactive)
  (color-theme-solarized-dark)
  (set-face-foreground 'secondary-selection "darkblue")
  (set-face-background 'secondary-selection "lightblue")
  (set-face-background 'font-lock-doc-face "black")
  (set-face-foreground 'font-lock-doc-face "wheat")
  (set-face-background 'font-lock-string-face "black")
  (set-face-foreground 'org-todo "green")
  (set-face-background 'org-todo "black"))

(eval-after-load 'color-theme (my/setup-color-theme))

Time

I like having the clock in the modeline.

(display-time-mode 1)

Turn off mouse interface

Disable menu bar, tool bar, scroll bar and tooltip.

(when window-system
  (menu-bar-mode -1)
  (tool-bar-mode -1)
  (scroll-bar-mode -1)
  (tooltip-mode -1))

Transparency

I like to set few transparency to my Emacs.

(set-frame-parameter (selected-frame) 'alpha '(85 70))
(add-to-list 'default-frame-alist '(alpha 85 70))

Word wrap at 80 characters

Even if the 80 characters convention is less to less use, it still provides the best display of the code according to the scale.

(add-hook 'after-init-hook 'auto-fill-mode)
(setq-default fill-column 80)
(setq default-major-mode 'text-mode)
(setq text-mode-hook 'turn-on-auto-fill)

Org Mode

One of my favourite mode in Emacs. I mainly use it for takes notes, but you can do plenty of stuff with it.

Add language support for compiling

With that, I can compile many languages.

(org-babel-do-load-languages
 'org-babel-load-languages '((C . t)
			     (css . t)
			     (dot . t)
			     (emacs-lisp t)
			     (gnuplot . t)
			     (java . t)
			     (latex . t)
			     (makefile . t)
			     (org . t)
			     (python . t)
			     (ruby . t)
			     (sass . t)
			     (scala . t)
			     (sh . t)
			     ))

Indent org file automaticaly

(with-eval-after-load 'org       
  (setq org-startup-indented t)
  (add-hook 'org-mode-hook #'visual-line-mode))

Files

Here are the Org files I use. I was inspired by Sacha chua for the structure.

101things.org Goals for 101 things in 1001 days with my love
archive.org Archived subtrees
business.org Business-related notes and TODOs
decisions.org Pending, current, and reviewed decisions
learning.org Learning plan
organizer.org My main Org file. Inbox for M-x org-capture, tasks, weekly reviews, etc.
projects.org Projects I work on
routine.org Daily tasks

Modules

Org has a whole bunch of optional modules. These are the ones I'm currently experimenting with.

(setq org-modules '(org-bbdb
		    org-gnus
		    org-info
		    org-habit
		    org-irc
		    org-mouse
		    org-protocol
		    org-toc))
(eval-after-load 'org
  '(org-load-modules-maybe t))

(setq org-export-backends '(ascii beamer html icalendar latex man md org texinfo))

Keyboard shortcuts

All of this useful shortcuts are from Sacha Chua, I enjoy it!

(bind-key "C-c r" 'org-capture)
(bind-key "C-c a" 'org-agenda)
(bind-key "C-c l" 'org-store-link)
(bind-key "C-c L" 'org-insert-link-global)
(bind-key "C-c O" 'org-open-at-point-global)
(bind-key "<f9> <f9>" 'org-agenda-list)
(bind-key "<f9> <f8>" (lambda () (interactive) (org-capture nil "r")))

append-next-kill is more useful to me than org-table-copy-region.

(with-eval-after-load 'org
  (bind-key "C-M-w" 'append-next-kill org-mode-map)
  (bind-key "C-TAB" 'org-cycle org-mode-map)
  (bind-key "C-c v" 'org-show-todo-tree org-mode-map)
  (bind-key "C-c C-r" 'org-refile org-mode-map)
  (bind-key "C-c R" 'org-reveal org-mode-map)
  (bind-key "C-c o" 'my/org-follow-entry-link org-mode-map)
  (bind-key "C-c d" 'my/org-move-line-to-destination org-mode-map)
  (bind-key "C-c f" 'my/org-file-blog-index-entries org-mode-map)
  (bind-key "C-c t s"  'my/split-sentence-and-capitalize org-mode-map)
  (bind-key "C-c t -"  'my/split-sentence-delete-word-and-capitalize org-mode-map)
  (bind-key "C-c t d"  'my/delete-word-and-capitalize org-mode-map)

  (bind-key "C-c C-p C-p" 'my/org-publish-maybe org-mode-map)
  (bind-key "C-c C-r" 'my/org-refile-and-jump org-mode-map))

I don't use the diary, but I do use the clock a lot.

(with-eval-after-load 'org-agenda
  (bind-key "i" 'org-agenda-clock-in org-agenda-mode-map))

Speed commands

These are great for quickly acting on tasks.

(setq org-use-effective-time t)

(defun my/org-use-speed-commands-for-headings-and-lists ()
  "Activate speed commands on list items too."
  (or (and (looking-at org-outline-regexp) (looking-back "^\**"))
      (save-excursion (and (looking-at (org-item-re)) (looking-back "^[ \t]*")))))
(setq org-use-speed-commands 'my/org-use-speed-commands-for-headings-and-lists)

(with-eval-after-load 'org
  (add-to-list 'org-speed-commands-user '("x" org-todo "DONE"))
  (add-to-list 'org-speed-commands-user '("y" org-todo-yesterday "DONE"))
  (add-to-list 'org-speed-commands-user '("!" my/org-clock-in-and-track))
  (add-to-list 'org-speed-commands-user '("s" call-interactively 'org-schedule))
  (add-to-list 'org-speed-commands-user '("d" my/org-move-line-to-destination))
  (add-to-list 'org-speed-commands-user '("i" call-interactively 'org-clock-in))
  (add-to-list 'org-speed-commands-user '("P" call-interactively 'org2blog/wp-post-subtree))
  (add-to-list 'org-speed-commands-user '("o" call-interactively 'org-clock-out))
  (add-to-list 'org-speed-commands-user '("$" call-interactively 'org-archive-subtree))
  (bind-key "!" 'my/org-clock-in-and-track org-agenda-mode-map))

From http://stackoverflow.com/questions/15011703/is-there-an-emacs-org-mode-command-to-jump-to-an-org-heading

(setq org-goto-interface 'outline
      org-goto-max-level 10)
(require 'imenu)
(setq org-startup-folded nil)
(bind-key "C-c j" 'org-clock-goto) ;; jump to current task from anywhere
(bind-key "C-c C-w" 'org-refile)
(setq org-cycle-include-plain-lists 'integrate)
  1. Viewing, navigating, and editing the Org tree

    I often cut and paste subtrees. This makes it easier to cut something and paste it elsewhere in the hierarchy.

    (with-eval-after-load 'org
      (bind-key "C-c k" 'org-cut-subtree org-mode-map)
      (setq org-yank-adjusted-subtrees t))
    

Taking notes

My org files are in my personal directory, which is actually a symlink to a directory in my Dropbox. That way, I can update my Org files from multiple computers.

(setq org-directory "~/personal")
(setq org-default-notes-file "~/personal/organizer.org")
  1. Date trees

    This quickly adds a same-level heading for the succeeding day.

    (defun my/org-insert-heading-for-next-day ()
      "Insert a same-level heading for the following day."
      (interactive)
      (let ((new-date
    	 (seconds-to-time
    	  (+ 86400.0
    	     (float-time
    	      (org-read-date nil 'to-time (elt (org-heading-components) 4)))))))
        (org-insert-heading-after-current)
        (insert (format-time-string "%Y-%m-%d\n\n" new-date))))
    
  2. Templates

    I use org-capture templates to quickly jot down tasks, ledger entries, notes, and other semi-structured pieces of information.

    (defun my/org-contacts-template-email (&optional return-value)
      "Try to return the contact email for a template.
        If not found return RETURN-VALUE or something that would ask the user."
      (or (cadr (if (gnus-alive-p)
    		(gnus-with-article-headers
    		 (mail-extract-address-components
    		  (or (mail-fetch-field "Reply-To") (mail-fetch-field "From") "")))))
          return-value
          (concat "%^{" org-contacts-email-property "}p")))
    
    
    (defvar my/org-basic-task-template "* TODO %^{Task}
      :PROPERTIES:
      :Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}
      :END:
      Captured %<%Y-%m-%d %H:%M>
      %?
    
      %i
      " "Basic task data")
    (setq org-capture-templates
          `(("T" "Quick task" entry
    	 (file+headline "~/personal/organizer.org" "Inbox")
    	 "* TODO %^{Task}\nSCHEDULED: %t\n"
    	 :immediate-finish t) 
    	("b" "Business task" entry
    	 (file+headline "~/personal/business.org" "Tasks")
    	 ,my/org-basic-task-template)
    	("i" "Interrupting task" entry
    	 (file+headline "~/personal/organizer.org" "Inbox")
    	 "* STARTED %^{Task}"
    	 :clock-in :clock-resume)
    	("p" "People task" entry
    	 (file+headline "~/personal/people.org" "Tasks")
    	 ,my/org-basic-task-template)
    	("q" "Quick note" item
    	 (file+headline "~/personal/organizer.org" "Quick notes")
    	 ,my/org-basic-task-template)
    	("t" "Tasks" entry
    	 (file+headline "~/personal/organizer.org" "Inbox")
    	 ,my/org-basic-task-template)
    	))
    (bind-key "C-M-r" 'org-capture)
    
    1. Allow refiling in the middle(ish) of a capture

      This lets me use C-c C-r to refile a capture and then jump to the new location. I wanted to be able to file tasks under projects so that they could inherit the QUANTIFIED property that I use to track time (and any Beeminder-related properties too), but I also wanted to be able to clock in on them.

      (defun my/org-refile-and-jump ()
        (interactive)
        (if (derived-mode-p 'org-capture-mode)
            (org-capture-refile)
          (call-interactively 'org-refile))
        (org-refile-goto-last-stored))
      (eval-after-load 'org-capture
        '(bind-key "C-c C-r" 'my/org-refile-and-jump org-capture-mode-map))
      
  3. Refiling

    org-refile lets you organize notes by typing in the headline to file them under.

    (setq org-reverse-note-order t)
    (setq org-refile-use-outline-path nil)
    (setq org-refile-allow-creating-parent-nodes 'confirm)
    (setq org-refile-use-cache nil)
    (setq org-refile-targets '((org-agenda-files . (:maxlevel . 6))))
    (setq org-blank-before-new-entry nil)
    
    1. Jump to Org location by substring

      ;; Example: (org-refile 4 nil (my/org-refile-get-location-by-substring "Other Emacs"))
      (defun my/org-refile-get-location-by-substring (regexp &optional file)
        "Return the refile location identified by REGEXP."
        (let ((org-refile-targets org-refile-targets) tbl)
          (setq org-refile-target-table (org-refile-get-targets)))
        (unless org-refile-target-table
          (user-error "No refile targets"))
        (cl-find regexp org-refile-target-table
      	   :test
      	   (lambda (a b)
      	     (and
      	      (string-match a (car b))
      	      (or (null file)
      		  (string-match file (elt b 1)))))))
      (defun my/org-refile-subtree-to (name)
        (org-refile nil nil (my/org-refile-get-location-exact name)))
      
      (defun my/org-refile-get-location-exact (name &optional file)
        "Return the refile location identified by NAME."
        (let ((org-refile-targets org-refile-targets) tbl)
          (setq org-refile-target-table (org-refile-get-targets)))
        (unless org-refile-target-table
          (user-error "No refile targets"))
        (cl-find name org-refile-target-table
      	   :test (lambda (a b)
      		   (and (string-equal a (car b))
      			(or (null file)
      			    (string-match file (elt b 1)))))))
      ;; Example: (my/org-clock-in-refile "Off my computer")
      (defun my/org-clock-in-refile (location &optional file)
        "Clocks into LOCATION.
      LOCATION and FILE can also be regular expressions for `my/org-refile-get-location-by-substring'."
        (interactive (list (my/org-refile-get-location)))
        (save-window-excursion
          (save-excursion
            (if (stringp location) (setq location (my/org-refile-get-location-by-substring location file)))
            (org-refile 4 nil location)
            (org-clock-in))))
      
      (defun my/org-finish-previous-task-and-clock-in-new-one (location &optional file)
        (interactive (list (my/org-refile-get-location)))
        (save-window-excursion
          (org-clock-goto)
          (org-todo 'done))
        (my/org-clock-in-and-track-by-name location file))
      
      (defun my/org-clock-in-and-track-by-name (location &optional file)
        (interactive (list (my/org-refile-get-location)))
        (save-window-excursion
          (save-excursion
            (if (stringp location) (setq location (my/org-refile-get-location-exact location file)))
            (org-refile 4 nil location)
            (my/org-clock-in-and-track))))
      (defun my/org-off-my-computer (category)
        (interactive "MCategory: ")
        (my/org-clock-in-refile "Off my computer")
        (quantified-track category))
      
    2. Quick way to jump

      (defun my/org-jump ()
        (interactive)
        (let ((current-prefix-arg '(4)))
          (call-interactively 'org-refile)))
      

Tasks

  1. Managing tasks

    1. Track TODO state

      The parentheses indicate keyboard shortcuts that I can use to set the task state. @ and ! toggle logging. @ prompts you for a note, and ! automatically logs the timestamp of the state change.

      (setq org-todo-keywords
           '((sequence
      	"TODO(t)"  ; next action
      	"STARTED(s)"
      	"WAITING(w@/!)"
      	"SOMEDAY(.)" "|" "DONE(x!)" "CANCELLED(c@)")
             (sequence "TOBUY" "TOSHRINK" "TOCUT"  "TOSEW" "|" "DONE(x)")))
      
      (setq org-todo-keyword-faces
            '(("TODO" . (:foreground "green" :weight bold))
      	("DONE" . (:foreground "cyan" :weight bold))
      	("WAITING" . (:foreground "red" :weight bold))
      	("SOMEDAY" . (:foreground "gray" :weight bold))))
      
      (setq org-log-done 'time)
      
    2. Projects

      Projects are headings with the :project: tag, so we generally don't want that tag inherited, except when we display unscheduled tasks that don't belong to any projects.

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

      This code makes it easy for me to focus on one project and its tasks.

      (add-to-list 'org-speed-commands-user '("N" org-narrow-to-subtree))
      (add-to-list 'org-speed-commands-user '("W" widen))
      
      (defun my/org-agenda-for-subtree ()
        (interactive)
        (when (derived-mode-p 'org-agenda-mode) (org-agenda-switch-to))
        (my/org-with-current-task
         (let ((org-agenda-view-columns-initially t))
           (org-agenda nil "t" 'subtree))))
      (add-to-list 'org-speed-commands-user '("T" my/org-agenda-for-subtree))
      

      There's probably a proper way to do this, maybe with <. Oh, that would work nicely. < C-c a t too.

    3. Tag tasks with GTD-ish contexts

      This defines keyboard shortcuts for those, too.

      (setq org-tag-alist '(("@work" . ?b)
      		      ("@home" . ?h)
      		      ("@writing" . ?w)
      		      ("@errands" . ?e)
      		      ("@love" . ?d)
      		      ("@coding" . ?c)
      		      ("@phone" . ?p)
      		      ("@reading" . ?r)
      		      ("@computer" . ?l)
      		      ("quantified" . ?q)
      		      ("fuzzy" . ?0)
      		      ("highenergy" . ?1)))
      
    4. Enable filtering by effort estimates

      That way, it's easy to see short tasks that I can finish.

      (add-to-list 'org-global-properties
      	     '("Effort_ALL". "0:05 0:15 0:30 1:00 2:00 3:00 4:00"))
      
    5. Track time

      (use-package org
        :load-path "~/elisp/org-mode/lisp"
        :init
        (progn
          (setq org-expiry-inactive-timestamps t)
          (setq org-clock-idle-time nil)
          (setq org-log-done 'time)
          (setq org-clock-continuously nil)
          (setq org-clock-persist t)
          (setq org-clock-in-switch-to-state "STARTED")
          (setq org-clock-in-resume nil)
          (setq org-show-notification-handler 'message)
          (setq org-clock-report-include-clocking-task t))
        :config
        (org-clock-persistence-insinuate))
      

      Too many clock entries clutter up a heading.

      (setq org-log-into-drawer "LOGBOOK")
      (setq org-clock-into-drawer 1)
      
    6. Habits

      I like using org-habits to track consistency. My task names tend to be a bit long, though, so I've configured the graph column to show a little bit more to the right.

      (setq org-habit-graph-column 80)
      (setq org-habit-show-habits-only-for-today nil)
      

      If you want to use habits, be sure to schedule your tasks and add a STYLE property with the value of habit to the tasks you want displayed.

  2. Estimating tasks

    From "Add an effort estimate on the fly when clocking in" on the Org Hacks page.

    (add-hook 'org-clock-in-prepare-hook
    	  'my/org-mode-ask-effort)
    
    (defun my/org-mode-ask-effort ()
      "Ask for an effort estimate when clocking in."
      (unless (org-entry-get (point) "Effort")
        (let ((effort
    	   (completing-read
    	    "Effort: "
    	    (org-entry-get-multivalued-property (point) "Effort"))))
          (unless (equal effort "")
    	(org-set-property "Effort" effort)))))
    
  3. Modifying org agenda so that I can display a subset of tasks

    I want to create an agenda command that displays a list of tasks by context. That way, I can quickly preview a bunch of contexts and decide what I feel like doing the most.

    (defvar my/org-agenda-limit-items nil "Number of items to show in agenda to-do views; nil if unlimited.")
    (eval-after-load 'org
      '(defadvice org-agenda-finalize-entries (around sacha activate)
         (if my/org-agenda-limit-items
    	 (progn
    	   (setq list (mapcar 'org-agenda-highlight-todo list))
    	   (setq ad-return-value
    		 (subseq list 0 my/org-agenda-limit-items))
    	   (when org-agenda-before-sorting-filter-function
    	     (setq list (delq nil (mapcar org-agenda-before-sorting-filter-function list))))
    	   (setq ad-return-value
    		 (mapconcat 'identity
    			    (delq nil
    				  (subseq
    				   (sort list 'org-entries-lessp)
    				   0
    				   my/org-agenda-limit-items))
    			    "\n")))
           ad-do-it)))
    
  4. Task dependencies

    (setq org-enforce-todo-dependencies t)
    (setq org-track-ordered-property-with-tag t)
    (setq org-agenda-dim-blocked-tasks t)
    

Navigationx

Pop to mark

Jump to mark, and pop a new position for mark off the ring. (Does not affect global mark ring).

(bind-key "C-x p" 'pop-to-mark-command)
(setq set-mark-command-repeat-pop t)

Help-swoop - quickly finding lines

List the all lines to another buffer, which is able to squeeze by any words you input. At the same time, the original buffer’s cursor is jumping line to line according to moving up and down the list.

(use-package helm-swoop
  :bind (("C-S-s" . helm-swoop)
	 ("M-i" . helm-swoop)
	 ("M-s s" . helm-swoop)
	 ("M-s M-s" . helm-swoop)
	 ("M-I" . helm-swoop-back-to-last-point)
	 ("C-c M-i" . helm-multi-swoop)
	 ("C-x M-i" . helm-multi-swoop-all)
	 )
  :config
  (progn
    (define-key isearch-mode-map (kbd "M-i") 'helm-swoop-from-isearch)
    (define-key helm-swoop-map (kbd "M-i") 'helm-multi-swoop-all-from-helm-swoop)))

Windmove - switching between windows

Windmove lets you move between windows with something more natural than cycling through C-x o (other-window). Windmove doesn’t behave well with Org, so we need to use different keybindings.

(use-package windmove
  :bind
  (("<f2> <right>" . windmove-right)
   ("<f2> <left>" . windmove-left)
   ("<f2> <up>" . windmove-up)
   ("<f2> <down>" . windmove-down)
   ))     

More window movement

Display an overlay in each window showing a unique key, then ask user for the window where move to.

(use-package switch-window
  :bind (("C-x o" . switch-window)))

Frequently-accessed files

Registers allow you to jump to a file or other location quickly. To jump to a register, use C-x r j followed by the letter of the register. Using registers for all these file shortcuts is probably a bit of a waste since I can easily define my own keymap, but since I rarely go beyond register A anyway. Also, I might as well add shortcuts for refiling.

(defvar my/refile-map (make-sparse-keymap))

(defmacro my/defshortcut (key file)
  `(progn
     (set-register ,key (cons 'file ,file))
     (define-key my/refile-map
       (char-to-string ,key)
       (lambda (prefix)
	 (interactive "p")
	 (let ((org-refile-targets '(((,file) :maxlevel . 6)))
	       (current-prefix-arg (or current-prefix-arg '(4))))
	   (call-interactively 'org-refile))))))

(my/defshortcut ?P "~/personal/people.org")
(my/defshortcut ?a "~/.config/awesome/rc.lua")
(my/defshortcut ?c "~/.emacs.d/config.org")
(my/defshortcut ?d "~/personal/decisions.org")
(my/defshortcut ?l "~/personal/learning.org")
(my/defshortcut ?o "~/personal/organizer.org")
(my/defshortcut ?p "~/personal/projects.org")
(my/defshortcut ?r "~/personal/routine.org")
(my/defshortcut ?s "~/personal/school.org")

Smartscan

From: https://github.com/itsjeyd/emacs-config/blob/emacs24/init.el

This makes M-n and M-p look for the symbol at point.

(use-package smartscan
  :defer t
  :config (global-smartscan-mode t))

Dired

Give the possibility to display files from a directory.

(require 'find-dired)
(setq find-ls-option '("-print0 | xargs -0 ls -ld" . "-ld"))

Move to beginning of line

From: http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/

This function is a mix of C-a and M-m

(defun my/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]
		'my/smarter-move-beginning-of-line)

Recent files

Really useful to know the list of tiles that were operated on recently.

(require 'recentf)
(setq recentf-max-saved-items 200
      recentf-max-menu-items 15)
(recentf-mode)

Copy filename to clipboard

From: http://emacsredux.com/blog/2013/03/27/copy-filename-to-the-clipboard/

Give the possibility to copy the name of the currently visited file to the clipboard.

(defun prelude-copy-file-name-to-clipboard ()
  "Copy the current buffer file name to the clipboard."
  (interactive)
  (let ((filename (if (equal major-mode 'dired-mode)
		      default-directory
		    (buffer-file-name))))
    (when filename
      (kill-new filename)
      (message "Copied buffer file name '%s' to the clipboard." filename))))

Reading

(defun xah-toggle-margin-right ()
  "Toggle the right margin between `fill-column' or window width.
This command is convenient when reading novel, documentation."
  (interactive)
  (if (eq (cdr (window-margins)) nil)
      (set-window-margins nil 0 (- (window-body-width) fill-column))
    (set-window-margins nil 0 0)))

Shuffling lines

(defun my/shuffle-lines-in-region (beg end)
  (interactive "r")
  (let ((list (split-string (buffer-substring beg end) "[\r\n]+")))
    (delete-region beg end)
    (insert (mapconcat 'identity (shuffle-list list) "\n"))))

Writing

Avoiding weasel words

(use-package artbollocks-mode
  :defer t
  :load-path  "~/elisp/artbollocks-mode"
  :config
  (progn
    (setq artbollocks-weasel-words-regex
	  (concat "\\b" (regexp-opt
			 '("one of the"
			   "should"
			   "just"
			   "sort of"
			   "a lot"
			   "probably"
			   "maybe"
			   "perhaps"
			   "I think"
			   "really"
			   "pretty"
			   "nice"
			   "action"
			   "utilize"
			   "leverage") t) "\\b"))
    ;; Don't show the art critic words, or at least until I figure
    ;; out my own jargon
    (setq artbollocks-jargon nil)))

Org agenda

Basic configuration

I am a very fan about the organization made by Sacha Chua, which is why most of the functions added above come essentially from her.

Here is the place where I put all my Org files that will be read by Org agenda.

(setq org-agenda-files
      (delq nil
	    (mapcar (lambda (x) (and (file-exists-p x) x))
		    '("~/personal/organizer.org"
		      "~/personal/school.org"
		      "~/personal/routine.org"
		      "~/personal/decisions.org"
		      "~/personal/people.org"
		      "~/personal/projects.org"
		      "~/personal/learning.org"
		      "~/personal/101things.org"))))
(add-to-list 'auto-mode-alist '("\\.txt$" . org-mode))

I like looking at two days at a time when I plan using the Org agenda. I want to see my log entries, but I don't want to see scheduled items that I've finished. I like seeing a time grid so that I can get a sense of how appointments are spread out.

(setq org-agenda-span 2)
(setq org-agenda-tags-column -100) ; take advantage of the screen width
(setq org-agenda-sticky nil)
(setq org-agenda-inhibit-startup t)
(setq org-agenda-use-tag-inheritance t)
(setq org-agenda-show-log t)
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)
(setq org-agenda-time-grid
      '((daily today require-timed)
	"----------------"
	(800 1000 1200 1400 1600 1800)))
(setq org-columns-default-format "%14SCHEDULED %Effort{:} %1PRIORITY %TODO %50ITEM %TAGS")

Starting my weeks on Saturday

I like looking at weekends as week beginnings instead, so I want the Org agenda to start on Saturdays.

(setq org-agenda-start-on-weekday 6)

Display projects with associated subtasks

I wanted a view that showed projects with a few subtasks underneath them. Here's a sample of the output:

Headlines with TAGS match: +PROJECT
Press `C-u r' to search again with new search string
  organizer:  Set up communication processes for Awesome Foundation Toronto
  organizer:  TODO Announce the next pitch night
  organizer:  TODO Follow up with the winner of the previous pitch night for any news to include in the updates

  organizer:  Tidy up the house so that I can find things quickly
  organizer:  TODO Inventory all the things in closets and boxes         :@home:
  organizer:  TODO Drop things off for donation                       :@errands:

  organizer:  Learn how to develop for Android devices

(defun my/org-agenda-project-agenda ()
  "Return the project headline and up to `my/org-agenda-limit-items' tasks."
  (save-excursion
    (let* ((marker (org-agenda-new-marker))
	   (heading
	    (org-agenda-format-item "" (org-get-heading) (org-get-category) nil))
	   (org-agenda-restrict t)
	   (org-agenda-restrict-begin (point))
	   (org-agenda-restrict-end (org-end-of-subtree 'invisible))
	   ;; Find the TODO items in this subtree
	   (list (org-agenda-get-day-entries (buffer-file-name) (calendar-current-date) :todo)))
      (org-add-props heading
	  (list 'face 'defaults
		'done-face 'org-agenda-done
		'undone-face 'default
		'mouse-face 'highlight
		'org-not-done-regexp org-not-done-regexp
		'org-todo-regexp org-todo-regexp
		'org-complex-heading-regexp org-complex-heading-regexp
		'help-echo
		(format "mouse-2 or RET jump to org file %s"
			(abbreviate-file-name
			 (or (buffer-file-name (buffer-base-buffer))
			     (buffer-name (buffer-base-buffer))))))
	'org-marker marker
	'org-hd-marker marker
	'org-category (org-get-category)
	'type "tagsmatch")
      (concat heading "\n"
	      (org-agenda-finalize-entries list)))))

(defun my/org-agenda-projects-and-tasks (match)
  "Show TODOs for all `org-agenda-files' headlines matching MATCH."
  (interactive "MString: ")
  (let ((todo-only nil))
    (if org-agenda-overriding-arguments
	(setq todo-only (car org-agenda-overriding-arguments)
	      match (nth 1 org-agenda-overriding-arguments)))
    (let* ((org-tags-match-list-sublevels
	    org-tags-match-list-sublevels)
	   (completion-ignore-case t)
	   rtn rtnall files file pos matcher
	   buffer)
      (when (and (stringp match) (not (string-match "\\S-" match)))
	(setq match nil))
      (when match
	(setq matcher (org-make-tags-matcher match)
	      match (car matcher) matcher (cdr matcher)))
      (catch 'exit
	(if org-agenda-sticky
	    (setq org-agenda-buffer-name
		  (if (stringp match)
		      (format "*Org Agenda(%s:%s)*"
			      (or org-keys (or (and todo-only "M") "m")) match)
		    (format "*Org Agenda(%s)*" (or (and todo-only "M") "m")))))
	(org-agenda-prepare (concat "TAGS " match))
	(org-compile-prefix-format 'tags)
	(org-set-sorting-strategy 'tags)
	(setq org-agenda-query-string match)
	(setq org-agenda-redo-command
	      (list 'org-tags-view `(quote ,todo-only)
		    (list 'if 'current-prefix-arg nil `(quote ,org-agenda-query-string))))
	(setq files (org-agenda-files nil 'ifmode)
	      rtnall nil)
	(while (setq file (pop files))
	  (catch 'nextfile
	    (org-check-agenda-file file)
	    (setq buffer (if (file-exists-p file)
			     (org-get-agenda-file-buffer file)
			   (error "No such file %s" file)))
	    (if (not buffer)
		;; If file does not exist, error message to agenda
		(setq rtn (list
			   (format "ORG-AGENDA-ERROR: No such org-file %s" file))
		      rtnall (append rtnall rtn))
	      (with-current-buffer buffer
		(unless (derived-mode-p 'org-mode)
		  (error "Agenda file %s is not in `org-mode'" file))
		(save-excursion
		  (save-restriction
		    (if org-agenda-restrict
			(narrow-to-region org-agenda-restrict-begin
					  org-agenda-restrict-end)
		      (widen))
		    (setq rtn (org-scan-tags 'my/org-agenda-project-agenda matcher todo-only))
		    (setq rtnall (append rtnall rtn))))))))
	(if org-agenda-overriding-header
	    (insert (org-add-props (copy-sequence org-agenda-overriding-header)
			nil 'face 'org-agenda-structure) "\n")
	  (insert "Headlines with TAGS match: ")
	  (add-text-properties (point-min) (1- (point))
			       (list 'face 'org-agenda-structure
				     'short-heading
				     (concat "Match: " match)))
	  (setq pos (point))
	  (insert match "\n")
	  (add-text-properties pos (1- (point)) (list 'face 'org-warning))
	  (setq pos (point))
	  (unless org-agenda-multi
	    (insert "Press `C-u r' to search again with new search string\n"))
	  (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
	(org-agenda-mark-header-line (point-min))
	(when rtnall
	  (insert (mapconcat 'identity rtnall "\n") ""))
	(goto-char (point-min))
	(or org-agenda-multi (org-agenda-fit-window-to-buffer))
	(add-text-properties (point-min) (point-max)
			     `(org-agenda-type tags
					       org-last-args (,todo-only ,match)
					       org-redo-cmd ,org-agenda-redo-command
					       org-series-cmd ,org-cmd))
	(org-agenda-finalize)
	(setq buffer-read-only t)))))

Org agenda custom commands

There are quite a few custom commands here, and I often forget to use them. =) But it's good to define them, and over time, I'll get the hang of using these more!

Key Description
. What am I waiting for?
T Not really an agenda command - shows the to-do tree in the current file
b Shows business-related tasks
o Shows personal tasks and miscellaneous tasks (o: organizer)
w Show all tasks for the upcoming week
W Show all tasks for the upcoming week, aside from the routine ones
g … Show tasks by context: b - business; c - coding; w - writing; p - phone; d - drawing, h - home
0 Show common contexts with up to 3 tasks each, so that I can choose what I feel like working on
) (shift-0) Show common contexts with all the tasks associated with them
9 Show common contexts with up to 3 unscheduled tasks each
( (shift-9) Show common contexts with all the unscheduled tasks associated with them
d Timeline for today (agenda, clock summary)
u Unscheduled tasks to do if I have free time
U Unscheduled tasks that are not part of projects
P Tasks by priority
p My projects
2 Projects with tasks
(defvar my/org-agenda-contexts
  '((tags-todo "+@phone")
    (tags-todo "+@work")
    (tags-todo "+@love")
    (tags-todo "+@coding")
    (tags-todo "+@writing")
    (tags-todo "+@computer")
    (tags-todo "+@home")
    (tags-todo "+@errands"))
  "Usual list of contexts.")
  (bind-key "<apps> a" 'org-agenda)

Make it easy to mark a task as done

Great for quickly going through the to-do list. Gets rid of one extra keystroke. ;)

(defun my/org-agenda-done (&optional arg)
  "Mark current TODO as done.
This changes the line at point, all other lines in the agenda referring to
the same tree node, and the headline of the tree node in the Org-mode file."
  (interactive "P")
  (org-agenda-todo "DONE"))
;; Override the key definition for org-exit
(define-key org-agenda-mode-map "x" 'my/org-agenda-done)

Make it easy to mark a task as done and create a follow-up task

(defun my/org-agenda-mark-done-and-add-followup ()
  "Mark the current TODO as done and add another task after it.
Creates it at the same level as the previous task, so it's better to use
this with to-do items than with projects or headings."
  (interactive)
  (org-agenda-todo "DONE")
  (org-agenda-switch-to)
  (org-capture 0 "t"))
;; Override the key definition
(define-key org-agenda-mode-map "X" 'my/org-agenda-mark-done-and-add-followup)

Capture something based on the agenda

(defun my/org-agenda-new ()
  "Create a new note or task at the current agenda item.
Creates it at the same level as the previous task, so it's better to use
this with to-do items than with projects or headings."
  (interactive)
  (org-agenda-switch-to)
  (org-capture 0))
;; New key assignment
(define-key org-agenda-mode-map "N" 'my/org-agenda-new)

Sorting by date and priority

(setq org-agenda-sorting-strategy
      '((agenda time-up priority-down tag-up category-keep effort-up)
	;; (todo user-defined-up todo-state-up priority-down effort-up)
	(todo todo-state-up priority-down effort-up) 
	(tags user-defined-up)
	(search category-keep)))
(setq org-agenda-cmp-user-defined 'my/org-sort-agenda-items-user-defined)
(require 'cl)
(defun my/org-get-context (txt)
  "Find the context."
  (car (member-if
	(lambda (item) (string-match "@" item))
	(get-text-property 1 'tags txt))))

(defun my/org-compare-dates (a b)
  "Return 1 if A should go after B, -1 if B should go after A, or 0 if a = b."
  (cond
   ((and (= a 0) (= b 0)) nil)
   ((= a 0) 1)
   ((= b 0) -1)
   ((> a b) 1)
   ((< a b) -1)
   (t nil)))

(defun my/org-complete-cmp (a b)
  (let* ((state-a (or (get-text-property 1 'todo-state a) ""))
	 (state-b (or (get-text-property 1 'todo-state b) "")))
    (or
     (if (member state-a org-done-keywords-for-agenda) 1)
     (if (member state-b org-done-keywords-for-agenda) -1))))

(defun my/org-date-cmp (a b)
  (let* ((sched-a (or (get-text-property 1 'org-scheduled a) 0))
	 (sched-b (or (get-text-property 1 'org-scheduled b) 0))
	 (deadline-a (or (get-text-property 1 'org-deadline a) 0))
	 (deadline-b (or (get-text-property 1 'org-deadline b) 0)))
    (or
     (my/org-compare-dates
      (my/org-min-date sched-a deadline-a)
      (my/org-min-date sched-b deadline-b)))))

(defun my/org-min-date (a b)
  "Return the smaller of A or B, except for 0."
  (funcall (if (and (> a 0) (> b 0)) 'min 'max) a b))

(defun my/org-sort-agenda-items-user-defined (a b)
  ;; compare by deadline, then scheduled date; done tasks are listed at the very bottom
  (or
   (my/org-complete-cmp a b)
   (my/org-date-cmp a b)))

(defun my/org-context-cmp (a b)
  "Compare CONTEXT-A and CONTEXT-B."
  (let ((context-a (my/org-get-context a))
	(context-b (my/org-get-context b)))
    (cond
     ((null context-a) +1)
     ((null context-b) -1)
     ((string< context-a context-b) -1)
     ((string< context-b context-a) +1)
     (t nil))))

(defun my/org-sort-agenda-items-todo (a b)
  (or
   (org-cmp-time a b)
   (my/org-complete-cmp a b)
   (my/org-context-cmp a b)
   (my/org-date-cmp a b)
   (org-cmp-todo-state a b)
   (org-cmp-priority a b)
   (org-cmp-effort a b)))

Preventing things from falling through the cracks

This helps me keep track of unscheduled tasks, because I sometimes forget to assign tasks a date. I also want to keep track of stuck projects.

(defun my/org-agenda-list-unscheduled (&rest ignore)
  "Create agenda view for tasks that are unscheduled and not done."
  (let* ((org-agenda-todo-ignore-with-date t)
	 (org-agenda-overriding-header "List of unscheduled tasks: "))
    (org-agenda-get-todos)))
(setq org-stuck-projects
      '("+PROJECT-MAYBE-DONE"
	("TODO")
	nil
	"\\<IGNORE\\>"))

Projects

(defun my/org-show-active-projects ()
  "Show my current projects."
  (interactive)
  (org-tags-view nil "project-inactive-someday"))

Archiving

(defun my/org-archive-done-tasks ()
  "Archive finished or cancelled tasks."
  (interactive)
  (org-map-entries
   (lambda ()
     (org-archive-subtree)
     (setq org-map-continue-from (outline-previous-heading)))
   "TODO=\"DONE\"|TODO=\"CANCELLED\"" (if (org-before-first-heading-p) 'file 'tree)))

Compare times and effort estimates

This is for comparing times in column view and in tables.

(defun my/compare-times (clocked estimated)
  (if (and (> (length clocked) 0) estimated)
      (format "%.2f"
	      (/ (* 1.0 (org-hh:mm-string-to-minutes clocked))
		 (org-hh:mm-string-to-minutes estimated)))
    ""))

Plugins configuration

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.

(use-package company
  :config
  (add-hook 'after-init-hook 'global-company-mode)
  (setq company-tooltip-limit 20)                      ; bigger popup window
  (setq company-tooltip-align-annotations 't)          ; align annotations to the right tooltip border
  (setq company-idle-delay .3)                         ; decrease delay before autocompletion popup shows
  (setq company-begin-commands '(self-insert-command)) ; start autocompletion only after typing

Emacs Lisp

Eldoc

Eldoc provides minibuffer hints when working with Emacs Lisp

(use-package "eldoc"
  :diminish eldoc-mode
  :commands turn-on-eldoc-mode
  :defer t
  :init
  (progn
  (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
  (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode)
  (add-hook 'ielm-mode-hook 'turn-on-eldoc-mode)))

Refactoring

More things that I need to get used to…

;; C-c C-v l : elint current buffer in clean environment.
;; C-c C-v L : elint current buffer by multiple emacs binaries.
;;             See `erefactor-lint-emacsen'
;; C-c C-v r : Rename symbol in current buffer.
;;             Resolve `let' binding as long as i can.
;; C-c C-v R : Rename symbol in requiring modules and current buffer.
;; C-c C-v h : Highlight current symbol in this buffer
;;             and suppress `erefacthr-highlight-mode'.
;; C-c C-v d : Dehighlight all by above command.
;; C-c C-v c : Switch prefix bunch of symbols.
;;             ex: '(hoge-var hoge-func) -> '(foo-var foo-func)
;; C-c C-v ? : Display flymake elint warnings/errors

(use-package erefactor
  :config
  (define-key emacs-lisp-mode-map "\C-c\C-v" erefactor-map))

(use-package paredit)
(use-package redshank
  :disabled t
  :defer t
  :init (add-hook 'emacs-lisp-mode-hook 'redshank-mode))

Jumping to code

(define-key emacs-lisp-mode-map (kbd "C-c .") 'find-function-at-point)
(bind-key "C-c f" 'find-function)

Sorting

(defun my/sort-sexps-in-region (beg end)
  "Can be handy for sorting out duplicates.
Sorts the sexps from BEG to END. Leaves the point at where it
couldn't figure things out (ex: syntax errors)."
  (interactive "r")
  (let ((input (buffer-substring beg end))
	list last-point form result)
    (save-restriction
      (save-excursion
	(narrow-to-region beg end)
	(goto-char (point-min))
	(setq last-point (point-min))
	(setq form t)
	(while (and form (not (eobp)))
	  (setq form (ignore-errors (read (current-buffer))))
	  (when form
	    (add-to-list
	     'list
	     (cons
	      (prin1-to-string form)
	      (buffer-substring last-point (point))))
	    (setq last-point (point))))
	(setq list (sort list (lambda (a b) (string< (car a) (car b)))))
	(delete-region (point-min) (point))
	(insert (mapconcat 'cdr list "\n"))))))

Evaluation

Borrowed from Steve Purcell’s config. This pretty-prints the results.

'(bind-key "M-:" 'pp-eval-expression)

(defun sanityinc/eval-last-sexp-or-region (prefix)
  "Eval region from BEG to END if active, otherwise the last sexp."
  (interactive "P")
  (if (and (mark) (use-region-p))
      (eval-region (min (point) (mark)) (max (point) (mark)))
    (pp-eval-last-sexp prefix)))

(bind-key "C-x C-e" 'sanityinc/eval-last-sexp-or-region emacs-lisp-mode-map)

HTML/CSS

Emmet

Minor mode providing support for Zen Coding by producing HTML from CSS-like selector.

(use-package emmet-mode
  :config
  (add-hook 'sgml-mode-hook 'emmet-mode)
  (add-hook 'css-mode-hook 'emmet-mode)
  (add-hook 'web-mode-hook 'emmet-mode))

LESS

(use-package less-css-mode
  :mode "\\.less\\'"
  :interpreter ("less" . less-css-mode))

LaTeX

Configuration for LaTeX mode.

Enable LaTeX mode

(setq Tex-PDF-mode t)

Update PDF automaticaly with DocView

(add-hook 'doc-view-mode-hook 'auto-revert-mode)
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)

Configuration

      (setq TeX-auto-save t)
      (setq TeX-parse-self t)
      (setq-default TeX-master nil)
      (add-hook 'LaTeX-mode-hook 'visual-line-mode)
;;      (add-hook 'LaTeX-mode-hook 'flyspell-mode)
      (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
      (add-hook 'LaTeX-mode-hook 'auto-fill-mode)
      (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
      (setq reftex-plug-into-AUCTeX t)

Script command for LaTeX compiling

(setq latex-run-command "pdflatex -synctex=1 -interaction=nonstopmode --shell-escape")
(setq LaTeX-command "latex -synctex=1 -interaction=nonstopmode --shell-escape")

Integrate PDF Tools with Emacs

(setq TeX-source-correlate-method (quote synctex))
(setq TeX-source-correlate-mode t)
(setq TeX-source-correlate-start-server t)
(setq TeX-view-program-selection
      (quote
       ((output-pdf "PDF Tools")
	((output-dvi has-no-display-manager)
	 "dvi2tty")
	((output-dvi style-pstricks)
	 "dvips and gv")
	(output-dvi "xdvi")
	(output-(point)df "Evince")
	(output-html "xdg-open"))))

Lua

(use-package lua-mode
  :mode "\\.lua\\'"
  :interpreter ("lua" . lua-mode))

Markdown

To use that mode, don't forget to install markdown package on your OS.

(use-package markdown-mode 
  :mode (("\\`README\\.md\\'" . gfm-mode)
	 ("\\.md\\'"          . markdown-mode)
	 ("\\.markdown\\'"    . markdown-mode))
  :config
  (use-package markdown-preview-mode))

Python

Anaconda

Anaconda-mode is a mode for code navigation, documentation lookup and completion for Python.

I prefer use Anaconda that is more easier to configurate and support company-mode than Jedi that I find quite old.

(use-package anaconda-mode
  :config
  (add-hook 'python-mode-hook 'anaconda-mode)
  (add-hook 'python-mode-hook #'(lambda ()
				  (add-to-list 'company-backends 'company-anaconda))))

Company Anaconda

Anaconda backend for company-mode

(use-package company-anaconda  
  :config
  (eval-after-load "company"
    '(add-to-list 'company-backends 'company-anaconda))
  (add-hook 'python-mode-hook 'anaconda-mode))

SQL

SQL indent

(use-package sql-indent
  :mode "\\.sql\\'"
  :interpreter ("sql" . sql-indent)) 

Guide-key

It's really difficult to remember all the keyboard shortcuts. The guide-key package pops up help after a short delay.

(use-package guide-key
  :defer t
  :diminish guide-key-mode
  :config
  (progn
    (setq guide-key/guide-key-sequence '("C-x r" "C-x 4" "C-c"))
    (guide-key-mode 1)))

Helm

Helm is an Emacs framework for incremental completions and narrowing selections. It helps to rapidly complete file names, buffer names, or any other Emacs interactions requiring selecting an item from a list of possible choices.

(use-package helm
  :diminish helm-mode
  :init
  (progn
    (require 'helm-config)
    (setq helm-candidate-number-limit 100)
    ;; From https://gist.github.com/antifuchs/9238468
    (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't).
	  helm-input-idle-delay 0.01  ; this actually updates things
					; reeeelatively quickly.
	  helm-yas-display-key-on-candidate t
	  helm-quick-update t
	  helm-M-x-requires-pattern nil
	  helm-ff-skip-boring-files t)
    (helm-mode))
  :bind (("C-c h" . helm-mini)
	 ("C-h a" . helm-apropos)
	 ("C-x C-b" . helm-buffers-list)
	 ("C-x b" . helm-buffers-list)
	 ("M-y" . helm-show-kill-ring)
	 ("M-x" . helm-M-x)
	 ("C-x c o" . helm-occur)
	 ("C-x c s" . helm-swoop)
	 ("C-x c y" . helm-yas-complete)
	 ("C-x c Y" . helm-yas-create-snippet-on-region)
	 ("C-x c b" . my/helm-do-grep-book-notes)
	 ("C-x c SPC" . helm-all-mark-rings)))
(ido-mode -1) ;; Turn off ido mode in case I enabled it accidentally

Really useful for describing bindings

(use-package helm-descbinds
  :defer t
  :bind (("C-h b" . helm-descbinds)
	 ("C-h w" . helm-descbinds)))

List match lines to another buffer, which is able to squeeze by any words you input. At the same time, the original buffer's cursor is jumping line to line according to moving up and down the line list.

Getting Helm and org-refile to clock in or create tasks

(ert-deftest my/org-capture-prefill-template ()
  (should
   ;; It should fill things in one field at ia time
   (string=
    (my/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World")
    "* TODO Hello World\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
    ))
  (should
   (string=
    (my/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World" "<2015-01-01>")
    "* TODO Hello World\nSCHEDULED: <2015-01-01>\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"))
  (should
   (string=
    (my/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World" "<2015-01-01>" "0:05")
    "* TODO Hello World\nSCHEDULED: <2015-01-01>\n:PROPERTIES:\n:Effort: 0:05\n:END:\n%?\n")))

(defun my/org-capture-prefill-template (template &rest values)
  "Pre-fill TEMPLATE with VALUES."
  (setq template (or template (org-capture-get :template)))
  (with-temp-buffer
    (insert template)
    (goto-char (point-min))
    (while (re-search-forward
	    (concat "%\\("

		    "\\[\\(.+\\)\\]\\|"
		    "<\\([^>\n]+\\)>\\|"
		    "\\([tTuUaliAcxkKInfF]\\)\\|"
		    "\\(:[-a-zA-Z]+\\)\\|"
		    "\\^\\({\\([^}]*\\)}\\)"
		    "?\\([gGtTuUCLp]\\)?\\|"
		    "%\\\\\\([1-9][0-9]*\\)"
		    "\\)") nil t)
      (if (car values)
	  (replace-match (car values) nil t))
      (setq values (cdr values)))
    (buffer-string)))

(defun my/org-get-current-refile-location ()
  "Return the current entry as a location understood by org-refile."
  (interactive)
  (list (elt (org-heading-components) 4)
	(or buffer-file-name
	    (with-current-buffer (buffer-base-buffer (current-buffer))
	      buffer-file-name))
	nil
	(point)))

(defun my/helm-org-create-task (candidate)
  "Creates the task and returns the location."
  (let ((entry (org-capture-select-template "T")))
    (org-capture-set-plist entry)
    (org-capture-get-template)
    (org-capture-set-target-location)
    (condition-case error
	(progn
	  (org-capture-put
	   :template
	   (org-capture-fill-template
	    (my/org-capture-prefill-template (org-capture-get :template)
					     candidate)))
	  (org-capture-place-template
	   (equal (car (org-capture-get :target)) 'function))
	  (setq org-refile-target-table (org-refile-get-targets))
	  ;; Return the new location
	  (my/org-get-current-refile-location))
      ((error quit)
       (if (get-buffer "*Capture*") (kill-buffer "*Capture*"))
       (error "Capture abort: %s" error)))))

;; (my/org-refile-get-location-by-substring "Try again")

(defvar my/helm-org-refile-locations nil)
(defvar my/org-refile-last-location nil)

(defun my/helm-org-clock-in-and-track-from-refile (candidate)
  (let ((location (org-refile--get-location candidate my/helm-org-refile-locations)))
    (save-window-excursion
    (org-refile 4 nil location)
    (my/org-clock-in-and-track)
    t)))

(defun my/org-get-todays-items-as-refile-candidates ()
  "Return items scheduled for today, ready for choosing during refiling."
  (delq
   nil
   (mapcar
    (lambda (s)
    (if (get-text-property 0 'org-marker s)
	  (list
	   s
	   (buffer-file-name (marker-buffer (get-text-property 0 'org-marker s)))
	   nil
	   (marker-position (get-text-property 0 'org-marker s)))))
    (save-window-excursion (my/org-get-entries-fn (calendar-current-date) (calendar-current-date))))))

;; Based on http://emacs.stackexchange.com/questions/4063/how-to-get-the-raw-data-for-an-org-mode-agenda-without-an-agenda-view
(defun my/org-get-entries-fn (begin end)
  "Return org schedule items between BEGIN and END.
USAGE:  (org-get-entries-fn '(6 1 2015) '(6 30 2015))"
  (require 'calendar)
  (require 'org)
  (require 'org-agenda)
  (require 'cl)
  (unless
    (and
     (calendar-date-is-valid-p begin)
     (calendar-date-is-valid-p end))
    (let ((debug-on-quit nil))
    (signal 'quit `("One or both of your gregorian dates are invalid."))))
  (let* (
       result
       (org-agenda-prefix-format "  • ")
       (org-agenda-entry-types '(:scheduled))
       (date-after
	(lambda (date num)
	  "Return the date after NUM days from DATE."
	  (calendar-gregorian-from-absolute
	   (+ (calendar-absolute-from-gregorian date) num))))
       (enumerate-days
	(lambda (begin end)
	  "Enumerate date objects between BEGIN and END."
	  (when (> (calendar-absolute-from-gregorian begin)
		   (calendar-absolute-from-gregorian end))
	    (error "Invalid period : %S - %S" begin end))
	  (let ((d begin) ret (cont t))
	    (while cont
	      (push (copy-sequence d) ret)
	      (setq cont (not (equal d end)))
	      (setq d (funcall date-after d 1)))
	    (nreverse ret)))) )
    (org-agenda-reset-markers)
    (setq org-agenda-buffer
	(when (buffer-live-p org-agenda-buffer)
	  org-agenda-buffer))
    (org-compile-prefix-format nil)
    (setq result
	(loop for date in (funcall enumerate-days begin end) append
	      (loop for file in (org-agenda-files nil 'ifmode)
		    append
		    (progn
		      (org-check-agenda-file file)
		      (apply 'org-agenda-get-day-entries file date org-agenda-entry-types)))))
    (unless (buffer-live-p (get-buffer org-agenda-buffer-name))
    (get-buffer-create org-agenda-buffer-name))
    (with-current-buffer (get-buffer org-agenda-buffer-name)
    (org-agenda-mode)
    (setq buffer-read-only t)
    (let ((inhibit-read-only t))
	(erase-buffer))
    (mapcar
     (lambda (x)
       (let ((inhibit-read-only t))
	 (insert (format "%s" x) "\n")))
     result))
    ;;    (display-buffer org-agenda-buffer-name t)
    result))

(defun my/helm-org-refile-read-location (tbl)
  (setq my/helm-org-refile-locations tbl)
  (helm
   (list
    ;; (helm-build-sync-source "Today's tasks"
    ;;   :candidates (mapcar (lambda (a) (cons (car a) a))
    ;;                       (my/org-get-todays-items-as-refile-candidates))
    ;;   :action '(("Select" . identity)
    ;;             ("Clock in and track" . my/helm-org-clock-in-and-track-from-refile)
    ;;             ("Draw index card" . my/helm-org-prepare-index-card-for-subtree))
    ;;   :history 'org-refile-history)
    (helm-build-sync-source "Refile targets"
    :candidates (mapcar (lambda (a) (cons (car a) a)) tbl)
    :action '(("Select" . identity)
	      ("Clock in and track" . my/helm-org-clock-in-and-track-from-refile)
	      ("Draw index card" . my/helm-org-prepare-index-card-for-subtree))
    :history 'org-refile-history)
    (helm-build-dummy-source "Create task"
    :action (helm-make-actions
	     "Create task"
	     'my/helm-org-create-task)))))

(defun my/org-refile-get-location (&optional prompt default-buffer new-nodes no-exclude)
  "Prompt the user for a refile location, using PROMPT.
  PROMPT should not be suffixed with a colon and a space, because
  this function appends the default value from
  `org-refile-history' automatically, if that is not empty.
  When NO-EXCLUDE is set, do not exclude headlines in the current subtree,
  this is used for the GOTO interface."
  (let ((org-refile-targets org-refile-targets)
      (org-refile-use-outline-path org-refile-use-outline-path)
      excluded-entries)
    (when (and (derived-mode-p 'org-mode)
	     (not org-refile-use-cache)
	     (not no-exclude))
    (org-map-tree
     (lambda()
       (setq excluded-entries
	     (append excluded-entries (list (org-get-heading t t)))))))
    (setq org-refile-target-table
	(org-refile-get-targets default-buffer excluded-entries)))
  (unless org-refile-target-table
    (user-error "No refile targets"))
  (let* ((cbuf (current-buffer))
       (partial-completion-mode nil)
       (cfn (buffer-file-name (buffer-base-buffer cbuf)))
       (cfunc (if (and org-refile-use-outline-path
		       org-outline-path-complete-in-steps)
		  'org-olpath-completing-read
		'org-icompleting-read))
       (extra (if org-refile-use-outline-path "/" ""))
       (cbnex (concat (buffer-name) extra))
       (filename (and cfn (expand-file-name cfn)))
       (tbl (mapcar
	     (lambda (x)
	       (if (and (not (member org-refile-use-outline-path
				     '(file full-file-path)))
			(not (equal filename (nth 1 x))))
		   (cons (concat (car x) extra " ("
				 (file-name-nondirectory (nth 1 x)) ")")
			 (cdr x))
		 (cons (concat (car x) extra) (cdr x))))
	     org-refile-target-table))
       (completion-ignore-case t)
       cdef
       (prompt (concat prompt
		       (or (and (car org-refile-history)
				(concat " (default " (car org-refile-history) ")"))
			   (and (assoc cbnex tbl) (setq cdef cbnex)
				(concat " (default " cbnex ")"))) ": "))
       pa answ parent-target child parent old-hist)
    (setq old-hist org-refile-history)
    ;; Use Helm's sources instead
    (setq answ (my/helm-org-refile-read-location tbl))
    (cond
     ((and (stringp answ)
	 (setq pa (org-refile--get-location answ tbl)))
    (org-refile-check-position pa)
    (when (or (not org-refile-history)
	      (not (eq old-hist org-refile-history))
	      (not (equal (car pa) (car org-refile-history))))
      (setq org-refile-history
	    (cons (car pa) (if (assoc (car org-refile-history) tbl)
			       org-refile-history
			     (cdr org-refile-history))))
      (if (equal (car org-refile-history) (nth 1 org-refile-history))
	  (pop org-refile-history)))
    (setq my/org-refile-last-location pa)
    pa)
     ((and (stringp answ) (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ))
    (setq parent (match-string 1 answ)
	  child (match-string 2 answ))
    (setq parent-target (org-refile--get-location parent tbl))
    (when (and parent-target
	       (or (eq new-nodes t)
		   (and (eq new-nodes 'confirm)
			(y-or-n-p (format "Create new node \"%s\"? "
					  child)))))
      (org-refile-new-child parent-target child)))
     ((listp answ) answ) ;; Sacha: Helm returned a refile location
     ((not (equal answ t))
    (user-error "Invalid target location")))))

(fset 'org-refile-get-location 'my/org-refile-get-location)

Impatient mode

See the effect of your HTML as you type it.

To use it, you need to enable the web server provided by _simple-httpd_ For that, use M-x httpd-start

Then, open your browser to http://localhost:8080/imp/ and select your buffer to watch your changes appear as you type!

(use-package impatient-mode
  :config
  (add-hook 'web-mode-hook 'httpd-start)
  (add-hook 'web-mode-hook 'impatient-mode)
  (add-hook 'css-mode-hook 'httpd-start)
  (add-hook 'css-mode-hook 'impatient-mode))

Internet Relay Chat

IRC is a great way to hang out with other people.

(use-package erc
  :config
  (setq erc-hide-list '("PART" "QUIT" "JOIN"))
  (setq erc-autojoin-channels-alist '(("freenode.net"
				       "#emacs"
				       "#org-mode"))
	erc-server "irc.freenode.net"
	erc-nick "rememberYou"))
;;(erc :server "irc.freenode.net" :port 6667 :nick "rememberYou"))

Java

Configurate Java for Emacs is quite simple eclim. All you need to do, it's to install Eclipse and eclim.

Eclim

Is a protocol for communicating with an Eclipse server from vim. Fortunately, Emacs can also use eclim as an emacs port exists called emacs-eclim.

First of all, you need to download eclim with the Java Jar file as an installer and put the eclim and eclimd executables in the same folder where you installed Eclipse (for my case, /opt/eclipse).

(use-package eclim
  :init
  (add-hook 'java-mode-hook 'eclim-mode)
  :config
  (setq eclimd-autostart t)
  (setq eclimd-default-workspace '"~/Documents/Projects/Java/")
  (setq eclim-eclipse-dirs '"/opt/eclipse")
  (setq eclim-executable '"/opt/eclipse/eclim")
  (setq help-at-pt-display-when-idle t)
  (setq help-at-pt-timer-delay 0.1)
  (help-at-pt-set-timer))

company-emacs-eclim

From company-mode and provides auto-completion with eclim. For some reasons, I need to manualy launch company-mode by myself when opening a java buffer, I should fix that.

(use-package company-emacs-eclim
  :commands company-emacs-eclim-setup)

JavaScript

I don't often programming in JavaScript, but when I do, I like to have a confortable setup. For my JavaScript configuration, I took my sources from the blog of Nicolas Petton that I found really well explain.

Setting up Emacs for JavaScript (part #1)

Setting up Emacs for JavaScript (part #2)

js2-mode

By default, Emacs use js-mode as major mode for JavaScript buffers and I prefer use js2-mode instead because of his abilities to parses buffers and builds an AST for things like syntax highlighting.

(use-package js2-mode
  :init (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
  :config
  ;; Better imenu
  (add-hook 'js2-mode-hook #'js2-imenu-extras-mode))

js2-refactor

Provides powerful refactoring based on the AST generated by js2-mode

(use-package js2-refactor
  :init (add-hook 'js2-mode-hook #'js2-refactor-mode)
  :config
  (js2r-add-keybindings-with-prefix "C-c C-r")
  (define-key js2-mode-map (kbd "C-k") #'js2r-kill)

  ;; js-mode (which js2 is based on) binds "M-." which conflicts with xref, so
  ;; unbind it.
  (define-key js-mode-map (kbd "M-.") nil)

  (add-hook 'js2-mode-hook (lambda ()
			     (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))

xref-js2

Makes it easy to jump to function references or definitions.

(use-package xref-js2)

Tern

Parses JavaScript files in a project and does type inference to provide meaningful completion (with type hints) and support for cross-references.

Unfortunately, tern has some problems with the cross-references that why I'm using xref-js2 instead for that.

(use-package tern
  :config
  (bind-key "C-c C-c" 'compile tern-mode-keymap)      
  (add-hook 'js2-mode-hook (lambda ()
			     (tern-mode)
			     (company-mode)))

  ;; Disable completion keybindings, as we use xref-js2 instead
  (define-key tern-mode-keymap (kbd "M-.") nil)
  (define-key tern-mode-keymap (kbd "M-,") nil))

If you plan to use it, don’t forget installing it via npm

sudo npm install -g tern

Then adding a .tern-project file to your project root.

Here’s an example setup for a project that uses requirejs and jQuery, ignoring files from the bower_components directory:

{
    "libs": [
	"jquery"
    ],
    "loadEagerly": [
	"./**/*.js"
    ],
    "dontLoad": [
	"./bower_components/"
    ],
    "plugins": {
	"requirejs": {
	    "baseURL": "./"
	}
    }
}

company-tern

From company-mode and provides auto-completion with tern

(use-package company-tern
  :init (add-to-list 'company-backends 'company-tern))

Ledger

(use-package ledger-mode
  :ensure t
  :init
  (setq ledger-clear-whole-transactions 1)
  :mode "\\.dat\\'")

Move text

MoveText will move the current line (or if marked, the current region’s, whole lines.)

(use-package move-text
  :config
  (move-text-default-bindings))

Multi cursors

Multiple cursors for Emacs.

(use-package multiple-cursors
  :bind (("C-S-c C-S-c" . mc/edit-lines)
	 ("C->"         .  mc/mark-next-like-this)
	 ("C-<"         . mc/mark-previous-like-this)
	 ("C-c C-<"     . mc/mark-all-like-this)))

PDF-Tools

PDF Tools is, among other things, a replacement of DocView for PDF files. The key difference is, that pages are not pre-rendered by e.g. ghostscript and stored in the file-system, but rather created on-demand and stored in memory.

(pdf-tools-install)

Rainbow Mode

rainbow-mode is a minor mode for Emacs which displays strings representing colors with the color they represent as background.

(use-package rainbow-mode
  :commands rainbow-mode)

  (use-package web-mode
    :config
    (add-hook 'css-mode-hook 'rainbow-mode)
    (add-hook 'web-mode-hook 'rainbow-mode))

Skewer Mode

Provides live interaction with JavaScript, CSS, and HTML in a web browser. Expressions are sent on-the-fly from an editing buffer to be evaluated in the browser, just like Emacs does with an inferior Lisp process in Lisp modes.

(add-hook 'js2-mode-hook 'skewer-mode)
(add-hook 'css-mode-hook 'skewer-css-mode)
(add-hook 'html-mode-hook 'skewer-html-mode)
(add-hook 'web-mode-hook 'skewer-html-mode)

Simple HTTPD

A simple Emacs web server.

(use-package simple-httpd
  :config
  (setq httpd-root "/var/www/html"))

Smartparens

(use-package smartparens
  :config
  (progn
    (require 'smartparens-config)
    (add-hook 'emacs-lisp-mode-hook 'smartparens-mode)
    (add-hook 'emacs-lisp-mode-hook 'show-smartparens-mode)

;;;;;;;;;;;;;;;;;;;;;;;;
    ;; keybinding management

    (define-key sp-keymap (kbd "C-c s r n") 'sp-narrow-to-sexp)
    (define-key sp-keymap (kbd "C-M-f") 'sp-forward-sexp)
    (define-key sp-keymap (kbd "C-M-b") 'sp-backward-sexp)
    (define-key sp-keymap (kbd "C-M-d") 'sp-down-sexp)
    (define-key sp-keymap (kbd "C-M-a") 'sp-backward-down-sexp)
    (define-key sp-keymap (kbd "C-S-a") 'sp-beginning-of-sexp)
    (define-key sp-keymap (kbd "C-S-d") 'sp-end-of-sexp)

    (define-key sp-keymap (kbd "C-M-e") 'sp-up-sexp)
    (define-key emacs-lisp-mode-map (kbd ")") 'sp-up-sexp)
    (define-key sp-keymap (kbd "C-M-u") 'sp-backward-up-sexp)
    (define-key sp-keymap (kbd "C-M-t") 'sp-transpose-sexp)

    (define-key sp-keymap (kbd "C-M-n") 'sp-next-sexp)
    (define-key sp-keymap (kbd "C-M-p") 'sp-previous-sexp)

    (define-key sp-keymap (kbd "C-M-k") 'sp-kill-sexp)
    (define-key sp-keymap (kbd "C-M-w") 'sp-copy-sexp)

    (define-key sp-keymap (kbd "M-<delete>") 'sp-unwrap-sexp)
    (define-key sp-keymap (kbd "M-<backspace>") 'sp-backward-unwrap-sexp)

    (define-key sp-keymap (kbd "C-<right>") 'sp-forward-slurp-sexp)
    (define-key sp-keymap (kbd "C-<left>") 'sp-forward-barf-sexp)
    (define-key sp-keymap (kbd "C-M-<left>") 'sp-backward-slurp-sexp)
    (define-key sp-keymap (kbd "C-M-<right>") 'sp-backward-barf-sexp)

    (define-key sp-keymap (kbd "M-D") 'sp-splice-sexp)
    (define-key sp-keymap (kbd "C-M-<delete>") 'sp-splice-sexp-killing-forward)
    (define-key sp-keymap (kbd "C-M-<backspace>") 'sp-splice-sexp-killing-backward)
    (define-key sp-keymap (kbd "C-S-<backspace>") 'sp-splice-sexp-killing-around)

    (define-key sp-keymap (kbd "C-]") 'sp-select-next-thing-exchange)
    (define-key sp-keymap (kbd "C-<left_bracket>") 'sp-select-previous-thing)
    (define-key sp-keymap (kbd "C-M-]") 'sp-select-next-thing)

    (define-key sp-keymap (kbd "M-F") 'sp-forward-symbol)
    (define-key sp-keymap (kbd "M-B") 'sp-backward-symbol)

    (define-key sp-keymap (kbd "C-c s t") 'sp-prefix-tag-object)
    (define-key sp-keymap (kbd "C-c s p") 'sp-prefix-pair-object)
    (define-key sp-keymap (kbd "C-c s c") 'sp-convolute-sexp)
    (define-key sp-keymap (kbd "C-c s a") 'sp-absorb-sexp)
    (define-key sp-keymap (kbd "C-c s e") 'sp-emit-sexp)
    (define-key sp-keymap (kbd "C-c s p") 'sp-add-to-previous-sexp)
    (define-key sp-keymap (kbd "C-c s n") 'sp-add-to-next-sexp)
    (define-key sp-keymap (kbd "C-c s j") 'sp-join-sexp)
    (define-key sp-keymap (kbd "C-c s s") 'sp-split-sexp)

;;;;;;;;;;;;;;;;;;
    ;; pair management

    (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
    (sp-local-pair 'web-mode "<" nil :when '(my/sp-web-mode-is-code-context))

;;; markdown-mode
    (sp-with-modes '(markdown-mode gfm-mode rst-mode)
      (sp-local-pair "*" "*" :bind "C-*")
      (sp-local-tag "2" "**" "**")
      (sp-local-tag "s" "```scheme" "```")
      (sp-local-tag "<"  "<_>" "</_>" :transform 'sp-match-sgml-tags))

;;; tex-mode latex-mode
    (sp-with-modes '(tex-mode plain-tex-mode latex-mode)
      (sp-local-tag "i" "1d5f8e69396c521f645375107197ea4dfbc7b792quot;<" "1d5f8e69396c521f645375107197ea4dfbc7b792quot;>"))

;;; html-mode
    (sp-with-modes '(html-mode sgml-mode web-mode)
      (sp-local-pair "<" ">"))

;;; lisp modes
    (sp-with-modes sp--lisp-modes
      (sp-local-pair "(" nil :bind "C-("))))

Spotify

Control the spotify application from Emacs.

(use-package spotify
  :load-path "~/.emacs.d/spotify.el"
  :config
  (spotify-enable-song-notifications)
  (setq spotify-oauth2-client-id "Your-ID")
  (setq spotify-oauth2-client-secret "Your-PW"))

Undo tree

Emacs's undo system allows you to recover any past state of a buffer. To do this, Emacs treats "undo itself as just another editing action that can be undone.

(use-package undo-tree
  :diminish undo-tree-mode
  :config
  (progn
    (global-undo-tree-mode)
    (setq undo-tree-visualizer-timestamps t)
    (setq undo-tree-visualizer-diff t)))

Web beautify

web-beautify is a formatting package of HTML, CSS and JavaScript/JSON for Emacs. It uses the command-line/node.js javascript formatter from http://jsbeautifier.org/ to format whole html, css, js or json files, or region.

(require 'web-beautify) ;; Not necessary if using ELPA package
(eval-after-load 'js2-mode
  '(add-hook 'js2-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-js-buffer t t))))

;; Or if you're using 'js-mode' (a.k.a 'javascript-mode')
(eval-after-load 'js
  '(add-hook 'js-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-js-buffer t t))))

(eval-after-load 'json-mode
  '(add-hook 'json-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-js-buffer t t))))

(eval-after-load 'sgml-mode
  '(add-hook 'html-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-html-buffer t t))))

(eval-after-load 'web-mode
  '(add-hook 'web-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-html-buffer t t))))

(eval-after-load 'css-mode
  '(add-hook 'css-mode-hook
	     (lambda ()
	       (add-hook 'before-save-hook 'web-beautify-css-buffer t t))))

Web Mode

An autonomous emacs major-mode for editing web templates.

(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.blade\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))

Keychord

(use-package key-chord
  :init
  (progn
    (fset 'key-chord-define 'my/key-chord-define)
    (setq key-chord-one-key-delay 0.16)
    (key-chord-mode 1)
    (key-chord-define-global "yy"    'my/window-movement/body)
    (key-chord-define-global "jw"     'switch-window)))

Hydra

(use-package hydra
  :config
  (defhydra my/window-movement ()
    ("h" windmove-left)
    ("l" windmove-right)
    ("j" windmove-down)
    ("k" windmove-up)
    ("y" other-window "other")
    ("f" find-file "file")
    ("F" find-file-other-window "other file")
    ("v" (progn (split-window-right) (windmove-right)))
    ("o" delete-other-windows :color blue)
    ("a" ace-window)
    ("s" ace-swap-window)
    ("d" delete-window "delete")
    ("D" ace-delete-window "ace delete")
    ("i" ace-delete-other-windows)
    ("b" helm-buffers-list)
    ("q" nil))
  (defhydra join-lines ()
    ("n" join-line)
    ("p" (join-line 1))))

Winner Mode

Winner Mode is a global minor mode. When activated, it allows you to “undo” (and “redo”) changes in the window configuration.

(use-package winner
  :defer t)

YASnippet

YASnippet is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates.

(require 'yasnippet)
(yas-global-mode 1)

Mail

BBDB

Not working, don't fucking know why…

;; (require 'bbdb-loaddefs "~/elisp/bbdb/lisp/bbdb-loaddefs.el")
;; (require 'bbdb)
;; (bbdb-initialize 'gnus 'message)
;; (bbdb-insinuate-message)
;; (add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)
;; (setq bbdb-file "~/.emacs.d/bbdb")
;; (setq bbdb-send-mail-style 'gnus)
;; (setq bbdb-complete-name-full-completion t)
;; (setq bbdb-completion-type 'primary-or-name)
;; (setq bbdb-complete-name-allow-cycling t)
;; (setq bbdb-always-add-address t)
;; (setq bbbd-message-caching-enabled t)
;; (setq bbdb-use-alternate-names t)
;; (setq bbdb-north-american-phone-numbers-p nil)
;;(setq
;; bbdb-offer-save 1
;; bbdb-use-pop-up t
;; bbdb-electric-p t
;; bbdb-popup-target-lines  1
;; )

Gnus

I use Dovecot (IMAP server) with OfflineIMAP (IMAP synchronization) because I can read more faster my mails with Gnus.

(setq gnus-always-read-dribble-file t)
(setq message-directory "~/Maildir")
(setq gnus-secondary-select-methods
      '((nnmaildir "GMail" (directory "~/Maildir"))))
(setq gnus-directory "~/Maildir/News/")
(setq nnfolder-directory "~/Maildir/Archives/")

SMTP

Small piece of code allowing me to send mails with C-x m

(setq send-mail-function 'smtpmail-send-it
      message-send-mail-function 'smtpmail-send-it
      smtpmail-starttls-credentials
      '(("smtp.gmail.com" 587 nil nil))
      smtpmail-auth-credentials
      (expand-file-name "~/.authinfo")
      smtpmail-default-smtp-server "smtp.gmail.com"
      smtpmail-smtp-server "smtp.gmail.com"
      smtpmail-stream-type  'ssl
      smtpmail-smtp-service 587)