on text editing
gnu ed
My favourite editor is gnu ed(1). It’s a mature line-based editor that is still actively maintained, currently at version 1.19. ed is–in my opinion—the best editor.
General usage
The general usage of ed(1) is very terse and relies on regular expression operators, which are applied linewise. It has a small set of commands that can be very effectively combined.
Some patterns
- To change arbitrary text inside brackets on a given line, one can
execute
s/(.*)/(reg)
. - We can put a blank line after lines matching a pattern
(g/reg/s/$/\)
. - Trim leading whitespace
(s/^[ ]*/)
, or trailing whitespace(s/[ ]*$/)
.
Special operators
\( and \)
can be used to capture regex. Example: The commandg/canon/s/\(canon\/\)/\1index.html
, where\1
evaluates tocanon/
, substitutescanon
withcanon/index.html
throughout the text.- The operator
'%'
evaluates to the current file name. Example: You can type!cc %
to compile the current file.
ssh support
Remote editing via ssh is possible:
r !ssh user@host "cat /path/to/local/file" // make some editing w !ssh user@host "cat > /path/to/remote/file"
External tools
ed(1) can utilize other command line tools for different purposes.
For example, we can use fmt
to break lines at 72 chars.
e !fmt -w72 %
A more complicated use-case is formatting a selection. This can be
achieved by combining sed
with fmt
as
r !sed -n '<n>,<m>p' % | fmt -w 72
where <n>
and <m>
are line numbers.
Scripting
The easiest way to script ed is using here scripts:
ed -s file <<< $'H\n<ed commands>\nw'
Here, H
lets ed(1) print out help messages.
Rectangle operations
It is possible to do rectangle operations in ed. For example, to delete 3 columns after column 6, we can do
s/\(.\(6\)\).\(3\)/\1/g
The global g
can be replaced with a line range.
ed(1) with syntax highlighting
There is a GNU ed fork with syntax highlighting.
Limitations
If you need to work with multiple files, ed(1) is not the strongest
programme, because it can only open one file at a time. A possible
workflow is to make use of screen
with terminal commands such as
cat
, grep
, and find
and use e
to open files within ed(1).
It's also fine to use gnu emacs, a nice editor with a graphical user interface that supports multiple files.
gnu emacs
General usage
When using emacs, it is sometimes advised to launch it as a daemon
with server-start
and to keep it running for the entire session.
This allows you to open other files from the command line through
the emacsclient
command. Files will open in the emacs window that
is already open.
However, I prefer to start a single emacs instance and use eshell
inside it. The advantage of eshell over your operating system's
terminal emulator is that files can be opened directly with C-f
.
Other emacs keybindings are also consistent inside eshell.
The manual
The emacs manual is very good. Within emacs, it can be evoked from
everywhere by executing C-h r
. It this doesn't work, it's
probably not installed. In debian, it can be installed through apt
install emacs-common-non-dfsg
.
Useful functions
emacs comes with many useful built-in functionalities, which are well-documented in the aforementioned manual. Additional functionalities can be added through external repositories. In the following, I list the ones I use.
Hippie expand
When activated, Hippie Expand provides low-overhead auto-completion,
based on text in open buffers. Start typing a word, and then invoke
auto-completion with M-/
. Hippie Expand completes the word by
cycling through different auto-completion mechanisms that can be
specified in the configuration file―see below. If the correct
expansion of the word has been passed by accident, use C-/
to cycle
back.
Keyboard macros
emacs lets you record and re-execute any chain of commands, which are
called keyboard macros. We use C-x (
to start and C-x )
to end
the recording. Once recorded, the macro can be executed repeatedly
through C-x e
. This is useful if the same action has to be
performed repeatedly throughout the text and there is no good regular
expression to capture. It allows for a more general structural
editing than the regular expression-based workflow in, for example,
ed(1).
apply-macro-to-region-lines
runs the keyboard macro on each line in
the region. I also sometimes just execute the macro a specific
[number]
of times via C-[number] C-x e
.
Gnus
gnus is a news and email reader that ships with emacs. It lets you subscribe to email inboxes and, for example, RSS feeds.
gnus hides emails that have been read. To view these older emails,
use /o
, which displays all email. Login credentials are stored in
$HOME/.authinfo
.
De- and encryption. gnus can de- and encrypt emails using GnupPG.
If the key is setup with the corresponding email address, emacs
encrypts and decrypts emails without the need for further
configuration. Emails are encrypted via C-c C-m c o
. Decryption
works automatically, if you receive an encrypted message and you
have the correct key added to your keyring.
Address book. An address book to store e-mail addresses can be
managed using the Insidious Big Brother Database (bbdb). The
package can be installed from the gnu repository via the emacs
package manager. Once it is installed, it needs to be configured in
the .gnus.el
and init.el
files as shown in the next section.
Start the address book on its own via M-x bbdb
and leave the regex
field empty. This lists all entries. New entries can be added via
c
(create). Add all addresses you want, save with s
and close
bbdb with q
(quit).
Now, when writing an email and filling out the address, bbdb will suggest contacts and cycle through them in another buffer.
Delay email sending. Gnus can schedule emails to be sent at a
certain time. This requires the following line in init.el
:
(gnus-delay-initialize)
(setq message-draft-headers '(References From))
(gnus-demon-add-handler 'gnus-delay-send-queue 60 nil)
(gnus-demon-init)
The second line ensures the correct time stamp. The last two lines
set up a demon to automatically push out queued messages every 60 min.
In a message buffer, press C-c C-j
instead of C-c C-c
. The
message is put into a folder called "delayed".
Unmark email. Emails marked as important in other email programmes
can be unmarked in gnus through M-u
.
Continue editing a drafted email. Emails saved under draft
can
be edited later by pressing D e
.
Dired
dired is a file browser that is shipped with emacs that can be
invoked through M-x dired
.
Selecting multiple files. Navigate in the directory holding the
files you want to search in. Using m
, mark all files you want to
modify.
If there are too many files to mark by hand, one can execute M-x
find-dired
and then provide suitable flags, such as -name
"*.cpp"
. This opens another dired buffer with the files that match
the regex. If you want to select all matches, press t
, which
toggles marks.
Replacing regular expression in several files. In dired, we can
replace a regular expression across several files. Select multiple
files as described above. Execute
dired-do-find-regexp-and-replace
or, alternatively, press Q
.
Follow the instructions. The files need to be explicitly saved—see
below.
Saving multiple files. For a large number of files, one can
execute M-x ibuffer
. Mark all unsaved files with * u
and save
them via S
, that is to say Shift+s
.
Filtering files. In order to search by filename and open the list
in a dired buffer, use M-x find-name-dired
.
org mode
- Introduction
org mode is a markup language, initially designed for task management within emacs. Since then, it has evolved into a markdown alternative for general note taking purposes. It has also export functionalities.
org mode is great for writing short and simple texts. For example, these blog pages are written in org mode and exported to html. For scientific writing, native LaTeX has more advantages, because things like author's affiliations, reference management, and layout customisation work better. In my experience, advanced options become increasingly more difficult to achieve and you get diminishing returns. Your document won't be true plain text anymore and the main argument for using org mode, that is its simplicity, is gone. At this point, you should use LaTeX.
When writing an org document, it is good practice to declare the document type with:
#+mode: -*- mode: org
The general syntax of modifying an org documents default behaviour is using
#+<keyword>
, followed by values. - Task management
Simple tasks require only two states,
TODO
andDONE
. We can also define our own states, although I currently don't use this functionality:#+todo: TODO WAIT IN-PROGRESS | DONE CANCELLED
The following creates a time stamp whenever a task is closed:
(setq org-log-done t)
The org-agenda view summarises tasks and can be used to scan across different files. In order to declare which files to scan, we use:
(setq org-agenda-files (list "~/org/scratch.org" "~/org/misc.org"))
The list of tasks can then be displayed via
M-x org-agenda
.A good workflow is to couple this with orgzly, to get the tasks synced between your mobile phone and your personal computer.
In addition, I currently have in my
init.el
, which opens the org-agenda view at start up:(setq inhibit-splash-screen t) (org-agenda-list) (delete-other-windows)
- Export
In general, org documents can contain metadata that will be used during export:
#+title: org mode #+author: ilhan özgen xian
Other possible metadata is
#+date
. If it's not defined, org mode will use the system's clock. - Interactive notebooks
An interesting application of org mode is literate programming, or the ability to create notebooks that have executable code mixed with exposition. This is done through Babel, which ships with org mode. One advantage of using org mode is that it allows mixing different programming languages in the same
session
. The syntax for defining an active code block is:#+begin_src python :session jupyter
The
:session pde
option specifies that the state of the workspace is saved and can be used further if it is referenced. This is useful for loading environment variables viabash
. The list of languages that are allowed to be executed within org are defined ininit.el
as:(org-babel-do-load-languages 'org-babel-load-languages '((shell . t) (python . t) (R . t)))
We can also control what gets exported:
#+begin_src python :session jupyter :exports both
The
:exports
option takes keywordsboth
,none
, andcode
.org mode's default behaviour is to ask for permission before evaluating a code block. This is for security reasons, but it gets tedious if there are a lot of blocks to be evaluated. In these cases, use:
(setq org-html-validation-link nil)
- org-tree-slide
org-tree-slide presents different sections of an org-file as individual slides. Open an org-file and execute
M-x org-tree-slide-mode
. Then, navigate through the slides usingC->
(forward) andC-<
(backward).
pdf-tools
pdf-tools is a suite to view and modify pdf files. In my opinion, it
works better than the built-in doc-view, which relies on converting
pdf files into png files. It can be installed through the
package-manager from melpa. After installing it, you need to M-x
pdf-tools-install
to activate it. In your init.el, you can also put
the following lines to activate pdf-tools and the associated
pdf-view:
(require 'pdf-tools) (pdf-loader-install)
If you only occasionally view pdf documents with emacs you don't need this package.
ebib
ebib is a BibTeX reference manager for emacs, written by J. Kremers. It can be installed through melpa. It has been recommended to me by Göktuǧ Kayaalp.
ebib is very straight-forward to use. One thing I struggled with was to export individual entries. Göktuǧ provided an answer:
In the top buffer you can hit
C e
to copy the selected entry's bibtex. Alsox
is for export, it prompts for a database name (i.e. a bibtex file opened in ebib, open files witho
, creates.bib
file if it doesn't exist, close database withc
). You can also mark withm
and do bulk export. Sadly it doesn't visibly indicate marked entries by default so it's a bit difficult to work with marks.
Underrated functionalities
M-x remember
saves the current selection to ".emacs.d/notes"M-x calendar
gives you calendar functionalities, where you can take notes and schedule appointments (viai d
)M-x diary
show appointments- gnus provides email and rss reader functionalities
- eww is a really good text-based web browser that can display images
- eshell is an alternative shell with elisp support
- tab-line-mode and global-tab-line-mode~ provide tab functionalities
- See also the article Batteries included with emacs and the follow-up More batteries included with emacs
M-x desktop-save
let's you save the current emacs session. You can reload it withM-x desktop-read
.
Build emacs from source
git clone https://git.savannah.gnu.org/git/emacs.git bash autogen.sh ./configure make
Notes
(setq default-directory (concat (getenv "HOME") "/"))
sets default directory to the home directory.(setq initial-buffer-choice "~/.emacs.d/scratch.org")
sets the initial buffer when emacs starts(set-face-attribute 'default nil :height 110)
sets the font size; similarly,(set-face-attribute 'default nil :font "Liberation Sans-12")
sets both the font family and the size.(add-hook 'org-mode-hook (lambda () (variable-pitch-mode t)))
activates variable pitch fonts in org buffers.(find-file "/home/ilhan/.emacs.d/notes")
opens a file at start up.(toggle-frame-fullscreen)
starts emacs in full screen.(savehist-mode t)
saves buffer history. Needs to be configured. From the emacs manual:For example, to save the history of commands invoked via
M-x
, add ‘command-history’ to the list in ‘savehist-additional-variables’.M-x visual-line-mode
wraps long lines andM-x display-line-numbers-mode
displays line numbers. This is nice for writing tex files.