NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
history.c File Reference

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

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "lib.h"
+ Include dependency graph for history.c:

Go to the source code of this file.

Data Structures

struct  History
 Saved list of user-entered commands/searches. More...
 

Macros

#define HC_FIRST   HC_CMD
 

Functions

static struct Historyget_history (enum HistoryClass hclass)
 Get a particular history. More...
 
static void init_history (struct History *h)
 Set up a new History ring buffer. More...
 
static int dup_hash_dec (struct HashTable *dup_hash, char *str)
 Decrease the refcount of a history string. More...
 
static int dup_hash_inc (struct HashTable *dup_hash, char *str)
 Increase the refcount of a history string. More...
 
static void shrink_histfile (void)
 Read, de-dupe and write the history file. More...
 
static void save_history (enum HistoryClass hclass, const char *str)
 Save one history string to a file. More...
 
static void remove_history_dups (enum HistoryClass hclass, const char *str)
 De-dupe the history. More...
 
int mutt_hist_search (const char *search_buf, enum HistoryClass hclass, char **matches)
 Find matches in a history list. 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...
 
void mutt_hist_add (enum HistoryClass hclass, const char *str, bool save)
 Add a string to a history. 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_reset_state (enum HistoryClass hclass)
 Move the 'current' position to the end of the History. More...
 
void mutt_hist_read_file (void)
 Read the History from a file. More...
 
bool mutt_hist_at_scratch (enum HistoryClass hclass)
 Is the current History position at the 'scratch' place? More...
 
void mutt_hist_save_scratch (enum HistoryClass hclass, const char *str)
 Save a temporary string to the History. More...
 

Variables

static struct History Histories [HC_MAX]
 
static int OldSize = 0
 

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 history.c.

Macro Definition Documentation

◆ HC_FIRST

#define HC_FIRST   HC_CMD

Definition at line 81 of file history.c.

Function Documentation

◆ get_history()

static struct History* get_history ( enum HistoryClass  hclass)
static

Get a particular history.

Parameters
hclassType of history to find
Return values
ptrHistory ring buffer

Definition at line 105 of file history.c.

106 {
107  const short c_history = cs_subset_number(NeoMutt->sub, "history");
108  if ((hclass >= HC_MAX) || (c_history == 0))
109  return NULL;
110 
111  struct History *hist = &Histories[hclass];
112  return hist->hist ? hist : NULL;
113 }
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
@ HC_MAX
Definition: lib.h:56
static struct History Histories[HC_MAX]
Definition: history.c:97
Saved list of user-entered commands/searches.
Definition: history.c:89
char ** hist
Array of history items.
Definition: history.c:90
Container for Accounts, Notifications.
Definition: neomutt.h:37
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:

◆ init_history()

static void init_history ( struct History h)
static

Set up a new History ring buffer.

Parameters
hHistory to populate

If the History already has entries, they will be freed.

Definition at line 121 of file history.c.

122 {
123  if (OldSize != 0)
124  {
125  if (h->hist)
126  {
127  for (int i = 0; i <= OldSize; i++)
128  FREE(&h->hist[i]);
129  FREE(&h->hist);
130  }
131  }
132 
133  const short c_history = cs_subset_number(NeoMutt->sub, "history");
134  if (c_history != 0)
135  h->hist = mutt_mem_calloc(c_history + 1, sizeof(char *));
136 
137  h->cur = 0;
138  h->last = 0;
139 }
static int OldSize
Definition: history.c:98
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:43
short cur
Current history item.
Definition: history.c:91
short last
Last history item.
Definition: history.c:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dup_hash_dec()

static int dup_hash_dec ( struct HashTable dup_hash,
char *  str 
)
static

Decrease the refcount of a history string.

Parameters
dup_hashHash Table containing unique history strings
strString to find
Return values
0String was deleted from the Hash Table
>0Refcount of string
-1Error, string not found

If the string's refcount is 1, then the string will be deleted.

Definition at line 151 of file history.c.

152 {
153  struct HashElem *elem = mutt_hash_find_elem(dup_hash, str);
154  if (!elem)
155  return -1;
156 
157  uintptr_t count = (uintptr_t) elem->data;
158  if (count <= 1)
159  {
160  mutt_hash_delete(dup_hash, str, NULL);
161  return 0;
162  }
163 
164  count--;
165  elem->data = (void *) count;
166  return count;
167 }
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
struct HashElem * mutt_hash_find_elem(const struct HashTable *table, const char *strkey)
Find the HashElem in a Hash Table element using a key.
Definition: hash.c:377
The item stored in a Hash Table.
Definition: hash.h:44
void * data
User-supplied data.
Definition: hash.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dup_hash_inc()

static int dup_hash_inc ( struct HashTable dup_hash,
char *  str 
)
static

Increase the refcount of a history string.

Parameters
dup_hashHash Table containing unique history strings
strString to find
Return values
numRefcount of string

If the string isn't found it will be added to the Hash Table.

Definition at line 177 of file history.c.

178 {
179  uintptr_t count;
180 
181  struct HashElem *elem = mutt_hash_find_elem(dup_hash, str);
182  if (!elem)
183  {
184  count = 1;
185  mutt_hash_insert(dup_hash, str, (void *) count);
186  return count;
187  }
188 
189  count = (uintptr_t) elem->data;
190  count++;
191  elem->data = (void *) count;
192  return count;
193 }
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ shrink_histfile()

static void shrink_histfile ( void  )
static

Read, de-dupe and write the history file.

Definition at line 198 of file history.c.

199 {
200  FILE *fp_tmp = NULL;
201  int n[HC_MAX] = { 0 };
202  int line, hclass, read;
203  char *linebuf = NULL, *p = NULL;
204  size_t buflen;
205  bool regen_file = false;
206  struct HashTable *dup_hashes[HC_MAX] = { 0 };
207 
208  const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
209  FILE *fp = mutt_file_fopen(c_history_file, "r");
210  if (!fp)
211  return;
212 
213  const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
214  const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
215  if (c_history_remove_dups)
216  {
217  for (hclass = 0; hclass < HC_MAX; hclass++)
218  dup_hashes[hclass] = mutt_hash_new(MAX(10, c_save_history * 2), MUTT_HASH_STRDUP_KEYS);
219  }
220 
221  line = 0;
222  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
223  {
224  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
225  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
226  {
227  mutt_error(_("Bad history file format (line %d)"), line);
228  goto cleanup;
229  }
230  /* silently ignore too high class (probably newer neomutt) */
231  if (hclass >= HC_MAX)
232  continue;
233  *p = '\0';
234  if (c_history_remove_dups && (dup_hash_inc(dup_hashes[hclass], linebuf + read) > 1))
235  {
236  regen_file = true;
237  continue;
238  }
239  n[hclass]++;
240  }
241 
242  if (!regen_file)
243  {
244  for (hclass = HC_FIRST; hclass < HC_MAX; hclass++)
245  {
246  if (n[hclass] > c_save_history)
247  {
248  regen_file = true;
249  break;
250  }
251  }
252  }
253 
254  if (regen_file)
255  {
256  fp_tmp = mutt_file_mkstemp();
257  if (!fp_tmp)
258  {
259  mutt_perror(_("Can't create temporary file"));
260  goto cleanup;
261  }
262  rewind(fp);
263  line = 0;
264  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
265  {
266  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
267  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
268  {
269  mutt_error(_("Bad history file format (line %d)"), line);
270  goto cleanup;
271  }
272  if (hclass >= HC_MAX)
273  continue;
274  *p = '\0';
275  if (c_history_remove_dups && (dup_hash_dec(dup_hashes[hclass], linebuf + read) > 0))
276  {
277  continue;
278  }
279  *p = '|';
280  if (n[hclass]-- <= c_save_history)
281  fprintf(fp_tmp, "%s\n", linebuf);
282  }
283  }
284 
285 cleanup:
286  mutt_file_fclose(&fp);
287  FREE(&linebuf);
288  if (fp_tmp)
289  {
290  if ((fflush(fp_tmp) == 0) && (fp = fopen(NONULL(c_history_file), "w")))
291  {
292  rewind(fp_tmp);
293  mutt_file_copy_stream(fp_tmp, fp);
294  mutt_file_fclose(&fp);
295  }
296  mutt_file_fclose(&fp_tmp);
297  }
298  if (c_history_remove_dups)
299  for (hclass = 0; hclass < HC_MAX; hclass++)
300  mutt_hash_free(&dup_hashes[hclass]);
301 }
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:260
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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:720
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
#define mutt_file_mkstemp()
Definition: file.h:112
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:38
#define mutt_error(...)
Definition: logging.h:87
#define mutt_perror(...)
Definition: logging.h:88
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:111
static int dup_hash_inc(struct HashTable *dup_hash, char *str)
Increase the refcount of a history string.
Definition: history.c:177
#define HC_FIRST
Definition: history.c:81
static int dup_hash_dec(struct HashTable *dup_hash, char *str)
Decrease the refcount of a history string.
Definition: history.c:151
#define MAX(a, b)
Definition: memory.h:30
#define _(a)
Definition: message.h:28
#define NONULL(x)
Definition: string2.h:37
A Hash Table.
Definition: hash.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save_history()

static void save_history ( enum HistoryClass  hclass,
const char *  str 
)
static

Save one history string to a file.

Parameters
hclassHistory type
strString to save

Definition at line 308 of file history.c.

309 {
310  static int n = 0;
311  char *tmp = NULL;
312 
313  if (!str || (*str == '\0')) /* This shouldn't happen, but it's safer. */
314  return;
315 
316  const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
317  FILE *fp = mutt_file_fopen(c_history_file, "a");
318  if (!fp)
319  return;
320 
321  tmp = mutt_str_dup(str);
322  const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
323  mutt_ch_convert_string(&tmp, c_charset, "utf-8", MUTT_ICONV_NO_FLAGS);
324 
325  /* Format of a history item (1 line): "<histclass>:<string>|".
326  * We add a '|' in order to avoid lines ending with '\'. */
327  fprintf(fp, "%d:", (int) hclass);
328  for (char *p = tmp; *p; p++)
329  {
330  /* Don't copy \n as a history item must fit on one line. The string
331  * shouldn't contain such a character anyway, but as this can happen
332  * in practice, we must deal with that. */
333  if (*p != '\n')
334  putc((unsigned char) *p, fp);
335  }
336  fputs("|\n", fp);
337 
338  mutt_file_fclose(&fp);
339  FREE(&tmp);
340 
341  if (--n < 0)
342  {
343  const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
344  n = c_save_history;
345  shrink_histfile();
346  }
347 }
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
static void shrink_histfile(void)
Read, de-dupe and write the history file.
Definition: history.c:198
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:752
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:71
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_history_dups()

static void remove_history_dups ( enum HistoryClass  hclass,
const char *  str 
)
static

De-dupe the history.

Parameters
hclassHistory to de-dupe
strString to find

If the string is found, it is removed from the history.

When removing dups, we want the created "blanks" to be right below the resulting h->last position. See the comment section above 'struct History'.

Definition at line 359 of file history.c.

360 {
361  struct History *h = get_history(hclass);
362  if (!h)
363  return; /* disabled */
364 
365  /* Remove dups from 0..last-1 compacting up. */
366  int source = 0;
367  int dest = 0;
368  while (source < h->last)
369  {
370  if (mutt_str_equal(h->hist[source], str))
371  FREE(&h->hist[source++]);
372  else
373  h->hist[dest++] = h->hist[source++];
374  }
375 
376  /* Move 'last' entry up. */
377  h->hist[dest] = h->hist[source];
378  int old_last = h->last;
379  h->last = dest;
380 
381  /* Fill in moved entries with NULL */
382  while (source > h->last)
383  h->hist[source--] = NULL;
384 
385  /* Remove dups from last+1 .. `$history` compacting down. */
386  const short c_history = cs_subset_number(NeoMutt->sub, "history");
387  source = c_history;
388  dest = c_history;
389  while (source > old_last)
390  {
391  if (mutt_str_equal(h->hist[source], str))
392  FREE(&h->hist[source--]);
393  else
394  h->hist[dest--] = h->hist[source--];
395  }
396 
397  /* Fill in moved entries with NULL */
398  while (dest > old_last)
399  h->hist[dest--] = NULL;
400 }
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition: history.c:105
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
+ 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 409 of file history.c.

410 {
411  if (!search_buf || !matches)
412  return 0;
413 
414  struct History *h = get_history(hclass);
415  if (!h)
416  return 0;
417 
418  int match_count = 0;
419  int cur = h->last;
420  const short c_history = cs_subset_number(NeoMutt->sub, "history");
421  do
422  {
423  cur--;
424  if (cur < 0)
425  cur = c_history;
426  if (cur == h->last)
427  break;
428  if (mutt_istr_find(h->hist[cur], search_buf))
429  matches[match_count++] = h->hist[cur];
430  } while (match_count < c_history);
431 
432  return match_count;
433 }
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:569
+ 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 438 of file history.c.

439 {
440  if (!NeoMutt)
441  return;
442 
443  const short c_history = cs_subset_number(NeoMutt->sub, "history");
444  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
445  {
446  struct History *h = &Histories[hclass];
447  if (!h->hist)
448  continue;
449 
450  /* The array has (`$history`+1) elements */
451  for (int i = 0; i <= c_history; i++)
452  {
453  FREE(&h->hist[i]);
454  }
455  FREE(&h->hist);
456  }
457 }
HistoryClass
Type to differentiate different histories.
Definition: lib.h:48
+ 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 465 of file history.c.

466 {
467  const short c_history = cs_subset_number(NeoMutt->sub, "history");
468  if (c_history == OldSize)
469  return;
470 
471  for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
472  init_history(&Histories[hclass]);
473 
474  OldSize = c_history;
475 }
static void init_history(struct History *h)
Set up a new History ring buffer.
Definition: history.c:121
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

484 {
485  struct History *h = get_history(hclass);
486  if (!h)
487  return; /* disabled */
488 
489  if (*str)
490  {
491  int prev = h->last - 1;
492  const short c_history = cs_subset_number(NeoMutt->sub, "history");
493  if (prev < 0)
494  prev = c_history;
495 
496  /* don't add to prompt history:
497  * - lines beginning by a space
498  * - repeated lines */
499  if ((*str != ' ') && (!h->hist[prev] || !mutt_str_equal(h->hist[prev], str)))
500  {
501  const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
502  if (c_history_remove_dups)
503  remove_history_dups(hclass, str);
504  const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
505  const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
506  if (save && (c_save_history != 0) && c_history_file)
507  save_history(hclass, str);
508  mutt_str_replace(&h->hist[h->last++], str);
509  if (h->last > c_history)
510  h->last = 0;
511  }
512  }
513  h->cur = h->last; /* reset to the last entry */
514 }
static void remove_history_dups(enum HistoryClass hclass, const char *str)
De-dupe the history.
Definition: history.c:359
static void save_history(enum HistoryClass hclass, const char *str)
Save one history string to a file.
Definition: history.c:308
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
+ 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 523 of file history.c.

524 {
525  struct History *h = get_history(hclass);
526  if (!h)
527  return ""; /* disabled */
528 
529  int next = h->cur;
530  do
531  {
532  next++;
533  const short c_history = cs_subset_number(NeoMutt->sub, "history");
534  if (next > c_history)
535  next = 0;
536  if (next == h->last)
537  break;
538  } while (!h->hist[next]);
539 
540  h->cur = next;
541  return NONULL(h->hist[h->cur]);
542 }
+ 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 551 of file history.c.

552 {
553  struct History *h = get_history(hclass);
554  if (!h)
555  return ""; /* disabled */
556 
557  int prev = h->cur;
558  do
559  {
560  prev--;
561  const short c_history = cs_subset_number(NeoMutt->sub, "history");
562  if (prev < 0)
563  prev = c_history;
564  if (prev == h->last)
565  break;
566  } while (!h->hist[prev]);
567 
568  h->cur = prev;
569  return NONULL(h->hist[h->cur]);
570 }
+ 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 579 of file history.c.

580 {
581  struct History *h = get_history(hclass);
582  if (!h)
583  return; /* disabled */
584 
585  h->cur = h->last;
586 }
+ 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 593 of file history.c.

594 {
595  int line = 0, hclass, read;
596  char *linebuf = NULL, *p = NULL;
597  size_t buflen;
598 
599  const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
600  if (!c_history_file)
601  return;
602 
603  FILE *fp = mutt_file_fopen(c_history_file, "r");
604  if (!fp)
605  return;
606 
607  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
608  {
609  read = 0;
610  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
611  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
612  {
613  mutt_error(_("Bad history file format (line %d)"), line);
614  break;
615  }
616  /* silently ignore too high class (probably newer neomutt) */
617  if (hclass >= HC_MAX)
618  continue;
619  *p = '\0';
620  p = mutt_str_dup(linebuf + read);
621  if (p)
622  {
623  const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
624  mutt_ch_convert_string(&p, "utf-8", c_charset, MUTT_ICONV_NO_FLAGS);
625  mutt_hist_add(hclass, p, false);
626  FREE(&p);
627  }
628  }
629 
630  mutt_file_fclose(&fp);
631  FREE(&linebuf);
632 }
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:483
+ 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 645 of file history.c.

646 {
647  struct History *h = get_history(hclass);
648  if (!h)
649  return false; /* disabled */
650 
651  return h->cur == h->last;
652 }
+ 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 662 of file history.c.

663 {
664  struct History *h = get_history(hclass);
665  if (!h)
666  return; /* disabled */
667 
668  /* Don't check if str has a value because the scratch buffer may contain
669  * an old garbage value that should be overwritten */
670  mutt_str_replace(&h->hist[h->last], str);
671 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ Histories

struct History Histories[HC_MAX]
static

Definition at line 1 of file history.c.

◆ OldSize

int OldSize = 0
static

Definition at line 98 of file history.c.