NeoMutt  2025-12-11-980-ge38c27
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 (struct HistoryModuleData *mod_data)
 Free all the history lists.
 
void mutt_hist_init (struct HistoryModuleData *mod_data)
 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 54 of file lib.h.

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

◆ ExpandoDataHistory

Expando UIDs for History.

See also
ED_HISTORY, ExpandoDomain
Enumerator
ED_HIS_MATCH 

HistoryEntry.history.

ED_HIS_NUMBER 

HistoryEntry.num.

Definition at line 81 of file lib.h.

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

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 471 of file history.c.

472{
473 struct History *h = get_history(hclass);
474 if (!h)
475 return; /* disabled */
476
477 if (str && *str)
478 {
479 int prev = h->last - 1;
480 const short c_history = cs_subset_number(NeoMutt->sub, "history");
481 if (prev < 0)
482 prev = c_history;
483
484 /* don't add to prompt history:
485 * - lines beginning by a space
486 * - repeated lines */
487 if ((*str != ' ') && (!h->hist[prev] || !mutt_str_equal(h->hist[prev], str)))
488 {
489 const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
490 if (c_history_remove_dups)
491 remove_history_dups(hclass, str);
492 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
493 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
494 if (save && (c_save_history != 0) && c_history_file)
495 save_history(hclass, str);
496 mutt_str_replace(&h->hist[h->last++], str);
497 if (h->last > c_history)
498 h->last = 0;
499 }
500 }
501 h->cur = h->last; /* reset to the last entry */
502}
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:346
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:308
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
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 636 of file history.c.

637{
638 struct History *h = get_history(hclass);
639 if (!h)
640 return false; /* disabled */
641
642 return h->cur == h->last;
643}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_cleanup()

void mutt_hist_cleanup ( struct HistoryModuleData * mod_data)

Free all the history lists.

Parameters
mod_dataHistory module data

Definition at line 429 of file history.c.

430{
431 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
432 {
433 struct History *h = &mod_data->histories[hclass];
434 if (!h->hist)
435 continue;
436
437 /* The array has (mod_data->old_size+1) elements */
438 for (int i = 0; i <= mod_data->old_size; i++)
439 {
440 FREE(&h->hist[i]);
441 }
442 FREE(&h->hist);
443 }
444}
HistoryClass
Type to differentiate different histories.
Definition lib.h:55
#define HC_FIRST
Definition history.c:84
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
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 caller graph for this function:

◆ mutt_hist_init()

void mutt_hist_init ( struct HistoryModuleData * mod_data)

Create a set of empty History ring buffers.

Parameters
mod_dataHistory module data

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

Definition at line 453 of file history.c.

454{
455 const short c_history = cs_subset_number(NeoMutt->sub, "history");
456 if (c_history == mod_data->old_size)
457 return;
458
459 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
460 init_history(&mod_data->histories[hclass], mod_data->old_size);
461
462 mod_data->old_size = c_history;
463}
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 511 of file history.c.

512{
513 struct History *h = get_history(hclass);
514 if (!h)
515 return ""; /* disabled */
516
517 int next = h->cur;
518 const short c_history = cs_subset_number(NeoMutt->sub, "history");
519 do
520 {
521 next++;
522 if (next > c_history)
523 next = 0;
524 if (next == h->last)
525 break;
526 } while (!h->hist[next]);
527
528 h->cur = next;
529 return NONULL(h->hist[h->cur]);
530}
#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 539 of file history.c.

540{
541 struct History *h = get_history(hclass);
542 if (!h)
543 return ""; /* disabled */
544
545 int prev = h->cur;
546 const short c_history = cs_subset_number(NeoMutt->sub, "history");
547 do
548 {
549 prev--;
550 if (prev < 0)
551 prev = c_history;
552 if (prev == h->last)
553 break;
554 } while (!h->hist[prev]);
555
556 h->cur = prev;
557 return NONULL(h->hist[h->cur]);
558}
+ 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 581 of file history.c.

582{
583 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
584 if (!c_history_file)
585 return;
586
587 FILE *fp = mutt_file_fopen(c_history_file, "r");
588 if (!fp)
589 return;
590
591 int line = 0;
592 int hclass = 0;
593 int read = 0;
594 char *linebuf = NULL;
595 char *p = NULL;
596 size_t buflen = 0;
597
598 const char *const c_charset = cc_charset();
599 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NONE)))
600 {
601 read = 0;
602 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
603 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
604 {
605 mutt_error(_("%s:%d: Bad history file format"), c_history_file, line);
606 continue;
607 }
608 /* silently ignore too high class (probably newer neomutt) */
609 if (hclass >= HC_MAX)
610 continue;
611 *p = '\0';
612 p = mutt_str_dup(linebuf + read);
613 if (p)
614 {
615 mutt_ch_convert_string(&p, "utf-8", c_charset, MUTT_ICONV_NONE);
616 mutt_hist_add(hclass, p, false);
617 FREE(&p);
618 }
619 }
620
621 mutt_file_fclose(&fp);
622 FREE(&linebuf);
623}
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:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
@ MUTT_RL_NONE
No flags are set.
Definition file.h:43
#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:471
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition charset.c:819
#define MUTT_ICONV_NONE
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 567 of file history.c.

568{
569 struct History *h = get_history(hclass);
570 if (!h)
571 return; /* disabled */
572
573 h->cur = h->last;
574}
+ 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 653 of file history.c.

654{
655 struct History *h = get_history(hclass);
656 if (!h)
657 return; /* disabled */
658
659 /* Don't check if str has a value because the scratch buffer may contain
660 * an old garbage value that should be overwritten */
661 mutt_str_replace(&h->hist[h->last], str);
662}
+ 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 396 of file history.c.

397{
398 if (!find || !matches)
399 return 0;
400
401 struct History *h = get_history(hclass);
402 if (!h)
403 return 0;
404
405 int cur = h->last;
406 const short c_history = cs_subset_number(NeoMutt->sub, "history");
407
408 do
409 {
410 cur--;
411 if (cur < 0)
412 cur = c_history;
413
414 if (cur == h->last)
415 break;
416
417 if (mutt_istr_find(h->hist[cur], find))
418 ARRAY_ADD(matches, h->hist[cur]);
419
420 } while (ARRAY_SIZE(matches) < c_history);
421
422 return ARRAY_SIZE(matches);
423}
#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 669 of file history.c.

670{
671 struct StringArray matches = ARRAY_HEAD_INITIALIZER;
672
673 int match_count = mutt_hist_search(buf_string(buf), hclass, &matches);
674 if (match_count != 0)
675 {
676 if (match_count == 1)
677 {
678 const char **pstr = ARRAY_GET(&matches, 0);
679 buf_strcpy(buf, *pstr);
680 }
681 else
682 {
683 dlg_history(buf, &matches);
684 }
685 }
686
687 ARRAY_FREE(&matches);
688}
#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:401
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:396
+ Here is the call graph for this function:
+ Here is the caller graph for this function: