NeoMutt  2025-12-11-769-g906513
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

Read/write command history from/to a file. More...

#include <stdbool.h>
#include "functions.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  HistoryEntry
 A line in the History menu. More...
 

Enumerations

enum  HistoryClass {
  HC_EXT_COMMAND , HC_ALIAS , HC_NEO_COMMAND , HC_FILE ,
  HC_PATTERN , HC_OTHER , HC_MAILBOX , HC_MAX ,
  HC_NONE = HC_MAX
}
 Type to differentiate different histories. More...
 
enum  ExpandoDataHistory { ED_HIS_MATCH = 1 , ED_HIS_NUMBER }
 Expando UIDs for History. More...
 

Functions

void mutt_hist_add (enum HistoryClass hclass, const char *str, bool save)
 Add a string to a history.
 
bool mutt_hist_at_scratch (enum HistoryClass hclass)
 Is the current History position at the 'scratch' place?
 
void mutt_hist_cleanup (void)
 Free all the history lists.
 
void mutt_hist_init (void)
 Create a set of empty History ring buffers.
 
char * mutt_hist_next (enum HistoryClass hclass)
 Get the next string in a History.
 
char * mutt_hist_prev (enum HistoryClass hclass)
 Get the previous string in a History.
 
void mutt_hist_read_file (void)
 Read the History from a file.
 
void mutt_hist_reset_state (enum HistoryClass hclass)
 Move the 'current' position to the end of the History.
 
void mutt_hist_save_scratch (enum HistoryClass hclass, const char *str)
 Save a temporary string to the History.
 
int mutt_hist_search (const char *find, enum HistoryClass hclass, struct StringArray *matches)
 Find matches in a history list.
 
void mutt_hist_complete (struct Buffer *buf, enum HistoryClass hclass)
 Complete a string from a history list.
 
int main_hist_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has change - Implements observer_t -.
 
void dlg_history (struct Buffer *buf, struct StringArray *matches)
 Select an item from a history list -.
 

Detailed Description

Read/write command history from/to a file.

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 lib.h.

Enumeration Type Documentation

◆ HistoryClass

Type to differentiate different histories.

Saved lists of recently-used:

Enumerator
HC_EXT_COMMAND 

External commands.

HC_ALIAS 

Aliases.

HC_NEO_COMMAND 

NeoMutt commands.

HC_FILE 

Files.

HC_PATTERN 

Patterns.

HC_OTHER 

Miscellaneous strings.

HC_MAILBOX 

Mailboxes.

HC_MAX 
HC_NONE 

No History.

Definition at line 53 of file lib.h.

54{
56 HC_ALIAS,
58 HC_FILE,
60 HC_OTHER,
62 HC_MAX,
63 HC_NONE = HC_MAX,
64};
@ HC_FILE
Files.
Definition lib.h:58
@ HC_EXT_COMMAND
External commands.
Definition lib.h:55
@ HC_MAILBOX
Mailboxes.
Definition lib.h:61
@ HC_ALIAS
Aliases.
Definition lib.h:56
@ HC_NEO_COMMAND
NeoMutt commands.
Definition lib.h:57
@ HC_NONE
No History.
Definition lib.h:63
@ HC_MAX
Definition lib.h:62
@ HC_PATTERN
Patterns.
Definition lib.h:59
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:60

◆ ExpandoDataHistory

Expando UIDs for History.

See also
ED_HISTORY, ExpandoDomain
Enumerator
ED_HIS_MATCH 

HistoryEntry.history.

ED_HIS_NUMBER 

HistoryEntry.num.

Definition at line 80 of file lib.h.

81{
82 ED_HIS_MATCH = 1,
84};
@ ED_HIS_MATCH
HistoryEntry.history.
Definition lib.h:82
@ ED_HIS_NUMBER
HistoryEntry.num.
Definition lib.h:83

Function Documentation

◆ mutt_hist_add()

void mutt_hist_add ( enum HistoryClass hclass,
const char * str,
bool save )

Add a string to a history.

Parameters
hclassHistory to add to
strString to add
saveShould the changes be saved to file immediately?

Definition at line 469 of file history.c.

470{
471 struct History *h = get_history(hclass);
472 if (!h)
473 return; /* disabled */
474
475 if (str && *str)
476 {
477 int prev = h->last - 1;
478 const short c_history = cs_subset_number(NeoMutt->sub, "history");
479 if (prev < 0)
480 prev = c_history;
481
482 /* don't add to prompt history:
483 * - lines beginning by a space
484 * - repeated lines */
485 if ((*str != ' ') && (!h->hist[prev] || !mutt_str_equal(h->hist[prev], str)))
486 {
487 const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
488 if (c_history_remove_dups)
489 remove_history_dups(hclass, str);
490 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
491 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
492 if (save && (c_save_history != 0) && c_history_file)
493 save_history(hclass, str);
494 mutt_str_replace(&h->hist[h->last++], str);
495 if (h->last > c_history)
496 h->last = 0;
497 }
498 }
499 h->cur = h->last; /* reset to the last entry */
500}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition helpers.c:168
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
static void remove_history_dups(enum HistoryClass hclass, const char *str)
De-dupe the history.
Definition history.c:344
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition history.c:91
static void save_history(enum HistoryClass hclass, const char *str)
Save one history string to a file.
Definition history.c:306
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
Saved list of user-entered commands/searches.
Definition module_data.h:34
short cur
Current history item.
Definition module_data.h:36
short last
Last history item.
Definition module_data.h:37
char ** hist
Array of history items.
Definition module_data.h:35
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_at_scratch()

bool mutt_hist_at_scratch ( enum HistoryClass hclass)

Is the current History position at the 'scratch' place?

Parameters
hclassHistory to use
Return values
trueHistory is at 'scratch' place

The last entry in the history is used as a 'scratch' area. It can be overwritten as the user types and edits.

To get (back) to the scratch area, call mutt_hist_next(), mutt_hist_prev() or mutt_hist_reset_state().

Definition at line 631 of file history.c.

632{
633 struct History *h = get_history(hclass);
634 if (!h)
635 return false; /* disabled */
636
637 return h->cur == h->last;
638}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_cleanup()

void mutt_hist_cleanup ( void )

Free all the history lists.

Definition at line 426 of file history.c.

427{
429 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
430 {
431 struct History *h = &mod_data->histories[hclass];
432 if (!h->hist)
433 continue;
434
435 /* The array has (mod_data->old_size+1) elements */
436 for (int i = 0; i <= mod_data->old_size; i++)
437 {
438 FREE(&h->hist[i]);
439 }
440 FREE(&h->hist);
441 }
442}
HistoryClass
Type to differentiate different histories.
Definition lib.h:54
#define HC_FIRST
Definition history.c:84
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
@ MODULE_ID_HISTORY
ModuleHistory, History
Definition module_api.h:69
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
History private Module data.
Definition module_data.h:44
struct History histories[HC_MAX]
Command histories, one for each HistoryClass.
Definition module_data.h:46
int old_size
The previous number of history entries to save.
Definition module_data.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_init()

void mutt_hist_init ( void )

Create a set of empty History ring buffers.

This just creates empty histories. To fill them, call mutt_hist_read_file().

Definition at line 450 of file history.c.

451{
453 const short c_history = cs_subset_number(NeoMutt->sub, "history");
454 if (c_history == mod_data->old_size)
455 return;
456
457 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
458 init_history(&mod_data->histories[hclass], mod_data->old_size);
459
460 mod_data->old_size = c_history;
461}
static void init_history(struct History *h, int old_size)
Set up a new History ring buffer.
Definition history.c:109
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_next()

char * mutt_hist_next ( enum HistoryClass hclass)

Get the next string in a History.

Parameters
hclassHistory to choose
Return values
ptrNext string

If there is no next string, and empty string will be returned.

Definition at line 509 of file history.c.

510{
511 struct History *h = get_history(hclass);
512 if (!h)
513 return ""; /* disabled */
514
515 int next = h->cur;
516 const short c_history = cs_subset_number(NeoMutt->sub, "history");
517 do
518 {
519 next++;
520 if (next > c_history)
521 next = 0;
522 if (next == h->last)
523 break;
524 } while (!h->hist[next]);
525
526 h->cur = next;
527 return NONULL(h->hist[h->cur]);
528}
#define NONULL(x)
Definition string2.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_prev()

char * mutt_hist_prev ( enum HistoryClass hclass)

Get the previous string in a History.

Parameters
hclassHistory to choose
Return values
ptrPrevious string

If there is no previous string, and empty string will be returned.

Definition at line 537 of file history.c.

538{
539 struct History *h = get_history(hclass);
540 if (!h)
541 return ""; /* disabled */
542
543 int prev = h->cur;
544 const short c_history = cs_subset_number(NeoMutt->sub, "history");
545 do
546 {
547 prev--;
548 if (prev < 0)
549 prev = c_history;
550 if (prev == h->last)
551 break;
552 } while (!h->hist[prev]);
553
554 h->cur = prev;
555 return NONULL(h->hist[h->cur]);
556}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_read_file()

void mutt_hist_read_file ( void )

Read the History from a file.

The file $history_file is read and parsed into separate History ring buffers.

Definition at line 579 of file history.c.

580{
581 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
582 if (!c_history_file)
583 return;
584
585 FILE *fp = mutt_file_fopen(c_history_file, "r");
586 if (!fp)
587 return;
588
589 int line = 0, hclass = 0, read = 0;
590 char *linebuf = NULL, *p = NULL;
591 size_t buflen;
592
593 const char *const c_charset = cc_charset();
594 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
595 {
596 read = 0;
597 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
598 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
599 {
600 mutt_error(_("%s:%d: Bad history file format"), c_history_file, line);
601 continue;
602 }
603 /* silently ignore too high class (probably newer neomutt) */
604 if (hclass >= HC_MAX)
605 continue;
606 *p = '\0';
607 p = mutt_str_dup(linebuf + read);
608 if (p)
609 {
610 mutt_ch_convert_string(&p, "utf-8", c_charset, MUTT_ICONV_NO_FLAGS);
611 mutt_hist_add(hclass, p, false);
612 FREE(&p);
613 }
614 }
615
616 mutt_file_fclose(&fp);
617 FREE(&linebuf);
618}
const char * cc_charset(void)
Get the cached value of $charset.
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition file.c:678
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition file.h:40
#define mutt_error(...)
Definition logging2.h:94
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition history.c:469
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition charset.c:817
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition charset.h:66
#define _(a)
Definition message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_reset_state()

void mutt_hist_reset_state ( enum HistoryClass hclass)

Move the 'current' position to the end of the History.

Parameters
hclassHistory to reset

After calling mutt_hist_next() and mutt_hist_prev(), this function resets the current position ('cur' pointer).

Definition at line 565 of file history.c.

566{
567 struct History *h = get_history(hclass);
568 if (!h)
569 return; /* disabled */
570
571 h->cur = h->last;
572}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_save_scratch()

void mutt_hist_save_scratch ( enum HistoryClass hclass,
const char * str )

Save a temporary string to the History.

Parameters
hclassHistory to alter
strString to set

Write a 'scratch' string into the History's current position. This is useful to preserver a user's edits.

Definition at line 648 of file history.c.

649{
650 struct History *h = get_history(hclass);
651 if (!h)
652 return; /* disabled */
653
654 /* Don't check if str has a value because the scratch buffer may contain
655 * an old garbage value that should be overwritten */
656 mutt_str_replace(&h->hist[h->last], str);
657}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_search()

int mutt_hist_search ( const char * find,
enum HistoryClass hclass,
struct StringArray * matches )

Find matches in a history list.

Parameters
[in]findString to find
[in]hclassHistory list
[out]matchesAll the matching lines
Return values
numMatches found

Definition at line 394 of file history.c.

395{
396 if (!find || !matches)
397 return 0;
398
399 struct History *h = get_history(hclass);
400 if (!h)
401 return 0;
402
403 int cur = h->last;
404 const short c_history = cs_subset_number(NeoMutt->sub, "history");
405
406 do
407 {
408 cur--;
409 if (cur < 0)
410 cur = c_history;
411
412 if (cur == h->last)
413 break;
414
415 if (mutt_istr_find(h->hist[cur], find))
416 ARRAY_ADD(matches, h->hist[cur]);
417
418 } while (ARRAY_SIZE(matches) < c_history);
419
420 return ARRAY_SIZE(matches);
421}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition string.c:528
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_complete()

void mutt_hist_complete ( struct Buffer * buf,
enum HistoryClass hclass )

Complete a string from a history list.

Parameters
bufBuffer in which to save string
hclassHistory list to use

Definition at line 664 of file history.c.

665{
666 struct StringArray matches = ARRAY_HEAD_INITIALIZER;
667
668 int match_count = mutt_hist_search(buf_string(buf), hclass, &matches);
669 if (match_count != 0)
670 {
671 if (match_count == 1)
672 {
673 const char **pstr = ARRAY_GET(&matches, 0);
674 buf_strcpy(buf, *pstr);
675 }
676 else
677 {
678 dlg_history(buf, &matches);
679 }
680 }
681
682 ARRAY_FREE(&matches);
683}
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void dlg_history(struct Buffer *buf, struct StringArray *matches)
Select an item from a history list -.
int mutt_hist_search(const char *find, enum HistoryClass hclass, struct StringArray *matches)
Find matches in a history list.
Definition history.c:394
+ Here is the call graph for this function:
+ Here is the caller graph for this function: