NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

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

#include <stdbool.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.

Enumerations

enum  HistoryClass {
  HC_CMD, HC_ALIAS, HC_COMMAND, HC_FILE,
  HC_PATTERN, HC_OTHER, HC_MBOX, HC_MAX
}
 Type to differentiate different histories. More...
 

Functions

void mutt_hist_add (enum HistoryClass hclass, const char *str, bool save)
 Add a string to a history. More...
 
bool mutt_hist_at_scratch (enum HistoryClass hclass)
 Is the current History position at the 'scratch' place? More...
 
void mutt_hist_free (void)
 Free all the history lists. More...
 
void mutt_hist_init (void)
 Create a set of empty History ring buffers. More...
 
char * mutt_hist_next (enum HistoryClass hclass)
 Get the next string in a History. More...
 
char * mutt_hist_prev (enum HistoryClass hclass)
 Get the previous string in a History. More...
 
void mutt_hist_read_file (void)
 Read the History from a file. More...
 
void mutt_hist_reset_state (enum HistoryClass hclass)
 Move the 'current' position to the end of the History. More...
 
void mutt_hist_save_scratch (enum HistoryClass hclass, const char *str)
 Save a temporary string to the History. More...
 
int mutt_hist_search (const char *search_buf, enum HistoryClass hclass, char **matches)
 Find matches in a history list. More...
 
void dlg_select_history (char *buf, size_t buflen, char **matches, int match_count)
 Select an item from a history list. More...
 
bool config_init_history (struct ConfigSet *cs)
 Register history config variables - Implements module_init_config_t. More...
 

Variables

short C_History
 Config: Number of history entries to keep in memory per category. More...
 
char * C_HistoryFile
 Config: File to save history in. More...
 
bool C_HistoryRemoveDups
 Config: Remove duplicate entries from the history. More...
 
short C_SaveHistory
 Config: Number of history entries to save per category. More...
 

Detailed Description

Read/write command history from/to a file.

Authors
  • Michael R. Elkins

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_CMD 

External commands.

HC_ALIAS 

Aliases.

HC_COMMAND 

NeoMutt commands.

HC_FILE 

Files.

HC_PATTERN 

Patterns.

HC_OTHER 

Miscellaneous strings.

HC_MBOX 

Mailboxes.

HC_MAX 

Definition at line 52 of file lib.h.

53 {
54  HC_CMD,
55  HC_ALIAS,
56  HC_COMMAND,
57  HC_FILE,
58  HC_PATTERN,
59  HC_OTHER,
60  HC_MBOX,
61  HC_MAX,
62 };
NeoMutt commands.
Definition: lib.h:56
Mailboxes.
Definition: lib.h:60
External commands.
Definition: lib.h:54
Patterns.
Definition: lib.h:58
Aliases.
Definition: lib.h:55
Definition: lib.h:61
Miscellaneous strings.
Definition: lib.h:59
Files.
Definition: lib.h:57

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

465 {
466  struct History *h = get_history(hclass);
467  if (!h)
468  return; /* disabled */
469 
470  if (*str)
471  {
472  int prev = h->last - 1;
473  if (prev < 0)
474  prev = C_History;
475 
476  /* don't add to prompt history:
477  * - lines beginning by a space
478  * - repeated lines */
479  if ((*str != ' ') && (!h->hist[prev] || !mutt_str_equal(h->hist[prev], str)))
480  {
482  remove_history_dups(hclass, str);
483  if (save && (C_SaveHistory != 0) && C_HistoryFile)
484  save_history(hclass, str);
485  mutt_str_replace(&h->hist[h->last++], str);
486  if (h->last > C_History)
487  h->last = 0;
488  }
489  }
490  h->cur = h->last; /* reset to the last entry */
491 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
static void save_history(enum HistoryClass hclass, const char *str)
Save one history string to a file.
Definition: history.c:299
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
static void remove_history_dups(enum HistoryClass hclass, const char *str)
De-dupe the history.
Definition: history.c:347
short C_SaveHistory
Config: Number of history entries to save per category.
Definition: config.c:40
short cur
Definition: history.c:89
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
char * C_HistoryFile
Config: File to save history in.
Definition: config.c:38
bool C_HistoryRemoveDups
Config: Remove duplicate entries from the history.
Definition: config.c:39
short last
Definition: history.c:90
char ** hist
Definition: history.c:88
+ 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 618 of file history.c.

619 {
620  struct History *h = get_history(hclass);
621  if (!h)
622  return false; /* disabled */
623 
624  return h->cur == h->last;
625 }
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
short cur
Definition: history.c:89
short last
Definition: history.c:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_free()

void mutt_hist_free ( void  )

Free all the history lists.

Definition at line 424 of file history.c.

425 {
426  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
427  {
428  struct History *h = &Histories[hclass];
429  if (!h->hist)
430  continue;
431 
432  /* The array has (`$history`+1) elements */
433  for (int i = 0; i <= C_History; i++)
434  {
435  FREE(&h->hist[i]);
436  }
437  FREE(&h->hist);
438  }
439 }
static struct History Histories[HC_MAX]
Definition: history.c:95
#define HC_FIRST
Definition: history.c:79
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
Saved list of user-entered commands/searches.
Definition: history.c:86
HistoryClass
Type to differentiate different histories.
Definition: lib.h:52
#define FREE(x)
Definition: memory.h:40
char ** hist
Definition: history.c:88
Definition: lib.h:61
+ 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 447 of file history.c.

448 {
449  if (C_History == OldSize)
450  return;
451 
452  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
453  init_history(&Histories[hclass]);
454 
455  OldSize = C_History;
456 }
static struct History Histories[HC_MAX]
Definition: history.c:95
#define HC_FIRST
Definition: history.c:79
static int OldSize
Definition: history.c:96
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
static void init_history(struct History *h)
Set up a new History ring buffer.
Definition: history.c:118
HistoryClass
Type to differentiate different histories.
Definition: lib.h:52
Definition: lib.h:61
+ 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 500 of file history.c.

501 {
502  struct History *h = get_history(hclass);
503  if (!h)
504  return ""; /* disabled */
505 
506  int next = h->cur;
507  do
508  {
509  next++;
510  if (next > C_History)
511  next = 0;
512  if (next == h->last)
513  break;
514  } while (!h->hist[next]);
515 
516  h->cur = next;
517  return NONULL(h->hist[h->cur]);
518 }
#define NONULL(x)
Definition: string2.h:37
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
short cur
Definition: history.c:89
short last
Definition: history.c:90
char ** hist
Definition: history.c:88
+ 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 527 of file history.c.

528 {
529  struct History *h = get_history(hclass);
530  if (!h)
531  return ""; /* disabled */
532 
533  int prev = h->cur;
534  do
535  {
536  prev--;
537  if (prev < 0)
538  prev = C_History;
539  if (prev == h->last)
540  break;
541  } while (!h->hist[prev]);
542 
543  h->cur = prev;
544  return NONULL(h->hist[h->cur]);
545 }
#define NONULL(x)
Definition: string2.h:37
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
short cur
Definition: history.c:89
short last
Definition: history.c:90
char ** hist
Definition: history.c:88
+ 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 568 of file history.c.

569 {
570  int line = 0, hclass, read;
571  char *linebuf = NULL, *p = NULL;
572  size_t buflen;
573 
574  if (!C_HistoryFile)
575  return;
576 
577  FILE *fp = mutt_file_fopen(C_HistoryFile, "r");
578  if (!fp)
579  return;
580 
581  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, 0)))
582  {
583  read = 0;
584  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
585  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
586  {
587  mutt_error(_("Bad history file format (line %d)"), line);
588  break;
589  }
590  /* silently ignore too high class (probably newer neomutt) */
591  if (hclass >= HC_MAX)
592  continue;
593  *p = '\0';
594  p = mutt_str_dup(linebuf + read);
595  if (p)
596  {
597  mutt_ch_convert_string(&p, "utf-8", C_Charset, 0);
598  mutt_hist_add(hclass, p, false);
599  FREE(&p);
600  }
601  }
602 
603  mutt_file_fclose(&fp);
604  FREE(&linebuf);
605 }
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:754
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:464
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:667
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_error(...)
Definition: logging.h:84
char * C_HistoryFile
Config: File to save history in.
Definition: config.c:38
#define FREE(x)
Definition: memory.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Definition: lib.h:61
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
+ 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 554 of file history.c.

555 {
556  struct History *h = get_history(hclass);
557  if (!h)
558  return; /* disabled */
559 
560  h->cur = h->last;
561 }
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
short cur
Definition: history.c:89
short last
Definition: history.c:90
+ 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 635 of file history.c.

636 {
637  struct History *h = get_history(hclass);
638  if (!h)
639  return; /* disabled */
640 
641  /* Don't check if str has a value because the scratch buffer may contain
642  * an old garbage value that should be overwritten */
643  mutt_str_replace(&h->hist[h->last], str);
644 }
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
short last
Definition: history.c:90
char ** hist
Definition: history.c:88
+ 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 *  search_buf,
enum HistoryClass  hclass,
char **  matches 
)

Find matches in a history list.

Parameters
[in]search_bufString 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 (!search_buf || !matches)
399  return 0;
400 
401  struct History *h = get_history(hclass);
402  if (!h)
403  return 0;
404 
405  int match_count = 0;
406  int cur = h->last;
407  do
408  {
409  cur--;
410  if (cur < 0)
411  cur = C_History;
412  if (cur == h->last)
413  break;
414  if (mutt_istr_find(h->hist[cur], search_buf))
415  matches[match_count++] = h->hist[cur];
416  } while (match_count < C_History);
417 
418  return match_count;
419 }
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:37
Saved list of user-entered commands/searches.
Definition: history.c:86
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:103
short cur
Definition: history.c:89
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:656
short last
Definition: history.c:90
char ** hist
Definition: history.c:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_history()

void dlg_select_history ( char *  buf,
size_t  buflen,
char **  matches,
int  match_count 
)

Select an item from a history list.

Parameters
[in]bufBuffer in which to save string
[in]buflenBuffer length
[out]matchesItems to choose from
[in]match_countNumber of items

Definition at line 96 of file dlghistory.c.

97 {
98  bool done = false;
99  char title[256];
100 
101  snprintf(title, sizeof(title), _("History '%s'"), buf);
102 
103  struct Menu *menu = mutt_menu_new(MENU_GENERIC);
105  dlg->help_data = HistoryHelp;
106  dlg->help_menu = MENU_GENERIC;
107 
109  menu->title = title;
111 
112  menu->max = match_count;
113  menu->mdata = matches;
114 
115  while (!done)
116  {
117  switch (mutt_menu_loop(menu))
118  {
119  case OP_GENERIC_SELECT_ENTRY:
120  mutt_str_copy(buf, matches[menu->current], buflen);
121  /* fall through */
122 
123  case OP_EXIT:
124  done = true;
125  break;
126  }
127  }
128 
129  mutt_menu_pop_current(menu);
130  mutt_menu_free(&menu);
132 }
History Dialog, dlg_select_history()
Definition: mutt_window.h:82
GUI selectable list of items.
Definition: mutt_menu.h:52
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:134
#define _(a)
Definition: message.h:28
A division of the screen.
Definition: mutt_window.h:115
struct MuttWindow * dialog_create_simple_index(struct Menu *menu, enum WindowType type)
Create a simple index Dialog.
Definition: dialog.c:165
const char * title
Title of this menu.
Definition: mutt_menu.h:54
static void history_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the history list - Implements Menu::make_entry()
Definition: dlghistory.c:81
static const struct Mapping HistoryHelp[]
Help Bar for the History Selection dialog.
Definition: dlghistory.c:44
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:135
void dialog_destroy_simple_index(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: dialog.c:209
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
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:716
int current
Current entry.
Definition: mutt_menu.h:56
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:88
Generic selection list.
Definition: keymap.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ config_init_history()

bool config_init_history ( struct ConfigSet cs)

Register history config variables - Implements module_init_config_t.

Definition at line 64 of file config.c.

65 {
66  return cs_register_variables(cs, HistoryVars, 0);
67 }
struct ConfigDef HistoryVars[]
Definition: config.c:43
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
Register a set of config items.
Definition: set.c:286
+ Here is the call graph for this function:

Variable Documentation

◆ C_History

short C_History

Config: Number of history entries to keep in memory per category.

Definition at line 37 of file config.c.

◆ C_HistoryFile

char* C_HistoryFile

Config: File to save history in.

Definition at line 38 of file config.c.

◆ C_HistoryRemoveDups

bool C_HistoryRemoveDups

Config: Remove duplicate entries from the history.

Definition at line 39 of file config.c.

◆ C_SaveHistory

short C_SaveHistory

Config: Number of history entries to save per category.

Definition at line 40 of file config.c.