<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Emacs on dev@iostream.pl</title><link>https://dev.iostream.pl/tags/emacs/</link><description>Recent content in Emacs on dev@iostream.pl</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sat, 25 Jul 2026 00:20:00 +0200</lastBuildDate><atom:link href="https://dev.iostream.pl/tags/emacs/index.xml" rel="self" type="application/rss+xml"/><item><title>Seek &amp; Destroy</title><link>https://dev.iostream.pl/posts/2026-07-25/</link><pubDate>Sat, 25 Jul 2026 00:20:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-07-25/</guid><description>&lt;p&gt;Every respectable text editor supports searching and replacing text, whether interactively or automatically. Editors from the upper shelves can also work with regular expressions.&lt;/p&gt;
&lt;p&gt;And then there is the editor from the highest shelf — Emacs — which handles all of this brilliantly, in several different ways.&lt;/p&gt;
&lt;h1 id="searching"&gt;Searching
&lt;/h1&gt;&lt;p&gt;In an average text editor, searching for text requires pressing a keyboard shortcut. Alternatively, you can try to remember beneath which pile of debris on your desk the mouse is buried, move it around until the pointer appears, and click whichever button opens the appropriate dialog box.&lt;/p&gt;
&lt;p&gt;Then you type the search term, confirm it, and the text is found. Thank you very much, and we hope to see you again during your next search.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But not in Emacs.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;By default, the King of Editors provides &lt;strong&gt;incremental search&lt;/strong&gt;. Pressing &lt;code&gt;C-s&lt;/code&gt; — or invoking &lt;code&gt;M-x isearch-forward&lt;/code&gt; — starts the search and waits for input in the minibuffer.&lt;/p&gt;
&lt;p&gt;With every character you type, Emacs attempts to find the entire string entered so far and moves the cursor to the matching location in the text. The current match is highlighted by default. Any other occurrences visible in the buffer are highlighted as well, using a different combination of foreground and background colours.&lt;/p&gt;
&lt;p&gt;The search string is remembered between searches. Pressing &lt;code&gt;C-s&lt;/code&gt; again moves the cursor to the next occurrence of the current search string.&lt;/p&gt;
&lt;p&gt;When Emacs reaches the end of the buffer, it displays an appropriate message in the minibuffer. Pressing &lt;code&gt;C-s&lt;/code&gt; once more wraps the search around and continues from the beginning of the buffer.&lt;/p&gt;
&lt;h2 id="searching-backwards"&gt;Searching backwards
&lt;/h2&gt;&lt;p&gt;Incremental search also works &lt;strong&gt;backwards&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;C-r&lt;/code&gt; shortcut — or &lt;code&gt;M-x isearch-backward&lt;/code&gt; — behaves just like forward incremental search, except that it moves in the opposite direction.&lt;/p&gt;
&lt;p&gt;After reaching the &lt;em&gt;beginning&lt;/em&gt; of the buffer, Emacs displays an appropriate message in the minibuffer. Pressing &lt;code&gt;C-r&lt;/code&gt; again wraps the search around and continues from the &lt;em&gt;end of the buffer&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="search-results"&gt;Search results
&lt;/h2&gt;&lt;p&gt;Pressing &lt;code&gt;M-s o&lt;/code&gt; during an incremental search — which invokes &lt;code&gt;M-x isearch-occur&lt;/code&gt; — opens another &lt;em&gt;window&lt;/em&gt; containing the search results: every line in which the requested phrase occurs.&lt;/p&gt;
&lt;p&gt;The matching phrase is, naturally, highlighted so that it stands out. At the top of the window, Emacs displays a summary showing how many matches were found, on how many lines, and in which buffer.&lt;/p&gt;
&lt;p&gt;More importantly, the results are navigable. Move to any entry and press &lt;code&gt;RET&lt;/code&gt;, and Emacs takes you directly to the corresponding line in the original buffer.&lt;/p&gt;
&lt;h2 id="non-incremental-search"&gt;Non-incremental search
&lt;/h2&gt;&lt;p&gt;What if someone simply wants to enter a complete search string first and then jump to its first occurrence?&lt;/p&gt;
&lt;p&gt;A traditional, non-incremental search can be performed as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-s RET &amp;lt;search text&amp;gt; RET&lt;/code&gt; — or &lt;code&gt;M-x search-forward&lt;/code&gt; — searches forwards,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-r RET &amp;lt;search text&amp;gt; RET&lt;/code&gt; — or &lt;code&gt;M-x search-backward&lt;/code&gt; — searches backwards.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, it works much like incremental search, except that you press &lt;code&gt;RET&lt;/code&gt; before entering the phrase.&lt;/p&gt;
&lt;h2 id="case-sensitivity"&gt;Case sensitivity
&lt;/h2&gt;&lt;p&gt;By default, Emacs uses a convenient mechanism known as &lt;strong&gt;case folding&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As long as the search string contains only lowercase letters, Emacs ignores case and attempts to match as many occurrences as possible. As soon as you enter an uppercase letter, the search becomes case-sensitive.&lt;/p&gt;
&lt;p&gt;During an incremental search, &lt;code&gt;M-c&lt;/code&gt; toggles case sensitivity explicitly, so there is no need to introduce an uppercase letter merely to change the matching behaviour.&lt;/p&gt;
&lt;h2 id="searching-with-regular-expressions"&gt;Searching with regular expressions
&lt;/h2&gt;&lt;p&gt;Emacs also provides both incremental and non-incremental searches based on regular expressions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-x re-search-forward&lt;/code&gt; searches forwards for the next piece of text matching the given regular expression. When a match is found, the cursor is moved to its end. If no match exists, Emacs displays an appropriate message in the minibuffer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-x re-search-backward&lt;/code&gt; performs the same operation in the opposite direction.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-M-s&lt;/code&gt; — &lt;code&gt;M-x isearch-forward-regexp&lt;/code&gt; — starts an incremental forward search using a regular expression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-M-r&lt;/code&gt; — &lt;code&gt;M-x isearch-backward-regexp&lt;/code&gt; — starts an incremental backward search using a regular expression.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="searching-within-a-region"&gt;Searching within a region
&lt;/h2&gt;&lt;p&gt;By default, Emacs searches through the buffer. To limit a search to a particular region, one can use a small but extremely useful trick: &lt;strong&gt;narrowing&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;C-x n n&lt;/code&gt; — or invoke &lt;code&gt;M-x narrow-to-region&lt;/code&gt; — to narrow the buffer to the currently selected region.&lt;/p&gt;
&lt;p&gt;This is interesting because the rest of the text temporarily disappears. All subsequent operations, including searching, are restricted to the visible part of the buffer.&lt;/p&gt;
&lt;p&gt;Once the work is complete, press &lt;code&gt;C-x n w&lt;/code&gt; — or invoke &lt;code&gt;M-x widen&lt;/code&gt; — to restore the hidden text to its rightful place.&lt;/p&gt;
&lt;h2 id="search-history"&gt;Search history
&lt;/h2&gt;&lt;p&gt;Search history is, of course, preserved.&lt;/p&gt;
&lt;p&gt;While searching, you can use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-p&lt;/code&gt; to recall the previous search string,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-n&lt;/code&gt; to move to the next search string in the history.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="other-useful-commands"&gt;Other useful commands
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-y&lt;/code&gt; — &lt;code&gt;M-x yank&lt;/code&gt; — inserts the most recently killed text into the search string, because why would it not?&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-w&lt;/code&gt; adds the remainder of the word at point to the search string.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="replacing"&gt;Replacing
&lt;/h1&gt;&lt;p&gt;Once again, the King of Editors refuses to blend in with the crowd and offers something better than the competition.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;M-%&lt;/code&gt; — &lt;code&gt;M-x query-replace&lt;/code&gt; — interactively replaces occurrences of one string with another, starting from the position at which the command was invoked.&lt;/p&gt;
&lt;p&gt;At every match, Emacs asks the user what should happen next:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;y&lt;/code&gt; replaces the current match and moves to the next one,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;n&lt;/code&gt; skips the current match and moves to the next one,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;q&lt;/code&gt; ends the replacement operation,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!&lt;/code&gt; replaces the current match and every remaining match without asking any more unnecessary questions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other available actions can be found, for example, by invoking:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;M-x describe-function RET query-replace RET
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;C-M-%&lt;/code&gt; — &lt;code&gt;M-x query-replace-regexp&lt;/code&gt; — works in the same way, but uses regular expressions.&lt;/p&gt;
&lt;p&gt;Emacs also tries to preserve the &lt;strong&gt;capitalisation style&lt;/strong&gt; of the replaced text.&lt;/p&gt;
&lt;p&gt;Suppose that every occurrence of &lt;code&gt;windows&lt;/code&gt; must be replaced with &lt;code&gt;linux&lt;/code&gt;. Emacs may perform the following replacements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;windows&lt;/code&gt; becomes &lt;code&gt;linux&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Windows&lt;/code&gt; becomes &lt;code&gt;Linux&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WINDOWS&lt;/code&gt; becomes &lt;code&gt;LINUX&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;The author believes that Windows should be replaced with Linux not only in this example, but also in the lives of us all.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="non-interactive-replacement"&gt;Non-interactive replacement
&lt;/h2&gt;&lt;p&gt;Emacs also provides commands that replace all matching occurrences without asking for confirmation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-x replace-string&lt;/code&gt; replaces every occurrence of one string with another, starting from the position at which the command was invoked.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-x replace-regexp&lt;/code&gt; replaces every piece of text matching the given regular expression with the specified replacement string, again starting from the current position.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="replacing-within-a-region"&gt;Replacing within a region
&lt;/h2&gt;&lt;p&gt;If a region is active, Emacs performs replacement commands within that region by default.&lt;/p&gt;
&lt;p&gt;There is no need to narrow or widen the buffer manually — although, naturally, Emacs will not prevent anyone from doing so.&lt;/p&gt;</description></item><item><title>2026-06-29</title><link>https://dev.iostream.pl/posts/2026-06-29/</link><pubDate>Mon, 29 Jun 2026 19:15:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-06-29/</guid><description>&lt;h1 id="buffer-overflow"&gt;Buffer Overflow
&lt;/h1&gt;&lt;p&gt;Today we begin in a slightly unusual place.&lt;/p&gt;
&lt;h2 id="interrupting-the-current-operation"&gt;Interrupting the Current Operation
&lt;/h2&gt;&lt;p&gt;If there is one key binding worth remembering before you even open your first file in Emacs, it is this one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While Emacs is executing some more complicated Lisp code, it may occasionally stop responding to user commands and give the impression that it has frozen.&lt;/p&gt;
&lt;p&gt;Nothing could be further from the truth.&lt;/p&gt;
&lt;p&gt;Emacs is not dead. It is merely busy executing that unfortunate piece of Lisp.&lt;/p&gt;
&lt;p&gt;There are two possible approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wait patiently until the Lisp interpreter finishes its work,&lt;/li&gt;
&lt;li&gt;or interrupt it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The latter is usually more practical.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-g&lt;/code&gt; interrupts the current operation. It works when Emacs is running a long command, waiting for minibuffer input, or otherwise pretending not to hear you.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-x keyboard-quit&lt;/code&gt; is the function bound to &lt;code&gt;C-g&lt;/code&gt; by default. Calling it manually is usually pointless: when Emacs is busy, you cannot invoke it, and when Emacs is not busy, there is nothing to interrupt. Still, the name is worth knowing if you ever decide to remap keys.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you forget everything else from this section, remember &lt;code&gt;C-g&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When something goes wrong, Emacs will usually listen.&lt;/p&gt;
&lt;p&gt;Lisp programmers are less predictable.&lt;/p&gt;
&lt;h1 id="what-does-this-key-do"&gt;What Does This Key Do?
&lt;/h1&gt;&lt;p&gt;Let us continue.&lt;/p&gt;
&lt;p&gt;Emacs contains an excellent built-in help system. One of its most useful features is the ability to ask:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;What command is this key binding actually running?&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;To find out, use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-x describe-key&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or, more conveniently, &lt;code&gt;C-h k&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Emacs will then ask you to press a key sequence, mouse button, or menu item.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-h k C-p
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;opens a help buffer describing the command bound to &lt;code&gt;C-p&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="describe key" class="gallery-image" data-flex-basis="3381px" data-flex-grow="1408" height="45" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-29/emacs-1.png" width="634"&gt;&lt;/p&gt;
&lt;p&gt;A shortened version looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-p runs the command previous-line.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;It is bound to C-p and &amp;lt;up&amp;gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Move cursor vertically up ARG lines.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;This function is for interactive use only;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;in Lisp code use `forward-line&amp;#39; with negative argument instead.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even this small fragment tells us quite a lot:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;which function is bound to the key,&lt;/li&gt;
&lt;li&gt;where the function comes from,&lt;/li&gt;
&lt;li&gt;which other keys invoke the same command,&lt;/li&gt;
&lt;li&gt;what the command does,&lt;/li&gt;
&lt;li&gt;whether it is meant for interactive use,&lt;/li&gt;
&lt;li&gt;and sometimes which related commands or variables are worth knowing about.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is one of Emacs&amp;rsquo; great strengths.&lt;/p&gt;
&lt;p&gt;The program is not merely configurable. It is also unusually good at explaining itself.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Bookmark:&lt;/strong&gt; if you have reached this point and started yawning, leave this article open. Tomorrow you will know exactly where to resume reading.&lt;/p&gt;
&lt;p&gt;You do not have to thank me.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h1 id="what-does-this-function-do"&gt;What Does This Function Do?
&lt;/h1&gt;&lt;p&gt;The same idea works in the other direction.&lt;/p&gt;
&lt;p&gt;If you know the name of a function and want to inspect it, use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-x describe-function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or simply &lt;code&gt;C-h f&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-h f find-file
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;opens a help buffer for the function used to visit files.&lt;/p&gt;
&lt;p&gt;&lt;img alt="describe function" class="gallery-image" data-flex-basis="1882px" data-flex-grow="784" height="32" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-29/emacs-2.png" width="251"&gt;&lt;/p&gt;
&lt;p&gt;A shortened fragment looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;find-file is an interactive function in `files.el`.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;It is bound to &amp;lt;open&amp;gt; and C-x C-f.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Edit file FILENAME.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Switch to a buffer visiting file FILENAME, creating one if none already exists.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;You can visit files on remote machines by specifying something like:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/ssh:SOME_REMOTE_MACHINE:FILE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;You can also visit local files as a different user by specifying:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/sudo::FILE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;To visit a file without conversion and without automatically choosing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a major mode, use M-x find-file-literally.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is why reading Emacs help buffers is often surprisingly useful.&lt;/p&gt;
&lt;p&gt;Even a command as ordinary as &lt;code&gt;find-file&lt;/code&gt; turns out to do more than merely open files.&lt;/p&gt;
&lt;p&gt;Several useful details appear immediately:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wildcards&lt;/strong&gt; — file name patterns can be expanded, allowing multiple files to be opened at once.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote files&lt;/strong&gt; — paths such as &lt;code&gt;/ssh:some-host:some-file&lt;/code&gt; open files over SSH.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Files as another user&lt;/strong&gt; — paths such as &lt;code&gt;/sudo::some-file&lt;/code&gt; allow editing files with elevated privileges.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last option is useful for editing configuration files that require administrative access.&lt;/p&gt;
&lt;p&gt;Other possible uses are left to the reader&amp;rsquo;s imagination and the local security department.&lt;/p&gt;
&lt;p&gt;At this point, Dear Reader, I assume you have already typed a single &lt;code&gt;*&lt;/code&gt; in some directory full of random files and discovered that Emacs can open rather more things than expected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;images,&lt;/li&gt;
&lt;li&gt;PDFs,&lt;/li&gt;
&lt;li&gt;OpenOffice and LibreOffice documents,&lt;/li&gt;
&lt;li&gt;documents produced by that office suite which now apparently wishes to be known as a co-pilot,&lt;/li&gt;
&lt;li&gt;EPUB and MOBI files,&lt;/li&gt;
&lt;li&gt;archives,&lt;/li&gt;
&lt;li&gt;and many other formats.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It probably will not play your movies, but it can certainly inspect archives.&lt;/p&gt;
&lt;p&gt;What to do with all those joyfully opened files will be discussed a little later.&lt;/p&gt;
&lt;h1 id="buffers-and-frames"&gt;Buffers and Frames
&lt;/h1&gt;&lt;p&gt;Dividing the working area of a frame into two or more windows was invented mainly so that several buffers could be displayed side by side.&lt;/p&gt;
&lt;p&gt;Anyone who writes code probably understands the value of that immediately.&lt;/p&gt;
&lt;p&gt;The King of Editors can split a frame both horizontally and vertically. The resulting windows can be split again, although not forever. Once a window becomes too small, Emacs will politely refuse and display an appropriate message.&lt;/p&gt;
&lt;p&gt;Useful key bindings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x 2&lt;/code&gt; — split the current window horizontally&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 3&lt;/code&gt; — split the current window vertically&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 1&lt;/code&gt; — delete all other windows and return to a single-window layout&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 0&lt;/code&gt; — delete the current window&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 5 2&lt;/code&gt; — create a new frame&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 5 1&lt;/code&gt; — delete other frames&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x 5 0&lt;/code&gt; — delete the current frame&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x o&lt;/code&gt; — move focus to the next window&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x S-o&lt;/code&gt; — move focus to the previous window&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A very important detail:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-x 1&lt;/code&gt; removes window splits, but it does not kill any buffers. The buffers remain open; only one of them is currently visible.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Arbitrary frame splitting" class="gallery-image" data-flex-basis="222px" data-flex-grow="92" height="870" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-29/emacs-3.png" srcset="https://dev.iostream.pl/posts/2026-06-29/emacs-3_hu_a4277411b90ad2d4.png 800w, https://dev.iostream.pl/posts/2026-06-29/emacs-3.png 806w" width="806"&gt;&lt;/p&gt;
&lt;h1 id="working-with-multiple-buffers"&gt;Working with Multiple Buffers
&lt;/h1&gt;&lt;p&gt;Emacs can open as many buffers as available memory allows.&lt;/p&gt;
&lt;p&gt;Because of that, there is usually no point in starting another Emacs instance every time you want to open another file. When you need another file, open it in the same Emacs session.&lt;/p&gt;
&lt;p&gt;Emacs was designed for working with many buffers at once. Running several separate instances is possible, but in everyday use it is rarely necessary.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Yes, this is the &amp;ldquo;a little later&amp;rdquo; mentioned above.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;If a file is no longer needed, kill its buffer with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-x k
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By default, Emacs asks what to do with buffers that contain unsaved changes.&lt;/p&gt;
&lt;p&gt;You can move to the previous or next buffer with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x Left&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x Right&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also switch directly to a named buffer using:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-x b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the buffer visits a file, its name is usually the same as the file name.&lt;/p&gt;
&lt;p&gt;If you do not remember the exact name, press &lt;code&gt;TAB&lt;/code&gt;. Emacs will display possible completions in a temporary window. You can also start typing and let completion narrow the list.&lt;/p&gt;
&lt;p&gt;Completion, selection, and minibuffer behavior are, of course, topics for another volume of the Emacs saga.&lt;/p&gt;
&lt;p&gt;To list all buffers, use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C-x C-b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This opens a buffer containing the buffer list. You can move into that buffer and choose one of the listed entries.&lt;/p&gt;
&lt;p&gt;The buffer list does not automatically refresh every time a new buffer is created. This makes sense once you realize that the buffer list is itself just another buffer.&lt;/p&gt;
&lt;p&gt;Press:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to refresh it.&lt;/p&gt;
&lt;p&gt;What else can be done inside the buffer list?&lt;/p&gt;
&lt;p&gt;As homework, press:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and read the help page.&lt;/p&gt;
&lt;h1 id="scrolling-another-window"&gt;Scrolling Another Window
&lt;/h1&gt;&lt;p&gt;One of the more useful Emacs features is the ability to scroll the contents of another window while continuing to work in the current one.&lt;/p&gt;
&lt;p&gt;No switching back and forth.&lt;/p&gt;
&lt;p&gt;No mouse.&lt;/p&gt;
&lt;p&gt;No unnecessary ceremony.&lt;/p&gt;
&lt;p&gt;If you are writing in one window and need to inspect something above or below in another window, Emacs has you covered.&lt;/p&gt;
&lt;p&gt;This is especially useful when both windows display different parts of the same file and you want to check what regrettable code you wrote earlier.&lt;/p&gt;
&lt;p&gt;Useful key bindings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-M-v&lt;/code&gt; — scroll the other window down&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-M-S-v&lt;/code&gt; — scroll the other window up&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternative bindings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M-PageDown&lt;/code&gt; — scroll the other window down&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-PageUp&lt;/code&gt; — scroll the other window up&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is one of those features that sounds minor until you start using it. After a few days, working without it feels unnecessarily clumsy.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;A note that will age badly and is not really on topic:&lt;/strong&gt; at the moment, southern Poland is experiencing temperatures that feel entirely incompatible with human life. Some people of questionable judgment still insist that climate change does not exist, and that trains in the seventeenth century were also stuffy.&lt;/p&gt;
&lt;p&gt;Drink enough water.&lt;/p&gt;
&lt;p&gt;This is not a joke.&lt;/p&gt;
&lt;p&gt;Otherwise, the seventeenth-century train will arrive for you personally.&lt;/p&gt;

 &lt;/blockquote&gt;</description></item><item><title>2026-06-25</title><link>https://dev.iostream.pl/posts/2026-06-25/</link><pubDate>Thu, 25 Jun 2026 11:15:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-06-25/</guid><description>&lt;h1 id="installation"&gt;Installation
&lt;/h1&gt;&lt;p&gt;There isn&amp;rsquo;t much to say about installing Emacs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every respectable Linux distribution includes Emacs in its package repositories. Simply use your distribution&amp;rsquo;s package manager.&lt;/li&gt;
&lt;li&gt;The same is true for the BSD family.&lt;/li&gt;
&lt;li&gt;On macOS, you can install it using &lt;code&gt;Homebrew&lt;/code&gt;, &lt;code&gt;MacPorts&lt;/code&gt;, or download a native build from &lt;a class="link" href="https://emacsformacosx.com/" target="_blank" rel="noopener"
 &gt;https://emacsformacosx.com/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;On Windows, simply download the official installer (&lt;code&gt;.exe&lt;/code&gt;) or the ZIP archive and extract it somewhere sensible.&lt;/li&gt;
&lt;li&gt;On Android, install the official &lt;code&gt;.apk&lt;/code&gt; package and allow applications from unknown sources in the system settings.&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;A small note:&lt;/strong&gt; if you have no interest in running the graphical version, most Unix-like systems also provide an &lt;code&gt;emacs-nox&lt;/code&gt; package.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Of course, you can always build Emacs from source.&lt;/p&gt;
&lt;p&gt;But why would you, when you could spend that hour starting another flame war on Twitter (formerly &amp;ldquo;X&amp;rdquo;), Reddit, or simply improving your thumb&amp;rsquo;s scrolling endurance on social media?&lt;/p&gt;
&lt;p&gt;Personally, I&amp;rsquo;d rather spend that hour weeding the vegetable garden.&lt;/p&gt;
&lt;p&gt;Usenet has long since passed into history, and no equally entertaining place for operating-system flame wars has ever truly replaced it.&lt;/p&gt;
&lt;h1 id="getting-started"&gt;Getting Started
&lt;/h1&gt;&lt;h2 id="launching-emacs"&gt;Launching Emacs
&lt;/h2&gt;&lt;p&gt;Launching the Finest Editor Known to Humankind is surprisingly simple.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On graphical desktops, Emacs should appear in your applications menu like any other program.&lt;/li&gt;
&lt;li&gt;On Windows, if you extracted the ZIP archive instead of running the installer, start &lt;code&gt;bin\runemacs.exe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you prefer a purely terminal-based experience, simply run:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;emacs -nw
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is where the Emacs journey truly begins.&lt;/p&gt;
&lt;p&gt;The first launch of an unmodified (&lt;em&gt;vanilla&lt;/em&gt;) Emacs under X11, Windows, or macOS opens a window featuring the GNU antelope, a welcome screen, and a few introductory notes.&lt;/p&gt;
&lt;p&gt;Curiously, what most desktop environments call a &lt;em&gt;window&lt;/em&gt;, Emacs calls a &lt;strong&gt;frame&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The reason is historical.&lt;/p&gt;
&lt;p&gt;Long before graphical user interfaces became commonplace, Emacs already knew how to divide a terminal screen into multiple independent editing areas called &lt;strong&gt;windows&lt;/strong&gt;. When graphical support arrived, the terminology remained unchanged: the top-level GUI object became a &lt;em&gt;frame&lt;/em&gt;, while the individual editing regions inside it continued to be called &lt;em&gt;windows&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Some traditions are simply too old to change.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Emacs main window" class="gallery-image" data-flex-basis="230px" data-flex-grow="96" data-title-escaped="Emacs main window" height="908" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-25/emacs-1.png" srcset="https://dev.iostream.pl/posts/2026-06-25/emacs-1_hu_1d06649b4d62bc31.png 800w, https://dev.iostream.pl/posts/2026-06-25/emacs-1.png 872w" title="Emacs main window" width="872"&gt;&lt;/p&gt;
&lt;h1 id="meet-the-interface"&gt;Meet the Interface
&lt;/h1&gt;&lt;p&gt;A default Emacs frame consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a menu bar,&lt;/li&gt;
&lt;li&gt;a toolbar (whose appearance ranges from &amp;ldquo;functional&amp;rdquo; to &amp;ldquo;deeply unfortunate&amp;rdquo;, although fortunately it can be hidden),&lt;/li&gt;
&lt;li&gt;one or more editing buffers,&lt;/li&gt;
&lt;li&gt;and the command line, better known as the &lt;strong&gt;minibuffer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="buffers"&gt;Buffers
&lt;/h2&gt;&lt;p&gt;A &lt;strong&gt;buffer&lt;/strong&gt; is the place where text is edited.&lt;/p&gt;
&lt;p&gt;Unlike most editors, however, an Emacs buffer is not necessarily associated with a file.&lt;/p&gt;
&lt;p&gt;Buffers may contain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;source code,&lt;/li&gt;
&lt;li&gt;documentation,&lt;/li&gt;
&lt;li&gt;shell sessions,&lt;/li&gt;
&lt;li&gt;email,&lt;/li&gt;
&lt;li&gt;directory listings,&lt;/li&gt;
&lt;li&gt;Git status,&lt;/li&gt;
&lt;li&gt;help pages,&lt;/li&gt;
&lt;li&gt;or virtually anything else.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This abstraction is one of the core ideas behind Emacs.&lt;/p&gt;
&lt;p&gt;Every buffer contains an editing area together with a &lt;strong&gt;mode line&lt;/strong&gt;, which displays useful information such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the buffer name,&lt;/li&gt;
&lt;li&gt;whether the buffer has unsaved changes,&lt;/li&gt;
&lt;li&gt;the current cursor position,&lt;/li&gt;
&lt;li&gt;and the active editing mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="major-modes"&gt;Major Modes
&lt;/h2&gt;&lt;p&gt;Most editing behavior in Emacs is controlled by &lt;strong&gt;major modes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A major mode typically corresponds to the type of document being edited.&lt;/p&gt;
&lt;p&gt;Whether you&amp;rsquo;re writing C code, XML, Markdown, Lisp, YAML, or something entirely your own, the selected mode determines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;syntax highlighting,&lt;/li&gt;
&lt;li&gt;indentation rules,&lt;/li&gt;
&lt;li&gt;available commands,&lt;/li&gt;
&lt;li&gt;keyboard shortcuts,&lt;/li&gt;
&lt;li&gt;and countless editor behaviors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Creating your own modes is also entirely possible, should inspiration strike.&lt;/p&gt;
&lt;h2 id="the-minibuffer"&gt;The Minibuffer
&lt;/h2&gt;&lt;p&gt;The &lt;strong&gt;minibuffer&lt;/strong&gt; serves as the communication channel between Emacs and its user.&lt;/p&gt;
&lt;p&gt;Emacs displays prompts and status messages there, while the user enters commands, filenames, search patterns, and countless other parameters.&lt;/p&gt;
&lt;p&gt;The minibuffer supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;command history,&lt;/li&gt;
&lt;li&gt;TAB completion,&lt;/li&gt;
&lt;li&gt;and context-sensitive suggestions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It may look like a single line of text, but it is one of the most heavily used parts of Emacs.&lt;/p&gt;
&lt;h2 id="windows-and-frames"&gt;Windows and Frames
&lt;/h2&gt;&lt;p&gt;A frame may be divided into multiple &lt;strong&gt;windows&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Each window displays a buffer.&lt;/p&gt;
&lt;p&gt;Interestingly, multiple windows may display the very same buffer simultaneously, each with its own cursor position and viewport.&lt;/p&gt;
&lt;p&gt;Only the minibuffer is shared across the entire frame.&lt;/p&gt;
&lt;h1 id="keys-and-commands"&gt;Keys and Commands
&lt;/h1&gt;&lt;p&gt;Emacs documentation uses a notation that initially looks mysterious but quickly becomes second nature.&lt;/p&gt;
&lt;p&gt;The most common forms are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C-x&lt;/strong&gt; — hold the &lt;strong&gt;Control&lt;/strong&gt; key while pressing &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-f&lt;/strong&gt; — execute the first key sequence, release the regular keys (you may keep holding Control if you like), then execute the second.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-x&lt;/strong&gt; — hold the &lt;strong&gt;Meta&lt;/strong&gt; key. On most PC keyboards this is simply the left &lt;strong&gt;Alt&lt;/strong&gt; key. I strongly recommend getting used to the left Alt immediately, since the right one is often reserved for national characters or other platform-specific input methods.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-M-x&lt;/strong&gt; — press both Control and Meta together.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S-x&lt;/strong&gt; — press Shift together with the specified key.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, one notation deserves its own paragraph.&lt;/p&gt;
&lt;h2 id="m-x"&gt;M-x
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;M-x&lt;/code&gt; executes an Emacs command.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;M-x&lt;/code&gt;, release the keys, type the command name into the minibuffer, and press Enter.&lt;/p&gt;
&lt;p&gt;Almost everything Emacs can do—apart from simply inserting text—is ultimately implemented as a Lisp function.&lt;/p&gt;
&lt;p&gt;Some of those functions appear in menus.&lt;/p&gt;
&lt;p&gt;Some are bound to keyboard shortcuts.&lt;/p&gt;
&lt;p&gt;All of them can be executed directly via &lt;code&gt;M-x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;choosing &lt;strong&gt;File → Open&amp;hellip;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;pressing &lt;code&gt;C-x C-f&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;executing &lt;code&gt;M-x find-file&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;all invoke exactly the same underlying function.&lt;/p&gt;
&lt;p&gt;&lt;img alt="M-x find-file" class="gallery-image" data-flex-basis="335px" data-flex-grow="139" data-title-escaped="M-x find-file" height="630" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-25/emacs-2.png" srcset="https://dev.iostream.pl/posts/2026-06-25/emacs-2_hu_9996e68af439c3f.png 800w, https://dev.iostream.pl/posts/2026-06-25/emacs-2.png 881w" title="M-x find-file" width="881"&gt;&lt;/p&gt;
&lt;h1 id="useful-keyboard-shortcuts"&gt;Useful Keyboard Shortcuts
&lt;/h1&gt;&lt;p&gt;The following commands quickly become second nature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C-x C-c&lt;/strong&gt; — exit Emacs. Generally considered a questionable life decision, although shutting down the computer is usually accepted as a valid excuse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-f&lt;/strong&gt; — open an existing file or create a new one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-s&lt;/strong&gt; — save the current buffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-w&lt;/strong&gt; — save the current buffer under a different name.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x k&lt;/strong&gt; — kill (close) the current buffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x Left&lt;/strong&gt; — previous buffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x Right&lt;/strong&gt; — next buffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-b&lt;/strong&gt; — list all buffers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x h&lt;/strong&gt; — select the entire buffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="editing-text"&gt;Editing Text
&lt;/h1&gt;&lt;p&gt;Unlike some other editors, Emacs does not have separate &amp;ldquo;insert&amp;rdquo; and &amp;ldquo;command&amp;rdquo; modes.&lt;/p&gt;
&lt;p&gt;Open a file.&lt;/p&gt;
&lt;p&gt;Start typing.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all there is to it.&lt;/p&gt;
&lt;p&gt;Modern keyboards provide cursor keys, Home, End, Page Up, and Page Down, and Emacs fully supports them.&lt;/p&gt;
&lt;p&gt;For historical reasons—and because terminals were not always so well equipped—traditional Emacs key bindings are also available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C-a&lt;/strong&gt; — beginning of line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-e&lt;/strong&gt; — end of line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-f&lt;/strong&gt; — forward one character&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-b&lt;/strong&gt; — backward one character&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-p&lt;/strong&gt; — previous line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-n&lt;/strong&gt; — next line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-v&lt;/strong&gt; — previous page&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-v&lt;/strong&gt; — next page&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-w&lt;/strong&gt; — copy selected text&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-w&lt;/strong&gt; — cut selected text&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-y&lt;/strong&gt; — paste&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-y&lt;/strong&gt; — immediately after &lt;code&gt;C-y&lt;/code&gt;, cycle through previous clipboard entries&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-k&lt;/strong&gt; — kill text from the cursor to the end of the line. Pressing it twice at the beginning of a line removes the entire line.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x h&lt;/strong&gt; — select the whole buffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-_&lt;/strong&gt; (or &lt;code&gt;C-x u&lt;/code&gt;) — undo, with unlimited history.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphical Emacs naturally supports selecting text with the mouse.&lt;/p&gt;
&lt;p&gt;Keyboard users, however, can set the beginning of a selection using &lt;code&gt;C-SPC&lt;/code&gt;, move the cursor to the desired position, and then perform any operation on the selected region.&lt;/p&gt;
&lt;p&gt;It is one of those habits that soon becomes completely automatic.&lt;/p&gt;
&lt;p&gt;One unexpected benefit of learning Emacs is that the keyboard shortcuts tend to follow you.&lt;/p&gt;
&lt;p&gt;Bash, the Python REPL, GDB, and many other command-line programs borrow their line-editing behavior from GNU Readline, whose default key bindings are deliberately Emacs-like.&lt;/p&gt;
&lt;p&gt;Even if you eventually decide that Emacs is not your editor of choice, the time spent learning &lt;code&gt;C-a&lt;/code&gt;, &lt;code&gt;C-e&lt;/code&gt;, &lt;code&gt;C-k&lt;/code&gt;, or &lt;code&gt;M-f&lt;/code&gt; will continue to pay dividends every time you open a terminal.&lt;/p&gt;
&lt;p&gt;In fact, many people use Emacs key bindings every day without realizing where they originally came from.&lt;/p&gt;</description></item><item><title>2026-06-20</title><link>https://dev.iostream.pl/posts/2026-06-20/</link><pubDate>Sat, 20 Jun 2026 08:15:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-06-20/</guid><description>&lt;h1 id="what-is-emacs-and-do-i-need-it"&gt;What Is Emacs, and Do I Need It?
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;GNU Emacs is a text editor originally created by Richard Stallman for the PDP-10 platform.&lt;/li&gt;
&lt;li&gt;GNU Emacs is a universal development environment available on Unix and Unix-like systems, Microsoft Windows, macOS, and many others.&lt;/li&gt;
&lt;li&gt;GNU Emacs is an operating system disguised as a text editor.&lt;/li&gt;
&lt;li&gt;GNU Emacs is a philosophy and a way of life.&lt;/li&gt;
&lt;li&gt;GNU Emacs is a religion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All right, let&amp;rsquo;s start over.&lt;/p&gt;
&lt;h2 id="a-brief-history"&gt;A Brief History
&lt;/h2&gt;&lt;p&gt;Richard Stallman, while working at MIT, became increasingly frustrated with proprietary software. Not only was it often full of bugs, but there was usually little anyone outside the vendor could do to fix them. Bug reports rarely led to meaningful improvements, and users were expected to simply accept whatever they were given.&lt;/p&gt;
&lt;p&gt;Eventually, Stallman left MIT and launched the GNU Project, whose goal was to create a completely free Unix-like operating system.&lt;/p&gt;
&lt;p&gt;Emacs itself began as a collection of macros for the TECO editor. After a rapid evolution, it became a standalone application and eventually one of the most influential pieces of software in the free software ecosystem. A large community of developers, thousands of articles, books, tutorials, and decades of active use suggest that Emacs still has a long future ahead of it.&lt;/p&gt;
&lt;p&gt;Not everyone, however, was happy with the project&amp;rsquo;s leadership style. The most significant fork occurred when developers from Lucid, who wanted to use Emacs as the foundation of their development environment, split off and created Lucid Emacs. This project later evolved into XEmacs.&lt;/p&gt;
&lt;p&gt;Incidentally, the &amp;ldquo;X&amp;rdquo; in XEmacs has nothing to do with whether the editor can run under the X Window System. Both GNU Emacs and XEmacs work perfectly well with or without X11.&lt;/p&gt;
&lt;p&gt;Over the years, various other forks appeared, often for technical or political reasons. While some introduced interesting ideas, none managed to surpass GNU Emacs itself. XEmacs, despite its innovations, gradually lost momentum. A long period without significant releases and declining community activity eventually left the project effectively dormant. Its website still feels like a time capsule from the late 1990s, apparently untouched by mobile devices, TLS certificates, or modern web design.&lt;/p&gt;
&lt;h2 id="what-is-emacs"&gt;What Is Emacs?
&lt;/h2&gt;&lt;h3 id="a-text-editor"&gt;A Text Editor
&lt;/h3&gt;&lt;p&gt;At its core, Emacs is a text editor.&lt;/p&gt;
&lt;p&gt;This remains the primary goal of the project: creating an exceptionally capable environment for editing text of all kinds. Source code, notes, books, articles, documentation, LaTeX manuscripts, configuration files—everything is ultimately text, and Emacs is designed to handle all of it.&lt;/p&gt;
&lt;h3 id="a-lisp-interpreter-and-runtime-environment"&gt;A Lisp Interpreter and Runtime Environment
&lt;/h3&gt;&lt;p&gt;One of Emacs&amp;rsquo; defining features is its built-in Lisp interpreter.&lt;/p&gt;
&lt;p&gt;Through Emacs Lisp, users can extend the editor to perform virtually any task imaginable. Email clients, news readers, calendars, web browsers, file managers, games, and countless other tools are available either as part of the standard distribution or through third-party packages.&lt;/p&gt;
&lt;p&gt;Need an AI assistant? Someone has almost certainly written one already.&lt;/p&gt;
&lt;p&gt;Installing extensions is typically as simple as fetching the appropriate package from a repository and enabling it.&lt;/p&gt;
&lt;h3 id="a-development-environment"&gt;A Development Environment
&lt;/h3&gt;&lt;p&gt;For many users, Emacs serves primarily as an integrated development environment.&lt;/p&gt;
&lt;p&gt;Support exists for an astonishing number of programming languages. Syntax highlighting, code navigation, language servers, debugging tools, build systems, version control integration, documentation generation, shells, terminals, and countless other development tools are readily available.&lt;/p&gt;
&lt;p&gt;Whether you write C++, Go, Python, Rust, Lisp, or something more obscure, chances are that someone has already built excellent Emacs support for it.&lt;/p&gt;
&lt;h3 id="an-environment-for-markup-languages"&gt;An Environment for Markup Languages
&lt;/h3&gt;&lt;p&gt;Emacs is equally comfortable working with markup and document-oriented formats.&lt;/p&gt;
&lt;p&gt;XML, HTML, YAML, Markdown, Org Mode, TeX, LaTeX, DocBook, and many others are all well supported. Validation, transformation, navigation, and editing tools are often available out of the box.&lt;/p&gt;
&lt;p&gt;The live preview capabilities available for TeX and LaTeX workflows remain particularly impressive even today.&lt;/p&gt;
&lt;h3 id="anything-you-can-convince-lisp-to-do"&gt;Anything You Can Convince Lisp to Do
&lt;/h3&gt;&lt;p&gt;Ultimately, Emacs is whatever you can persuade Emacs Lisp to become.&lt;/p&gt;
&lt;p&gt;This flexibility is both its greatest strength and one of the reasons why Emacs users occasionally develop a reputation for eccentricity.&lt;/p&gt;
&lt;h2 id="what-emacs-is-not"&gt;What Emacs Is Not
&lt;/h2&gt;&lt;h3 id="a-universal-solution"&gt;A Universal Solution
&lt;/h3&gt;&lt;p&gt;Emacs is an incredibly powerful tool, but it is not magic.&lt;/p&gt;
&lt;p&gt;Installing Emacs will not automatically teach you a programming language, system administration, networking, or software architecture. It can help you work more effectively, but it cannot replace knowledge or experience.&lt;/p&gt;
&lt;h2 id="is-emacs-for-me"&gt;Is Emacs for Me?
&lt;/h2&gt;&lt;p&gt;Perhaps.&lt;/p&gt;
&lt;p&gt;Emacs may be a good fit if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You want a consistent environment for editing, programming, writing, note-taking, and other text-oriented tasks.&lt;/li&gt;
&lt;li&gt;You enjoy highly configurable tools.&lt;/li&gt;
&lt;li&gt;You appreciate software that can evolve alongside your workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Emacs may not be a good fit if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editing configuration files makes you uncomfortable.&lt;/li&gt;
&lt;li&gt;You expect every feature to be immediately discoverable through graphical menus.&lt;/li&gt;
&lt;li&gt;You are unwilling to invest time learning new tools.&lt;/li&gt;
&lt;li&gt;Your primary computing activity consists of scrolling through social media feeds on a phone.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Emacs has a steep learning curve, but it rewards patience. For many users it eventually becomes much more than an editor; it becomes the environment in which a significant portion of their computing life takes place.&lt;/p&gt;
&lt;p&gt;Whether that sounds exciting or alarming is entirely up to you.&lt;/p&gt;</description></item></channel></rss>