#+AUTHOR: Terencio Agozzino #+TITLE: GNU Emacs Configuration * Table of Content :TOC: - [[#about][About]] - [[#emacs-initialization][Emacs Initialization]] - [[#packages-sources][Packages Sources]] - [[#use-package][use-package]] - [[#start-up][Start Up]] - [[#authentification][Authentification]] - [[#better-defaults][Better defaults]] - [[#customization][Customization]] - [[#theme][Theme]] - [[#turn-off-mouse-interface][Turn off mouse interface]] - [[#languages][Languages]] - [[#css][CSS]] - [[#csv][CSV]] - [[#docker][Docker]] - [[#emacs-lisp][Emacs Lisp]] - [[#html][HTML]] - [[#java][Java]] - [[#javascript][JavaScript]] - [[#json][JSON]] - [[#latex][LaTeX]] - [[#lua][Lua]] - [[#markdown][Markdown]] - [[#plantuml][PlantUML]] - [[#python][Python]] - [[#sql][SQL]] - [[#typescript][TypeScript]] - [[#vuejs][Vue.js]] - [[#yaml][YAML]] - [[#yarn][Yarn]] - [[#advanced-configuration][Advanced Configuration]] - [[#alert][Alert]] - [[#auto-completion][Auto-Completion]] - [[#backups][Backups]] - [[#browser][Browser]] - [[#buffers][Buffers]] - [[#calculator][Calculator]] - [[#calendar][Calendar]] - [[#dashboard][Dashboard]] - [[#dired][Dired]] - [[#ending-up][Ending Up]] - [[#epub][EPUB]] - [[#files-frequently-consulted][Files Frequently Consulted]] - [[#spelling][Spelling]] - [[#history][History]] - [[#hydra][Hydra]] - [[#general][General]] - [[#irc][IRC]] - [[#ivy][Ivy]] - [[#ledger][Ledger]] - [[#linters][Linters]] - [[#lorem-ipsum][Lorem Ipsum]] - [[#mail][Mail]] - [[#navigation][Navigation]] - [[#parenthesis][Parenthesis]] - [[#paste][Paste]] - [[#pdf][PDF]] - [[#point-and-region][Point and Region]] - [[#projectile][Projectile]] - [[#recent-files][Recent Files]] - [[#revealjs][Reveal.js]] - [[#version-control][Version Control]] - [[#whitespaces][Whitespaces]] - [[#windows][Windows]] - [[#word-wrap][Word Wrap]] - [[#yasnippet][YASnippet]] - [[#org-mode][Org-Mode]] - [[#agenda][Agenda]] - [[#capture][Capture]] - [[#clock][Clock]] - [[#contacts][Contacts]] - [[#custormization][Custormization]] - [[#encryption--decryption][Encryption / Decryption]] - [[#journal][Journal]] - [[#languages-1][Languages]] * About After using GNU Emacs for a while, I decided to create my own config to simplify my daily life by adding scripts, useful functions, etc. For more informations about myself, you can visit my [[http://terencio-agozzino.com/][website]]. To manage package configurations, I use the [[https://github.com/jwiegley/use-package/][use-package]] package from John Wiegley, that I recommend. This configuration is mainly based on the following user configurations: - [[https://github.com/jwiegley/dot-emacs/][John Wiegley]] (=jwiegley=); - [[https://github.com/sachac][Sacha Chua]] (=sachac=); - [[https://github.com/angrybacon/dotemacs][Mathieu Marques]] (=angrybacon=). Thanks to them for their incredible work! * Emacs Initialization ** Packages Sources In order to install packages, it is useful to configure the package sources. #+BEGIN_SRC emacs-lisp :tangle yes (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ("melpa" . "http://melpa.org/packages/") ("org" . "http://orgmode.org/elpa/"))) #+END_SRC ** use-package To be able to manage its configuration with =use-package= it is necessary to first install it, if you don't already. #+BEGIN_SRC emacs-lisp :tangle yes (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (use-package delight :ensure t) (use-package diminish :ensure t) (use-package use-package-ensure-system-package :ensure t) #+END_SRC * Start Up ** Authentification I put my =.authinfo.gpg= file in [[https://github.com/syncthing/syncthing][Syncthing]] in order to be able to easily use my configuration on other devices. #+BEGIN_SRC emacs-lisp :tangle yes (setq auth-sources '("~/.gnupg/shared/.authinfo.gpg" "~/.authinfo.gpg" "~/.authinfo" "~/.netrc")) #+END_SRC ** Better defaults For a better user experience of GNU Emacs, here are the default values I use. #+BEGIN_SRC emacs-lisp :tangle yes (setq ad-redefinition-action 'accept ; Silence warnings for redefinition cursor-in-non-selected-windows t ; Hide the cursor in inactive windows display-time-default-load-average nil ; Don't display load average fill-column 80 ; Set width for automatic line breaks help-window-select t ; Focus new help windows when opened inhibit-startup-screen t ; Disable start-up screen initial-scratch-message "" ; Empty the initial *scratch* buffer load-prefer-newer t ; Prefers the newest version of a file scroll-conservatively most-positive-fixnum ; Always scroll by one line select-enable-clipboard t ; Merge system's and Emacs' clipboard tab-width 4 ; Set width for tabs use-package-always-ensure t ; Avoid the :ensure keyword for each package user-full-name "Terencio Agozzino" ; Set the full name of the current user user-mail-address "terencio.agozzino@gmail.com" ; Set the email address of the current user vc-follow-symlinks t) ; Always follow the symlinks (cd "~/") ; Move to the user directory (column-number-mode 1) ; Show the column number (display-time-mode 1) ; Enable time in the mode-line (fset 'yes-or-no-p 'y-or-n-p) ; Replace yes/no prompts with y/n (global-hl-line-mode) ; Hightlight current line (show-paren-mode 1) ; Show the parent #+END_SRC ** Customization To avoid overloading the GNU Emacs custormization =init.el= file made by the user with the UI, I add the generated code in a separate file. #+BEGIN_SRC emacs-lisp :tangle yes (setq-default custom-file (expand-file-name "custom.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file t)) #+END_SRC ** Theme I like the light on dark because I find it to be more restful. #+BEGIN_SRC emacs-lisp :tangle yes (use-package nord-theme :config (add-to-list 'custom-theme-load-path (expand-file-name "~/.emacs.d/themes/")) (load-theme 'nord t)) (use-package smart-mode-line :defer 0.1 :custom (sml/theme 'respectful) :config (sml/setup)) #+END_SRC ** Turn off mouse interface Since I never use the mouse with GNU Emacs, I prefer not to use certain graphical elements as seen as the menu bar, toolbar, scrollbar and tooltip that I find invasive. #+BEGIN_SRC emacs-lisp :tangle yes (when window-system (menu-bar-mode -1) ; Disable the menu bar (scroll-bar-mode -1) ; Disable the scroll bar (tool-bar-mode -1) ; Disable the tool bar (tooltip-mode -1)) ; Disable the tooltips #+END_SRC * Languages ** CSS #+BEGIN_SRC emacs-lisp :tangle yes (use-package css-mode :custom (css-indent-offset 2)) #+END_SRC *** =emmet-mode= Powerful minor mode to produce HTML from CSS-like selector. #+BEGIN_SRC emacs-lisp :tangle yes (use-package emmet-mode :defer 6 :hook (sgml-mode css-mode web-mode)) #+END_SRC *** =less-css-mode= Awesome package to programming in LESS. #+BEGIN_SRC emacs-lisp :tangle yes (use-package less-css-mode :mode "\\.less\\'" :interpreter ("less" . less-css-mode)) #+END_SRC *** =sass-mode= Awesome package to programming in SASS. #+BEGIN_SRC emacs-lisp :tangle yes (use-package scss-mode :mode "\\.scss\\'") #+END_SRC ** CSV #+BEGIN_SRC emacs-lisp :tangle yes (use-package csv-mode) #+END_SRC ** Docker I like to use Docker when I need to install various databases or other services that only work on a particular operating system while keeping my operating system clean. #+BEGIN_SRC emacs-lisp :tangle yes (use-package dockerfile-mode :delight dockerfile-mode "δ" :mode "Dockerfile\\'") #+END_SRC ** Emacs Lisp #+BEGIN_SRC emacs-lisp :tangle yes (use-package elisp-mode :ensure nil :delight emacs-lisp-mode "ξ") #+END_SRC *** Eldoc Provides minibuffer hints when working with Emacs Lisp. #+BEGIN_SRC emacs-lisp :tangle yes (use-package eldoc :diminish :hook (emacs-lisp-mode . eldoc-mode)) #+END_SRC ** HTML #+BEGIN_SRC emacs-lisp :tangle yes (use-package sgml-mode :delight html-mode "HTML" :hook ((html-mode . me/html-set-pretty-print-function) (html-mode . sgml-electric-tag-pair-mode) (html-mode . sgml-name-8bit-mode) (html-mode . toggle-truncate-lines)) :custom (sgml-basic-offset 2) :preface (defun me/html-set-pretty-print-function () (setq me/pretty-print-function #'sgml-pretty-print))) #+END_SRC ** Java Configuring Java for GNU Emacs is very simple with =eclim=. All you need to do is install =Eclipse= and =eclim=. *** Eclim #+BEGIN_QUOTE Eclim is an Eclipse plugin which exposes Eclipse features through a server interface. When this server is started, the command line utility eclim can be used to issue requests to that server. [[https://github.com/senny/emacs-eclim][James Chochlinski]] #+END_QUOTE To use this plugin, you must download =eclim= with the Java Jar file as installer and put the executables =eclim= and =eclimd= in the same folder where you installed =Eclipse= (in my case, =/opt/eclipse=). Now all that remains is to configure =eclim=: #+BEGIN_SRC emacs-lisp :tangle yes (use-package eclim :defer 3 :hook (java-mode . eclim-mode) :custom (eclimd-autostart t) (eclimd-default-workspace '"~/Documents/Projects/Java/") (eclim-eclipse-dirs '"/opt/eclipse") (eclim-executable '"/opt/eclipse/eclim") (help-at-pt-display-when-idle t) (help-at-pt-timer-delay 0.1) :config (help-at-pt-set-timer)) #+END_SRC *** =company-emacs-eclim= =eclim= backend for =company-mode=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package company-emacs-eclim :after (company eclim) :commands company-emacs-eclim-setup) #+END_SRC *** Gradle Most of my Java projects are made with =gradle=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package gradle-mode :delight gradle-mode "γ" :mode "\\.gradle\\'" :interpreter ("gradle" . gradle-mode)) #+END_SRC ** JavaScript For my JavaScript configuration, I took my sources from the Nicolas Petton's blog which I found very well explained. [[https://emacs.cafe/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html][Setting up Emacs for JavaScript (part #1)]] [[https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2.html][Setting up Emacs for JavaScript (part #2)]] I like to use [[https://prettier.io/][prettier]] to get my TypeScript code clean. To use it, don't forget to install it with your package manager. #+BEGIN_SRC emacs-lisp :tangle yes (use-package prettier-js :diminish :custom (prettier-js-args '("--trailing-comma" "es5" "--single-quote" "true" "--print-width" "100"))) #+END_SRC *** =js2-mode2= By default, GNU Emacs uses =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. #+BEGIN_SRC emacs-lisp :tangle yes (use-package js2-mode :hook (js2-mode . js2-imenu-extras-mode) :mode "\\.js\\'" :custom (js-indent-level 2)) #+END_SRC *** =js2-refactor= Provides powerful refactoring based on the AST generated by =js2-mode=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package js2-refactor :defer 5 :bind (:map js2-mode-map ("C-k" . js2r-kill) ("M-." . nil)) :hook ((js2-mode . js2-refactor-mode) (js2-mode . (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t)))) :config (js2r-add-keybindings-with-prefix "C-c C-r")) #+END_SRC *** =xref-js2= Makes it easy to jump to function references or definitions. #+BEGIN_SRC emacs-lisp :tangle yes (use-package xref-js2 :defer 5) #+END_SRC *** =tern= Parses JavaScript files in a project and makes type inference to provide meaningful completion (with type clues) and cross-reference support. Unfortunately, =tern= has some problems with cross-references that explain why I am using =xref-js2= instead. #+BEGIN_SRC emacs-lisp :tangle yes (use-package tern :ensure-system-package (tern . "npm install -g tern") :defer 5 :bind (("C-c C-c" . compile) :map tern-mode-keymap ("M-." . nil)) :hook ((js2-mode . company-mode) (js2-mode . tern-mode))) #+END_SRC Then, add a =.tern-project= file to the root of your project. Here is an example configuration for a project that uses =requirejs= and =jQuery=, without taking into account of the =bower_components= directory: #+BEGIN_SRC json { "libs": [ "jquery" ], "loadEagerly": [ "./**/*.js" ], "dontLoad": [ "./bower_components/" ], "plugins": { "requirejs": { "baseURL": "./" } } } #+END_SRC *** =company-tern= =tern= backend for =company-mode=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package company-tern :after (company tern) :config (add-to-list 'company-backends 'company-tern)) #+END_SRC ** JSON #+BEGIN_SRC emacs-lisp :tangle yes (use-package json-mode :delight json-mode "J" :mode "\\.json\\'" :hook (before-save . my-json-mode-before-save-hook) :preface (defun my-json-mode-before-save-hook () (when (eq major-mode 'json-mode) (json-pretty-print-buffer-ordered)))) #+END_SRC ** LaTeX I use LaTeX for my reports, CVs, summaries, etc. #+BEGIN_SRC emacs-lisp :tangle yes (use-package tex :ensure auctex :hook (LaTeX-mode . reftex-mode) :custom (TeX-PDF-mode t) (TeX-auto-save t) (TeX-byte-compile t) (TeX-clean-confirm nil) (TeX-master 'dwim) (TeX-parse-self t) (TeX-source-correlate-mode t) (TeX-view-program-selection '((output-pdf "Evince") (output-html "xdg-open")))) #+END_SRC I want a TeX engine that can deal with Unicode and use any font I like. #+BEGIN_SRC emacs-lisp :tangle yes (setq-default TeX-engine 'xetex) #+END_SRC *** =company-auctex= AUCTeX backend for company-mode. #+BEGIN_SRC emacs-lisp :tangle yes (use-package company-auctex :after (auctex company) :config (company-auctex-init)) #+END_SRC *** =reftex= Minor mode with distinct support for \label, \ref and \cite in LaTeX. #+BEGIN_SRC emacs-lisp :tangle yes (use-package reftex :after auctex) #+END_SRC ** Lua I rarely program in Lua, but when I do, =lua-mode= satisfies me amply. #+BEGIN_SRC emacs-lisp :tangle yes (use-package lua-mode :delight lua-mode "Λ" :mode "\\.lua\\'" :interpreter ("lua" . lua-mode)) #+END_SRC ** Markdown Before you can use this package, make sure you install =markdown= on your operating system. #+BEGIN_SRC emacs-lisp :tangle yes (use-package markdown-mode :delight markdown-mode "μ" :mode ("INSTALL\\'" "CONTRIBUTORS\\'" "LICENSE\\'" "README\\'" "\\.markdown\\'" "\\.md\\'")) #+END_SRC ** PlantUML All my diagrams are made with PlantUML. #+BEGIN_SRC emacs-lisp :tangle yes (use-package plantuml-mode :defer 3) #+END_SRC ** Python I prefer to use =anaconda-mode= which I find easier to configure, because it supports =company-mode= better than =jedi= which is quite old. #+BEGIN_SRC emacs-lisp :tangle yes (use-package python :delight python-mode "π" :bind (("M-[" . python-nav-backward-block) ("M-]" . python-nav-forward-block))) #+END_SRC *** =anaconda-mode= #+BEGIN_SRC emacs-lisp :tangle yes (use-package anaconda-mode :after python :hook ((anaconda-mode anaconda-eldoc-mode) . python-mode)) #+END_SRC *** =company-anaconda= Anaconda backend for =company-mode=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package company-anaconda :after (anaconda-mode company) :config (add-to-list 'company-backends 'company-anaconda)) #+END_SRC ** SQL =sql-indent= gives me the possibility to easily manage =.sql= files. #+BEGIN_SRC emacs-lisp :tangle yes (use-package sql-indent :delight sql-mode "Σ" :mode "\\.sql\\'" :interpreter ("sql" . sql-mode)) #+END_SRC ** TypeScript #+BEGIN_SRC emacs-lisp :tangle yes (use-package tide :after (company flycheck) :preface (defun setup-tide-mode () (interactive) (tide-setup) (flycheck-mode +1) (setq flycheck-check-syntax-automatically '(save mode-enabled)) (eldoc-mode +1) (tide-hl-identifier-mode +1) (company-mode +1)) :hook (before-save . tide-format-before-save)) #+END_SRC ** Vue.js #+BEGIN_SRC emacs-lisp :tangle yes (use-package vue-mode :delight vue-mode "V" :mode "\\.vue\\'" :hook (vue-mode . prettier-js-mode) :custom (mmm-submode-decoration-level 0) (vue-html-extra-indent 2)) #+END_SRC ** YAML =yaml-mode= gives me the possibility to easily manage =.yml= files. #+BEGIN_SRC emacs-lisp :tangle yes (use-package yaml-mode :delight yaml-mode "ψ" :mode "\\.yml\\'" :interpreter ("yml" . yml-mode)) #+END_SRC ** Yarn =yarn-mode= gives me the possibility to easily manage =.yarn-lock= files. #+BEGIN_SRC emacs-lisp :tangle yes (use-package yarn-mode :delight yarn-mode "Y") #+END_SRC * Advanced Configuration ** Alert Most packages use =alerts= to make notifications with =libnotify=. Don't forget to first install a notification daemon, like =dunst=. #+BEGIN_QUOTE Alert is a Growl-workalike for Emacs which uses a common notification interface and multiple, selectable "styles", whose use is fully customizable by the user. [[https://github.com/jwiegley/alert][John Wiegley]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package alert :custom (alert-default-style 'libnotify)) #+END_SRC ** Auto-Completion =company= provides auto-completion at point and to Displays a small pop-in containing the candidates. #+BEGIN_QUOTE 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. [[http://company-mode.github.io/][Dmitry Gutov]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package company :defer 2 :diminish :custom (company-begin-commands '(self-insert-command)) (company-idle-delay .1) (company-minimum-prefix-length 2) (company-show-numbers t) (company-tooltip-align-annotations 't) (global-company-mode t)) #+END_SRC I use =company= with =company-box= that allows a company front-end with icons. #+BEGIN_SRC emacs-lisp :tangle yes (use-package company-box :after company :diminish :hook (company-mode . company-box-mode)) #+END_SRC ** Backups It is important to have a stable backup environment. Don't hesitate to save a lot. *NOTE:* the functions defined below avoid running a bash command when saving certain files with GNU Emacs. #+BEGIN_SRC emacs-lisp :tangle yes (use-package files :ensure nil :preface (defvar *afilename-cmd* '(("/home/someone/.Xresources" . "xrdb -merge ~/.Xresources") ("/home/someone/.xbindkeysrc" . "xbindkeys -p")) "File association list with their respective command.") (defun my/cmd-after-saved-file () "Execute a command after saved a specific file." (let* ((match (assoc (buffer-file-name) *afilename-cmd*))) (when match (shell-command (cdr match))))) :hook (after-save . my/cmd-after-saved-file) :custom (backup-directory-alist `(("." . ,(expand-file-name "backups/" user-emacs-directory)))) (delete-old-versions -1) (vc-make-backup-files t) (version-control t)) #+END_SRC ** Browser I prefer to use Chromium, the open-source version of Google Chrome that I find faster than Firefox. Maybe I should switch for qutebrowser. #+BEGIN_SRC emacs-lisp :tangle yes (setq browse-url-browser-function 'browse-url-chromium) #+END_SRC *** =atomic chrome= Helpful when I need to edit text areas of the browser in GNU Emacs. #+BEGIN_SRC emacs-lisp :tangle yes (use-package atomic-chrome :defer 2 :preface (defun atomic-chrome-server-running-p () (cond ((executable-find "lsof") (zerop (call-process "lsof" nil nil nil "-i" ":64292"))) ((executable-find "netstat") (zerop (call-process-shell-command "netstat -aon | grep 64292"))))) :init (if (atomic-chrome-server-running-p) (message "Can't start atomic-chrome server, because port 64292 is already used") (atomic-chrome-start-server))) #+END_SRC *** =engine-mode= I use it to do most of my web searches without leaving GNU Emacs. #+BEGIN_SRC emacs-lisp :tangle yes (use-package engine-mode :defer 3 :config (defengine amazon "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=%s" :keybinding "a") (defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "d") (defengine github "https://github.com/search?ref=simplesearch&q=%s" :keybinding "g") (defengine google-images "http://www.google.com/images?hl=en&source=hp&biw=1440&bih=795&gbv=2&aq=f&aqi=&aql=&oq=&q=%s" :keybinding "i") (defengine google-maps "http://maps.google.com/maps?q=%s" :keybinding "m" :docstring "Mappin' it up.") (defengine stack-overflow "https://stackoverflow.com/search?q=%s" :keybinding "s") (defengine youtube "http://www.youtube.com/results?aq=f&oq=&search_query=%s" :keybinding "y") (defengine wikipedia "http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s" :keybinding "w" :docstring "Searchin' the wikis.") (engine-mode t)) #+END_SRC ** Buffers Buffers can quickly become a mess. For some people, it's not a problem, but I like being able to find my way easily. #+BEGIN_SRC emacs-lisp :tangle yes (use-package ibuffer :defer 1 :bind ("C-x C-b" . ibuffer)) (use-package ibuffer-projectile :after ibuffer :preface (defun my/ibuffer-projectile () (ibuffer-projectile-set-filter-groups) (unless (eq ibuffer-sorting-mode 'alphabetic) (ibuffer-do-sort-by-alphabetic))) :hook (ibuffer . my/ibuffer-projectile)) #+END_SRC ** Calculator May be useful in a timely manner. #+BEGIN_SRC emacs-lisp :tangle yes (use-package calc :defer t :custom (math-additional-units '((GiB "1024 * MiB" "Giga Byte") (MiB "1024 * KiB" "Mega Byte") (KiB "1024 * B" "Kilo Byte") (B nil "Byte") (Gib "1024 * Mib" "Giga Bit") (Mib "1024 * Kib" "Mega Bit") (Kib "1024 * b" "Kilo Bit") (b "B / 8" "Bit"))) (math-units-table nil)) #+END_SRC ** Calendar Remembering all the dates is not obvious, especially since some varies every year. In order to remember each important date, I recorded the list of important dates according to my country, Belgium. It is very likely that some dates are different in your country, therefore, adapt the configuration below accordingly. #+BEGIN_SRC emacs-lisp :tangle yes (use-package calendar :custom (calendar-mark-holidays-flag t)) (use-package holidays :ensure nil :custom (holiday-bahai-holidays nil) (holiday-christian-holidays '((holiday-fixed 1 6 "Epiphany") (holiday-fixed 2 2 "Candlemas") (holiday-easter-etc -47 "Mardi Gras") (holiday-easter-etc 0 "Easter Day") (holiday-easter-etc 1 "Easter Monday") (holiday-easter-etc 39 "Ascension") (holiday-easter-etc 49 "Pentecost") (holiday-fixed 8 15 "Assumption") (holiday-fixed 11 1 "All Saints' Day") (holiday-fixed 11 2 "Day of the Dead") (holiday-fixed 11 22 "Saint Cecilia's Day") (holiday-fixed 12 1 "Saint Eloi's Day") (holiday-fixed 12 4 "Saint Barbara") (holiday-fixed 12 6 "Saint Nicholas Day") (holiday-fixed 12 25 "Christmas Day"))) (holiday-general-holidays '((holiday-fixed 1 1 "New Year's Day") (holiday-fixed 2 14 "Valentine's Day") (holiday-fixed 3 8 "International Women's Day") (holiday-fixed 10 31 "Halloween") (holiday-fixed 11 11 "Armistice of 1918"))) (holiday-hebrew-holidays nil) (holiday-islamic-holidays nil) (holiday-local-holidays '((holiday-fixed 5 1 "Labor Day") (holiday-float 3 0 0 "Grandmothers' Day") (holiday-float 4 4 3 "Secretary's Day") (holiday-float 5 0 2 "Mother's Day") (holiday-float 6 0 3 "Father's Day"))) (holiday-oriental-holidays nil)) #+END_SRC ** Dashboard Always good to have a dashboard. #+BEGIN_SRC emacs-lisp :tangle yes (use-package dashboard :preface (defun my/dashboard-banner () "Set a dashboard banner including information on package initialization time and garbage collections." (setq dashboard-banner-logo-title (format "Emacs ready in %.2f seconds with %d garbage collections." (float-time (time-subtract after-init-time before-init-time)) gcs-done))) :init (add-hook 'after-init-hook 'dashboard-refresh-buffer) (add-hook 'dashboard-mode-hook 'my/dashboard-banner) :custom (dashboard-startup-banner 'logo) :config (dashboard-setup-startup-hook)) #+END_SRC ** Dired For those who didn't know, GNU Emacs is also a file explorer. #+BEGIN_SRC emacs-lisp :tangle yes (use-package dired :ensure nil :delight dired-mode "Dired" :custom (dired-auto-revert-buffer t) (dired-dwim-target t) (dired-hide-details-hide-symlink-targets nil) (dired-listing-switches "-alh") (dired-ls-F-marks-symlinks nil) (dired-recursive-copies 'always)) (use-package dired-x :ensure nil :preface (defun my/dired-revert-after-cmd (command &optional output error) (revert-buffer)) :config (advice-add 'dired-smart-shell-command :after #'my/dired-revert-after-cmd)) #+END_SRC ** Ending Up I'm using an =.org= file to maintain my GNU Emacs configuration. However, at his launch, it will loads the =config.el= source file for a faster loading. The code below, executes =org-babel-tangle= asynchronously when =config.org= is saved. #+BEGIN_SRC emacs-lisp :tangle yes (use-package async) (defvar *config-file* (expand-file-name "config.org" user-emacs-directory) "The configuration file.") (defvar *config-last-change* (nth 5 (file-attributes *config-file*)) "Last modification time of the configuration file.") (defvar *show-async-tangle-results* nil "Keeps *emacs* async buffers around for later inspection.") (defun my/config-updated () "Checks if the configuration file has been updated since the last time." (time-less-p *config-last-change* (nth 5 (file-attributes *config-file*)))) (defun my/config-tangle () "Tangles the org file asynchronously." (when (my/config-updated) (setq *config-last-change* (nth 5 (file-attributes *config-file*))) (my/async-babel-tangle *config-file*))) (defun my/async-babel-tangle (org-file) "Tangles the org file asynchronously." (let ((init-tangle-start-time (current-time)) (file (buffer-file-name)) (async-quiet-switch "-q")) (async-start `(lambda () (require 'org) (org-babel-tangle-file ,org-file)) (unless *show-async-tangle-results* `(lambda (result) (if result (message "SUCCESS: %s successfully tangled (%.2fs)." ,org-file (float-time (time-subtract (current-time) ',init-tangle-start-time))) (message "ERROR: %s as tangle failed." ,org-file))))))) #+END_SRC ** EPUB #+BEGIN_SRC emacs-lisp :tangle yes (use-package nov :mode ("\\.epub\\'" . nov-mode) :custom (nov-text-width 75)) #+END_SRC ** Files Frequently Consulted Registers allow you to jump quickly to a file or other location. To switch to a registry, use =C-x r j= followed by the registry letter. Using registers for all these file shortcuts is probably a bit unnecessary since I can easily define my own keymap, but anyway, I rarely go beyond the register. #+BEGIN_SRC emacs-lisp :tangle yes (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 ?I "~/.config/i3/config") (my/defshortcut ?S "~/.config/sway/config") (my/defshortcut ?X "~/.Xresources") (my/defshortcut ?b "~/.personal/other/purchases.org") (my/defshortcut ?c "~/.emacs.d/config.org") (my/defshortcut ?i "~/.emacs.d/init.el") (my/defshortcut ?m "~/.personal/other/movies.org") (my/defshortcut ?o "~/.personal/agenda/organizer.org") (my/defshortcut ?p "~/.personal/agenda/people.org") (my/defshortcut ?r "~/.personal/agenda/routine.org") (my/defshortcut ?s "~/.personal/agenda/school.org") #+END_SRC ** Spelling *** Abbreviations According to a list of misspelled words, =abbrev= auto-correct these words on the fly. #+BEGIN_SRC emacs-lisp :tangle yes (use-package abbrev :defer 1 :ensure nil :custom (abbrev-file-name (expand-file-name ".abbrev_defs" user-emacs-directory)) (abbrev-mode 1) :config (if (file-exists-p abbrev-file-name) (quietly-read-abbrev-file))) #+END_SRC *** Fly Spell For the other words that would not be in my list of abbreviations, =flyspell= enables spell checking on-the-fly in GNU Emacs. #+BEGIN_SRC emacs-lisp :tangle yes (use-package flyspell :defer 1 :custom (flyspell-abbrev-p t) (flyspell-issue-message-flag nil) (flyspell-issue-welcome-flag nil) (flyspell-mode 1)) (use-package flyspell-correct-ivy :after flyspell :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-word-generic)) :custom (flyspell-correct-interface 'flyspell-correct-ivy)) (use-package ispell :custom (ispell-silently-savep t)) #+END_SRC *** Grammar Checker [[https://languagetool.org/][LanguageTool]] is great for correcting your grammar. Combined with =abbrev-mode= and =flyspell=, you will have better documents. In order to be able to use it locally, download the desktop version and change the paths indicated below. #+BEGIN_SRC emacs-lisp :tangle yes (use-package langtool :defer 2 :diminish :custom (langtool-language-tool-jar "~/lib/LangueageTool-4.2/languagetool-commandline.jar") (langtool-language-tool-server-jar "~/lib/LanguageTool-4.2/languagetool-server.jar")) #+END_SRC ** History Provides the ability to have commands and their history saved so that whenever you return to work, you can re-run things as you need them. This is not a radical function, it is part of a good user experience. #+BEGIN_SRC emacs-lisp :tangle yes (use-package savehist :ensure nil :custom (history-delete-duplicates t) (history-length t) (savehist-additional-variables '(kill-ring search-ring regexp-search-ring)) (savehist-file (expand-file-name "history" user-emacs-directory)) (savehist-save-minibuffer-history 1) :config (savehist-mode 1)) #+END_SRC ** Hydra Hydra allows me to display a list of all the commands implemented in the echo area and easily interact with them. #+BEGIN_QUOTE Once you summon the Hydra through the prefixed binding (the body + any one head), all heads can be called in succession with only a short extension. The Hydra is vanquished once Hercules, any binding that isn't the Hydra's head, arrives. Note that Hercules, besides vanquishing the Hydra, will still serve his original purpose, calling his proper command. This makes the Hydra very seamless, it's like a minor mode that disables itself auto-magically. [[https://github.com/abo-abo/hydra][Oleh Krehel]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package hydra :defer 2 :bind (("C-c L" . hydra-ledger/body) ("C-c P" . hydra-projectile/body) ("C-c b" . hydra-buffer/body) ("C-c c" . hydra-clock/body) ("C-c e" . hydra-erc/body) ("C-c f" . hydra-flycheck/body) ("C-c g" . hydra-toggle/body) ("C-c m" . hydra-magit/body) ("C-c o" . hydra-org/body) ("C-c s" . hydra-spelling/body) ("C-c p t" . hydra-typescript/body) ("C-c y" . hydra-yasnippet/body) ("C-c w" . hydra-windows/body))) #+END_SRC *** Hydra / Buffer Group Buffer commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-buffer (:color blue) " ^ ^Buffer^ ^Do^ ^──────^─────────────^──^────────── _q_ quit _k_ kill ^^ _l_ list ^^ _n_ next ^^ _p_ previous ^^ ^^ " ("q" nil) ("k" kill-buffer) ("l" ibuffer) ("n" next-buffer) ("p" previous-buffer)) #+END_SRC *** Hydra / Clock Group clock commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-clock (:color blue) " ^ ^Clock^ ^Do^ ^─────^─────────────^──^───────── _q_ quit _c_ cancel ^^ _d_ display ^^ _e_ effort ^^ _i_ in ^^ _j_ jump ^^ _o_ out ^^ _r_ report ^^ ^^ " ("q" nil) ("c" org-clock-cancel) ("d" org-clock-display) ("e" org-clock-modify-effort-estimate) ("i" org-clock-in) ("j" org-clock-goto) ("o" org-clock-out) ("r" org-clock-report)) #+END_SRC *** Hydra / ERC Group ERC commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-erc (:color blue) " ^ ^ERC^ ^Do^ ^───^─────────────^──^──────────── _q_ quit _c_ connect ^^ _d_ disconnect ^^ _j_ join ^^ _n_ names ^^ _u_ users ^^ ^^ " ("q" nil) ("c" my/erc-start-or-switch) ("d" erc-quit-server) ("j" erc-join-channel) ("n" erc-channel-names) ("u" my/erc-count-users)) #+END_SRC *** Hydra / Flycheck Group Flycheck commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-flycheck (:color blue) " ^ ^Flycheck^ ^Errors^ ^Checker^ ^────────^──────────^──────^────────────^───────^───── _q_ quit _<_ previous _?_ describe _M_ manual _>_ next _d_ disable _v_ verify setup _f_ check _m_ mode ^^ _l_ list _s_ select ^^ ^^ ^^ " ("q" nil) ("<" flycheck-previous-error :color pink) (">" flycheck-next-error :color pink) ("?" flycheck-describe-checker) ("M" flycheck-manual) ("d" flycheck-disable-checker) ("f" flycheck-buffer) ("l" flycheck-list-errors) ("m" flycheck-mode) ("s" flycheck-select-checker) ("v" flycheck-verify-setup)) #+END_SRC *** Hydra / Ledger Group Ledger commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-ledger (:color blue) " ^ ^Ledger^ ^Do^ ^──────^─────────────^──^─────── _q_ quit _a_ add ^^ _c_ clear ^^ _C_ copy ^^ _d_ delete ^^ _r_ report ^^ ^^ " ("q" nil) ("a" ledger-add-transaction) ("c" ledger-mode-clean-buffer) ("C" ledger-copy-transaction-at-point) ("d" ledger-delete-current-transaction) ("r" ledger-report)) #+END_SRC *** Hydra / Magit Group Magit commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-magit (:color blue) " ^ ^Magit^ ^Do^ ^─────^─────────────^──^──────── _q_ quit _b_ blame ^^ _c_ clone ^^ _i_ init ^^ _s_ status ^^ ^^ " ("q" nil) ("b" magit-blame) ("c" magit-clone) ("i" magit-init) ("s" magit-status)) #+END_SRC *** Hydra / Org Group Org commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-org (:color blue) " ^ ^Org^ ^Do^ ^───^─────────────^──^───────────── _q_ quit _A_ archive ^^ _a_ agenda ^^ _c_ capture ^^ _d_ decrypt ^^ _i_ insert-link ^^ _j_ jump-task ^^ _k_ cut-subtree ^^ _o_ open-link ^^ _r_ refile ^^ _s_ store-link ^^ _t_ todo-tree ^^ ^^ " ("q" nil) ("A" my/org-archive-done-tasks) ("a" org-agenda) ("c" org-capture) ("d" org-decrypt-entry) ("k" org-cut-subtree) ("i" org-insert-link-global) ("j" my/org-jump) ("o" org-open-at-point-global) ("r" org-refile) ("s" org-store-link) ("t" org-show-todo-tree)) #+END_SRC *** Hydra / Projectile Group Projectile commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-projectile (:color blue) " ^ ^Projectile^ ^Buffers^ ^Find^ ^Search^ ^──────────^────────^───────^───────────^────^──────────────^──────^──────────── _q_ quit _b_ list _d_ directory _r_ replace _i_ reset cache _K_ kill all _D_ root _R_ regexp replace ^^ _S_ save all _f_ file _s_ ag ^^ ^^ _p_ project ^^ ^^ ^^ ^^ ^^ " ("q" nil) ("b" counsel-projectile-switch-to-buffer) ("d" counsel-projectile-find-dir) ("D" projectile-dired) ("f" counsel-projectile-find-file) ("i" projectile-invalidate-cache :color red) ("K" projectile-kill-buffers) ("p" counsel-projectile-switch-project) ("r" projectile-replace) ("R" projectile-replace-regexp) ("s" counsel-projectile-ag) ("S" projectile-save-project-buffers)) #+END_SRC *** Hydra / Spelling Group spelling commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-spelling (:color blue) " ^ ^Spelling^ ^Errors^ ^Checker^ ^────────^──────────^──────^────────────^───────^─────── _q_ quit _<_ previous _c_ correction ^^ _>_ next _d_ dictionary ^^ _f_ check _m_ mode ^^ ^^ ^^ " ("q" nil) ("<" flyspell-correct-previous :color pink) (">" flyspell-correct-next :color pink) ("c" ispell) ("d" ispell-change-dictionary) ("f" flyspell-buffer) ("m" flyspell-mode)) #+END_SRC *** Hydra / Toggle Group toggle commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-toggle (:color blue) " ^ ^Toggle^ ^Do^ ^──────^─────────────^──^──────────────────── _q_ quit _a_ abbrev ^^ _r_ rainbow-delimiters ^^ _s_ smartparens ^^ _w_ winner ^^ ^^ " ("q" nil) ("a" abbrev-mode) ("r" rainbow-delimiters-mode) ("s" smartparens-mode) ("w" winner-mode)) #+END_SRC *** Hydra / TypeScript Group TypeScript commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-typescript (:color blue) " ^ ^TypeScript^ ^Do^ ^──────────^──────────^──^──────── _q_ quit _b_ back ^^ _e_ errors ^^ _j_ jump ^^ _r_ references ^^ _R_ restart ^^ ^^ " ("q" nil) ("b" tide-jump-back) ("e" tide-project-errors) ("j" tide-jump-to-definition) ("r" tide-references) ("R" tide-restart-server)) #+END_SRC *** Hydra / YASnippet Group YASnippet commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-yasnippet (:color blue) " ^ ^YASnippet^ ^Do^ ^─────────^──────────^──^──────── _q_ quit _i_ insert ^^ _m_ mode ^^ _n_ new ^^ ^^ " ("q" nil) ("i" ivy-yasnippet) ("m" yas-minor-mode) ("n" yas-new-snippet)) #+END_SRC *** Hydra / Windows Group window-related commands. #+BEGIN_SRC emacs-lisp :tangle yes (defhydra hydra-windows (:color pink) " ^ ^Windows^ ^Window^ ^Zoom^ ^───────^───────────^──────^────────────^────^────── _q_ quit _b_ balance _-_ out ^^ _i_ heighten _+_ in ^^ _j_ narrow _=_ reset ^^ _k_ lower ^^ ^^ _l_ widen ^^ ^^ _s_ swap ^^ ^^ ^^ ^^ " ("q" nil) ("b" balance-windows) ("i" enlarge-window) ("j" shrink-window-horizontally) ("k" shrink-window) ("l" enlarge-window-horizontally) ("s" switch-window-then-swap-buffer :color blue) ("-" text-scale-decrease) ("+" text-scale-increase) ("=" (text-scale-increase 0))) #+END_SRC ** General *** =aggressive-indent= Auto-indent code as you write. #+BEGIN_QUOTE =electric-indent-mode= is enough to keep your code nicely aligned when all you do is type. However, once you start shifting blocks around, transposing lines, or slurping and barfing sexps, indentation is bound to go wrong. =aggressive-indent-mode= is a minor mode that keeps your code *always* indented. It reindents after every change, making it more reliable than electric-indent-mode. [[https://github.com/Malabarba/aggressive-indent-mode][Artur Malabarba]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package aggressive-indent :defer 2 :hook ((css-mode . aggressive-indent-mode) (emacs-lisp-mode . aggressive-indent-mode) (js-mode . aggressive-indent-mode) (lisp-mode . aggressive-indent-mode)) :custom (aggressive-indent-comments-too)) #+END_SRC *** =ipcalc= Allows to calculate the network ranges. #+BEGIN_SRC emacs-lisp :tangle yes (use-package ipcalc :defer 4) #+END_SRC *** =move-text= Moves the current line (or if marked, the current region's, whole lines). #+BEGIN_SRC emacs-lisp :tangle yes (use-package move-text :defer 2 :bind (("M-p" . move-text-up) ("M-n" . move-text-down)) :config (move-text-default-bindings)) #+END_SRC *** =paradox= Improved GNU Emacs standard package menu. #+BEGIN_QUOTE Project for modernizing Emacs' Package Menu. With improved appearance, mode-line information. Github integration, customizability, asynchronous upgrading, and more. [[https://github.com/Malabarba/paradox][Artur Malabarba]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package paradox :defer 2 :custom (paradox-column-width-package 27) (paradox-column-width-version 13) (paradox-execute-asynchronously t) (paradox-hide-wiki-packages t) :config (paradox-enable) (remove-hook 'paradox-after-execute-functions #'paradox--report-buffer-print)) #+END_SRC *** =rainbow-mode= Colorize colors as text with their value. #+BEGIN_SRC emacs-lisp :tangle yes (use-package rainbow-mode :defer 2 :hook (prog-mode)) #+END_SRC **** Replace the current file with the saved one Avoids call the function or reload Emacs. #+BEGIN_SRC emacs-lisp :tangle yes (use-package autorevert :ensure nil :diminish auto-revert-mode :bind ("C-x R" . revert-buffer) :custom (auto-revert-verbose nil) :config (global-auto-revert-mode 1)) #+END_SRC *** =try= Useful to temporary use a package. #+BEGIN_SRC emacs-lisp :tangle yes (use-package try :defer 5) #+END_SRC *** =undo-tree= GNU Emacs's undo system allows you to recover any past state of a buffer. To do this, Emacs treats "undo itself as another editing that can be undone". #+BEGIN_SRC emacs-lisp :tangle yes (use-package undo-tree :diminish :bind ("C--" . undo-tree-redo) :init (global-undo-tree-mode) :custom (undo-tree-visualizer-timestamps t) (undo-tree-visualizer-diff t)) #+END_SRC *** =web-mode= An autonomous emacs major-mode for editing web templates. #+BEGIN_SRC emacs-lisp :tangle yes (use-package web-mode :delight web-mode "☸" :hook (((css-mode web-mode) . rainbow-mode) (web-mode . prettier-js-mode)) :mode (("\\.blade\\.php\\'" . web-mode) ("\\.html?\\'" . web-mode) ("\\.jsx\\'" . web-mode) ("\\.php$" . my/php-setup) ("\\.tsx\\'" . web-mode)) :init (add-hook 'web-mode-hook (lambda () (when (string-equal "tsx" (file-name-extension buffer-file-name)) (setup-tide-mode)))) :custom (web-mode-attr-indent-offset 2) (web-mode-block-padding 2) (web-mode-css-indent-offset 2) (web-mode-code-indent-offset 2) (web-mode-comment-style 2) (web-mode-enable-current-element-highlight t) (web-mode-markup-indent-offset 2)) #+END_SRC *** =which-key= It's difficult to remember all the keyboard shortcuts. The =which-key= package helps to solve this. I used =guide-key= in my past days, but =which-key= is a good replacement. #+BEGIN_SRC emacs-lisp :tangle yes (use-package which-key :diminish :config (which-key-mode)) #+END_SRC *** =wiki-summary= It is impossible to know everything, which is why a quick description of a term, without breaking its workflow, is ideal. #+BEGIN_SRC emacs-lisp :tangle yes (use-package wiki-summary :defer 1 :bind ("C-c W" . wiki-summary)) #+END_SRC ** IRC IRC is the best way for me to get a quick answer to a simple question and to learn from more competent people than me on a subject. I'd rather use =erc= than =rcirc= because I find =rcirc= very minimal. Besides, for people like me, who want to store your password in a /GPG/ file, you just need to specify a file priority list with =auth-sources=, to tell =erc= where to start looking for your password first. Of course, don't forget to add this line in your =.authinfo.gpg= file, where // and // match your real information: #+BEGIN_EXAMPLE machine irc.freenode.net login password #+END_EXAMPLE Then encrypt that file with =gpg -c .authinfo= and don't forget to delete the =.authinfo= file. Finally, specify to =erc= that you use a =.authinfo= file with: =(setq erc-prompt-for-nickserv-password nil)=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package erc :defer 3 :delight erc-mode "ε" :preface (defun my/erc-start-or-switch () "Connects to ERC, or switch to last active buffer." (interactive) (if (get-buffer "irc.freenode.net:6667") (erc-track-switch-buffer 1) (erc :server "irc.freenode.net" :port 6667 :nick "rememberYou"))) (defun my/erc-count-users () "Displays the number of users connected on the current channel." (interactive) (if (get-buffer "irc.freenode.net:6667") (let ((channel (erc-default-target))) (if (and channel (erc-channel-p channel)) (message "%d users are online on %s" (hash-table-count erc-channel-users) channel) (user-error "The current buffer is not a channel"))) (user-error "You must first start ERC"))) (defun my/erc-notify (nickname message) "Displays a notification message for ERC." (let* ((channel (buffer-name)) (nick (erc-hl-nicks-trim-irc-nick nickname)) (title (if (string-match-p (concat "^" nickname) channel) nick (concat nick " (" channel ")"))) (msg (s-trim (s-collapse-whitespace message)))) (alert (concat nick ": " msg) :title title))) (defun my/erc-preprocess (string) "Avoids channel flooding." (setq str (string-trim (replace-regexp-in-string "\n+" " " str)))) :hook ((ercn-notify . my/erc-notify) (erc-send-pre . my/erc-preprocess)) :custom-face (erc-action-face ((t (:foreground "#8fbcbb")))) (erc-error-face ((t (:foreground "#bf616a")))) (erc-input-face ((t (:foreground "#ebcb8b")))) (erc-notice-face ((t (:foreground "#ebcb8b")))) (erc-timestamp-face ((t (:foreground "#a3be8c")))) :custom (erc-autojoin-channels-alist '(("freenode.net" "#archlinux" "#bash" "#emacs" "#gentoo" "#i3" "#latex" "#lineageos" "#org-mode" "#python" "#sway"))) (erc-autojoin-timing 'ident) (erc-fill-function 'erc-fill-static) (erc-fill-static-center 22) (erc-header-line-format "%n on %t (%m)") (erc-hide-list '("JOIN" "PART" "QUIT")) (erc-kill-buffer-on-part t) (erc-kill-queries-on-quit t) (erc-kill-server-buffer-on-quit t) (erc-lurker-hide-list '("JOIN" "PART" "QUIT")) (erc-lurker-threshold-time 43200) (erc-prompt-for-nickserv-password nil) (erc-server-reconnect-attempts 5) (erc-server-reconnect-timeout 3) (erc-track-exclude-types '("JOIN" "MODE" "NICK" "PART" "QUIT" "324" "329" "332" "333" "353" "477")) :config (add-to-list 'erc-modules 'notifications) (add-to-list 'erc-modules 'spelling) (erc-services-mode 1) (erc-update-modules)) (use-package erc-hl-nicks :after erc) (use-package erc-image :after erc) #+END_SRC ** Ivy I used =helm= before, but I find =ivy= faster and lighter. #+BEGIN_QUOTE Ivy is a generic completion mechanism for Emacs. While it operates similarly to other completion schemes such as icomplete-mode, Ivy aims to be more efficient, smaller, simpler, and smoother to use yet highly customizable. [[https://github.com/abo-abo/ivy][Oleh Krehel]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package counsel :after ivy :diminish :config (counsel-mode)) (use-package ivy :defer 0.1 :diminish :bind (("C-c C-r" . ivy-resume) ("C-x B" . ivy-switch-buffer-other-window)) :custom (ivy-count-format "(%d/%d) ") (ivy-display-style 'fancy) (ivy-use-virtual-buffers t) :config (ivy-mode)) (use-package ivy-pass :after ivy :commands ivy-pass) (use-package ivy-rich :after ivy :custom (ivy-virtual-abbreviate 'full ivy-rich-switch-buffer-align-virtual-buffer t ivy-rich-path-style 'abbrev) :config (ivy-set-display-transformer 'ivy-switch-buffer 'ivy-rich-switch-buffer-transformer)) (use-package swiper :after ivy :bind (("C-s" . swiper) ("C-r" . swiper))) #+END_SRC ** Ledger #+BEGIN_QUOTE Ledger is a powerful, double-entry accounting system that is accessed from the UNIX command-line. [[https://github.com/ledger/ledger][John Wiegley]] #+END_QUOTE Before you can use this configuration, make sure you install =ledger= on your operating system. Now all we have to do is configure =ledger-mode=: #+BEGIN_SRC emacs-lisp :tangle yes (use-package ledger-mode :ensure-system-package (ledger . "trizen -S --noconfirm ledger") :mode ("\\.dat\\'" "\\.ledger\\'") :bind (:map ledger-mode-map ("C-x C-s" . my/ledger-save)) :preface (defun my/ledger-save () "Automatically clean the ledger buffer at each save." (interactive) (save-excursion (when (buffer-modified-p) (with-demoted-errors (ledger-mode-clean-buffer)) (save-buffer)))) :custom (ledger-clear-whole-transactions t) (ledger-reconcile-default-commodity "EUR") (ledger-reports '(("account statement" "%(binary) reg --real [[ledger-mode-flags]] -f %(ledger-file) ^%(account)") ("balance sheet" "%(binary) --real [[ledger-mode-flags]] -f %(ledger-file) bal ^assets ^liabilities ^equity") ("budget" "%(binary) --empty -S -T [[ledger-mode-flags]] -f %(ledger-file) bal ^assets:bank ^assets:receivables ^assets:cash ^assets:budget") ("budget goals" "%(binary) --empty -S -T [[ledger-mode-flags]] -f %(ledger-file) bal ^assets:bank ^assets:receivables ^assets:cash ^assets:'budget goals'") ("budget obligations" "%(binary) --empty -S -T [[ledger-mode-flags]] -f %(ledger-file) bal ^assets:bank ^assets:receivables ^assets:cash ^assets:'budget obligations'") ("budget debts" "%(binary) --empty -S -T [[ledger-mode-flags]] -f %(ledger-file) bal ^assets:bank ^assets:receivables ^assets:cash ^assets:'budget debts'") ("cleared" "%(binary) cleared [[ledger-mode-flags]] -f %(ledger-file)") ("equity" "%(binary) --real [[ledger-mode-flags]] -f %(ledger-file) equity") ("income statement" "%(binary) --invert --real -S -T [[ledger-mode-flags]] -f %(ledger-file) bal ^income ^expenses -p \"this month\"")) (ledger-report-use-header-line nil))) (use-package flycheck-ledger :after ledger-mode) #+END_SRC *NOTE:* by default, =ledger= uses the [[ https://xkcd.com/1179/][ISO 8601]] format to write dates, which is the recommended format. ** Linters Flycheck lints warnings and errors directly within buffers. #+BEGIN_SRC emacs-lisp :tangle yes (use-package flycheck :defer 2 :diminish :init (global-flycheck-mode) :custom (flycheck-display-errors-delay .3) (flycheck-python-pylint-executable "/usr/bin/pylint") (flycheck-pylintrc "/home/someone/.pylintrc") (flycheck-stylelintrc "~/.stylelintrc.json") :config (flycheck-add-mode 'javascript-eslint 'web-mode) (flycheck-add-mode 'typescript-tslint 'web-mode)) #+END_SRC ** Lorem Ipsum I could use =try= when I need to use =lipsum=, but since I use =defer=, the packet load attribute has no impact on =emacs-init-time=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package lorem-ipsum :defer 5 :bind (("C-c C-v l" . lorem-ipsum-insert-list) ("C-c C-v p" . lorem-ipsum-insert-paragraphs) ("C-c C-v s" . lorem-ipsum-insert-sentences))) #+END_SRC ** Mail After trying =gnus= that I found too old and =notmuch= that in my opinion lacks features like the ability to delete some emails and be able to write emails easily with =org=, I finally found my happiness with =mu4e=. I use =mbsync= to be capable of synchronizing mail on IMAP server with local Maildir folder. I'm used to using =offlineimap=, but I find it slower than =mbsync=, that's why I separated myself from it. *NOTE:* to use =mbsync= with your Gmail account, you will need to enable access for less secure apps in your Google account. *** mu4e Before you can use this configuration, make sure you install =mu= on your operating system and create directories corresponding to those in your mailbox. Now all that remains is to configure =mu4e=: #+BEGIN_SRC emacs-lisp :tangle yes (use-package mu4e :ensure nil :ensure-system-package mu :custom (mu4e-attachment-dir "~/Downloads") (mu4e-confirm-quit nil) (mu4e-compose-signature-auto-include nil) (mu4e-completing-read-function 'ivy-completing-read) (mu4e-drafts-folder "/gmail/Drafts") (mu4e-get-mail-command "mbsync -a") (mu4e-maildir "~/Maildir") (mu4e-maildir-shortcuts '(("/gmail/INBOX" . ?i) ("/gmail/All Mail" . ?a) ("/gmail/Deleted Items" . ?d) ("/gmail/Drafts" . ?D) ("/gmail/Important" . ?i) ("/gmail/Sent Mail" . ?s) ("/gmail/Starred" . ?S))) (mu4e-html2text-command "iconv -c -t utf-8 | pandoc -f html -t plain") (mu4e-org-contacts-file "~/.personal/agenda/contacts.org") (mu4e-refile-folder "/gmail/Archive") (mu4e-sent-folder "/gmail/Sent Mail") (mu4e-sent-messages-behavior 'delete) (mu4e-trash-folder "/gmail/Trash") (mu4e-update-interval 60) (mu4e-use-fancy-chars t) (mail-user-agent 'mu4e-user-agent) (mu4e-view-show-addresses t) (mu4e-view-show-images t) :config (add-to-list 'mu4e-headers-actions '("org-contact-add" . mu4e-action-add-org-contact) t) (add-to-list 'mu4e-view-actions '("org-contact-add" . mu4e-action-add-org-contact) t)) (use-package org-mu4e :ensure nil :custom (org-mu4e-convert-to-html t)) #+END_SRC Being able to read mails is a good thing, but being notified when we receive mails is better! The following few lines allow you to receive desktop notifications and modeline display for =mu4e=: #+BEGIN_SRC emacs-lisp :tangle yes (use-package mu4e-alert :after mu4e :hook ((after-init . mu4e-alert-enable-mode-line-display) (after-init . mu4e-alert-enable-notifications)) :config (mu4e-alert-set-default-style 'libnotify)) #+END_SRC *** Sending Mail For you can send mails, create the =.authinfo= file if it is not already done. Then add the following two lines replacing /terencio.agozzino/ (which corresponds to my gmail address terencio.agozzino@gmail.com without the domain name) and // by those that match your real information: #+BEGIN_EXAMPLE machine imap.gmail.com login terencio.agozzino password port 993 machine smtp.gmail.com login terencio.agozzino password port 465 #+END_EXAMPLE Similar to IRC, if you want to store your password in a /GPG/ file, you just need to specify a file priority list with =auth-sources=, to tell GNU Emacs where to start looking for your password first. Then encrypt that file with =gpg -c .authinfo= and don't forget to delete the =.authinfo= file. #+BEGIN_SRC emacs-lisp :tangle yes (use-package message :ensure nil :custom (send-mail-function 'smtpmail-send-it)) (use-package smtpmail :ensure nil :custom (smtpmail-smtp-server "smtp.gmail.com") (smtpmail-smtp-service 465) (smtpmail-stream-type 'ssl)) #+END_SRC All you need now is to test sending your mails with =C-x m= or directly from =mu4e=! ** Navigation This function is a mix of =C-a= and =M-m=. From: http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/ #+BEGIN_SRC emacs-lisp :tangle yes (defun my/smarter-move-beginning-of-line (arg) "Moves 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)))) (global-set-key [remap org-beginning-of-line] #'my/smarter-move-beginning-of-line) (global-set-key [remap move-beginning-of-line] #'my/smarter-move-beginning-of-line) #+END_SRC ** Parenthesis *** =rainbow-delimiters= #+BEGIN_QUOTE rainbow-delimiters is a "rainbow parentheses"-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth. Each successive level is highlighted in a different color. This makes it easy to spot matching delimiters, orient yourself in the code, and tell which statements are at a given depth. [[https://github.com/Fanael/rainbow-delimiters][Fanael Linithien]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package rainbow-delimiters :defer 1 :hook (prog-mode . rainbow-delimiters-mode)) #+END_SRC *** =smartparens= In my opinion, it is the most powerful package to deal with the parenthesis. Anyway, if you don't like it, you can try taking a look at =paredit= or =autopair=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package smartparens :defer 1 :diminish :config (smartparens-global-mode 1)) #+END_SRC ** Paste #+BEGIN_QUOTE This mode allows to paste whole buffers or parts of buffers to pastebin-like services. It supports more than one service and will failover if one service fails. [[https://github.com/etu/webpaste.el][Elis Hirwing]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package webpaste :defer 3 :bind (("C-c C-p C-b" . webpaste-paste-buffer) ("C-c C-p C-r" . webpaste-paste-region))) #+END_SRC Same principle for images with =imgbb=. This package selects an image and upload it to [[https://imgbb.com/][imgbb]], making sure to display the URL of the image in the minibuffer and place it in the kill ring. #+BEGIN_SRC emacs-lisp :tangle yes (use-package imgbb :defer 2) #+END_SRC ** PDF #+BEGIN_QUOTE 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. [[https://github.com/politza/pdf-tools][Andras Politz]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package pdf-tools :defer 1 :init (pdf-tools-install :no-query)) (use-package pdf-view :ensure nil :after pdf-tools :bind (:map pdf-view-mode-map ("C-s" . isearch-forward)) :custom (pdf-view-use-unicode-ligther nil)) #+END_SRC ** Point and Region Increase region by semantic units. It tries to be smart about it and adapt to the structure of the current major mode. #+BEGIN_SRC emacs-lisp :tangle yes (use-package expand-region :defer 2 :bind (("C-+" . er/contract-region) ("C-=" . er/expand-region))) #+END_SRC I find useful to delete a line and a region with only =C-w=. #+BEGIN_SRC emacs-lisp :tangle yes (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))))) #+END_SRC ** Projectile #+BEGIN_QUOTE Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies (when feasible). For instance - finding project files has a portable implementation written in pure Emacs Lisp without the use of GNU find (but for performance sake an indexing mechanism backed by external commands exists as well). [[https://github.com/bbatsov/projectile][Bozhidar Batsov]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package projectile :defer 1 :custom (projectile-cache-file (expand-file-name ".projectile-cache" user-emacs-directory)) (projectile-completion-system 'ivy) (projectile-enable-caching t) (projectile-known-projects-file (expand-file-name ".projectile-bookmarks" user-emacs-directory)) (projectile-mode-line '(:eval (projectile-project-name))) :config (projectile-global-mode)) #+END_SRC ** Recent Files Provides fast access to the recent files. #+BEGIN_SRC emacs-lisp :tangle yes (use-package recentf :defer 2 :bind ("C-c r" . recentf-open-files) :init (recentf-mode) :custom (recentf-max-menu-items 15) (recentf-max-saved-items 200) :config (run-at-time nil (* 5 60) 'recentf-save-list)) #+END_SRC ** Reveal.js I tend to use Beamer for scientific presentations, and Reveal.js for others. #+BEGIN_SRC emacs-lisp :tangle yes (use-package ox-reveal :defer 3 :after org :custom (org-reveal-root "http://cdn.jsdelivr.net/reveal.js/3.0.0/") (org-reveal-mathjax t)) #+END_SRC ** Version Control It is quite common to work on Git repositories, so it is important to have a configuration that we like. #+BEGIN_QUOTE [[https://github.com/magit/magit][Magit]] is an interface to the version control system Git, implemented as an Emacs package. Magit aspires to be a complete Git porcelain. While we cannot (yet) claim that Magit wraps and improves upon each and every Git command, it is complete enough to allow even experienced Git users to perform almost all of their daily version control tasks directly from within Emacs. While many fine Git clients exist, only Magit and Git itself deserve to be called porcelains. [[https://github.com/tarsius][Jonas Bernoulli]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package git-commit :after magit :hook (git-commit-mode . my/git-commit-auto-fill-everywhere) :custom (git-commit-summary-max-length 50) :preface (defun my/git-commit-auto-fill-everywhere () (setq fill-column 72) (setq-local comment-auto-fill-only-comments nil))) (use-package magit :defer 2) #+END_SRC In addition to that, I like to see the lines that are being modified in the file while it is being edited. #+BEGIN_SRC emacs-lisp :tangle yes (use-package git-gutter :defer 2 :diminish :init (global-git-gutter-mode +1)) #+END_SRC Finally, one last package that I like to use with Git to easily see the changes made by previous commits. #+BEGIN_SRC emacs-lisp :tangle yes (use-package git-timemachine :defer 3 :diminish) #+END_SRC ** Whitespaces It is often annoying to see unnecessary blank spaces at the end of a line or file. #+BEGIN_SRC emacs-lisp :tangle yes (add-hook 'before-save-hook 'delete-trailing-whitespace) #+END_SRC *** =hungry-delete= #+BEGIN_QUOTE Deleting a whitespace character will delete all whitespace until the next non-whitespace character. [[https://github.com/nflath/hungry-delete][Nathaniel Flath]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package hungry-delete :defer 2 :diminish :config (global-hungry-delete-mode)) #+END_SRC ** Windows Don't ask before killing a buffer. I know what I'm doing. #+BEGIN_SRC emacs-lisp :tangle yes (global-set-key [remap kill-buffer] #'kill-this-buffer) #+END_SRC *** =switch-window= Displays an overlay in each window showing a unique key, then asks the user where to move in the window. Most people use =ace-window=, but I prefer =switch-window= because I find this package more ergonomic by using the fact of displaying the buffer number by hiding its contents. #+BEGIN_SRC emacs-lisp :tangle yes (use-package switch-window :defer 1 :bind (("C-x o" . switch-window) ("C-x w" . switch-window-then-swap-buffer))) #+END_SRC *** =windmove= Allows you to move from one window to another with something more natural than cycling through =C-x o= (=other-window=). #+BEGIN_SRC emacs-lisp :tangle yes (use-package windmove :defer 1 :bind (("C-c h" . windmove-left) ("C-c j" . windmove-down) ("C-c k" . windmove-up) ("C-c l" . windmove-right))) #+END_SRC *** =winner= I often undo's and redo's with window configurations. #+BEGIN_QUOTE Winner mode is a global minor mode that records the changes in the window configuration (i.e. how the frames are partitioned into windows) so that the changes can be "undone" using the command =winner-undo=. By default this one is bound to the key sequence ctrl-c left. If you change your mind (while undoing), you can press ctrl-c right (calling =winner-redo=). [[https://github.com/emacs-mirror/emacs/blob/master/lisp/winner.el][Ivar Rummelhoff]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package winner :defer 2 :config (winner-mode 1)) #+END_SRC ** Word Wrap I like to have lines of the same length. #+BEGIN_SRC emacs-lisp :tangle yes (use-package simple :ensure nil :diminish (auto-fill-function) :bind ("C-x p" . pop-to-mark-command) :hook ((prog-mode . turn-on-auto-fill) (text-mode . turn-on-auto-fill)) :custom (set-mark-command-repeat-pop t)) #+END_SRC ** YASnippet #+BEGIN_QUOTE YASnippet is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates. [[https://github.com/joaotavora/yasnippet][João Távora]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package yasnippet :defer 1 :diminish yas-minor-mode :config (yas-global-mode)) (use-package yasnippet-snippets :after yasnippet :config (yasnippet-snippets-initialize)) (use-package ivy-yasnippet :after yasnippet) (use-package react-snippets :after yasnippet) #+END_SRC * Org-Mode One of my favorite modes in GNU Emacs. I mainly use it to organize my life, take notes and make my presentations, but you can do lots of things with it. =org-mode= it's like the sky, without limits. #+BEGIN_QUOTE Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system. [[http://orgmode.org/][Carsten Dominik]] #+END_QUOTE #+BEGIN_SRC emacs-lisp :tangle yes (use-package org :ensure org-plus-contrib :delight org-mode "Ø" :preface (defun my/org-compare-times (clocked estimated) "Gets the ratio between the timed time and the estimated time." (if (and (> (length clocked) 0) estimated) (format "%.2f" (/ (* 1.0 (org-hh:mm-string-to-minutes clocked)) (org-hh:mm-string-to-minutes estimated))) "")) (defun my/org-archive-done-tasks () "Archives 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))) (defun my/org-jump () "Jumps to a specific task." (interactive) (let ((current-prefix-arg '(4))) (call-interactively 'org-refile))) (defun my/org-use-speed-commands-for-headings-and-lists () "Activates 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]*"))))) :hook (after-save . my/config-tangle) :custom (org-blank-before-new-entry nil) (org-cycle-include-plain-lists 'integrate) (org-ditaa-jar-path "~/lib/ditaa0_9.jar") (org-expiry-inactive-timestamps t) (org-export-backends '(ascii beamer html icalendar latex man md org texinfo)) (org-log-done 'time) (org-log-into-drawer "LOGBOOK") (org-modules '(org-crypt org-habit org-info org-irc org-mouse org-protocol)) (org-refile-allow-creating-parent-nodes 'confirm) (org-refile-use-cache nil) (org-refile-use-outline-path nil) (org-refile-targets '((org-agenda-files . (:maxlevel . 6)))) (org-startup-folded nil) (org-startup-indented t) (org-tag-alist '(("@coding" . ?c) ("@computer" . ?l) ("@errands" . ?e) ("@home" . ?h) ("@phone" . ?p) ("@reading" . ?r) ("@school" . ?s) ("@work" . ?b) ("@writing" . ?w) ("crypt" . ?C) ("fuzzy" . ?0) ("highenergy" . ?1))) (org-tags-exclude-from-inheritance '("crypt" "project")) (org-todo-keywords '((sequence "TODO(t)" "STARTED(s)" "WAITING(w@/!)" "SOMEDAY(.)" "|" "DONE(x!)" "CANCELLED(c@)") (sequence "TOBUY" "TOSHRINK" "TOCUT" "TOSEW" "|" "DONE(x)"))) (org-use-effective-time t) (org-use-speed-commands 'my/org-use-speed-commands-for-headings-and-lists) (org-yank-adjusted-subtrees t) :config (add-to-list 'org-global-properties '("Effort_ALL". "0:05 0:15 0:30 1:00 2:00 3:00 4:00")) (add-to-list 'org-speed-commands-user '("!" my/org-clock-in-and-track)) (add-to-list 'org-speed-commands-user '("$" call-interactively 'org-archive-subtree)) (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 '("o" call-interactively 'org-clock-out)) (add-to-list 'org-speed-commands-user '("s" call-interactively 'org-schedule)) (add-to-list 'org-speed-commands-user '("x" org-todo "DONE")) (add-to-list 'org-speed-commands-user '("y" org-todo-yesterday "DONE")) (org-clock-persistence-insinuate) (org-load-modules-maybe t)) #+END_SRC If like me, you're tired of manually updating your tables of contents, =toc-org= will maintain a table of contents at the first heading that has a =:TOC:= tag. #+BEGIN_SRC emacs-lisp :tangle yes (use-package toc-org :after org :hook (org-mode . toc-org-enable)) #+END_SRC For a cleaner online mode. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-indent :after org :ensure nil :diminish) #+END_SRC ** Agenda Nowadays, it is crucial to be organized. Even more than before. That is why it is important to take the time to make a configuration that is simple to use and that makes your life easier with an irreproachable organization. =org-agenda= allows me to be organized with daily tasks. As a result, I can use my time to the fullest. I put my =org= files in [[https://github.com/syncthing/syncthing][Syncthing]] in order to be able to check my agenda and update it from several computers and smartphones. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-agenda :ensure nil :after org :bind (:map org-agenda-mode-map ("X" . my/org-agenda-mark-done-and-add-followup) ("x" . my/org-agenda-done)) :preface (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")) (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")) :custom (org-agenda-dim-blocked-tasks t) (org-agenda-files '("~/.personal/agenda")) (org-agenda-inhibit-startup t) (org-agenda-show-log t) (org-agenda-skip-deadline-if-done t) (org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled) (org-agenda-skip-scheduled-if-done t) (org-agenda-span 2) (org-agenda-start-on-weekday 6) (org-agenda-sticky nil) (org-agenda-tags-column -100) (org-agenda-time-grid '((daily today require-timed))) (org-agenda-use-tag-inheritance t) (org-columns-default-format "%14SCHEDULED %Effort{:} %1PRIORITY %TODO %50ITEM %TAGS") (org-default-notes-file "~/.personal/agenda/organizer.org") (org-directory "~/.personal") (org-enforce-todo-dependencies t) (org-habit-graph-column 80) (org-habit-show-habits-only-for-today nil) (org-track-ordered-property-with-tag t)) #+END_SRC ** Capture =org-capture= templates saves you a lot of time when adding new entries. I use it to quickly record tasks, ledger entries, notes and other semi-structured information. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-capture :ensure nil :after org :preface (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" "Template for basic task.") (defvar my/org-contacts-template "* %(org-contacts-template-name) :PROPERTIES: :ADDRESS: %^{289 Cleveland St. Brooklyn, 11206 NY, USA} :BIRTHDAY: %^{yyyy-mm-dd} :EMAIL: %(org-contacts-template-email) :NOTE: %^{NOTE} :END:" "Template for org-contacts.") (defvar my/org-ledger-card-template "%(org-read-date) %^{Payee} Expenses:%^{Account} €%^{Amount} Liabilities:CreditsCards:Belfius" "Template for credit card transaction with ledger.") (defvar my/org-ledger-cash-template "%(org-read-date) * %^{Payee} Expenses:%^{Account} €%^{Amount} Assets:Cash:Wallet" "Template for cash transaction with ledger.") :custom (org-capture-templates `(("B" "Book" checkitem (file+headline "~/.personal/other/books.org" "Books") "- [ ] %^{Book}" :immediate-finish t) ("L" "Learning" checkitem (file+headline "~/.personal/other/learning.org" "Things") "- [ ] %^{Thing}" :immediate-finish t) ("M" "Movie" checkitem (file+headline "~/.personal/other/movies.org" "Movies") "- [ ] %^{Movie}" :immediate-finish t) ("P" "Purchase" checkitem (file+headline "~/.personal/other/purchases.org" "Purchases") "- [ ] %^{Item}" :immediate-finish t) ("c" "Contact" entry (file+headline "~/.personal/agenda/contacts.org" "Friends"), my/org-contacts-template :empty-lines 1) ("l" "Ledger") ("lb" "Bank" plain (file ,(format "~/.personal/ledger/ledger-%s.dat" (format-time-string "%Y"))), my/org-ledger-card-template :empty-lines 1 :immediate-finish t) ("lc" "Cash" plain (file ,(format "~/.personal/ledger/ledger-%s.dat" (format-time-string "%Y"))), my/org-ledger-cash-template :empty-lines 1 :immediate-finish t) ("p" "People" entry (file+headline "~/.personal/agenda/people.org" "Tasks"), my/org-basic-task-template :empty-lines 1) ("s" "School" entry (file+headline "~/.personal/agenda/school.org" "Tasks"), my/org-basic-task-template :empty-lines 1) ("t" "Task" entry (file+headline "~/.personal/agenda/organizer.org" "Tasks"), my/org-basic-task-template :empty-lines 1)))) #+END_SRC ** Clock Being organized is one thing, but being optimal is another. =org-clock= allows you to estimate your tasks and time them. This is useful, since with experience, you can have a better estimate of the time that needs to be given to each task. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-clock :ensure nil :after org :preface (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))))) :hook (org-clock-in-prepare-hook . my/org-mode-ask-effort) :custom (org-clock-continuously nil) (org-clock-in-switch-to-state "STARTED") (org-clock-out-remove-zero-time-clocks t) (org-clock-persist t) (org-clock-persist-query-resume nil) (org-clock-report-include-clocking-task t) (org-show-notification-handler (lambda (msg) (alert msg)))) #+END_SRC ** Contacts The best solution to maintain your contacts. I tend to use =org-contacts= to remember their birthdays so I can be the first to wish them that. Be careful that to install it, this one is available with =org-plus-contrib=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-contacts :ensure nil :after org :custom (org-contacts-files '("~/.personal/agenda/contacts.org"))) #+END_SRC ** Custormization Let's change the foreground and the weight of each keywords. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-faces :ensure nil :after org :custom (org-todo-keyword-faces '(("DONE" . (:foreground "cyan" :weight bold)) ("SOMEDAY" . (:foreground "gray" :weight bold)) ("TODO" . (:foreground "green" :weight bold)) ("WAITING" . (:foreground "red" :weight bold))))) #+END_SRC ** Encryption / Decryption To be able to enable encryption and decryption of =.gpg= files with =org-mode=, we will need to install =gnupg2=. Once this is done, we simply configure =org-crypt= to accept our public key identifier to allow asymmetric encryption. *NOTE:* you need to modify the =org-crypt-key= variable to replace my key identifier, by yours (or =nil= to allow symmetric encryption). #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-crypt :ensure nil :after org :init (org-crypt-use-before-save-magic) :custom (org-crypt-key "E9AADC36E94A672D1A07D49B208FCDBB98190562")) #+END_SRC ** Journal Recently, I started writing a journal about my daily life as I read that journals improve mental claritym, help solve problems, improve overall focus, insight and understanding, track the overall development and facilitate personal growth. #+BEGIN_SRC emacs-lisp :tangle yes (use-package org-journal :after org :bind (("C-c t" . org-journal-new-entry) ("C-c Y" . journal-file-yesterday)) :preface (defun get-journal-file-yesterday () "Gets filename for yesterday's journal entry." (let* ((yesterday (time-subtract (current-time) (days-to-time 1))) (daily-name (format-time-string "%Y%m%d" yesterday))) (expand-file-name (concat org-journal-dir daily-name)))) (defun journal-file-yesterday () "Creates and load a file based on yesterday's date." (interactive) (find-file (get-journal-file-yesterday))) :custom (org-journal-date-format "%e %b %Y (%A)") (org-journal-dir "~/.personal/journal/2018/") (org-journal-enable-encryption t) (org-journal-file-format "%Y%m%d") (org-journal-time-format "")) #+END_SRC ** Languages With that, I can compile many languages with =org-mode=. #+BEGIN_SRC emacs-lisp :tangle yes (use-package ob-C :ensure nil :after org) (use-package ob-css :ensure nil :after org) (use-package ob-ditaa :ensure nil :after org) (use-package ob-dot :ensure nil :after org) (use-package ob-emacs-lisp :ensure nil :after org) (use-package ob-gnuplot :ensure nil :after org) (use-package ob-java :ensure nil :after org) (use-package ob-js :ensure nil :after org) (use-package ob-latex :ensure nil :after org) (use-package ob-ledger :ensure nil :after org) (use-package ob-makefile :ensure nil :after org) (use-package ob-org :ensure nil :after org) (use-package ob-plantuml :ensure nil :after org :custom (org-plantuml-jar-path (expand-file-name "~/lib/plantuml.jar"))) (use-package ob-python :ensure nil :after org) (use-package ob-ruby :ensure nil :after org) (use-package ob-shell :ensure nil :after org) (use-package ob-sql :ensure nil :after org) #+END_SRC