Posts

  • 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/

  • Debugging Errors in Emacs

    I recently wrote an article on debugging Emacs commands. In it I mentioned M-x toggle-debug-on-error and debug-on-error briefly, but after posting the article I realized that many people probably don’t understand how this works exactly.

    The obvious thing that happens when debug-on-error is enabled is that when an error happen you’re seeing its backtrace (or stacktrace, depending on the terminology you prefer). What’s not so obvious (even, if it’s in the name) is that this buffer is actually a debugger buffer and you can do a lot with it. Here are a few examples:

    1. Navigate the Stack Trace: Move your cursor in the *Backtrace* buffer to different lines representing various stack frames.
    2. Examine Local Variables: Press v (debugger-toggle-locals) while on a stack frame to display local variables for that frame.
    3. Evaluate Expressions: Use e (debugger-eval-expression) to evaluate Lisp expressions in the context of the current frame.
    4. Step Through Code: Use d to step into function calls and evaluate expressions one by one.
    5. Continue Execution: Press c to continue normal execution. (note, that unless you change something, this will result in the error you’re trying to debug)
    6. Quit Debugging: Enter q to exit the debugger and abort the current command.
    7. View Help: Type ? to see a list of available debugger commands.
    8. Record Evaluations: Use E to evaluate an expression and save the result in the Debugger-record buffer.

    It’s important to understand that debugger runs in the environment of the error, allowing you to examine variable values precisely as they were at the time of the error. This makes it a powerful tool for understanding and fixing issues in your Emacs Lisp code.

    That debugging experience is one of the most powerful features of Lisps in general, and it’s one of the reasons why developing and debugging Emacs packages is pretty pleasant and productive experience. Provided you’re familiar with how to use the debugger in such cases that it.

    You can more help inside Emacs by pressing C-h m while in a debugger buffer.

    So, to recap - in case you run into some errors you should run the command M-x toggle-debug-on-error, re-run whatever action caused the error and then navigate the stacktrace in the debugger to figure out what went wrong exactly.

    To debug an error that happens during loading of the init file, use the option --debug-init. This binds debug-on-error to t while loading the init file, and bypasses the condition-case which normally catches errors in the init file.

    That’s all I have for you today. I hope you’ve learned something useful today and next time you run into some error you’ll be able to fix it in no time!

  • Customizing Color Themes

    Every now and then you’d be trying out a new color theme, that you really like overall, but you’d like to tweak a bit here and there to make it perfect. After all, that’s what Emacs is all about - creating the perfect editor for yourself.

    Sometimes you might be dealing with missing face definitions or configuration options that you might want to submit upstream, but most of the time the changes you’d like to see are probably quite subjective and belong in your personal config. So, how do you make those changes?

    There are 3 common ways to adjust font faces in Emacs and I’ll briefly cover all of them. Option number 1 is the tried and true classic custom-set-faces:

    (custom-set-faces
     '(region ((t (:inherit nil :background "RoyalBlue4"))))
     '(highlight ((t (:inherit region :background "dark olive green"))))
     '(hl-line ((t (:inherit highlight)))))
    

    That’s what gets generate if you’re adjusting faces with something like M-x customize-face. The bad thing about this approach is that those customizations will active regardless of your currently selected color theme and if you like to switch themes that’s not cool. Fortunately, it’s easily to narrow customizations to a particular theme with custom-theme-set-faces:

    (custom-theme-set-faces
     'zenburn
     '(region ((t (:inherit nil :background "RoyalBlue4"))))
     '(highlight ((t (:inherit region :background "dark olive green"))))
     '(hl-line ((t (:inherit highlight)))))
    

    Looking good!

    Note: custom-set-faces works by calling custom-theme-set-faces for the user theme, a special theme referring to settings made via Customize.

    Finally, you can just set a specific face using set-face-attribute like this:

    (set-face-attribute 'font-lock-builtin-face nil :weight 'bold)
    

    I’d suggest perusing the documentation of set-face-attribute (e.g. with C-h f) as it explains in great detail all the possible attributes you can configure for a font face. The number of properties you can set is truly epic, but most of the time you’ll need to tweak only a couple of them. (e.g. :foreground, :background, etc)

    Technically speaking, you can go a step further than that and define your own theme that extends the color theme you want to modify1, but that’s an overkill unless you plan to distribute this theme as a package.

    All the examples above are kind of random, so I’ll conclude here with some real modifications I do in my config to the popular Catppuccin theme:

    (use-package catppuccin-theme
      :config
      ;; or 'latte, 'macchiato, or 'mocha
      (setq catppuccin-flavor 'macchiato)
      (load-theme 'catppuccin t)
      (custom-theme-set-faces
       'catppuccin
       ;; by default the theme uses the same face as for comments, which is wrong IMO
       '(font-lock-doc-face ((t (:foreground (catppuccin-color 'green)))))
       ;; font-lock variable definitions like function definitions
       '(font-lock-variable-face ((t (:inherit font-lock-function-face))))))
    

    The example above also shows how to access the colors from the palette of some color theme outside of its definition. Usually themes provide some API like theme-name-color to get able to get the color codes easily.

    Funny enough, as I’m writing this I realized that use-package actually has built-in support for customizing faces that I could have used instead. Here’s an example of that in action:

    (use-package zenburn-theme
      :preface
      (setq my/zenburn-colors-alist
            '((fg . "#DCDCCC") (bg . "#1C1C1C") (cyan . "#93E0E3")))
      :custom-face
      (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan)))))
      :config
      (load-theme 'zenburn t))
    

    This example also reminded me that I should expose the Zenburn colors via functions.

    So, to summarize:

    • If you’re using use-package it’s probably best to use it’s :custom-face functionality.
    • The rest of the time you most likely need custom-theme-set-faces.

    One thing is certain - with Emacs there always numerous ways to achieve something!

    Note: To see the new font faces in action you’ll either have to restart Emacs or evaluate Elisp code that sets them. (e.g. with C-x C-e)

    One final tip - if you’re wondering what’s the face used by some text, the best way to figure it out is with the M-x describe-char command. It will give you a ton of information, including something like this near the end:

    There are text properties here:
      face                 (font-lock-keyword-face markdown-code-face)
      font-lock-fontified  t
      font-lock-multiline  t
      fontified            t
      markdown-gfm-code    (2617 3092)
    

    I had placed my cursor over the word “use-package” in the code snippet above, while writing this article in markdown-mode, therefore the faces font-lock-keyword-face (coming from elisp-mode) and markdown-code-face (from markdown-mode).

    Do you have any tips on customizing color themes that you’d like share?

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

    1. Remember that Emacs allows you load multiple themes with them stacking one upon another. 

Subscribe via RSS | View Older Posts