[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/devil 355bcc9c14 34/49: Extract most of the README into a
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/devil 355bcc9c14 34/49: Extract most of the README into a separate manual |
Date: |
Mon, 15 May 2023 12:59:33 -0400 (EDT) |
branch: elpa/devil
commit 355bcc9c14efb14d174ca39c2efe958c6843c4ba
Author: Philip Kaludercic <philipk@posteo.net>
Commit: Susam Pal <susam@susam.net>
Extract most of the README into a separate manual
---
MANUAL.org | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
README.md | 594 +------------------------------------------------------------
2 files changed, 565 insertions(+), 593 deletions(-)
diff --git a/MANUAL.org b/MANUAL.org
new file mode 100644
index 0000000000..3cd3ca982b
--- /dev/null
+++ b/MANUAL.org
@@ -0,0 +1,564 @@
+#+title: Devil Mode
+#+author: Susam Pal
+#+email: susam@susam.net
+#+language: en
+#+options: ':t toc:nil author:t email:t num:t
+#+texinfo_dir_category: Emacs misc features
+#+texinfo_dir_title: Devil: (devil-mode)
+#+texinfo_dir_desc: Minor mode for Devil-like command entering
+
+#+texinfo: @insertcopying
+
+Devil mode intercepts our keystrokes and translates them to Emacs key
+sequences according to a configurable set of translation rules. For
+example, with the default translation rules, when we type =, x , f=,
+Devil translates it to =C-x C-f=.
+
+The choice of the comma key (=,=) to mean the control modifier key
+(=C-=) may seem outrageous. After all, the comma is a very important
+punctuation both in prose as well as in code. Can we really get away
+with using =,= to mean the =C-= modifier? It turns out, this terrible
+idea can be made to work without too much of a hassle. At least it works
+for me! It might work for you too. If it does not, Devil can be
+configured to use another key instead of =,= to mean the =C-= modifier.
+See the section [[#custom-devil-key][Custom Devil Key]] for an example.
+
+A sceptical reader may rightfully ask: If =,= is translated to =C-=, how
+on earth are we going to insert a literal =,= into the text when we need
+to? The section [[#typing-commas][Typing Commas]] answers this. But
+before we get there, we have some fundamentals to cover. Take the plunge
+and see what unfolds! Maybe you will like this! Maybe you will not! If
+you do not like this, you can always retreat to God mode, Evil mode, the
+vanilla key bindings, or whatever piques your fancy!
+
+* Notation
+:PROPERTIES:
+:CUSTOM_ID: notation
+:END:
+A quick note about the notation used in the document: The previous
+example shows that =, x , f= is translated to =C-x C-f=. What this
+really means is that the key sequence ,x,f is translated to ctrl+x
+ctrl+f. We do not really type any space after the commas. The key , is
+directly followed by the key x. However, the key sequence notation used
+in this document contains spaces between each keystroke. This is
+consistent with how key sequences are represented in Emacs in general
+and how Emacs functions like =key-description=, =describe-key=, etc.
+represent key sequences. When we really need to type a space, it is
+represented as =SPC=.
+
+* Install
+:PROPERTIES:
+:CUSTOM_ID: install
+:END:
+** Install Interactively from MELPA
+:PROPERTIES:
+:CUSTOM_ID: install-interactively-from-melpa
+:END:
+Devil is available via [[https://melpa.org/][MELPA]]. You may already
+have a preferred way of installing packages from MELPA. If so, install
+the package named =devil= to get Devil. For the sake of completeness,
+here is a very basic way of installing Devil from MELPA:
+
+1. Add the following to the Emacs initialization file (i.e., =~/.emacs=
+ or =~/.emacs.d/init.el= or =~/.config/emacs/init.el=):
+
+ #+begin_src sh
+ (require 'package)
+ (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/";)
t)
+ (package-initialize)
+ #+end_src
+
+2. Start Emacs with the updated initialization file and then type these
+ commands:
+
+ #+begin_example
+ M-x package-refresh-contents RET
+ M-x package-install RET devil RET
+ #+end_example
+
+3. Confirm that Devil is installed successfully with this command:
+
+ #+begin_example
+ M-x devil-show-version RET
+ #+end_example
+
+4. Enable Devil mode with this command:
+
+ #+begin_example
+ M-x global-devil-mode RET
+ #+end_example
+
+5. Type =, x , f= and watch Devil translate it to =C-x C-f= and invoke
+ the corresponding command.
+
+** Install Automatically from MELPA
+:PROPERTIES:
+:CUSTOM_ID: install-automatically-from-melpa
+:END:
+Here is yet another basic way to install and enable Devil using Elisp:
+
+#+begin_example
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/";) t)
+(package-initialize)
+(unless package-archive-contents
+ (package-refresh-contents))
+(unless (package-installed-p 'devil)
+ (package-install 'devil))
+(global-devil-mode)
+(global-set-key (kbd "C-,") 'global-devil-mode)
+#+end_example
+
+Now type =, x , f= and watch Devil translate it to =C-x C-f= and invoke
+the corresponding command. Type =C-,= to disable Devil mode. Type =C-,=
+again to enable it.
+
+** Install from Git Source
+:PROPERTIES:
+:CUSTOM_ID: install-from-git-source
+:END:
+If you prefer obtaining Devil from its Git repository, follow these
+steps:
+
+1. Clone Devil to your system:
+
+ #+begin_src sh
+ git clone https://github.com/susam/devil.git
+ #+end_src
+
+2. Add the following to your Emacs initialization:
+
+ #+begin_example
+ (add-to-list 'load-path "/path/to/devil/")
+ (require 'devil)
+ (global-devil-mode)
+ (global-set-key (kbd "C-,") 'global-devil-mode)
+ #+end_example
+
+3. Start the Emacs editor. Devil mode should now be enabled in all
+ buffers. The modeline of each buffer should show the =Devil= lighter.
+
+4. Type =, x , f= and watch Devil translate it to =C-x C-f= and invoke
+ the corresponding command. Type =C-,= to disable Devil mode. Type
+ =C-,= again to enable it.
+
+* Use Devil
+ :PROPERTIES:
+ :CUSTOM_ID: use-devil
+ :END:
+Assuming vanilla Emacs key bindings have not been changed and Devil has
+not been customised, here are some examples that demonstrate how Devil
+may be used:
+
+1. Type =, x , f= and watch Devil translate it to =C-x C-f= and invoke
+ the find file functionality.
+
+2. Type =, p= to move up one line.
+
+3. To move up multiple lines, type =, p p p= and so on. Some Devil key
+ sequences are repeatable keys. The repeatable Devil key sequences can
+ be repeated by typing the last key of the Devil key sequence over and
+ over again.
+
+4. Another example of a repeatable Devil key sequence is =, f f f= which
+ moves the cursor word by multiple characters. A few other examples of
+ repeatable keys are =, k k k= to kill lines, =, / / /= to undo
+ changs, etc. Type =C-h v devil-repeatable-keys RET= to see the
+ complete list of repeatable keys.
+
+5. Type =, s= and watch Devil translate it to =C-s= and invoke
+ incremental search.
+
+6. Type =, m s= and watch Devil translate it to =C-M-s= and invoke
+ regular-expression-based incremental search. Yes, =m= is translated
+ to =M-=.
+
+7. Type =, m m x= and watch Devil translate it to =M-x= and invoke the
+ corresponding command.
+
+8. Type =, u , f= and watch Devil translate it to =C-u C-f= and move the
+ cursor forward by 4 characters.
+
+9. Type =, u u , f= and the cursor moves forward by 16 characters. Devil
+ uses its translation rules and an additional keymap to make the input
+ key sequence behave like =C-u C-u C-f= which moves the cursor forward
+ by 16 characters.
+
+10. Type =, SPC= to type a comma followed by space. This is a special
+ key sequence to make it convenient to type a comma in the text. Note
+ that this sacrifices the use of =, SPC= to mean =C-SPC= which could
+ have been a convenient way to set a mark.
+
+11. Type =, z SPC= and watch Devil translate it to =C-SPC= and set a
+ mark. Yes, =, z= is translated to =C-= too.
+
+12. Similarly, type =, RET= to type a comma followed by the return key.
+ This is another special key.
+
+13. Type =, ,= to type a single comma. This special key is useful for
+ cases when you really need to type a single literal comma.
+
+* Typing Commas
+ :PROPERTIES:
+ :CUSTOM_ID: typing-commas
+ :END:
+Devil makes the questionable choice of using the comma as its activation
+key. As illustrated in the previous section, typing =, x , f= produces
+the same effect as typing =C-x C-f=. One might naturally wonder how then
+we are supposed to type literal commas.
+
+Most often when we edit text, we do not really type a comma in
+isolation. Often we immediately follow the comma with a space or a
+newline. This assumption usually holds good while editing regular text.
+However, this assumption may not hold in some situations, like while
+working with code when we need to add a single comma at the end of an
+existing line.
+
+In scenarios where the above assumption holds good, typing =, SPC=
+inserts a comma and a space. Similarly, typing =, RET= inserts a comma
+and a newline.
+
+In scenarios, when we do need to type a single comma, type =, ,=
+instead.
+
+Also, it is worth mentioning here that if all this fiddling with the
+comma key feels clumsy, we could always customise the Devil key to
+something else that feels better. We could also disable Devil mode
+temporarily and enable it again later with =C-,= as explained in section
+[[#use-devil][Use Devil]].
+
+* Devil Reader
+ :PROPERTIES:
+ :CUSTOM_ID: devil-reader
+ :END:
+The following points briefly describe how Devil reads Devil key
+sequences, translates them to Emacs key sequences, and runs commands
+bound to the key sequences:
+
+1. As soon as the Devil key is typed (which is =,= by default), Devil
+ wakes up and starts reading Devil key sequences. Type
+ =C-h v devil-key RET= to see the current Devil key.
+
+2. After each keystroke is read, Devil checks if the key sequence
+ accumulated is a special key. If it is, then the special command
+ bound to the special key is executed immediately. Note that this step
+ is performed before any translation rules are applied to the input
+ key sequence. This is how the Devil special key sequence =, SPC=
+ inserts a comma and a space. Type =C-h v devil-special-keys RET=
+ to see the list of special keys and the commands bound to them.
+
+3. If the key sequence accumulated so far is not a special key, then
+ Devil translates the Devil key sequence to a regular Emacs key
+ sequence. If the regular Emacs key sequence turns out to be a
+ complete key sequence and some command is found to be bound to it,
+ then that command is executed immediately. This is how the Devil key
+ sequence =, x , f= is translated to =C-x C-f= and the corresponding
+ binding is executed. If the translated key sequence is a complete key
+ sequence but no command is bound to it, then Devil displays a message
+ that the key sequence is undefined. Type
+ =C-h v devil-translations RET= to see the list of translation rules.
+
+4. After successfully translating a Devil key sequence to an Emacs key
+ sequence and executing the command bound to it, Devil checks if the
+ key sequence is a repeatable key sequence. If it is found to be a
+ repeatable key sequence, then Devil sets a transient map so that the
+ command can be repeated merely by typing the last keystroke of the
+ input key sequence. This is how =, p p p= moves the cursor up by
+ three lines. Type =C-h v devil-repeatable-keys RET= to see the
+ list of repeatable Devil key sequences.
+
+The variables =devil-special-keys=, =devil-translations=, and
+=devil-repeatable-keys= may contain keys or values with the string =%k=
+in them. This is a placeholder for =devil-key=. While applying the
+special keys, translation rules, or repeat rules, each =%k= is replaced
+with the actual value of =devil-key= before applying the rules.
+
+* Translation Rules
+ :PROPERTIES:
+ :CUSTOM_ID: translation-rules
+ :END:
+The following points provide an account of the translation rules that
+Devil follows in order to convert a Devil key sequence entered by the
+user to an Emacs key sequence:
+
+1. The input key vector read from the user is converted to a key
+ description (i.e., the string functions like =describe-key=,
+ =key-description=, produce). For example, if the user types ,x,f, it
+ is converted to =, x , f=.
+
+2. Now the resulting key description is translated with simple string
+ replacements. If any part of the string matches a key in
+ =devil-translations=, then it is replaced with the corresponding
+ value. For example, =, x , f= is translated to =C- x C- f=. Then
+ Devil normalises the result to =C-x C-f= by removing superfluous
+ spaces after the modifier keys.
+
+3. However, if the simple string based replacement leads to an invalid
+ Emacs key sequence, it skips the replacement that causes the
+ resulting Emacs key sequence to become invalid. For example
+ =, m ,= results in =C-M-C-= after the simple string replacement
+ because the default translation rules replace =,= with =C-= and =m=
+ with =M-=. However, =C-M-C-= is an invalid key sequence, so the
+ replacement of the second =,= to =C-= is skipped. Therefore, the
+ input =, m ,= is translated to =C-M-,= instead.
+
+* Translation Examples
+ :PROPERTIES:
+ :CUSTOM_ID: translation-examples
+ :END:
+By default, Devil supports a small but peculiar set of translation rules
+that can be used to avoid modifier keys while typing various types of
+key sequences. See =C-h v devil-translations RET= for the translation
+rules. Here are some examples that demonstrate the default translation
+rules. The obvious ones are shown first first. The more peculiar
+translations come later in the table.
+
+| Input | Translated | Remarks |
+|-----------+------------+-----------------------------------|
+| =, s= | =C-s= | =,= is replaced with =C-= |
+| =, m s= | =C-M-s= | =m= is replaced with =M-= |
+| =, z s= | =C-SPC= | =, z= is replaced with =C-= too |
+| =, z z= | =C-z= | ditto |
+| =, m m x= | =M-x= | =, m m= is replaced with =M-= too |
+| =, c , ,= | =C-c ,= | =, ,= is replaced with =,= |
+
+Note how we cannot use =, SPC= to set a mark because that key sequence
+is already reserved as a special key sequence in =devil-special-keys=,
+so Devil translates =, z= to =C-= too, so that we can still type =C-SPC=
+using =, z s= and set a mark.
+
+Also, note how the translation of =, m m= to =M-= allows us to enter a
+key sequence that begins with the =M-= modifier key.
+
+* Bonus Key Bindings
+ :PROPERTIES:
+ :CUSTOM_ID: bonus-key-bindings
+ :END:
+Devil adds the following additional key bindings only when Devil is
+enabled globally with =global-devil-mode=:
+
+- Adds the Devil key to =isearch-mode-map=, so that Devil key sequences
+ work in incremental search too.
+
+- Adds =u= to =universal-argument-more= to allow repeating the universal
+ argument command =C-u= simply by repeating =u=.
+
+As mentioned before these features are available only when Devil is
+enabled globally with =global-devil-mode=. If Devil is enabled locally
+with =devil-mode=, then these features are not available.
+
+* Custom Configuration Examples
+ :PROPERTIES:
+ :CUSTOM_ID: custom-configuration-examples
+ :END:
+In the examples presented below, the =(require 'devil)= calls may be
+omitted if Devil has been installed from MELPA. There are appropriate
+autoloads in place in the Devil package that would ensure that it is
+loaded automatically on enabling Devil mode. However, the =require=
+calls have been included in the examples below for the sake of
+completeness.
+
+** Local Mode
+ :PROPERTIES:
+ :CUSTOM_ID: local-mode
+ :END:
+While the section [[#use-devil][Use Devil]] shows how we enable Devil mode
globally,
+this section shows how we can enable it locally. Here is an example
+initialization code that enables Devil locally only in text buffers.
+
+#+begin_example
+(require 'devil)
+(add-hook 'text-mode-hook 'devil-mode)
+(global-set-key (kbd "C-,") 'devil-mode)
+#+end_example
+
+This is not recommended though because this does not provide a seamless
+Devil experience. For example, with Devil enabled locally in a text
+buffer like this, although we can type =, x , f= to launch the find-file
+minibuffer, we cannot use Devil key sequences in the minibuffer. Further
+the special keymaps described in the previous section work only when
+Devil is enabled globally.
+
+** Custom Appearance
+ :PROPERTIES:
+ :CUSTOM_ID: custom-appearance
+ :END:
+The following initialization code shows how we can customise Devil to
+show a Devil smiley (😈) in the modeline and the echo area.
+
+#+begin_example
+(require 'devil)
+(setq devil-lighter " \U0001F608")
+(setq devil-prompt "\U0001F608 %t")
+(global-devil-mode)
+(global-set-key (kbd "C-,") 'global-devil-mode)
+#+end_example
+
+This is how Emacs may look if emojis are rendered correctly:
+
+[[https://i.imgur.com/oYtwnGi.png][[[https://i.imgur.com/oYtwnGi.png]]]]
+
+** Custom Devil Key
+ :PROPERTIES:
+ :CUSTOM_ID: custom-devil-key
+ :END:
+The following initialization code shows how we can customise Devil to
+use a different Devil key.
+
+#+begin_example
+(defvar devil-key "<left>")
+(defvar devil-special-keys '(("%k %k" . (lambda () (interactive)
(devil-run-key "%k")))))
+(require 'devil)
+(global-devil-mode)
+(global-set-key (kbd "C-<left>") 'global-devil-mode)
+#+end_example
+
+The above example sets the Devil key to the left arrow key, perhaps
+another dubious choice for the Devil key. With this configuration, we
+can use =<left> x <left> f= and have Devil translate it to =C-x C-f=.
+
+Additionally, the above example defines the =devil-special-keys=
+variable to have a single entry that allows typing =<left> <left>= to
+produce the same effect as the original =<left>=. It removes the other
+entries, so that =<left> SPC= is no longer reserved as a special key.
+Thus =<left> SPC= can now be used to set a mark like one would normally
+expect.
+
+** Multiple Devil Keys
+ :PROPERTIES:
+ :CUSTOM_ID: multiple-devil-keys
+ :END:
+While this package provides the comma (=,=) as the default and the only
+Devil key, nothing stops you from extending the mode map to support
+multiple Devil keys. Say, you decide that in addition to activating
+Devil with =,= which also plays the role of =C-=, you also want to
+activate Devil with =.= which must now play the role of =M-=. To achieve
+such a result, you could use this initialization code as a starting
+point and then customise it further based on your requirements:
+
+#+begin_example
+(defvar devil-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd ",") #'devil)
+ (define-key map (kbd ".") #'devil)
+ map))
+(defvar devil-special-keys '((", ," . (lambda () (insert ",")))
+ (". ." . (lambda () (insert ".")))))
+(defvar devil-translations '(("," . "C-")
+ ("." . "M-")))
+(require 'devil)
+(global-devil-mode)
+#+end_example
+
+With this configuration, we can type =, x , f= for =C-x C-f= like
+before. But now we can also type =. x= for =M-x=. Similarly, we can type
+=, . s= for =C-M-s= and so on. Further, =, ,= inserts a literal comma
+and =. .= inserts a literal dot.
+
+Note that by default Devil configures only one activation key (=,=)
+because the more activation keys we add, the more intrusive Devil
+becomes during regular editing tasks. Every key that we reserve for
+activating Devil loses its default function and then we need workarounds
+to somehow invoke the default function associated with that key (like
+repeating =.= twice to insert a single =.= in the above example).
+Therefore, it is a good idea to keep the number of Devil keys as small
+as possible.
+
+* Why?
+ :PROPERTIES:
+ :CUSTOM_ID: why
+ :END:
+Why go to the trouble of creating and using something like this? Why not
+just remap caps lock to ctrl like every other sane person does? Or if it
+is so important to avoid modifier keys, why not use something like God
+mode or Evil mode?
+
+Well, for one, both God mode and Evil mode are modal editing modes.
+Devil, on the other hand, provides a modeless editing experience of
+Emacs as possible.
+
+Devil mode began as a fun little tiny experiment. From the outset, it
+was clear that using something as crucial as the comma for specifying
+the modifier key is asking for trouble. However, I still wanted to see
+how far I could go with it. It turned out that in a matter of days, I
+was using it full-time for all of my Emacs usage.
+
+This experiment was partly motivated by Macbook keyboards which do not
+have a right ctrl key. Being a touch-typist myself, I found it
+inconvenient to type key combinations like =C-x=, =C-a=, =C-w=, =C-s=,
+etc. where both the modifier key and the modified key need to be pressed
+with the left hand fingers. I am not particularly fond of remapping caps
+lock to behave like ctrl because that still suffers from the problem
+that key combinations like =C-x=, =C-a= require pressing both the
+modifier key and the modified key with the left hand fingers. I know
+many people remap both their caps lock and enter to behave like ctrl.
+While I think that is a fine solution, I was not willing to put up with
+the work required to make that work seamlessly across all the various
+operating systems I work on.
+
+What began as a tiny whimsical experiment a few years ago turned out to
+be quite effective, at least to me. I like that this solution is
+implemented purely as Elisp and therefore does not have any external
+dependency. I am sharing this solution here in the form of a minor mode,
+just in case, there is someone out there who might find this useful too.
+
+* Comparison with God Mode
+ :PROPERTIES:
+ :CUSTOM_ID: comparison-with-god-mode
+ :END:
+God mode provides a modal editing experience but Devil does not. Devil
+has the same underlying philosophy as that of God mode, i.e., the user
+should not have to learn new key bindings. However, Devil does not have
+a hard separation between insert mode and command mode like God mode
+has. Instead, Devil waits for an activation key (=,= by default) and as
+soon as it is activated, it intercepts and translates keys, runs the
+corresponding command, and then gets out of the way. So Devil tries to
+retain the modeless editing experience of vanilla Emacs as much as
+possible.
+
+Now it is worth mentioning that some of this modeless editing experience
+can be reproduced in god-mode too using its
+=god-execute-with-current-bindings= function. Here is an example:
+
+#+begin_example
+(global-set-key (kbd ",") #'god-execute-with-current-bindings)
+#+end_example
+
+With this configuration, God mode translates =, x f= to =C-x C-f=.
+Similarly =, g x= invokes =M-x= and =, G s= invokes =C-M-x=. This
+provides a modeless editing experience in God mode too. However, this
+experience does not extend seamlessly to minibuffers. Devil does extend
+its Devil key translation to minibuffers.
+
+Further note that in God mode the ctrl modifier has sticky behaviour,
+i.e., the modifier remains active automatically for the entire key
+sequence. Therefore in the above example, we type =,= only once while
+typing =, x f= to invoke =C-x C-f=. However, this sticky behaviour
+implies that we need some way to disambiguate between key sequences like
+=C-x C-o= (delete blank lines) and =C-x o= (other window). God mode
+solves this by introducing =SPC= to deactivate the modifier, e.g.,
+=, x o= translates to =C-x C-o= but =, x SPC o= translates to =C-x o=.
+Devil does not treat the modifier key as sticky which leads to simpler
+key sequences at the cost of a little additional typing, i.e., =, x , o=
+translates to =C-x C-o= and =, x o= translates to =C-x o=.
+
+To summarize, there are primarily three things that Devil does
+differently:
+
+- Provide a modeless editing experience from the outset.
+- Seamlessly extend the same editing experience to minibuffer,
+ incremental search, etc.
+- Translate key sequences using string replacements. This allows for
+ arbitrary and sophisticated key translations for the adventurous.
+- Choose non-sticky behaviour for the modifier keys.
+
+These differences could make Devil easier to use than God mode for some
+people but clumsy for other people. It depends on one's tastes and
+preferences.
+
+* Support
+ :PROPERTIES:
+ :CUSTOM_ID: support
+ :END:
+To report bugs, suggest improvements, or ask questions,
+[[https://github.com/susam/devil/issues][create issues]].
diff --git a/README.md b/README.md
index 749508cc33..39ef57e36b 100644
--- a/README.md
+++ b/README.md
@@ -13,599 +13,7 @@ charm the Devil! But beware, for in this sinister domain,
you must
relinquish your comma key and embrace an editing experience that
whispers wicked secrets into your fingertips!
-
-Contents
---------
-
-* [Introduction](#introduction)
-* [Notation](#notation)
-* [Install](#install)
- * [Install Interactively from MELPA](#install-interactively-from-melpa)
- * [Install Automatically from MELPA](#install-automatically-from-melpa)
- * [Install from Git Source](#install-from-git-source)
-* [Use Devil](#use-devil)
-* [Typing Commas](#typing-commas)
-* [Devil Reader](#devil-reader)
-* [Translation Rules](#translation-rules)
-* [Translation Examples](#translation-examples)
-* [Bonus Key Bindings](#bonus-key-bindings)
-* [Custom Configuration Examples](#custom-configuration-examples)
- * [Local Mode](#local-mode)
- * [Custom Appearance](#custom-appearance)
- * [Custom Devil Key](#custom-devil-key)
- * [Multiple Devil Keys](#multiple-devil-keys)
-* [Why?](#why)
-* [Comparison with God Mode](#comparison-with-god-mode)
-* [Support](#support)
-* [Channels](#channels)
-* [More](#more)
-
-
-Introduction
-------------
-
-Devil mode intercepts our keystrokes and translates them to Emacs key
-sequences according to a configurable set of translation rules. For
-example, with the default translation rules, when we type `, x , f`,
-Devil translates it to `C-x C-f`.
-
-The choice of the comma key (`,`) to mean the control modifier key
-(`C-`) may seem outrageous. After all, the comma is a very important
-punctuation both in prose as well as in code. Can we really get away
-with using `,` to mean the `C-` modifier? It turns out, this terrible
-idea can be made to work without too much of a hassle. At least it
-works for me! It might work for you too. If it does not, Devil can be
-configured to use another key instead of `,` to mean the `C-`
-modifier. See the section [Custom Devil Key](#custom-devil-key) for an
-example.
-
-A sceptical reader may rightfully ask: If `,` is translated to `C-`,
-how on earth are we going to insert a literal `,` into the text when
-we need to? The section [Typing Commas](#typing-commas) answers this.
-But before we get there, we have some fundamentals to cover. Take the
-plunge and see what unfolds! Maybe you will like this! Maybe you will
-not! If you do not like this, you can always retreat to God mode, Evil
-mode, the vanilla key bindings, or whatever piques your fancy!
-
-
-Notation
---------
-
-A quick note about the notation used in the document: The previous
-example shows that `, x , f` is translated to `C-x C-f`. What this
-really means is that the key sequence
-<kbd>,</kbd><kbd>x</kbd><kbd>,</kbd><kbd>f</kbd> is translated to
-<kbd>ctrl</kbd>+<kbd>x</kbd> <kbd>ctrl</kbd>+<kbd>f</kbd>. We do not
-really type any space after the commas. The key <kbd>,</kbd> is
-directly followed by the key <kbd>x</kbd>. However, the key sequence
-notation used in this document contains spaces between each keystroke.
-This is consistent with how key sequences are represented in Emacs in
-general and how Emacs functions like `key-description`,
-`describe-key`, etc. represent key sequences. When we really need to
-type a space, it is represented as `SPC`.
-
-
-Install
--------
-
-### Install Interactively from MELPA
-
-Devil is available via [MELPA](https://melpa.org/). You may already
-have a preferred way of installing packages from MELPA. If so, install
-the package named `devil` to get Devil. For the sake of completeness,
-here is a very basic way of installing Devil from MELPA:
-
- 1. Add the following to the Emacs initialization file (i.e.,
- `~/.emacs` or `~/.emacs.d/init.el` or `~/.config/emacs/init.el`):
-
- ```sh
- (require 'package)
- (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/";)
t)
- (package-initialize)
- ```
-
- 2. Start Emacs with the updated initialization file and then type
- these commands:
-
- ```
- M-x package-refresh-contents RET
- M-x package-install RET devil RET
- ```
-
- 3. Confirm that Devil is installed successfully with this command:
-
- ```
- M-x devil-show-version RET
- ```
-
- 4. Enable Devil mode with this command:
-
- ```
- M-x global-devil-mode RET
- ```
-
- 4. Type `, x , f` and watch Devil translate it to `C-x C-f` and
- invoke the corresponding command.
-
-
-### Install Automatically from MELPA
-
-Here is yet another basic way to install and enable Devil using Elisp:
-
-```elisp
-(require 'package)
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/";) t)
-(package-initialize)
-(unless package-archive-contents
- (package-refresh-contents))
-(unless (package-installed-p 'devil)
- (package-install 'devil))
-(global-devil-mode)
-(global-set-key (kbd "C-,") 'global-devil-mode)
-```
-
-Now type `, x , f` and watch Devil translate it to `C-x C-f` and
-invoke the corresponding command. Type `C-,` to disable Devil mode.
-Type `C-,` again to enable it.
-
-
-### Install from Git Source
-
-If you prefer obtaining Devil from its Git repository, follow these
-steps:
-
- 1. Clone Devil to your system:
-
- ```sh
- git clone https://github.com/susam/devil.git
- ```
-
- 2. Add the following to your Emacs initialization:
-
- ```elisp
- (add-to-list 'load-path "/path/to/devil/")
- (require 'devil)
- (global-devil-mode)
- (global-set-key (kbd "C-,") 'global-devil-mode)
- ```
-
- 3. Start the Emacs editor. Devil mode should now be enabled in all
- buffers. The modeline of each buffer should show the `Devil`
- lighter.
-
- 4. Type `, x , f` and watch Devil translate it to `C-x C-f` and
- invoke the corresponding command. Type `C-,` to disable Devil
- mode. Type `C-,` again to enable it.
-
-
-Use Devil
----------
-
-Assuming vanilla Emacs key bindings have not been changed and Devil
-has not been customised, here are some examples that demonstrate how
-Devil may be used:
-
- 1. Type `, x , f` and watch Devil translate it to `C-x C-f` and
- invoke the find file functionality.
-
- 2. Type `, p` to move up one line.
-
- 3. To move up multiple lines, type `, p p p` and so on. Some Devil
- key sequences are repeatable keys. The repeatable Devil key
- sequences can be repeated by typing the last key of the Devil key
- sequence over and over again.
-
- 4. Another example of a repeatable Devil key sequence is `, f f f`
- which moves the cursor word by multiple characters. A few other
- examples of repeatable keys are `, k k k` to kill lines, `, / / /`
- to undo changs, etc. Type `C-h v devil-repeatable-keys RET` to see
- the complete list of repeatable keys.
-
- 5. Type `, s` and watch Devil translate it to `C-s` and invoke
- incremental search.
-
- 6. Type `, m s` and watch Devil translate it to `C-M-s` and invoke
- regular-expression-based incremental search. Yes, `m` is
- translated to `M-`.
-
- 7. Type `, m m x` and watch Devil translate it to `M-x` and invoke
- the corresponding command.
-
- 8. Type `, u , f` and watch Devil translate it to `C-u C-f` and move
- the cursor forward by 4 characters.
-
- 9. Type `, u u , f` and the cursor moves forward by 16 characters.
- Devil uses its translation rules and an additional keymap to make
- the input key sequence behave like `C-u C-u C-f` which moves the
- cursor forward by 16 characters.
-
-10. Type `, SPC` to type a comma followed by space. This is a special
- key sequence to make it convenient to type a comma in the text.
- Note that this sacrifices the use of `, SPC` to mean `C-SPC` which
- could have been a convenient way to set a mark.
-
-11. Type `, z SPC` and watch Devil translate it to `C-SPC` and set a
- mark. Yes, `, z` is translated to `C-` too.
-
-12. Similarly, type `, RET` to type a comma followed by the return
- key. This is another special key.
-
-13. Type `, ,` to type a single comma. This special key is useful for
- cases when you really need to type a single literal comma.
-
-
-Typing Commas
--------------
-
-Devil makes the questionable choice of using the comma as its
-activation key. As illustrated in the previous section, typing
-`, x , f` produces the same effect as typing `C-x C-f`. One might
-naturally wonder how then we are supposed to type literal commas.
-
-Most often when we edit text, we do not really type a comma in
-isolation. Often we immediately follow the comma with a space or a
-newline. This assumption usually holds good while editing regular
-text. However, this assumption may not hold in some situations, like
-while working with code when we need to add a single comma at the end
-of an existing line.
-
-In scenarios where the above assumption holds good, typing `, SPC`
-inserts a comma and a space. Similarly, typing `, RET` inserts a comma
-and a newline.
-
-In scenarios, when we do need to type a single comma, type `, ,` instead.
-
-Also, it is worth mentioning here that if all this fiddling with the
-comma key feels clumsy, we could always customise the Devil key to
-something else that feels better. We could also disable Devil mode
-temporarily and enable it again later with `C-,` as explained in
-section [Get Started](#get-started).
-
-
-Devil Reader
-------------
-
-The following points briefly describe how Devil reads Devil key
-sequences, translates them to Emacs key sequences, and runs commands
-bound to the key sequences:
-
- 1. As soon as the Devil key is typed (which is `,` by default), Devil
- wakes up and starts reading Devil key sequences. Type `C-h v
- devil-key RET` to see the current Devil key.
-
- 2. After each keystroke is read, Devil checks if the key sequence
- accumulated is a special key. If it is, then the special command
- bound to the special key is executed immediately. Note that this
- step is performed before any translation rules are applied to the
- input key sequence. This is how the Devil special key sequence `,
- SPC` inserts a comma and a space. Type `C-h v
- devil-special-keys RET` to see the list of special keys and
- the commands bound to them.
-
- 3. If the key sequence accumulated so far is not a special key, then
- Devil translates the Devil key sequence to a regular Emacs key
- sequence. If the regular Emacs key sequence turns out to be a
- complete key sequence and some command is found to be bound to it,
- then that command is executed immediately. This is how the Devil
- key sequence `, x , f` is translated to `C-x C-f` and the
- corresponding binding is executed. If the translated key sequence
- is a complete key sequence but no command is bound to it, then
- Devil displays a message that the key sequence is undefined. Type
- `C-h v devil-translations RET` to see the list of translation
- rules.
-
- 4. After successfully translating a Devil key sequence to an Emacs
- key sequence and executing the command bound to it, Devil checks
- if the key sequence is a repeatable key sequence. If it is found
- to be a repeatable key sequence, then Devil sets a transient map
- so that the command can be repeated merely by typing the last
- keystroke of the input key sequence. This is how `, p p p` moves
- the cursor up by three lines. Type `C-h v devil-repeatable-keys
- RET` to see the list of repeatable Devil key sequences.
-
-The variables `devil-special-keys`, `devil-translations`, and
-`devil-repeatable-keys` may contain keys or values with the string
-`%k` in them. This is a placeholder for `devil-key`. While applying
-the special keys, translation rules, or repeat rules, each `%k` is
-replaced with the actual value of `devil-key` before applying the
-rules.
-
-
-Translation Rules
------------------
-
-The following points provide an account of the translation rules that
-Devil follows in order to convert a Devil key sequence entered by the
-user to an Emacs key sequence:
-
- 1. The input key vector read from the user is converted to a key
- description (i.e., the string functions like `describe-key`,
- `key-description`, produce). For example, if the user types
- <kbd>,</kbd><kbd>x</kbd><kbd>,</kbd><kbd>f</kbd>, it is converted
- to `, x , f`.
-
- 2. Now the resulting key description is translated with simple string
- replacements. If any part of the string matches a key in
- `devil-translations`, then it is replaced with the corresponding
- value. For example, `, x , f` is translated to `C- x C- f`. Then
- Devil normalises the result to `C-x C-f` by removing superfluous
- spaces after the modifier keys.
-
- 3. However, if the simple string based replacement leads to an
- invalid Emacs key sequence, it skips the replacement that causes
- the resulting Emacs key sequence to become invalid. For example `,
- m ,` results in `C-M-C-` after the simple string replacement
- because the default translation rules replace `,` with `C-` and
- `m` with `M-`. However, `C-M-C-` is an invalid key sequence, so
- the replacement of the second `,` to `C-` is skipped. Therefore,
- the input `, m ,` is translated to `C-M-,` instead.
-
-
-Translation Examples
---------------------
-
-By default, Devil supports a small but peculiar set of translation
-rules that can be used to avoid modifier keys while typing various
-types of key sequences. See `C-h v devil-translations RET` for the
-translation rules. Here are some examples that demonstrate the default
-translation rules. The obvious ones are shown first first. The more
-peculiar translations come later in the table.
-
-| Input | Translated | Remarks |
-|-----------|------------|------------------------------------|
-| `, s` | `C-s` | `,` is replaced with `C-` |
-| `, m s` | `C-M-s` | `m` is replaced with `M-` |
-| `, z s` | `C-SPC` | `, z` is replaced with `C-` too |
-| `, z z` | `C-z` | ditto |
-| `, m m x` | `M-x` | `, m m` is replaced with `M-` too |
-| `, c , ,` | `C-c ,` | `, ,` is replaced with `,` |
-
-Note how we cannot use `, SPC` to set a mark because that key sequence
-is already reserved as a special key sequence in `devil-special-keys`,
-so Devil translates `, z` to `C-` too, so that we can still type
-`C-SPC` using `, z s` and set a mark.
-
-Also, note how the translation of `, m m` to `M-` allows us to enter a
-key sequence that begins with the `M-` modifier key.
-
-
-Bonus Key Bindings
-------------------
-
-Devil adds the following additional key bindings only when Devil is
-enabled globally with `global-devil-mode`:
-
-- Adds the Devil key to `isearch-mode-map`, so that Devil key
- sequences work in incremental search too.
-
-- Adds `u` to `universal-argument-more` to allow repeating the
- universal argument command `C-u` simply by repeating `u`.
-
-As mentioned before these features are available only when Devil is
-enabled globally with `global-devil-mode`. If Devil is enabled locally
-with `devil-mode`, then these features are not available.
-
-
-Custom Configuration Examples
------------------------------
-
-In the examples presented below, the `(require 'devil)` calls may be
-omitted if Devil has been installed from MELPA. There are appropriate
-autoloads in place in the Devil package that would ensure that it is
-loaded automatically on enabling Devil mode. However, the `require`
-calls have been included in the examples below for the sake of
-completeness.
-
-
-### Local Mode
-
-While the section [Get Started](#get-started) shows how we enable
-Devil mode globally, this section shows how we can enable it locally.
-Here is an example initialization code that enables Devil locally only
-in text buffers.
-
-```elisp
-(require 'devil)
-(add-hook 'text-mode-hook 'devil-mode)
-(global-set-key (kbd "C-,") 'devil-mode)
-```
-
-This is not recommended though because this does not provide a
-seamless Devil experience. For example, with Devil enabled locally in
-a text buffer like this, although we can type `, x , f` to launch the
-find-file minibuffer, we cannot use Devil key sequences in the
-minibuffer. Further the special keymaps described in the previous
-section work only when Devil is enabled globally.
-
-
-### Custom Appearance
-
-The following initialization code shows how we can customise Devil to
-show a Devil smiley (😈) in the modeline and the echo area.
-
-```elisp
-(require 'devil)
-(setq devil-lighter " \U0001F608")
-(setq devil-prompt "\U0001F608 %t")
-(global-devil-mode)
-(global-set-key (kbd "C-,") 'global-devil-mode)
-```
-
-This is how Emacs may look if emojis are rendered correctly:
-
-[![Screenshot of Emacs with Devil
smiley][smiley-screenshot]][smiley-screenshot]
-
-[smiley-screenshot]: https://i.imgur.com/oYtwnGi.png
-
-
-### Custom Devil Key
-
-The following initialization code shows how we can customise Devil to
-use a different Devil key.
-
-```elisp
-(defvar devil-key "<left>")
-(defvar devil-special-keys '(("%k %k" . (lambda () (interactive)
(devil-run-key "%k")))))
-(require 'devil)
-(global-devil-mode)
-(global-set-key (kbd "C-<left>") 'global-devil-mode)
-```
-
-The above example sets the Devil key to the left arrow key, perhaps
-another dubious choice for the Devil key. With this configuration, we
-can use `<left> x <left> f` and have Devil translate it to `C-x C-f`.
-
-Additionally, the above example defines the `devil-special-keys`
-variable to have a single entry that allows typing `<left> <left>` to
-produce the same effect as the original `<left>`. It removes the other
-entries, so that `<left> SPC` is no longer reserved as a special key.
-Thus `<left> SPC` can now be used to set a mark like one would
-normally expect.
-
-
-### Multiple Devil Keys
-
-While this package provides the comma (`,`) as the default and the
-only Devil key, nothing stops you from extending the mode map to
-support multiple Devil keys. Say, you decide that in addition to
-activating Devil with `,` which also plays the role of `C-`, you also
-want to activate Devil with `.` which must now play the role of `M-`.
-To achieve such a result, you could use this initialization code as a
-starting point and then customise it further based on your
-requirements:
-
-```elisp
-(defvar devil-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd ",") #'devil)
- (define-key map (kbd ".") #'devil)
- map))
-(defvar devil-special-keys '((", ," . (lambda () (insert ",")))
- (". ." . (lambda () (insert ".")))))
-(defvar devil-translations '(("," . "C-")
- ("." . "M-")))
-(require 'devil)
-(global-devil-mode)
-```
-
-With this configuration, we can type `, x , f` for `C-x C-f` like
-before. But now we can also type `. x` for `M-x`. Similarly, we can
-type `, . s` for `C-M-s` and so on. Further, `, ,` inserts a literal
-comma and `. .` inserts a literal dot.
-
-Note that by default Devil configures only one activation key (`,`)
-because the more activation keys we add, the more intrusive Devil
-becomes during regular editing tasks. Every key that we reserve for
-activating Devil loses its default function and then we need
-workarounds to somehow invoke the default function associated with
-that key (like repeating `.` twice to insert a single `.` in the above
-example). Therefore, it is a good idea to keep the number of Devil
-keys as small as possible.
-
-
-Why?
-----
-
-Why go to the trouble of creating and using something like this? Why
-not just remap <kbd>caps lock</kbd> to <kbd>ctrl</kbd> like every
-other sane person does? Or if it is so important to avoid modifier
-keys, why not use something like God mode or Evil mode?
-
-Well, for one, both God mode and Evil mode are modal editing modes.
-Devil, on the other hand, provides a modeless editing experience of
-Emacs as possible.
-
-Devil mode began as a fun little tiny experiment. From the outset, it
-was clear that using something as crucial as the comma for specifying
-the modifier key is asking for trouble. However, I still wanted to see
-how far I could go with it. It turned out that in a matter of days, I
-was using it full-time for all of my Emacs usage.
-
-This experiment was partly motivated by Macbook keyboards which do not
-have a right <kbd>ctrl</kbd> key. Being a touch-typist myself, I found
-it inconvenient to type key combinations like `C-x`, `C-a`, `C-w`,
-`C-s`, etc. where both the modifier key and the modified key need to
-be pressed with the left hand fingers. I am not particularly fond of
-remapping <kbd>caps lock</kbd> to behave like <kbd>ctrl</kbd> because
-that still suffers from the problem that key combinations like `C-x`,
-`C-a` require pressing both the modifier key and the modified key with
-the left hand fingers. I know many people remap both their <kbd>caps
-lock</kbd> and <kbd>enter</kbd> to behave like <kbd>ctrl</kbd>. While
-I think that is a fine solution, I was not willing to put up with the
-work required to make that work seamlessly across all the various
-operating systems I work on.
-
-What began as a tiny whimsical experiment a few years ago turned out
-to be quite effective, at least to me. I like that this solution is
-implemented purely as Elisp and therefore does not have any external
-dependency. I am sharing this solution here in the form of a minor
-mode, just in case, there is someone out there who might find this
-useful too.
-
-
-Comparison with God Mode
-------------------------
-
-God mode provides a modal editing experience but Devil does not. Devil
-has the same underlying philosophy as that of God mode, i.e., the user
-should not have to learn new key bindings. However, Devil does not
-have a hard separation between insert mode and command mode like God
-mode has. Instead, Devil waits for an activation key (`,` by default)
-and as soon as it is activated, it intercepts and translates keys,
-runs the corresponding command, and then gets out of the way. So Devil
-tries to retain the modeless editing experience of vanilla Emacs as
-much as possible.
-
-Now it is worth mentioning that some of this modeless editing
-experience can be reproduced in god-mode too using its
-`god-execute-with-current-bindings` function. Here is an example:
-
-```elisp
-(global-set-key (kbd ",") #'god-execute-with-current-bindings)
-```
-
-With this configuration, God mode translates `, x f` to `C-x C-f`.
-Similarly `, g x` invokes `M-x` and `, G s` invokes `C-M-x`. This
-provides a modeless editing experience in God mode too. However, this
-experience does not extend seamlessly to minibuffers. Devil does
-extend its Devil key translation to minibuffers.
-
-Further note that in God mode the <kbd>ctrl</kbd> modifier has sticky
-behaviour, i.e., the modifier remains active automatically for the
-entire key sequence. Therefore in the above example, we type `,` only
-once while typing `, x f` to invoke `C-x C-f`. However, this sticky
-behaviour implies that we need some way to disambiguate between key
-sequences like `C-x C-o` (delete blank lines) and `C-x o` (other
-window). God mode solves this by introducing `SPC` to deactivate the
-modifier, e.g., `, x o` translates to `C-x C-o` but `, x SPC o`
-translates to `C-x o`. Devil does not treat the modifier key as sticky
-which leads to simpler key sequences at the cost of a little
-additional typing, i.e., `, x , o` translates to `C-x C-o` and `, x o`
-translates to `C-x o`.
-
-To summarize, there are primarily three things that Devil does
-differently:
-
- - Provide a modeless editing experience from the outset.
- - Seamlessly extend the same editing experience to minibuffer,
- incremental search, etc.
- - Translate key sequences using string replacements. This allows for
- arbitrary and sophisticated key translations for the adventurous.
- - Choose non-sticky behaviour for the modifier keys.
-
-These differences could make Devil easier to use than God mode for
-some people but clumsy for other people. It depends on one's tastes
-and preferences.
-
-
-Support
--------
-
-To report bugs, suggest improvements, or ask questions,
-[create issues][ISSUES].
-
-[ISSUES]: https://github.com/susam/devil/issues
-
+Read the [manual](./MANUAL.org) for more details on how to use Devil.
Channels
--------
- [nongnu] elpa/devil a98cb1a7bd 09/49: Automatically detect the activation key, (continued)
- [nongnu] elpa/devil a98cb1a7bd 09/49: Automatically detect the activation key, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 21eeb196f7 10/49: Explain how to configure multiple Devil keys, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 1cf89ce338 11/49: Add yank-pop as a repeatable command, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 402dcfd7fb 13/49: Fix repeatable key sequence for yank-pop, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil ef5449deda 16/49: Add kill-line and undo to repeatable keys, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 02464b7516 18/49: Explain why a single activation key is the default, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 4b1eba8a1c 24/49: Add stricter validation of translated key sequence, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 6943ff3e82 28/49: Remove custom version command., ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 459ce032e4 32/49: * devil.el (devil--log-command-loop-info): Use a single 'format', ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil fa6eb0a319 33/49: Move tests to separate file using ERT, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 355bcc9c14 34/49: Extract most of the README into a separate manual,
ELPA Syncer <=
- [nongnu] elpa/devil 79fd50fe22 36/49: Set version to 0.3.0, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil c60437c11b 39/49: Support making all key sequences repeatable, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil f6ddd7cac1 38/49: Fix undefined error for RET, <f10>, etc., ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 72ce585e59 42/49: Document devil-all-keys-repeatable in the manual, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 305a41dc55 45/49: Add MELPA badges, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 2fe542cbc6 46/49: Mention Emacs at the beginning of documentation, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil b84cd61eec 40/49: Format .org files consistently, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil a42a778ec3 43/49: Add devil-all-keys-repeatable to changelog, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil 1ddc4dc2e3 44/49: Fix key translation for key vector as Devil key, ELPA Syncer, 2023/05/15
- [nongnu] elpa/devil fbc422c666 20/49: Add steps to install Devil from MELPA, ELPA Syncer, 2023/05/15