NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
keymap.c File Reference

Keymap handling. More...

#include "config.h"
#include <ctype.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "mutt/lib.h"
#include "gui/lib.h"
#include "keymap.h"
+ Include dependency graph for keymap.c:

Go to the source code of this file.

Functions

struct Mappingkeymap_get_key_names (void)
 Get the KeyNames lookup table.
 
struct Keymapkeymap_alloc (size_t len, keycode_t *keys)
 Allocate space for a sequence of keys.
 
void keymap_free (struct Keymap **pptr)
 Free a Keymap.
 
void keymaplist_free (struct KeymapList *kml)
 Free a List of Keymaps.
 
struct Keymapkeymap_compare (struct Keymap *km1, struct Keymap *km2, size_t *pos)
 Compare two keymaps' keyscodes and return the bigger one.
 
void keymap_get_name (int c, struct Buffer *buf)
 Get the human name for a key.
 
bool keymap_expand_key (struct Keymap *km, struct Buffer *buf)
 Get the key string bound to a Keymap.
 
void keymap_expand_string (const char *str, struct Buffer *buf)
 Get a human-readable key string.
 
int parse_fkey (char *str)
 Parse a function key string.
 
int parse_keycode (const char *str)
 Parse a numeric keycode.
 
size_t parse_keys (const char *str, keycode_t *d, size_t max)
 Parse a key string into key codes.
 

Variables

static struct Mapping KeyNames []
 Key name lookup table.
 

Detailed Description

Keymap handling.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file keymap.c.

Function Documentation

◆ keymap_get_key_names()

struct Mapping * keymap_get_key_names ( void )

Get the KeyNames lookup table.

Return values
ptrKeyNames array

Definition at line 119 of file keymap.c.

120{
121 return KeyNames;
122}
static struct Mapping KeyNames[]
Key name lookup table.
Definition keymap.c:42
+ Here is the caller graph for this function:

◆ keymap_alloc()

struct Keymap * keymap_alloc ( size_t len,
keycode_t * keys )

Allocate space for a sequence of keys.

Parameters
lenNumber of keys
keysArray of keys
Return values
ptrSequence of keys

Definition at line 130 of file keymap.c.

131{
132 struct Keymap *km = MUTT_MEM_CALLOC(1, struct Keymap);
133
134 km->len = len;
136 memcpy(km->keys, keys, len * sizeof(keycode_t));
137
138 return km;
139}
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition keymap.h:31
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
A keyboard mapping.
Definition keymap.h:43
keycode_t * keys
Key sequence.
Definition keymap.h:49
short len
Length of key sequence (unit: sizeof (keycode_t))
Definition keymap.h:48
+ Here is the caller graph for this function:

◆ keymap_free()

void keymap_free ( struct Keymap ** pptr)

Free a Keymap.

Parameters
pptrKeymap to free

Definition at line 145 of file keymap.c.

146{
147 if (!pptr || !*pptr)
148 return;
149
150 struct Keymap *km = *pptr;
151 FREE(&km->macro);
152 FREE(&km->desc);
153 FREE(&km->keys);
154
155 FREE(pptr);
156}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
char * macro
Macro expansion (op == OP_MACRO)
Definition keymap.h:44
char * desc
Description of a macro for the help menu.
Definition keymap.h:45
+ Here is the caller graph for this function:

◆ keymaplist_free()

void keymaplist_free ( struct KeymapList * kml)

Free a List of Keymaps.

Parameters
kmlList of Keymaps to free

Definition at line 162 of file keymap.c.

163{
164 struct Keymap *km = NULL;
165 struct Keymap *km_tmp = NULL;
166 STAILQ_FOREACH_SAFE(km, kml, entries, km_tmp)
167 {
168 STAILQ_REMOVE(kml, km, Keymap, entries);
169 keymap_free(&km);
170 }
171}
void keymap_free(struct Keymap **pptr)
Free a Keymap.
Definition keymap.c:145
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ keymap_compare()

struct Keymap * keymap_compare ( struct Keymap * km1,
struct Keymap * km2,
size_t * pos )

Compare two keymaps' keyscodes and return the bigger one.

Parameters
[in]km1First keymap to compare
[in]km2Second keymap to compare
[out]posPosition where the two keycodes differ
Return values
ptrKeymap with a bigger ASCII keycode

Definition at line 180 of file keymap.c.

181{
182 *pos = 0;
183
184 while ((*pos < km1->len) && (*pos < km2->len))
185 {
186 if (km1->keys[*pos] < km2->keys[*pos])
187 return km2;
188
189 if (km1->keys[*pos] > km2->keys[*pos])
190 return km1;
191
192 *pos = *pos + 1;
193 }
194
195 return NULL;
196}
+ Here is the caller graph for this function:

◆ keymap_get_name()

void keymap_get_name ( int c,
struct Buffer * buf )

Get the human name for a key.

Parameters
[in]cKey code
[out]bufBuffer for the result

Definition at line 203 of file keymap.c.

204{
205 const char *name = mutt_map_get_name(c, KeyNames);
206 if (name)
207 {
208 buf_addstr(buf, name);
209 return;
210 }
211
212 if ((c < 256) && (c > -128) && iscntrl((unsigned char) c))
213 {
214 if (c < 0)
215 c += 256;
216
217 if (c < 128)
218 {
219 buf_addch(buf, '^');
220 buf_addch(buf, (c + '@') & 0x7f);
221 }
222 else
223 {
224 buf_add_printf(buf, "\\%d%d%d", c >> 6, (c >> 3) & 7, c & 7);
225 }
226 }
227 else if ((c >= KEY_F0) && (c < KEY_F(256))) /* this maximum is just a guess */
228 {
229 buf_add_printf(buf, "<F%d>", c - KEY_F0);
230 }
231 else if ((c < 256) && (c >= -128) && IsPrint(c))
232 {
233 buf_add_printf(buf, "%c", (unsigned char) c);
234 }
235 else
236 {
237 buf_add_printf(buf, "<%ho>", (unsigned short) c);
238 }
239}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:211
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition mapping.c:42
#define IsPrint(ch)
Definition mbyte.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ keymap_expand_key()

bool keymap_expand_key ( struct Keymap * km,
struct Buffer * buf )

Get the key string bound to a Keymap.

Parameters
[in]kmKeybinding map
[out]bufBuffer for the result
Return values
trueSuccess

Definition at line 247 of file keymap.c.

248{
249 if (!km || !buf)
250 return false;
251
252 for (int i = 0; i < km->len; i++)
253 {
254 keymap_get_name(km->keys[i], buf);
255 }
256
257 return true;
258}
void keymap_get_name(int c, struct Buffer *buf)
Get the human name for a key.
Definition keymap.c:203
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ keymap_expand_string()

void keymap_expand_string ( const char * str,
struct Buffer * buf )

Get a human-readable key string.

Parameters
[in]strRaw key string
[out]bufBuffer for the key string

Definition at line 265 of file keymap.c.

266{
267 if (!str)
268 return;
269
270 for (; *str; str++)
271 {
272 keymap_get_name(*str, buf);
273 }
274}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_fkey()

int parse_fkey ( char * str)

Parse a function key string.

Parameters
strString to parse
Return values
numNumber of the key
-1Error

Given "<f8>", it will return 8.

Definition at line 284 of file keymap.c.

285{
286 char *t = NULL;
287 int n = 0;
288
289 if ((str[0] != '<') || (mutt_tolower(str[1]) != 'f'))
290 return -1;
291
292 for (t = str + 2; *t && mutt_isdigit(*t); t++)
293 {
294 n *= 10;
295 n += *t - '0';
296 }
297
298 if (*t != '>')
299 return -1;
300 return n;
301}
int mutt_tolower(int arg)
Wrapper for tolower(3)
Definition ctype.c:126
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
Definition ctype.c:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_keycode()

int parse_keycode ( const char * str)

Parse a numeric keycode.

Parameters
strString to parse
Return values
numNumber of the key

This function parses the string <NNN> and uses the octal value as the key to bind.

Definition at line 311 of file keymap.c.

312{
313 char *end_char = NULL;
314 long int result = strtol(str + 1, &end_char, 8);
315
316 /* allow trailing whitespace, eg. < 1001 > */
317 while (mutt_isspace(*end_char))
318 end_char++;
319
320 /* negative keycodes don't make sense, also detect overflow */
321 if ((*end_char != '>') || (result < 0) || (result == LONG_MAX))
322 {
323 return -1;
324 }
325
326 return result;
327}
bool mutt_isspace(int arg)
Wrapper for isspace(3)
Definition ctype.c:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_keys()

size_t parse_keys ( const char * str,
keycode_t * d,
size_t max )

Parse a key string into key codes.

Parameters
strKey string
dArray for key codes
maxMaximum length of key sequence
Return values
numLength of key sequence

Definition at line 336 of file keymap.c.

337{
338 int n;
339 size_t len = max;
340 char buf[128] = { 0 };
341 char c;
342 char *t = NULL;
343
344 mutt_str_copy(buf, str, sizeof(buf));
345 char *s = buf;
346
347 while (*s && len)
348 {
349 *d = '\0';
350 if ((*s == '<') && (t = strchr(s, '>')))
351 {
352 t++;
353 c = *t;
354 *t = '\0';
355
357 if (n != -1)
358 {
359 s = t;
360 *d = n;
361 }
362 else if ((n = parse_fkey(s)) > 0)
363 {
364 s = t;
365 *d = KEY_F(n);
366 }
367 else if ((n = parse_keycode(s)) > 0)
368 {
369 s = t;
370 *d = n;
371 }
372
373 *t = c;
374 }
375
376 if (!*d)
377 {
378 *d = (unsigned char) *s;
379 s++;
380 }
381 d++;
382 len--;
383 }
384
385 return max - len;
386}
int parse_fkey(char *str)
Parse a function key string.
Definition keymap.c:284
int parse_keycode(const char *str)
Parse a numeric keycode.
Definition keymap.c:311
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition mapping.c:85
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition string.c:587
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ KeyNames

struct Mapping KeyNames[]
static

Key name lookup table.

Definition at line 42 of file keymap.c.

42 {
43 // clang-format off
44 { "<PageUp>", KEY_PPAGE },
45 { "<PageDown>", KEY_NPAGE },
46 { "<Up>", KEY_UP },
47 { "<Down>", KEY_DOWN },
48 { "<Right>", KEY_RIGHT },
49 { "<Left>", KEY_LEFT },
50 { "<Delete>", KEY_DC },
51 { "<BackSpace>", KEY_BACKSPACE },
52 { "<Insert>", KEY_IC },
53 { "<Home>", KEY_HOME },
54 { "<End>", KEY_END },
55 { "<Enter>", '\n' },
56 { "<Return>", '\r' },
57#ifdef KEY_ENTER
58 { "<KeypadEnter>", KEY_ENTER },
59#else
60 { "<KeypadEnter>", '\n' },
61#endif
62 { "<Esc>", '\033' }, // Escape
63 { "<Tab>", '\t' },
64 { "<Space>", ' ' },
65 { "<Hash>", '#' },
66 { "<Semicolon>", ';' },
67 { "<DoubleQuote>", '"' },
68 { "<Quote>", '\'' },
69 { "<Backslash>", '\\' },
70 { "<Backtick>", '`' },
71 { "<Dollar>", '$' },
72 { "<Less>", '<' },
73 { "<Greater>", '>' },
74#ifdef KEY_BTAB
75 { "<BackTab>", KEY_BTAB },
76#endif
77#ifdef KEY_NEXT
78 { "<Next>", KEY_NEXT },
79#endif
80 /* extensions supported by ncurses. values are filled in during initialization */
81
82 /* CTRL+key */
83 { "<C-Up>", -1 },
84 { "<C-Down>", -1 },
85 { "<C-Left>", -1 },
86 { "<C-Right>", -1 },
87 { "<C-Home>", -1 },
88 { "<C-End>", -1 },
89 { "<C-Next>", -1 },
90 { "<C-Prev>", -1 },
91
92 /* SHIFT+key */
93 { "<S-Up>", -1 },
94 { "<S-Down>", -1 },
95 { "<S-Left>", -1 },
96 { "<S-Right>", -1 },
97 { "<S-Home>", -1 },
98 { "<S-End>", -1 },
99 { "<S-Next>", -1 },
100 { "<S-Prev>", -1 },
101
102 /* ALT+key */
103 { "<A-Up>", -1 },
104 { "<A-Down>", -1 },
105 { "<A-Left>", -1 },
106 { "<A-Right>", -1 },
107 { "<A-Home>", -1 },
108 { "<A-End>", -1 },
109 { "<A-Next>", -1 },
110 { "<A-Prev>", -1 },
111 { NULL, 0 },
112 // clang-format on
113};