Emacs Tips and Tricks 1: Regions and Marks

Esperanto • English
Last updated: March 17, 2022

Don't raise your voice; improve your argument.
—Desmond Tutu

robert-keane-rlbG0pnQOU-unsplash

Table of contents

Introduction

I still have to find a better text editor than Emacs. What really makes Emacs shine is its configuration language—Emacs Lisp. Emacs uses it to the point that most of the functionality of Emacs itself, is implemented in Emacs Lisp. In this series, I will talk about the things that I discovered to make the use of Emacs even more enjoyable.

Regions

This command deletes a region if one is active, or deletes the character underneath the cursor.

(defun delete-char-or-region (&optional arg)
  (interactive "p")
  (if (region-active-p)
      (delete-region (region-beginning)
                     (region-end))
      (if (fboundp 'delete-char)
          (delete-char arg)
          (delete-forward-char arg))))

Compilation

I use this command frequently, and I use it from typesetting LaTeX documents, compiling Scribble documents, compiling code, and just about anything that I can use make with.

(defun compile-file ()
  (interactive)
  (compile "make -k"))

Scheme

I want to have a command that explicitly saves the input ring of Geiser:

(defun geiser-save ()
  (interactive)
  (geiser-repl--write-input-ring))

I also have the following, because I want to align the λ symbol nicely.

(defun my-scheme-mode-hook ()
  (put 'λ 'scheme-indent-function 1))

(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)

Server

This snippet ensures that the Emacs server, the one that emacsclient connects to, runs:

(require 'server)

(unless (server-running-p)
  (server-start))

Alternatively, you may run Emacs in daemon mode from the command-line:

$ emacs --daemon

I want a way to kill the current buffer, without being asked what buffer to kill. I will only get prompted if the current has been modified.

(defun kill-current-buffer ()
  (interactive)
  (kill-buffer (current-buffer)))

Marks

There have been plenty of times in the past when I needed a function that just marks a line. What I have is below. Executing it multiple times, marks multiple lines.

(defun mark-line (&optional arg)
  (interactive "p")
  (if (not mark-active)
      (progn
        (beginning-of-line)
        (push-mark)
        (setq mark-active t)))
  (forward-line arg))

Key bindings

The key bindings for the commands above, are listed below:

(bind-keys
 :map global-map
 ("<delete>" . delete-char-or-region)
 ("C-x C-k" . kill-current-buffer)
 ("C-x c" . compile-file)
 ("M-z" . mark-line))

(bind-keys
 :map scheme-mode-map
 ("C-c <tab>" . completion-at-point))

Closing remarks

I hope you’ll be able to find use of any of them. The rest of the configuration can be found here.