Table of Contents
- 1. About
- 2. Starting up
- 3. Personal informations
- 4. Emacs initialization
- 5. General configuration
- 5.1. Backups
- 5.2. Clean white spaces after saving
- 5.3. Highlight the current line
- 5.4. History
- 5.5. Killing text
- 5.6. Replaces "yes or no" with "y or n"
- 5.7. Set UTF-8
- 5.8. Show the column number and the parent
- 5.9. Theme
- 5.10. Time
- 5.11. Turn off mouse interface
- 5.12. Transparency
- 5.13. Word wrap at 80 characters
- 6. Org Mode
- 7. Navigationx
- 8. Reading
- 9. Shuffling lines
- 10. Writing
- 11. Org agenda
- 11.1. Basic configuration
- 11.2. Starting my weeks on Saturday
- 11.3. Display projects with associated subtasks
- 11.4. Org agenda custom commands
- 11.5. Make it easy to mark a task as done
- 11.6. Make it easy to mark a task as done and create a follow-up task
- 11.7. Capture something based on the agenda
- 11.8. Sorting by date and priority
- 11.9. Preventing things from falling through the cracks
- 11.10. Projects
- 11.11. Archiving
- 11.12. Compare times and effort estimates
- 12. Plugins configuration
- 12.1. Company
- 12.2. Emacs Lisp
- 12.3. HTML/CSS
- 12.4. LaTeX
- 12.5. Lua
- 12.6. Markdown
- 12.7. Python
- 12.8. SQL
- 12.9. Guide-key
- 12.10. Helm
- 12.11. Impatient mode
- 12.12. Internet Relay Chat
- 12.13. Java
- 12.14. JavaScript
- 12.15. Ledger
- 12.16. Move text
- 12.17. Multi cursors
- 12.18. PDF-Tools
- 12.19. Rainbow Mode
- 12.20. Skewer Mode
- 12.21. Simple HTTPD
- 12.22. Smartparens
- 12.23. Spotify
- 12.24. Undo tree
- 12.25. Web beautify
- 12.26. Web Mode
- 12.27. Keychord
- 12.28. Hydra
- 12.29. Winner Mode
- 12.30. YASnippet
- 13. Mail
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))
(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)
-
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")
-
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)))) -
Templates
I use
org-capturetemplates 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)-
Allow refiling in the middle(ish) of a capture
This lets me use
C-c C-rto 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))
-
-
Refiling
org-refilelets 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)-
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)) -
Quick way to jump
(defun my/org-jump () (interactive) (let ((current-prefix-arg '(4))) (call-interactively 'org-refile)))
-
Tasks
-
Managing tasks
-
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) -
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 ttoo. -
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))) -
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")) -
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) -
Habits
I like using
org-habitsto 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
habitto the tasks you want displayed.
-
-
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))))) -
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))) -
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)
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)