Many Markdown text editors under macOS or iOS come with a neat feature that lets you set the caret at a fixed position on screen, most often in the middle of the screen. This feature tries to emulate the way old mechanical typewriters used to work — it was the sheet of paper that was moving up or down, not the caret.
First, it is great for our neck not to have to look at the bottom the screen each time the caret reaches the bottom of the window. Then, having the caret always at the same position is a great time saver since you always know where it is and never have to hunt for it. I like both reasons a lot.
Emacs offers a similar feature, called centered-cursor-mode.
Once activated, nothing should change: open an empty file and start typing, the cursor starts at the top of the window and move down as usual. But as soon as you reach the approx. center of the screen, it stops moving and it is the lines of text that moves up each time you reach a new line. That is, unless you manually move the caret on another line. In that case, as soon as your resume typing the new line your caret is on will move to be at the middle of the screen.
Is it perfect? Nope. I would love if the caret was always in the middle of the screen, even when the file is empty, but it is great to have this extension nonetheless and I use all the time in Markdown files. This is how this blog post looks under Emacs, the caret will stay in the center, even while I mouse scroll to read it, unless I chose to move it elsewhere:
(Here, Emacs is running in fullscreen mode, using a custom theme, with a bunch of other features activated. What matters for us is that the carret is, more or less, in the middle of the screen.)
This is great but it gets better: you can tell Emacs to always turn that feature on for certain file extensions only. Say, for Markdown files. First, we need to add support for this centered thingy to Emacs.
Adding centered-cursor-mode to Emacs
If you have already added packages to your Emacs configuration, you probably just need to add this line to your init.el file:
But, David, what is this init.el and what is a package?
OK, we’re both brand new to Emacs. Welcome :)
When you start Emacs, it reads a default configuration file located in
~/.emacs.d/init.el. Emacs reads its content, and execute whatever it finds in it. And it does that each time you open Emacs, or you open a new Emacs window.
What do we write in that init file? Instructions, snippets of code that Emacs can understand, that tells it what we want it to do. The language Emacs understands is called Lisp, Emacs Lisp to be exact. Lisp is an odd language, but it is often very readable and it will let you do a lot of very different things. Complicated developper stuff, but also more basic user stuff, stuff like:
- “Dude, would you be kind enough to remember the cursor position each time I close and reopen a file. So I don’t have, thx” that would translate like this in Emacs Lisp:
(save-place-mode 1)(the 1 is for activating the feature, 0 would be to turn it off).
- “Emacs, as your new master, I order you to scroll one line at a time. Obey me.” would be translated as
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))Yeah, I know… Already a little bit less readable but at least you get the idea that this concern the mouse scroll.
- “Sweetie, would mind opening your windows maximized because I’m too lazy to click that stupid button each time, thx.' could be translated into:
(add-hook 'window-setup-hook 'toggle-frame-maximized t). Note that you could as well tell Emacs to open in fullscreen mode (hidding everything else on screen):
(add-hook 'window-setup-hook 'toggle-frame-fullscreen t).
In order to use packages, you need to configure Emacs and tell it what to do with packages — where to download any new package name it could find mentioned in your init.el, install it, and so on.
Here is my configuration. There are probably better ways to do it but — don’t forget, I’m a beginner too — this work well enough for me. I added thoses lines near the top of my init file, to be sure they’re loaded very early on when I open Emacs. (The
; before certain lire indicate comments, to help me remember what a section of code does, or they deactivate instructions that I don’t use but want to keep just in case.)
(require 'package) ;(add-to-list 'package-archives ; '("melpa-stable" . "https://stable.melpa.org/packages/")) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") t) (add-to-list 'package-archives '("tromey" . "http://tromey.com/elpa/") t) ;; Load and activate emacs packages. Do this first so that the ;; packages are loaded before you start trying to modify them. ;; This also sets the load path. (package-initialize) ;; Download the ELPA archive description if needed. ;; This informs Emacs about the latest versions of all packages, and ;; makes them available for download. (when (not package-archive-contents) (package-refresh-contents)) (require 'use-package) (setq use-package-always-ensure t)
With that, Emacs is able to find and download any new packages I tell it to use, and it will know what to do with them.
Automaticaly activate centered-cursor-mode on markdown files
Emacs uses modes to decide what to do with certain file types. Modes are like a set of predefined instructions, that are independ from each others. So, you can have a completely different Emacs configuration for txt files, org files, script files, Markdown files and so on. And I mean a completely different configuration, up to the font and the theme used in Emacs. But even though they’re independant, Modes can also be configured to work together and use one another, too. And all of that can be automated based on file extensions.
This is really very powerful and it is almost endlessly configurable but it comes at a cost: Emacs is hard to learn.
Emacs is an old software — its first release dates back 1976, at a time where GUI was not even a thing — and it shows in its… grumpy manners. If you probably can force Emacs to do whatever you want, configuring it is not for the faint of the heart, and it has a steep learning curve. Is it worth your time to learn using it? It’s up to you to decide. I’m not completely sold on it either, but I’m so impressed by what it can do, and by what I already managed to get out of it, that I keep on learning and using Emacs. Plus, once you get over the first impression, you discover an application that is willing to serve you, the way you want it. It’s just that it is old, with wrinckles here and there, it is not cool and not cute as younger apps, and it has a beard. Exactly like me — how not to like it?
Here is the relevant part of ‘my’ — most of it borrowed from other users, of course — Emacs Markdown configuration:
;;;;;;;;;;;;;;;; ;; ;; Markdown mode ;; ;;;;;;;;;;;;;;;; (add-hook 'markdown-mode-hook '(lambda () "My custom configuration for 'org-mode'." ;; custom theme for markdown (load-theme 'dracula t) (olivetti-mode) (olivetti-set-width 50) (centered-cursor-mode) (global-hl-line-mode +1) (‘toggle-hl-line-when-idle’) (save-place-mode 1) ;; using Ctrl+mouse scroll wheel: (use-package default-text-scale :defer 1 :config (default-text-scale-mode)) (set-face-attribute :family "EtBembo" (selected-frame) :height 200)))
(yep, Lisp and Emacs do love parenthesis.)
(ad-hook) tells Emacs to ‘hook’ all the following functions/options/modes to any Markdown file I openthrow at it (by default, they’re identified by their .md extension).
Our little package to keep the carted centered is squeezed between the two
Olivetti-mode lines — another great package worth a blog post, that makes Emacs look a little more pretty by centering the text on screen and by defining margins — and the lines
(global-hl-line-mode +1) and
(‘toggle-hl-line-when-idle’) — which are not a Chtulhu invocation, mind you: they tell Emacs to highlight the line the cursor is on (see previous screenshot).
To use this configuration, you can either copy-paste this whole block of code as it is, or just add a new line within your existing Markdown configuration, in your init.el file, that says:
There are more ‘pro’ ways to force Emacs to reload itself when you change its configuration, but restarting Emacs works too and it doesn’t require much explanations: restart Emacs.
Ok, your new package should now be loaded every time you open a Markdown file in Emacs. Enjoy.