I use Emacs for almost everything: coding, writing, taking notes, managing tasks, using version control, preparing presentations. I’m using it right now! Well I mean, I’m writing this in Emacs. There is also a good chance I’m using it now now. The two main reasons why I like it and would recommend it:
If I couldn’t use Emacs, I would definitely learn vim for these same reasons.
Some of the basic tweaks in my .emacs
file:
;; Disable startup screen
(setq inhibit-splash-screen t)
;; Turn the blinking off
(blink-cursor-mode 0)
;; Turn off the tool bar
(tool-bar-mode 0)
;; Change the font
;; (set-default-font "DejaVu Sans Mono 12") ;; (deprecated?)
(set-frame-font "DejaVu Sans Mono 12" nil t)
;; Show column number
(setq column-number-mode t)
;; turn off alarm bell
(setq ring-bell-function 'ignore)
Some miscellaneous commands that could be useful:
M-=
. There are other ways for LaTeX.M-p
/M-n
. (Useful when ssh-tunneling with broken key-bindings).M-x lgrep
command.C-M-x
.C-h b
.C-h a
.C-c
: C-c C-h
.C-x n n
(e.g. when refactoring).
C-x n w
.C-x 8
(C-x 8 C-h
for list).C-x TAB
or C-4 C-x TAB
to add a specific number of spaces (here 4).C-q <tab>
M-g g
M-x toggle-truncate-lines
M-x visual-line-mode
Regexp replace :
C-M-%
.\(
and \)
to define groups.\1
to refer to the first group.Windows:
C-x 1
remove other windows.C-x 2
split window horizontally.C-x 3
split window vertically.C-x +
balance windows.The kill ring is the equivalent of the clipboard, used to copy(kill) and paste(yank) stuff. Of note, deleting stuff also adds it to the kill ring.
M-w
.C-w
.C-y
.M-2 C-y
.C-y
), cycle through earlier kills with M-y
(useful if you don’t remember when you copied something).Call the quick interface of the calculator with C-x * q
(or M-x quick-calc
).
The result of the calculation will be shown and saved in the clipboard.
You can also evaluate a calculation in a buffer (make sure it’s flanked but empty lines) with C-x * e
, then q
to quit the calc mode.
For the standard interface, type C-x * c
(or M-x calc
).
By default it works in stack mode:
<ENTER>
adds a number to the stack.+
, -
, *
, /
, ^
performs an basic operations between the last 2 numbers.<TAB>
swaps the last 2 numbers.<BACKSPC>
removes last number in stack.M-0 <BACKSPC>
removes all numbers in stack.To use the more conventional algebraic mode, start with an apostrophe '
.
There’s a lot more to it (see manual).
For example it can convert different units with u c
, e.g. :
' 10 mi/h
, then u c m/s
' 1.80 m
, then u c mfi
' 23425 s
, then u c hms
Display the list of units with u v
.
I put this function and key binding in my .emacs
:
(defun consoleSplit ()
(interactive)
(save-excursion
(split-window-below)
(enlarge-window 15)))
(global-set-key (kbd "C-x 9") 'consoleSplit)
It splits the buffer in two and reduce the bottom buffer by 15 lines resulting in a large and a small buffer for example for a script and the console.
Usually packages are just .el
files to download and add in the folder defined in .emacs
(e.g. (add-to-list 'load-path "~/.emacs.d/lisp/")
).
However, there is easier way: MELPA package manager!
To install it, add to .emacs
:
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
Then to find and install a new package, use M-x list-packages
, find the package in the list and click on Install.
I use Solarized theme palette.
I installed the color-theme-sanityinc-solarized pacakge directly from MELPA.
Then I added the dark version as default with (load-theme 'sanityinc-solarized-dark t)
.
To change it interactively I run M-x load-theme
and then for example sanityinc-solarized-light
.
I also have an alias in my .bashrc
to open emacs directly in light mode:
alias emacsl="emacs --eval \"(load-theme 'sanityinc-solarized-light t)\""
Note: a theme can be “unloaded” using M-x disable-theme
.
I’ve also created some keybindings to switch between light and dark themes:
(defun lighten ()
(interactive)
(load-theme 'sanityinc-solarized-light t))
(global-set-key (kbd "C-c b l") 'lighten)
(defun darken ()
(interactive)
(load-theme 'sanityinc-solarized-dark t))
(global-set-key (kbd "C-c b d") 'darken)
The easiest is to install ESS through MELPA. Otherwise, see below (potentially outdated).
To install ESS, without needing the admin rights, the easiest way is to download and compile it in a dedicated folder (e.g. .emacs.d/lisp/ess
):
git clone https://github.com/emacs-ess/ESS.git .emacs.d/lisp/ess
cd .emacs.d/lisp/ess
make
Then add these lines to ~/.emacs
:
(add-to-list 'load-path "~/.emacs.d/lisp/ess/lisp/")
(load "ess-site")
I also have these ESS config:
(setq ess-default-style 'DEFAULT)
(setq ess-indent-level 2)
(setq ess-ask-for-ess-directory nil)
(setq ess-r-package-auto-set-evaluation-env nil)
The last one took me some times to figure out: when developing a R package, commands were evaluated in another environment so the objects didn’t exist in the usual R buffer (which was driving me crazy).
Recently I had an issue where the startup directory was not the buffer’s directory but the root of the git repo.
The solution was to define a ess-directory-function
like so:
(defun my-ess-directory-function ()
default-directory)
(setq ess-directory-function #'my-ess-directory-function)
To get auto-completion (with objects, functions or parameters) I use auto-complete. It’s also available through MELPA.
Then I configure it in my .emacs
:
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/lisp/ac-dict")
(ac-config-default)
(setq ac-auto-start nil)
(define-key ac-mode-map [C-tab] 'auto-complete)
(define-key ac-completing-map "\t" 'ac-complete)
(define-key ac-completing-map "\r" nil)
(setq ac-quick-help-delay 0.1)
By default, pressing underscore will insert a <-
instead of a _
.
This was supposed to ease the pain of writing assignments with the arrow.
However, now we actually want a _
most of the time (e.g. for ggplot2 functions).
Using smart underscores, <-
will be inserted only when following a space.
It’s available in MELPA.
Otherwise simply put this .el file in the load path and add these lines to ~/.emacs
:
(require 'ess-smart-underscore)
(setq ess-S-underscore-when-last-character-is-a-space t)
With polymode (MELPA), the mode depends on the position of the cursor in the document. For R + Markdown it means that we can edit the Markdown part in markdown-mode and run the R code as if in a R script.
I added this to my .emacs
:
(require 'poly-R)
(require 'poly-markdown)
(add-to-list 'auto-mode-alist '("\\.Rmd\\'" . poly-markdown+r-mode))
Some keybindings I set up but don’t end up using that much…
I tweaked a function to run rmarkdown::render
on the current buffer and bound it to C-c C-e
.
In .emacs
:
(defun renderRmd ()
(interactive)
(save-window-excursion
(message "Rendering %S" (buffer-file-name))
(shell-command (format "Rscript -e 'rmarkdown::render(%S)'" (buffer-file-name)))
(message "Done")))
(add-hook 'markdown-mode-hook
(lambda ()
(local-set-key (kbd "C-c C-e") 'renderRmd)))
(add-hook 'ess-mode-hook
(lambda ()
(local-set-key (kbd "C-c C-e") 'renderRmd)))
The key binding is active in markdown documents or R scripts (and so anywhere in a R-Markdown document).
dev.off()
When working remotely, I send dev.off()
to the R buffer using C-c C-d C-d
to “update” the PDF opened from a mounted server.
In .emacs
:
(defun devoff ()
(interactive)
(save-excursion
(message "Closing device")
(setq ess-command "dev.off()")
(ess-execute ess-command 'buffer nil nil)))
(add-hook 'ess-mode-hook
(lambda ()
(local-set-key (kbd "C-c C-d C-d") 'devoff)))
Note: I use options(device=function() pdf(width=9, height=7))
to specify the dimensions of the default Rplots.pdf created.
When developping a package, use the typical commands:
M-.
jump to a definitionM-,
jump back.Build the TAGS file with M-x ess-build-tags-for-directory
.
To use, activating the mode M-x xref-etags-mode
might be necessary.
I added this to my .emacs
:
(add-hook 'ess-mode-hook (lambda () (xref-etags-mode)))
When writing I prefer when long lines are wrapped without cutting a word: M-x visual-line-mode
I use ispell and flyspell.
To turn on the live spell check automatically for Latex and markdown documents:
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
(add-hook 'markdown-mode-hook 'flyspell-mode)
I use the american dictionary by default:
(setq ispell-dictionary "american")
(setq ispell-local-dictionary "american")
Most useful key binding (more at Emacs Manual):
M-$
to trigger spell checking on a word (for example flagged by flyspell).M-x ispell-buffer
to launch spell checking. See also ispell-region
or ispell-continue
.In the ispell
interface, select a correction (0..9
), skip (SPC
) or update the dictionary (a
ccept/i
nsert).
If using a GUI, flyspell-popup
(available on MELPA) provides a convenient pop-up interface that I bound to C-;
with:
(require 'flyspell)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-popup-correct)
On Ubuntu, more dictionaries are installed using aspell packages, for example the aspell-fr
for the French dictionary.
I tested the synosaurus
package a few times (available in MELPA).
It’s not as user friendly as some online resources but a good offline alternative.
It uses the WordNet database through the wn
command line.
The shortcut to list synonyms is C-c C-s l
.
In my .emacs
I added the synosaurus-mode
minor mode:
(add-hook 'LaTeX-mode-hook 'synosaurus-mode)
(add-hook 'markdown-mode-hook 'synosaurus-mode)
;; disable keybinding conflicting with markdown's
(eval-after-load "synosaurus"
'(define-key synosaurus-mode-map (kbd "C-c C-s i") nil))
(eval-after-load "synosaurus"
'(define-key synosaurus-mode-map (kbd "C-c C-s l") nil))
The langtool
package is available in MELPA.
It uses the LanguageTool JAR to highlight potential grammar problems (downloaded from here).
In my .emacs
:
(require 'langtool)
(setq langtool-language-tool-jar "/usr/local/Cellar/languagetool/3.8/libexec/languagetool-commandline.jar")
(setq langtool-default-language "en-US")
(setq langtool-mother-tongue "fr")
;; (setq langtool-disabled-rules '("WHITESPACE_RULE")) ;; optional
Specific rules can be disabled, see list of rules here. For example, WHITESPACE_RULE for LaTeX.
Then:
M-x langtool-check
to highlight problems.M-x langtool-check-done
to remove highlighting.M-x langtool-switch-default-language
to switch to another language, e.g. fr
I put some Emacs tricks (e.g. for table manipulation) on the LaTeX page.
I general I prefer to use AUCTeX (available through MELPA). It handles multi-file documents and keeps the annoying compilation buffer closed. My configuration is:
(setq TeX-PDF-mode t)
(setq-default TeX-master nil)
(setq LaTeX-verbatim-environments-local '("lstlisting"))
To count the full document, including \include
/\input
documents, I call texcount
with M-x latex-word-count
after adding this to the .emacs
configuration:
(defun latex-word-count ()
(interactive)
(shell-command (concat "texcount " "-sum -inc -sub=section " (buffer-file-name))))
To count words in a selected region, I use detex
to strip LaTeX commands and wc
to count words:
(defun latex-wc-region (&optional b e)
(interactive "r")
(shell-command-on-region b e "detex | wc -w"))
Sometimes I like to fold chunk of the document to improve clarity, e.g. frames in beamer document or figure/table in a manuscript.
I added to my .emacs
:
(add-hook 'LaTeX-mode-hook (lambda ()
(add-to-list 'LaTeX-fold-env-spec-list '("[frame]" ("frame")))
(setq TeX-fold-macro-spec-list (list ()))
(TeX-fold-mode 1)))
Then the main key bindings are:
C-c C-o C-e
folds an environment.C-c C-o C-r
folds a region.C-c C-o i
unfold an item.C-c C-o C-f
to switch the fold-mode on/offBecause I added frame in the list, I can select a bunch of frames, press C-c C-o C-r
and they all get folded (but not the rest).
Otherwise, I manually fold the frames/figures/tables that are distracting.
C-c C-s s
bold (strong).C-c C-s e
italic (emphasis).C-c C-s s
code
(code).C-c C-o
follow a link.C-c C-x C-l
to toggle the hide-url mode to get shorter links.C-c C-p
/C-c C-n
jump to previous/next outline.Pressing TAB
when the cursor is in a heading will cycle through heading-only/full view.
M-x orgtbl-mode
to format markdown tables like org-tables.
markdown-preview-mode
opens a page on the web browser and update it every time the buffer is saved.
Elpy combines several packages to provide a lot of nice features, e.g. code coloring, completion, syntax checks, formatting recommendations.
To install the dependencies for elpy:
pip install jedi autopep8 flake8
Then I have in my .emacs
:
(package-initialize) ;; if not present already
(elpy-enable)
(setq elpy-company-add-completion-from-shell t)
(setq elpy-shell-use-project-root nil)
(setq elpy-shell-display-buffer-after-send t)
(setq elpy-shell-starting-directory 'current-directory)
Keybindings that I use:
C-RET
or C-c C-y C-e
to send line to python and step.C-c C-y r
sends region to python. Same for function, class or buffer.C-up
/C-down
navigates between lines with same indentation as the current line.C-c C-d
open doc for symbol on point.C-c C-z
switch to Python shell (or start one).C-c C-n
go to next flymake error (previous with p).C-c C-e
edit all occurrences of symbol on point for refactoring (narrow if needed).Of note, I use the Jupyter console instead of the default interpreter.
So pip install jupyter
and in my .emacs
:
(setq python-shell-interpreter "jupyter"
python-shell-interpreter-args "console --simple-prompt"
python-shell-prompt-detect-failure-warning nil)
(add-to-list 'python-shell-completion-native-disabled-interpreters
"jupyter")
Sometimes I want to send the commands to a specific buffer. For example, when testing new packages within a Docker container, I start a shell buffer, run docker and python.
I installed isend from MELPA.
Then I simply go to the code buffer and run M-x isend-associate RET *shell* RET
.
At this point C-Enter
will send the command to the shell buffer.
c-basic-offset
(e.g. setting it with M-x set-variable
).{
/}
: C-M-f
/C-M-b
I’m following this tutorial.
M-x speedbar
.M-x sr-speedbar-toggle
.To open a shell buffer, type M-x shell
.
Then I use the Emacs Speaks SHELL package, that adds all the nice commands to send lines/regions from a script to a Shell buffer. In my .emacs
I added:
(require 'essh)
(defun essh-sh-hook ()
(define-key sh-mode-map "\C-c\C-r" 'pipe-region-to-shell)
(define-key sh-mode-map "\C-c\C-b" 'pipe-buffer-to-shell)
(define-key sh-mode-map "\C-c\C-j" 'pipe-line-to-shell)
(define-key sh-mode-map "\C-c\C-n" 'pipe-line-to-shell-and-step)
(define-key sh-mode-map "\C-c\C-f" 'pipe-function-to-shell)
(define-key sh-mode-map "\C-c\C-d" 'shell-cd-current-directory))
(add-hook 'sh-mode-hook 'essh-sh-hook)
The shortcuts are self-explanatory.
Install through MELPA:
In my .emacs
file:
(setq wdl-indent-level 4)
to change the indentation size.(setq-default indent-tabs-mode nil)
to make sure tabs are made of spaces (WDL doesn’t like mixing spaces and tabs).Eventually the minor mode whitespace-mode
is useful to explicitly show spaces and double-check that none of the indentations are made of tabs.
There is also an LSP implementation for WDL that can be used by Emacs to provide syntax validation and (some) auto-completion.
lsp-mode
, lsp-ui
and company-lsp
.pip install wdl-lsp
(or pip3
)..emacs
file:(require 'lsp-mode)
(add-to-list 'lsp-language-id-configuration '(wdl-mode . "wdl"))
(defgroup lsp-wdl nil
"LSP support for WDL."
:group 'lsp-mode
:link '(url-link "https://github.com/broadinstitute/wdl-ide"))
(defcustom lsp-wdl-server-command "wdl-lsp"
"Command to start wdl-lsp."
:group 'lsp-wdl
:risky t
:type 'file)
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection
(lambda () lsp-wdl-server-command))
:major-modes '(wdl-mode)
:priority -1
:server-id 'wdl))
(add-hook 'wdl-mode-hook #'lsp)
;; Syntax validation interface
(require 'lsp-ui)
(add-hook 'lsp-mode-hook 'lsp-ui-mode)
(setq lsp-ui-sideline-enable nil)
;; To get some auto-completion
(require 'company-lsp)
(push 'company-lsp company-backends)
The first time a file is opened, lsp will ask what is the root of the project.
This can be changed later using M-x lsp-workspace-folders-remove
and M-x lsp-workspace-folders-add
.
To visualize blanks (tabs, spaces, new lines) I use the minor mode whitespace-mode
.
To disable line wrapping: M-x toggle-truncate-lines
To insert a tab: C-q <tab>
To compare and merge two files, use Ediff mode by calling M-x ediff
(or M-x ediff-buffers
when diff should be done between existing buffers).
Once launched press:
|
to change the split mode (vertical/horizontal).n
/p
to go to the next/previous difference.a
to put A’s version to B.b
to put B’s version to A.q
to quit.?
to get the full list of shortcuts.I use the csv-mode
and the command c-c c-a
to align columns.
By default it understand ,
, ;
and \t
as separator.
If not I think the variable to customize is csv-separators
.
When opening a directory (C-x C-f
), Emacs shows the files in Dired mode:
d
/u
mark/unmark files for deletion.x
deletes files marked for deletion.% d regexp <RET>
flags file matching a regexp.R
rename a file.C
copy a file.Added to my .emacs
to show human-readable sizes:
(setq dired-listing-switches "-aBhl")
The built-in interface supports Git:
C-x v +
to pull.C-x v d
to show the status.C-x v v
to commit.C-x v P
to push.C-x v i
to add.C-x v =
to see differences.A more popular Git interface is Magit.
After installing magit using MELPA, invoke the main buffer with M-x magit-status
(or C-x g
) and then:
?
to list keystroke/commands.F u
to pull.g
to refresh.s
to stage file.c c
to commit.P u
to push.Magit configuration in my .emacs
:
(setq vc-handled-backends (delq 'Git vc-handled-backends))
(global-set-key (kbd "C-x g") 'magit-status)
Encryption is integrated directly. Just add the extension .gpg
to a file.
M-x ess-remote
to use a shell buffer as R buffer to send commands to. For example to send commands from a local R script to an R session on a server (connected through ssh in the shell buffer), or on an interactive job (launched in the shell buffer).Remote files can be accessed/edited by opening them with /ssh:USER@SERVER:/path/to/file
.
A shortcut to connect to a server might be, in the .emacs
:
(defun connect-SERVER ()
(interactive)
(dired "/ssh:USER@SERVER:/path/to/root"))
Update: I don’t use this anymore. I take temporary notes in Simplenote, some of which I save in org-mode if I want to keep them.
I use Evernote for easily keep notes synchronized across computer, tablet and smartphone. And there is a Emacs mode for it (of course!).
To install it, first run:
gem install evernote_oauth
git clone https://github.com/pymander/evernote-mode
cd evernote-mode/ruby
ruby setup.rb
I had an error with the last command and fixed it by changing ::Config::CONFIG
with ::RbConfig::CONFIG
in setup.rb
.
Then, copy evernote-mode.el
to the load path and add to .emacs
:
(require 'evernote-mode)
(setq evernote-developer-token "<MYTOKEN>")
(setq evernote-username "<MYUSERNAME>")
(setq evernote-enml-formatter-command '("w3m" "-dump" "-I" "UTF8" "-O" "UTF8"))
(global-set-key "\C-cec" 'evernote-create-note)
(global-set-key "\C-ceo" 'evernote-open-note)
(global-set-key "\C-ces" 'evernote-search-notes)
(global-set-key "\C-ceS" 'evernote-do-saved-search)
(global-set-key "\C-cew" 'evernote-write-note)
(global-set-key "\C-cep" 'evernote-post-region)
(global-set-key "\C-ceb" 'evernote-browser)
I retrieved my developer token (to use instead of <MYTOKEN>
) there.
Side notes:
M-x evernote-change-edit-mode TEXT
to change the edit mode to text.I now use Simplenote instead of Evernote, in order to make sure that I have an offline version of my notes at all time. Moreover it integrates (almost completely) the Markdown format. It makes it easy to take notes and to transfer them in our wiki (e.g. for conference notes). It’s also easier to clean the notes through emacs compared to the online page or apps.
There is a Emacs package that can be installed using MELPA: M-x package-install [RET] simplenote2 [RET]
.
The Simplenote buffer can be summoned by M-x simplenote2-browse
or M-x simplenote2-list
.
In list mode, the relevant commands are:
g
: sync with the server.a
: create a new noted
: mark note on the current line for deletionu
: unmark note on the current line for deletiont
: set tags for filtering^
: toggle tags filtering condition between “AND” and “OR”Other general commands include:
simplenote2-add-tag
and simplenote2-delete-tag
simplenote2-set-markdown
Update: I don’t use macs anymore so this section might be more outdated than the rest.
Here are some bits of configuration specific to OSX.
Using the maxframe elisp from Ryan McGeary. I’ll copy the maxframe.el
in the master branch of this repo in case it disappears.
(require 'maxframe)
(add-hook 'window-setup-hook 'maximize-frame t)
To change the annoying OSX bindings: paragraph jumping, home/end for line not page.
(define-key function-key-map (kbd "M-<down>") 'forward-paragraph)
(define-key function-key-map (kbd "M-<up>") 'backward-paragraph)
(global-set-key (kbd "<home>") 'beginning-of-line)
(global-set-key (kbd "<end>") 'end-of-line)
To specify where is ispell located.
(setq ispell-program-name "/usr/local/Cellar/ispell/3.4.00/bin/ispell")
Also something about the right-click (I don’t remember why I have that).
(eval-after-load "flyspell"
'(progn
(define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word)
(define-key flyspell-mouse-map [mouse-3] #'undefined)))
For LaTeX, I specified the PATH in .emacs
:
(setenv "PATH" (concat (getenv "PATH") ":/usr/texbin"))
(setq exec-path (append exec-path '("/usr/texbin")))
For pandoc and ESS, I defined a RSTUDIO_PANDOC in .emacs
:
(setenv "RSTUDIO_PANDOCPATH" (concat (getenv "RSTUDIO_PANDOC") ":/usr/local/bin"))