NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

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

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

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 46 of file lib.h.

47 {
48  HC_CMD,
49  HC_ALIAS,
50  HC_COMMAND,
51  HC_FILE,
52  HC_PATTERN,
53  HC_OTHER,
54  HC_MBOX,
55  HC_MAX,
56 };
NeoMutt commands.
Definition: lib.h:50
Mailboxes.
Definition: lib.h:54
External commands.
Definition: lib.h:48
Patterns.
Definition: lib.h:52
Aliases.
Definition: lib.h:49
Definition: lib.h:55
Miscellaneous strings.
Definition: lib.h:53
Files.
Definition: lib.h:51

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

487 {
488  struct History *h = get_history(hclass);
489  if (!h)
490  return; /* disabled */
491 
492  if (*str)
493  {
494  int prev = h->last - 1;
495  const short c_history = cs_subset_number(NeoMutt->sub, "history");
496  if (prev < 0)
497  prev = c_history;
498 
499  /* don't add to prompt history:
500  * - lines beginning by a space
501  * - repeated lines */
502  if ((*str != ' ') && (!h->hist[prev] || !mutt_str_equal(h->hist[prev], str)))
503  {
504  const bool c_history_remove_dups =
505  cs_subset_bool(NeoMutt->sub, "history_remove_dups");
506  if (c_history_remove_dups)
507  remove_history_dups(hclass, str);
508  const short c_save_history =
509  cs_subset_number(NeoMutt->sub, "save_history");
510  const char *const c_history_file =
511  cs_subset_path(NeoMutt->sub, "history_file");
512  if (save && (c_save_history != 0) && c_history_file)
513  save_history(hclass, str);
514  mutt_str_replace(&h->hist[h->last++], str);
515  if (h->last > c_history)
516  h->last = 0;
517  }
518  }
519  h->cur = h->last; /* reset to the last entry */
520 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
static void save_history(enum HistoryClass hclass, const char *str)
Save one history string to a file.
Definition: history.c:310
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
static void remove_history_dups(enum HistoryClass hclass, const char *str)
De-dupe the history.
Definition: history.c:362
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
short cur
Definition: history.c:91
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
short last
Definition: history.c:92
char ** hist
Definition: history.c:90
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 652 of file history.c.

653 {
654  struct History *h = get_history(hclass);
655  if (!h)
656  return false; /* disabled */
657 
658  return h->cur == h->last;
659 }
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
short cur
Definition: history.c:91
short last
Definition: history.c:92
+ 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 441 of file history.c.

442 {
443  if (!NeoMutt)
444  return;
445 
446  const short c_history = cs_subset_number(NeoMutt->sub, "history");
447  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
448  {
449  struct History *h = &Histories[hclass];
450  if (!h->hist)
451  continue;
452 
453  /* The array has (`$history`+1) elements */
454  for (int i = 0; i <= c_history; i++)
455  {
456  FREE(&h->hist[i]);
457  }
458  FREE(&h->hist);
459  }
460 }
static struct History Histories[HC_MAX]
Definition: history.c:97
#define HC_FIRST
Definition: history.c:81
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
Saved list of user-entered commands/searches.
Definition: history.c:88
HistoryClass
Type to differentiate different histories.
Definition: lib.h:46
#define FREE(x)
Definition: memory.h:40
char ** hist
Definition: history.c:90
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Definition: lib.h:55
+ 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 468 of file history.c.

469 {
470  const short c_history = cs_subset_number(NeoMutt->sub, "history");
471  if (c_history == OldSize)
472  return;
473 
474  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
475  init_history(&Histories[hclass]);
476 
477  OldSize = c_history;
478 }
static struct History Histories[HC_MAX]
Definition: history.c:97
#define HC_FIRST
Definition: history.c:81
static int OldSize
Definition: history.c:98
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
static void init_history(struct History *h)
Set up a new History ring buffer.
Definition: history.c:121
HistoryClass
Type to differentiate different histories.
Definition: lib.h:46
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Definition: lib.h:55
+ 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 529 of file history.c.

530 {
531  struct History *h = get_history(hclass);
532  if (!h)
533  return ""; /* disabled */
534 
535  int next = h->cur;
536  do
537  {
538  next++;
539  const short c_history = cs_subset_number(NeoMutt->sub, "history");
540  if (next > c_history)
541  next = 0;
542  if (next == h->last)
543  break;
544  } while (!h->hist[next]);
545 
546  h->cur = next;
547  return NONULL(h->hist[h->cur]);
548 }
#define NONULL(x)
Definition: string2.h:37
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
short cur
Definition: history.c:91
short last
Definition: history.c:92
char ** hist
Definition: history.c:90
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 557 of file history.c.

558 {
559  struct History *h = get_history(hclass);
560  if (!h)
561  return ""; /* disabled */
562 
563  int prev = h->cur;
564  do
565  {
566  prev--;
567  const short c_history = cs_subset_number(NeoMutt->sub, "history");
568  if (prev < 0)
569  prev = c_history;
570  if (prev == h->last)
571  break;
572  } while (!h->hist[prev]);
573 
574  h->cur = prev;
575  return NONULL(h->hist[h->cur]);
576 }
#define NONULL(x)
Definition: string2.h:37
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
short cur
Definition: history.c:91
short last
Definition: history.c:92
char ** hist
Definition: history.c:90
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 599 of file history.c.

600 {
601  int line = 0, hclass, read;
602  char *linebuf = NULL, *p = NULL;
603  size_t buflen;
604 
605  const char *const c_history_file =
606  cs_subset_path(NeoMutt->sub, "history_file");
607  if (!c_history_file)
608  return;
609 
610  FILE *fp = mutt_file_fopen(c_history_file, "r");
611  if (!fp)
612  return;
613 
614  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
615  {
616  read = 0;
617  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
618  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
619  {
620  mutt_error(_("Bad history file format (line %d)"), line);
621  break;
622  }
623  /* silently ignore too high class (probably newer neomutt) */
624  if (hclass >= HC_MAX)
625  continue;
626  *p = '\0';
627  p = mutt_str_dup(linebuf + read);
628  if (p)
629  {
630  const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
631  mutt_ch_convert_string(&p, "utf-8", c_charset, MUTT_ICONV_NO_FLAGS);
632  mutt_hist_add(hclass, p, false);
633  FREE(&p);
634  }
635  }
636 
637  mutt_file_fclose(&fp);
638  FREE(&linebuf);
639 }
#define mutt_error(...)
Definition: logging.h:88
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:486
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:758
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:71
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:667
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:38
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
Definition: lib.h:55
+ 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 585 of file history.c.

586 {
587  struct History *h = get_history(hclass);
588  if (!h)
589  return; /* disabled */
590 
591  h->cur = h->last;
592 }
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
short cur
Definition: history.c:91
short last
Definition: history.c:92
+ 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 669 of file history.c.

670 {
671  struct History *h = get_history(hclass);
672  if (!h)
673  return; /* disabled */
674 
675  /* Don't check if str has a value because the scratch buffer may contain
676  * an old garbage value that should be overwritten */
677  mutt_str_replace(&h->hist[h->last], str);
678 }
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
short last
Definition: history.c:92
char ** hist
Definition: history.c:90
+ 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 412 of file history.c.

413 {
414  if (!search_buf || !matches)
415  return 0;
416 
417  struct History *h = get_history(hclass);
418  if (!h)
419  return 0;
420 
421  int match_count = 0;
422  int cur = h->last;
423  const short c_history = cs_subset_number(NeoMutt->sub, "history");
424  do
425  {
426  cur--;
427  if (cur < 0)
428  cur = c_history;
429  if (cur == h->last)
430  break;
431  if (mutt_istr_find(h->hist[cur], search_buf))
432  matches[match_count++] = h->hist[cur];
433  } while (match_count < c_history);
434 
435  return match_count;
436 }
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
Saved list of user-entered commands/searches.
Definition: history.c:88
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
short cur
Definition: history.c:91
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:689
short last
Definition: history.c:92
char ** hist
Definition: history.c:90
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 125 of file dlghistory.c.

126 {
128 
129  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
130  char title[256];
131  snprintf(title, sizeof(title), _("History '%s'"), buf);
132  sbar_set_title(sbar, title);
133 
134  struct Menu *menu = dlg->wdata;
136  menu->max = match_count;
137  menu->mdata = matches;
138 
139  bool done = false;
140  while (!done)
141  {
142  switch (menu_loop(menu))
143  {
144  case OP_GENERIC_SELECT_ENTRY:
145  {
146  const int index = menu_get_index(menu);
147  mutt_str_copy(buf, matches[index], buflen);
148  done = true;
149  break;
150  }
151 
152  case OP_EXIT:
153  done = true;
154  break;
155  }
156  }
157 
158  simple_dialog_free(&dlg);
159 }
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
History Dialog, dlg_select_history()
Definition: mutt_window.h:85
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Definition: lib.h:67
Generic selection list.
Definition: type.h:45
#define _(a)
Definition: message.h:28
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
static const struct Mapping HistoryHelp[]
Help Bar for the History Selection dialog.
Definition: dlghistory.c:73
void * mdata
Private data.
Definition: lib.h:155
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
static void history_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the history list - Implements Menu::make_entry() -.
Definition: dlghistory.c:110
int max
Number of entries in the menu.
Definition: lib.h:71
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:749
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
void * wdata
Private data.
Definition: mutt_window.h:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function: