Posts

  • Essential Flyspell

    I’ve been a long time user of flyspell-mode and flyspell-prog-mode, but admittedly I keep forgetting some of it’s keybindings. And there aren’t that many of them to begin with!

    This article is my n-th attempt to help me memorize anything besides C-c $. So, here we go:

    • M-t (flyspell-auto-correct-word) - press this while in word with typo in it to trigger auto-correct. You can press it repeatedly to cycle through the list of candidates.
    • C-, (flyspell-goto-next-error) - go to the next typo in the current buffer
    • C-. (flyspell-auto-correct-word) - same as M-t
    • C-; (flyspell-auto-correct-previous-word) - automatically correct the last misspelled word. (you can cycle here as well)

    Last, but not least, there’s the only command I never forget - C-c $ (flyspell-correct-word-before-point). Why is this my go-to command? Well, its name is a bit misleading, as it can do two things:

    • auto-correct the word at (or before) point
    • add the same word to your personal dictionary, so Flyspell and ispell will stop flagging it

    Good stuff!

    There are more commands, but those are the ones you really need to know.1

    If you ever forget any of them, just do a quick C-h m RET flyspell-mode.

    Do you have some tips to share about using flyspell-mode (and maybe ispell as well)?

    That’s all I have for you today! Keep fixing those typos!

    P.S. If you’re completely new to flyspell-mode, you may want to check this article on the subject as well.

    1. Unless you’d like to trigger auto-correct with your mouse, that is. 

  • Speed up Emacs Startup by Tweaking the GC Settings

    A well-known Emacs performance optimization advice is to boost the garbage collector threshold (so GC collections happen less frequently). That’s something I’ve had in my Emacs config for ages:

    ;; reduce the frequency of garbage collection by making it happen on
    ;; each 50MB of allocated data (the default is on every 0.76MB)
    (setq gc-cons-threshold 50000000)
    

    Probably I should increase it to 100MB+ these days, given the proliferation of more resource-hungry tooling (e.g. LSP). On the other hand there are also some counter arguments to consider when it comes to setting a high GC threshold:

    The GC threshold setting after init is too high, IMNSHO, and its value seems arbitrary.

    If the OP thinks that Emacs will GC as soon as it allocates 100 MiB, then that’s a grave mistake! What really happens is the first time Emacs considers doing GC, if at that time more than 100 MiB have been allocated for Lisp objects, Emacs will GC. And since neither Lisp programs nor the user have any control on how soon Emacs will decide to check whether GC is needed, the actual amount of memory by the time Emacs checks could be many times the value of the threshold.

    My advice is to spend some time measuring the effect of increased GC threshold on operations that you care about and that take a long enough time to annoy, and use the lowest threshold value which produces a tangible improvement. Start with the default value, then enlarge it by a factor of 2 until you see only insignificant speedups. I would not expect the value you arrive at to be as high as 100 MiB.

    – Eli Zaretskii, Emacs maintainer

    One thing that’s not so common knowledge is that removing the GC limits during Emacs startup might improve the speedup quite a lot (the actual results will be highly dependent on your setup). Here’s what you need to do - just add the following bit to your early-init.el:

    ;; Temporarily increase GC threshold during startup
    (setq gc-cons-threshold most-positive-fixnum)
    
    ;; Restore to normal value after startup (e.g. 50MB)
    (add-hook 'emacs-startup-hook
              (lambda () (setq gc-cons-threshold (* 50 1024 1024))))
    

    most-positive-fixnum is a neat constant that represents the biggest positive integer that Emacs can handle. There’s also most-negative-fixnum that you might find handy in some cases.

    As for early-init.el - it was introduced in version 27 and is executed before init.el. Its primary purpose is to allow users to configure settings that need to take effect early in the startup process, such as disabling GUI elements or optimizing performance. This file is loaded before the package system and GUI initialization, giving it a unique role in customizing Emacs startup behavior.

    Here are some other settings that people like to tweak in early-init.el:

    ;; Disable toolbars, menus, and other visual elements for faster startup:
    (menu-bar-mode -1)
    (tool-bar-mode -1)
    (scroll-bar-mode -1)
    
    (setq inhibit-startup-screen t)
    
    ;; Load themes early to avoid flickering during startup (you need a built-in theme, though)
    (load-theme 'modus-operandi t)
    
    ;; tweak native compilation settings
    (setq native-comp-speed 2)
    

    I hope you get the idea! If you have any other tips on speeding up the Emacs startup time, I’d love to hear them!

    That’s all I have for you today. Keep hacking!

  • Relative Line Numbers

    Relative line numbers (relative to the current line) are super popular in the world of Vim, because there it’s super easy to move n lines up or down wiht j and k. In the world of Emacs most of us tend to just go some line using M-g g using a absolute line number or using avy (avy-goto-line).

    That being said, relative line numbers are easy to enable in Emacs and quite handy if you’re into evil-mode:

    (setq display-line-numbers-type 'relative)
    (global-display-line-numbers-mode +1)
    

    Relative line numbers are useful with the Emacs core commands forward-line (C-n) and previous-line (C-p) as well. Just trigger them with the universal prefix C-u and you can move quickly around:

    • C-u 5 C-n (move 5 lines forward)
    • C-u 10 C-p (move 10 lines backward)

    Easy-peasy!

    That’s all I have for you today! Keep hacking!

  • You have no idea how powerful isearch is!

    isearch is probably one of the most widely known Emacs commands. Every Emacs user knows that they can run it using C-s (to search forward) and C-r to search backwards. Everyone also knows they can keep pressing C-s and C-r to go over the list of matches in the current buffer. Even at this point that’s a very useful command. But that doesn’t even scratch the surface of what isearch can do!

    After you’ve started isearch you can actually do a lot more than pressing C-s and C-r:

    • Type DEL to cancel last input item from end of search string.
    • Type RET to exit, leaving point at location found.
    • Type LFD (C-j) to match end of line.
    • Type M-s M-< to go to the first match, M-s M-> to go to the last match. (super handy)
    • Type C-w to yank next word or character in buffer onto the end of the search string, and search for it. (very handy)
    • Type C-M-d to delete character from end of search string.
    • Type C-M-y to yank char from buffer onto end of search string and search for it.
    • Type C-M-z to yank from point until the next instance of a specified character onto end of search string and search for it.
    • Type M-s C-e to yank rest of line onto end of search string and search for it.
    • Type C-y to yank the last string of killed text.
    • Type M-y to replace string just yanked into search prompt with string killed before it.
    • Type C-q to quote control character to search for it.
    • Type C-x 8 RET to add a character to search by Unicode name, with completion.
    • C-g while searching or when search has failed cancels input back to what has been found successfully.
    • C-g when search is successful aborts and moves point to starting point.

    You can also toggle some settings write isearch is active:

    • Type M-s c to toggle search case-sensitivity.
    • Type M-s i to toggle search in invisible text.
    • Type M-s r to toggle regular-expression mode.
    • Type M-s w to toggle word mode.
    • Type M-s _ to toggle symbol mode.
    • Type M-s ' to toggle character folding.

    Type M-s SPC to toggle whitespace matching. In incremental searches, a space or spaces normally matches any whitespace defined by the variable search-whitespace-regexp; see also the variables isearch-lax-whitespace and isearch-regexp-lax-whitespace.

    Type M-s e to edit the search string in the minibuffer. That one is super useful!

    Also supported is a search ring of the previous 16 search strings:

    • Type M-n to search for the next item in the search ring.
    • Type M-p to search for the previous item in the search ring.
    • Type C-M-i to complete the search string using the search ring.

    Last, but not least - you can directly search for the symbol/thing at point:

    • Type M-s . to search for the symbol at point. (useful in the context of programming languages)
    • Type M-s M-. to search for the thing (e.g. word or symbol) at point.

    One of the most useful parts of that is the fact that a region is a thing. So you can mark a region (e.g. with expand-region or mark-*) and M-s M-. to immediately search for other instances of that text. Powerful stuff!

    Tip: You don’t really have to remember all those keybindings - just remember you can press C-h b to show them. (after you’ve started isearch)

    Most of the above text is coming straight from the docstring of isearch. It’s funny that I’ve been using Emacs for almost 20 years, I use isearch numerous times every day and I still often forget about much of its functionality.

    There’s more to isearch, though. Did you know it’s widely customizable as well? If you check its options with M-x customize-group isearch you’ll see there are over 30 (!!!) options there! Admittedly, I never used any of them, but you’ve got quite a lot of opportunities to tweak the behavior of isearch if you want to. Here’s an example of a customization some of you might find useful:

    ;; When isearching, enable M-<, M->, C-v and M-v to skip between matches
    ;; in an intuitive fashion.  Note that the `cua-selection-mode' bindings
    ;; for C-v and M-v bindings are not supported.
    (setq isearch-allow-motion t
          isearch-motion-changes-direction t)
    

    I hope you learned something useful today! Keep searching (the Emacs docs)!

  • The role of the Escape key in Emacs

    The Escape key (ESC) is legendary in vim, Emacs’s arch-rival. It’s so commonly used (mostly to switch back to normal mode and interrupt commands in progress) that you’ll find many articles on where to remap it (e.g. to Caps Lock), and there are also many keyboards that place ESC where ~ normally is, to make it more accessible.1

    In Emacs-land, however, we never really speak about ESC… Why so? Well, we use C-g to interrupt commands, and we obviously don’t have modal editing, at least not by default. Still, I think ESC has its uses in Emacs, even if they are not super obvious at first. For instance there’s the keyboard-escape-quit command, that’s described like this:

    Exit the current “mode” (in a generalized sense of the word). This command can exit an interactive command such as ‘query-replace’, can clear out a prefix argument or a region, can get out of the minibuffer or other recursive edit, cancel the use of the current buffer (for special-purpose buffers), or go back to just one window (by deleting all but the selected window).

    Basically, it’s a fancier way of doing C-g (keyboard-quit), and it’s mapped to ESC ESC ESC (triple escape). Not the most convenient keybinding, but still OK if your Escape is well positioned and you’d like to avoid holding down a modifier key.2 If you take a look at the keybinding in Emacs’s docs, though, you’ll see it’s listed as M-ESC ESC, rather than ESC ESC ESC. And this is what makes ESC really interesting - it serves as a substitute for Meta, but you don’t have to hold down ESC - instead M-something keybindings can be triggered by pressing ESC and the other key sequentially. Go ahead and try the following:

    • ESC x (same as M-x)
    • ESC g g (goto-line, same as M-g g)
    • ESC e (forward-sentence, same as M-e)

    I don’t know about you, but I think this is pretty handy, especially if you’re using macOS, where on many keyboards the Option (Meta) keys are pretty short, or one of them is even missing (the right one).

    For me using Emacs on macOS has always been a bit of a struggle, as the Meta is way more useful than Command (Super), and historically I swapped them3 because of this, but then I struggled when I had to use someone else’s keyboard. (or even my own, as I normally contained this rebinding only to Emacs). So, the ability to use ESC instead of Meta is definitely a welcome one, and I find myself doing this quite often.

    Before we wrap up consider keybindings like M->, M-! or M-% that require you to hold down both Shift and Meta when typing them. I think they way more pleasant as:

    • Esc >
    • Esc !
    • Esc %

    Admittedly, it took me a while to get used to this, as I didn’t pay much to the ESC key until I was fairly far into my Emacs journey. Topics like RSI prevention and keybinding ergonomics rarely bother young people.

    So, did you know about the role of ESC in Emacs? Are you making use of it? If you have any other tips to share on the subject I’d be happy to read them.

    That’s all I have for you today! ESC x forever!

    1. HHKB is probably the most famous example, but there are many many others that do the same. 

    2. I’m using a dual-function keybinding for what’s normally Caps Lock on most keyboards - it’s Control wwhen held down and Escape otherwise. For me that’s a good idea regardless of the editor someone’s using. 

    3. See https://batsov.com/articles/2012/10/14/emacs-on-osx/

Subscribe via RSS | View Older Posts