LEDITRC(5) File Formats Manual LEDITRC(5)

leditrcconfiguration file for ledit(1)

leditrc is the configuration file for the text editor ledit(1), which can be used to configure the theme and key bindings used.

The description of the format given here is terrible, so it's probably more useful to look at the example config provided in leditrc.example.

The parser recognizes four different types of structures: strings, lists, statements, and assignments.

A string is simply any sequence of characters surrounded by double quotes. Double quotes must be backslash-escaped. If a string does not contain any whitespace or the special characters ‘"’, ‘{’, ‘}’, or ‘=’, the double quotes are not required.

A statement is a sequence of strings, separated by whitespace and all on the same line.

An assignment is of the form ⟨identifier⟩ = ⟨structure⟩, where ⟨identifier⟩ is a string and ⟨structure⟩ is a string or a list.

A list is a sequence of assignments and/or statements that is enclosed by curly braces. The assignments/statements must be separated by newlines.

The configuration file consists of several top-level assignments which are described in the following sections.

Some terminology should probably be explained in order to understand the rest of this manual.

word
Whatever Pango defines a word to be. This probably uses Unicode semantics (UAX #29), but I'm not entirely sure.
bigword
A sequence of non-whitespace characters.
character
A Unicode character. Note that, when used as an argument (for instance when setting a mark), character can mean pretty much any string, as long as it is given to the program in one event. Yes, this is inconsistent and confusing.
grapheme
As defined by Unicode (UAX #29). A grapheme may be composed of multiple Unicode characters. The cursor is only allowed to be at valid grapheme boundaries, but some operations work with characters, while others work with graphemes.
paste buffer
When text is deleted or explicitly copied (yanked), it is written to the paste buffer so that it can be pasted later. The paste buffer is either character or line based, depending on whether the deletion/copying operation was line or character based. If a character based paste buffer is pasted, the text is inserted right at the cursor position. When it is line based, the text is inserted after the line.
softline/hardline
A hardline is an actual line separated from the other lines by a newline character. A softline is a displayed line, but might only be part of a hardline if the text is wrapped. ledit(1) can be in hardline or softline mode. Some commands change their behavior depending on this mode, for instance to move the cursor down a certain number of softlines instead of hardlines.

The theme may be configured by assigning theme to a list of assignments, each of which sets one of the following possible properties. Colors are given in the form #RRGGBB, where the ‘#’ is optional (mainly because ‘#’ also starts comments in the configuration file format).

text-font
Font used for all text. Default: Monospace
text-size
Text size (in points or whatever pango uses). Default: 12
text-fg
Text color in main editing area. Default: #000000
text-bg
Background color in main editing area. Default: #FFFFFF
cursor-fg
Color of text under cursor. Default: #FFFFFF
cursor-bg
Color of text cursor. Default: #000000
selection-fg
Color of selected text. Default: #FFFFFF
selection-bg
Color of selection. Default: #000000
bar-fg
Color of text in status bar/line editor. Default: #000000
bar-bg
Background color of status bar/line editor. Default: #CCCCCC
bar-cursor
Color of text cursor in line editor. Default: #000000
bar-fmt
Format string for the bottom bar. The following substitutions are performed:
%%
The character ‘%’ itself.
%l
The current line index of the cursor (1-indexed).
%b
The current byte index of the cursor (1-indexed). Note that this is really only the raw byte position. There currently is no way to get the unicode character position in the format string.
%k
The current keyboard layout used for mapping keys.
%m
The current mode.
%h
The current hardline/softline mode.
%s
A separator. The remaining space is divided equally between all separators.

Default: %k%s%l,%b%s%m|%h

scrollbar-width
Width of scrollbar in pixels. Default: 10
scrollbar-step
Number of pixels scrolled with each scroll event. Default: 20
scrollbar-bg
Background color of scrollbar. Default: #CCCCCC
scrollbar-fg
Color of scrollbar handle. Default: #000000
highlight-search
Whether entire words should be highlighted when searching or replacing with confirmation (true/false). Note that the mode is automatically switched to visual when this is set and a word needs to be highlighted. This is a bit weird, but in order to keep everything a bit more consistent, selections are curently only allowed in visual mode. Default: false
extra-line-spacing
Extra space between each line (in pixels). Note that this is very rudimentary at the moment. In particular, selections covering multiple lines do not highlight the extra space. Default: 0

The key bindings may be configured by assigning bindings to a list of the following assignments.

language

This is the language string for the key layout, as given by XKB.

basic-keys

This is a list of statements of the form

bind ⟨func_name⟩ [keysym ⟨keysym⟩] [text ⟨text⟩] [catchall] [modes ⟨modes⟩] [mods ⟨mods⟩]

keysym is the symbolic description for a key, text is the text corresponding to a key. catchall is a catchall for any key which can for instance be used to insert text. Note that a key binding containing catchall should always be at the end of the list so it does not prevent any other key bindings from being used.

Exactly one of text, keysym, and catchall must be specified. See KEYSYMS for a list of all currently supported keysyms.

mods specifies modifier keys. The current options are shift, control, mod1, mod3, mod4, mod5, and any. mod1 is usually Alt, mod4 is usually the super key. Note that mod2 and lock are missing because these are usually numlock and caps lock, respectively, which would mess up the key bindings because they would all need to optionally include these. This key handling is currently a bit of a mess because it isn't really clear which modifier keys should be ignored and which shouldn't. As an additional bit of weirdness, control is currently masked out before obtaining the text or symbolic name corresponding to a key because it can cause issues in certain cases (XKB tries to be “smart” and map some keys back to the default language, but that completely messes up all the key handling that ledit(1) does). Oh, one more thing - for keys that are specified with text instead of a keysym, shift is masked out of the current modifier state before checking if it matches the configured state because it is usually included implicitly in the text. Please let me know if you have any ideas how to make the key handling a bit nicer.

modes specifies the allowed modes and can be a combination of normal, visual, and insert.

Multiple mods or modes can be given by joining them with ‘|’.

⟨func_name⟩ may be one of the following functions. The possible modes are listed beside the function names. If num is listed beside the function name, this means that the function supports key repetition (the number can be constructed with the push functions). If char is listed beside the function name, this means that a character must be typed immediately after calling the function (this is used e.g. to get a character when setting a mark).

Functions that overwrite the paste buffer usually only do that in normal and visual mode. It isn't entirely clear what the best behavior here would be.

append-after-cursor [normal, visual, insert]
Move the cursor after the current character and enter insert mode.
append-after-eol [normal, visual, insert]
Move the cursor to the end of the current line and enter insert mode. This function modifies its behavior in softline mode.
append-line-above [normal, visual, insert]
Insert a line before the current line, move the cursor to it, and enter insert mode. This function modifies its behavior in softline mode. Note that even in softline mode, a hardline is inserted, but the insertion position may be different. This may not be entirely logical, but I'm not sure what would be more logical.
append-line-below [normal, visual, insert]
Insert a line after the current line, move the cursor to it, and enter insert mode. This function modifies its behavior in softline mode. Note that even in softline mode, a hardline is inserted, but the insertion position may be different. This may not be entirely logical, but I'm not sure what would be more logical.
change [normal, visual, insert] [num]
In normal and insert mode, delete the text from the current position until the position given by the next motion command and enter insert mode (or just stay in insert mode). In visual mode, delete the selected text and enter insert mode. num is used to influence the next motion command. change itself can also be used as the motion command, in which case the given number of lines is deleted. When that is the case, the behavior is modified in softline mode.
change-to-eol [normal]
Delete the text from the current position until the end of the line and enter insert mode. This function modifies its behavior in softline mode.
clipboard-copy [normal, visual, insert]
Copy the last text that was selected to the clipboard. Note: Due to the way this is currently implemented, text can be copied even if it isn't selected anymore, as long as nothing else has been selected in the meantime. I haven't decided yet if this is a feature or a bug.
clipboard-paste [normal, visual, insert]
Paste the clipboard contents at the current position. In visual mode, the current selection is first deleted. Note: The selection deletion and clipboard insertion are currently registered as two independent undo operations, so undo/redo will only undo/redo one of them at a time. This is a bug, but it is difficult to fix due to the bad design decisions made during the development of ledit(1).
cursor-down [normal, visual, insert] [num]
Move the cursor num lines down. In visual mode, the selection is changed. This function modifies its behavior in softline mode.
cursor-left [normal, visual, insert] [num]
Move the cursor num positions to the left, but only on the same line. In visual mode, the selection is changed. Note that the movement is visual, i.e. it will actually move logically forwards in right-to-left text.
cursor-right [normal, visual, insert] [num]
Move the cursor num positions to the right, but only on the same line. In visual mode, the selection is changed. Note that the movement is visual, i.e. it will actually move logically backwards in right-to-left text.
cursor-to-beginning [normal, visual, insert]
Move the cursor to the beginning of the current line. In visual mode, the selection is changed. This function modifies its behavior in softline mode. See also key-0
cursor-to-first-non-whitespace [normal, visual, insert]
Move the cursor to the first non-whitespace character on the current line. In visual mode, the selection is changed. This function modifies its behavior in softline mode.
cursor-up [normal, visual, insert] [num]
Move the cursor num lines up. In visual mode, the selection is changed. This function modifies its behavior in softline mode.
delete [normal, visual, insert] [num]
In normal or insert mode, delete the text from the current position until the position given by the next motion command. In visual mode, delete the selected text. num is used to influence the next motion command. delete itself can also be used as the motion command, in which case the given number of lines is deleted. When that is the case, the behavior is modified in softline mode.
delete-chars-backwards [normal, insert] [num]
Delete num unicode characters before the cursor, but at most up to the beginning of the current line.
delete-chars-backwards-multiline [normal, insert] [num]
Delete num unicode characters before the cursor, possibly going onto a previous line (the newline counts as one character).
delete-chars-forwards [normal, insert] [num]
Delete num unicode characters after the cursor, but at most up to the end of the current line.
delete-chars-forwards-multiline [normal, insert]
Delete num unicode characters before the cursor, possibly going onto another line (the newline counts as one character).
delete-graphemes-backwards [normal, insert] [num]
Delete num unicode graphemes before the cursor, but at most up to the beginning of the current line.
delete-graphemes-backwards-multiline [normal, insert] [num]
Delete num unicode graphemes before the cursor, possibly going onto a previous line (the newline counts as one grapheme).
delete-graphemes-forwards [normal, insert] [num]
Delete num unicode graphemes after the cursor, but at most up to the end of the current line.
delete-graphemes-forwards-multiline [normal, insert] [num]
Delete num unicode graphemes after the cursor, possibly going onto another line (the newline counts as one grapheme).
delete-to-eol [normal, insert]
Delete everything from the current position to the end of the line. This function modifies its behavior in softline mode.
enter-commandedit [normal, visual, insert]
Open the line editor for typing commands. In visual mode, the selection range is automatically pasted into the line editor so commands can be performed on it.
enter-insert [normal, visual]
Enter insert mode.
enter-searchedit-backwards [normal, insert, visual]
Open the line editor for searching backwards. Note that no regex is currently supported.
enter-searchedit-forwards [normal, insert, visual]
Open the line editor for searching forwards. Note that no regex is currently supported.
enter-visual [normal, insert]
Enter visual mode.
return-to-normal [normal, visual, insert]
Return to normal mode. If already in normal mode, discard all stored previous keys (e.g. key repetition).
find-char-backwards [normal, visual, insert] [num] [char]
Move cursor backward num times to the character given by char. Note that all the find-* functions are weird because the behavior changes slightly depending on the mode they are called in and whether they are used as a motion command for another command like delete. This behavior is approximately copied from vi and/or vim.
find-char-forwards [normal, visual, insert] [num] [char]
Move cursor forward num times to the character given by char. The caveat mentioned for find-char-backwards also applies.
find-next-char-backwards [normal, visual, insert] [num] [char]
Move cursor backward num times to the position after the character given by char. The caveat mentioned for find-char-backwards also applies.
find-next-char-forwards [normal, visual, insert] [num] [char]
Move cursor forward num times to the position before the character given by char. The caveat mentioned for find-char-backwards also applies.
insert-at-beginning [normal]
Move cursor to the beginning of the line and enter insert mode. This function changes its behavior in softline mode.
insert-text [insert]
Insert the typed text at the current cursor position.
join-lines [normal, insert] [num]
Join the current line with the next num lines. Whitespace at the beginning of the joined lines is deleted, but it is ensured that there is always at least a space between two joined lines. Note that this function always works on hard lines, regardless of the current mode.
jump-to-mark [normal, visual, insert] [char]
Jump to the mark given by char. In visual mode, the selection end is moved to the position of the mark.
key-0 [normal, visual, insert]
This is a special function to handle the usual vi behavior of using the key 0 both for moving to the beginning of the line and for adding the digit 0 to the end of the current key repetition number. If there was no previous key or the previous key expects a motion command, cursor-to-beginning is called. If the previous key was a number (i.e. one of the push commands), push-0 is called.
insert-mark [normal, visual, insert] [char]
Insert a mark char with the current position.
move-to-eol [normal, visual, insert]
Move to the end of the current line. In visual mode, the selection end is moved as well. This function modifies its behavior in softline mode.
move-to-line [normal, visual, insert] [num]
Move to line number num. If num is not give, move to the last line in the buffer. In visual mode, the selection end is moved as well.
next-bigword [normal, visual, insert] [num]
Move forward num bigwords. In visual mode, the selection is modified as well.
next-bigword-end [normal, visual, insert] [num]
Move forward num end-of-bigwords. In visual mode, the selection is modified as well.
next-word [normal, visual, insert] [num]
Move forward num words. In visual mode, the selection is modified as well.
next-word-end [normal, visual, insert] [num]
Move forward num end-of-words. In visual mode, the selection is modified as well.
paste-buffer [normal, insert]
Paste text from the paste buffer after the current cursor position if the buffer is character-based and after the current line if it is line-based. Note that this does take into account the hard line/soft line mode, but it behaves a bit weirdly when in soft line mode - it inserts the text after the current soft line but adds newlines on both sides. This behavior may be changed in the future if it turns out there's a more logical behavior for soft line mode.
paste-buffer-backwards [normal, insert]
Paste text from the paste buffer before the current cursor position if the buffer is character-based and before the current line if it is line-based. The quirk for paste-buffer applies here as well.
previous-bigword [normal, visual, insert] [num]
Move backward num bigwords. In visual mode, the selection is modified as well.
previous-word [normal, visual, insert] [num]
Move backward num words. In visual mode, the selection is modified as well.
push-0 [normal, visual, insert]
Add the digit 0 to the end of the current key repetition number. See also key-0
push-1 [normal, visual, insert]
Add the digit 1 to the end of the current key repetition number.
push-2 [normal, visual, insert]
Add the digit 2 to the end of the current key repetition number.
push-3 [normal, visual, insert]
Add the digit 3 to the end of the current key repetition number.
push-4 [normal, visual, insert]
Add the digit 4 to the end of the current key repetition number.
push-5 [normal, visual, insert]
Add the digit 5 to the end of the current key repetition number.
push-6 [normal, visual, insert]
Add the digit 6 to the end of the current key repetition number.
push-7 [normal, visual, insert]
Add the digit 7 to the end of the current key repetition number.
push-8 [normal, visual, insert]
Add the digit 8 to the end of the current key repetition number.
push-9 [normal, visual, insert]
Add the digit 9 to the end of the current key repetition number.
redo [normal, insert] [num]
Redo num operations. Note that this changes depending on the mode. All operations performed in insert mode are considered as one operation when performing redo in normal mode.
repeat-command [normal] [num]
Repeat the previous command num times.

!!!!!!!!!!!!! NOTE/FIXME: This is broken currently. In vi, everything done during insert mode is considered to be one operation, so it counts as one command when using repeat-command. However, since a lot of commands here now work in insert mode as well, that doesn't make much sense anymore. Most of the commands discard the previous key information because that's what should happen in normal mode, and it is not clear what the logical action would be in insert mode.

replace [normal] [char]
Replace the character under the cursor with char.
break-line [normal, insert]
Break the line at the current position, i.e. insert a newline character.
screen-down [normal, insert] [num]
Scroll num screens down.
screen-up [normal, insert] [num]
Scroll num screens up.
scroll-lines-down [normal, insert] [num]
Move num lines down. If count is not given, scroll down the number of lines specified by the last screen-down or screen-up command. If this is the first such command, scroll down half a screen. Note that this command works with soft lines, regardless of the current mode.
scroll-lines-up [normal, insert] [num]
Move num lines up. If count is not given, scroll up the number of lines specified by the last screen-down or screen-up command. If this is the first such command, scroll up half a screen. Note that this command works with soft lines, regardless of the current mode.
scroll-with-cursor-down [normal, insert] [num]
Move num lines down, attempting to leave the cursor in its current line and character position. Note that this command works with soft lines, regardless of the current mode.
scroll-with-cursor-up [normal, insert] [num]
Move num lines up, attempting to leave the cursor in its current line and character position. Note that this command works with soft lines, regardless of the current mode.
search-next [normal, insert, visual]
Move to the next search result.
search-previous [normal, insert, visual]
Move to the previous search result.
show-line [normal, visual, insert]
Show the current file name, whether the buffer has been modified since the last write, and current line number.
switch-selection-end [visual]
Switch the end of the selection that can be moved.
toggle-hard-line-based [normal, visual, insert]
Toggle the line mode between hardline and softline.
uppercase [normal, insert]
 
lowercase [normal, insert]
Replace the character at the current cursor position with the uppercase/lowercase version if it exists. If utf8proc support is not enabled, this will use the standard C library functions () and (), so it will not work with most Unicode characters. Note that even with utf8proc, it will not work in all cases because some characters require more complex handling (e.g. characters that require multiple characters when converted to uppercase), which is not supported.
undo [normal, insert] [num]
Undo num operations. Note that this changes depending on the mode. All operations performed in insert mode are considered as one operation when performing undo in normal mode.
yank [normal, visual, insert] [num]
In normal or insert mode, yank (copy to the paste buffer) the text from the current position until the position given by the next motion command. In visual mode, yank the selected text. num is used to influence the next motion command. yank itself can also be used as the motion command, in which case the given number of lines is yanked. When that is the case, the behavior is modified in softline mode.
yank-lines [normal, insert] [num]
Yank (copy to the paste buffer) num lines. This function modifies its behavior in softline mode.

Note: There are still a lot of weird parts when using functions in modes that they weren't originally designed for (e.g. a lot of them were only made for normal mode but now also work in insert mode). The behavior is not set in stone yet and will probably still change quite a bit based on any feedback I receive.

command-keys

This is the same as basic-keys, except that modes must be a combination of substitute, edit, edit-search, and edit-search-backwards.

substitute is the mode while performing a substitution with confirmation. edit is the mode while typing a command in the line editor. edit-search is the mode while typing a forwards search in the line editor. edit-search-backwards is the mode while typing a backwards search in the line editor.

The possible functions are given in the following list, with the allowed modes listed beside each function.

edit-backspace [edit, edit-search, edit-search-backwards]
Delete one unicode character before the cursor.
edit-cursor-left [edit, edit-search, edit-search-backwards]
Move the cursor one to the left.
edit-cursor-right [edit, edit-search, edit-search-backwards]
Move the cursor one to the right.
edit-cursor-to-beginning [edit, edit-search, edit-search-backwards]
Move the cursor to the beginning of the line.
edit-cursor-to-end [edit, edit-search, edit-search-backwards]
Move the cursor to the end of the line.
edit-delete [edit, edit-search, edit-search-backwards]
Delete one unicode character after the cursor.
edit-discard [edit, edit-search, edit-search-backwards]
Exit the line editor and cancel the search or command.
edit-insert-text [edit, edit-search, edit-search-backwards]
Insert the typed text in the line editor at the current cursor position.
edit-next-command [edit]
Move forwards through the command history.
edit-next-search [edit-search, edit-search-backwards]
Move forwards through the search history.
edit-previous-command [edit]
Move backwards through the command history.
edit-previous-search [edit-search, edit-search-backwards]
Move backwards through the search history.
edit-submit [edit]
Submit the command.
edit-submit-backwards-search [edit-search-backwards]
Submit the search.
edit-submit-search [edit-search]
Submit the search.
substitute-no [substitute]
Reject the current substitution.
substitute-no-all [substitute]
Reject the current substitution and all further ones.
substitute-yes [substitute]
Confirm the current substitution.
substitute-yes-all [substitute]
Confirm the current substitution and all further ones.

Note that the bindings for the substitution commands are also displayed on screen during the substitution. However, only the default English bindings are shown because anything else would require work (and might look very weird if the mapping includes characters like diacritics that can't be displayed properly on their own).

commands

This is a list of statements of the form

bind ⟨func_name⟩ ⟨text⟩

Note that the terminology is currently a bit inconsistent. Sometimes, “commands” refers to the key commands, sometimes to the commands written in the line editor, which are documented in this section.

Also note that the commands which take filenames currently use the entire rest of the line as the filename instead of doing any string parsing. This may be changed in the future.

The possible functions are given in the following list, together with the calling convention when calling them with the configured bindings.

 
⟨binding-text⟩[!] [filename]
Write the buffer to [filename], or, if no filename is given, to the file the buffer was read from. If ‘!’ is specified, the file will be attempted to be written to even if there is something blocking it (e.g. the modified date of the file is newer than it was when it was opened).

 
⟨binding-text⟩[!]
Quit. If ‘!’ is specified, quit even when there are unsaved changes.

 
⟨binding-text⟩[!] [filename]
Write and quit afterwards. The ‘!’ is interpreted as for normal writing.

 
[range]⟨binding-text⟩/pattern/replace/[options]
Substitute pattern with replace in the given line range.

Instead of ‘/’, any other unicode character may be used. The first unicode character after ⟨binding-text⟩ is used as the delimiter.

If no range is given, substitution is only performed on the current line. Note that no regex is currently supported.

The range consists of two line numbers separated by a comma or the special value ‘%’, which refers to the entire file. The following special values are possible instead of writing a line number directly:

The last line in the file.
'mark
The line of the previously set mark ⟨mark⟩. Note that even though marks can theoretically be any string of characters, they are only allowed to be one unicode character if they are used in a range. The special values < and > are possible, which refer to the first and last line, respectively, in the current selection.
The current line.

The options may be a combination of the following:

Perform substitution for all occurrences in the given lines instead of just the first one on each line.
Confirm each substitution before performing it.

 
⟨binding-text⟩
Open a new view. Each view is a window that shows the text in the current buffer, which is synced between the views.
 
⟨binding-text⟩[!]
Close a view. If ‘!’ is given, close the view even it is the last one and there are unsaved changes.

If the bindings configuration or any part of it is left out, the default is used. There are some more specific rules, but I'm too lazy to explain them right now. It is actually possible to overwrite just the default language without changing the bindings, but why would you want to do that?

A language mapping defines a mapping for the text associated with each key or command so the bindings still work with other keyboard layouts. Language mappings may be defined by assigning language-mapping to a list of the following assignments, once for each language. Note that any definition of language-mapping must come after bindings.

language

This is the language string for the key layout, as in bindings.

key-mapping

This is a list of statements of the form

⟨foreign⟩ ⟨native⟩

where ⟨foreign⟩ is the key text in the new language mapping and ⟨native⟩ is the key text given in bindings.

command-mapping

This is the same as key-mapping, but for the commands. Note that only the commands themselves are mapped, but the arguments are left alone. I don't think it makes much sense to try to map those as well - really the only reason for mapping commands is so that it is possible to save and quit with a different keyboard layout. If someone has a good idea for making other commands properly usable with other keyboard mappings, I might consider it, though.

These are the currently supported keysyms. I don't know what a lot of these are supposed to be, they were just copied from the list in the X header files. Let me know if there are any others I should add.

General keys

backspace begin break cancel clear delete down end escape execute find help home insert left linefeed menu mode-switch next num-lock page-down page-up pause print prior redo return right script-switch scroll-lock select space sysreq tab up undo

Function keys

f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35

Keypad keys

kp-0 kp-1 kp-2 kp-3 kp-4 kp-5 kp-6 kp-7 kp-8 kp-9 kp-add kp-begin kp-decimal kp-delete kp-divide kp-down kp-end kp-enter kp-equal kp-f1 kp-f2 kp-f3 kp-f4 kp-home kp-insert kp-left kp-multiply kp-next kp-page-down kp-page-up kp-prior kp-right kp-separator kp-space kp-subtract kp-tab kp-up

Weird keys that I don't know

l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15

See the example configuration file leditrc.example.

ledit(1)

lumidify <nobody@lumidify.org>

October 6, 2023