NeoMutt  2020-06-26-89-g172cd3
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 "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 79 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 103 of file history.c.

104 {
105  if ((hclass >= HC_MAX) || (C_History == 0))
106  return NULL;
107 
108  struct History *hist = &Histories[hclass];
109  return hist->hist ? hist : NULL;
110 }
static struct History Histories[HC_MAX]
Definition: history.c:95
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:36
Saved list of user-entered commands/searches.
Definition: history.c:86
char ** hist
Definition: history.c:88
Definition: lib.h:60
+ 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 118 of file history.c.

119 {
120  if (OldSize != 0)
121  {
122  if (h->hist)
123  {
124  for (int i = 0; i <= OldSize; i++)
125  FREE(&h->hist[i]);
126  FREE(&h->hist);
127  }
128  }
129 
130  if (C_History != 0)
131  h->hist = mutt_mem_calloc(C_History + 1, sizeof(char *));
132 
133  h->cur = 0;
134  h->last = 0;
135 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static int OldSize
Definition: history.c:96
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:36
short cur
Definition: history.c:89
short last
Definition: history.c:90
#define FREE(x)
Definition: memory.h:40
char ** hist
Definition: history.c:88
+ 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 147 of file history.c.

148 {
149  struct HashElem *elem = mutt_hash_find_elem(dup_hash, str);
150  if (!elem)
151  return -1;
152 
153  uintptr_t count = (uintptr_t) elem->data;
154  if (count <= 1)
155  {
156  mutt_hash_delete(dup_hash, str, NULL);
157  return 0;
158  }
159 
160  count--;
161  elem->data = (void *) count;
162  return count;
163 }
if(!test_colorize_)
Definition: acutest.h:499
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:369
void * data
User-supplied data.
Definition: hash.h:47
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
The item stored in a Hash Table.
Definition: hash.h:43
+ 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 173 of file history.c.

174 {
175  uintptr_t count;
176 
177  struct HashElem *elem = mutt_hash_find_elem(dup_hash, str);
178  if (!elem)
179  {
180  count = 1;
181  mutt_hash_insert(dup_hash, str, (void *) count);
182  return count;
183  }
184 
185  count = (uintptr_t) elem->data;
186  count++;
187  elem->data = (void *) count;
188  return count;
189 }
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:327
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:369
void * data
User-supplied data.
Definition: hash.h:47
The item stored in a Hash Table.
Definition: hash.h:43
+ 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 194 of file history.c.

195 {
196  FILE *fp_tmp = NULL;
197  int n[HC_MAX] = { 0 };
198  int line, hclass, read;
199  char *linebuf = NULL, *p = NULL;
200  size_t buflen;
201  bool regen_file = false;
202  struct HashTable *dup_hashes[HC_MAX] = { 0 };
203 
204  FILE *fp = mutt_file_fopen(C_HistoryFile, "r");
205  if (!fp)
206  return;
207 
209  for (hclass = 0; hclass < HC_MAX; hclass++)
210  dup_hashes[hclass] = mutt_hash_new(MAX(10, C_SaveHistory * 2), MUTT_HASH_STRDUP_KEYS);
211 
212  line = 0;
213  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, 0)))
214  {
215  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
216  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
217  {
218  mutt_error(_("Bad history file format (line %d)"), line);
219  goto cleanup;
220  }
221  /* silently ignore too high class (probably newer neomutt) */
222  if (hclass >= HC_MAX)
223  continue;
224  *p = '\0';
225  if (C_HistoryRemoveDups && (dup_hash_inc(dup_hashes[hclass], linebuf + read) > 1))
226  {
227  regen_file = true;
228  continue;
229  }
230  n[hclass]++;
231  }
232 
233  if (!regen_file)
234  {
235  for (hclass = HC_FIRST; hclass < HC_MAX; hclass++)
236  {
237  if (n[hclass] > C_SaveHistory)
238  {
239  regen_file = true;
240  break;
241  }
242  }
243  }
244 
245  if (regen_file)
246  {
247  fp_tmp = mutt_file_mkstemp();
248  if (!fp_tmp)
249  {
250  mutt_perror(_("Can't create temporary file"));
251  goto cleanup;
252  }
253  rewind(fp);
254  line = 0;
255  while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, 0)))
256  {
257  if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
258  (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
259  {
260  mutt_error(_("Bad history file format (line %d)"), line);
261  goto cleanup;
262  }
263  if (hclass >= HC_MAX)
264  continue;
265  *p = '\0';
266  if (C_HistoryRemoveDups && (dup_hash_dec(dup_hashes[hclass], linebuf + read) > 0))
267  {
268  continue;
269  }
270  *p = '|';
271  if (n[hclass]-- <= C_SaveHistory)
272  fprintf(fp_tmp, "%s\n", linebuf);
273  }
274  }
275 
276 cleanup:
277  mutt_file_fclose(&fp);
278  FREE(&linebuf);
279  if (fp_tmp)
280  {
281  if ((fflush(fp_tmp) == 0) && (fp = fopen(NONULL(C_HistoryFile), "w")))
282  {
283  rewind(fp_tmp);
284  mutt_file_copy_stream(fp_tmp, fp);
285  mutt_file_fclose(&fp);
286  }
287  mutt_file_fclose(&fp_tmp);
288  }
290  for (hclass = 0; hclass < HC_MAX; hclass++)
291  mutt_hash_free(&dup_hashes[hclass]);
292 }
#define NONULL(x)
Definition: string2.h:37
A Hash Table.
Definition: hash.h:84
#define mutt_perror(...)
Definition: logging.h:85
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
#define HC_FIRST
Definition: history.c:79
#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
#define MAX(a, b)
Definition: memory.h:30
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_file_mkstemp()
Definition: file.h:106
short C_SaveHistory
Config: Number of history entries to save per category.
Definition: config.c:39
int n
Definition: acutest.h:492
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
static int dup_hash_dec(struct HashTable *dup_hash, char *str)
Decrease the refcount of a history string.
Definition: history.c:147
#define mutt_error(...)
Definition: logging.h:84
char * C_HistoryFile
Config: File to save history in.
Definition: config.c:37
bool C_HistoryRemoveDups
Config: Remove duplicate entries from the history.
Definition: config.c:38
#define FREE(x)
Definition: memory.h:40
int const char int line
Definition: acutest.h:617
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:99
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Definition: lib.h:60
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
static int dup_hash_inc(struct HashTable *dup_hash, char *str)
Increase the refcount of a history string.
Definition: history.c:173
+ 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 299 of file history.c.

300 {
301  static int n = 0;
302  char *tmp = NULL;
303 
304  if (!str || (*str == '\0')) /* This shouldn't happen, but it's safer. */
305  return;
306 
307  FILE *fp = mutt_file_fopen(C_HistoryFile, "a");
308  if (!fp)
309  return;
310 
311  tmp = mutt_str_dup(str);
312  mutt_ch_convert_string(&tmp, C_Charset, "utf-8", 0);
313 
314  /* Format of a history item (1 line): "<histclass>:<string>|".
315  * We add a '|' in order to avoid lines ending with '\'. */
316  fprintf(fp, "%d:", (int) hclass);
317  for (char *p = tmp; *p; p++)
318  {
319  /* Don't copy \n as a history item must fit on one line. The string
320  * shouldn't contain such a character anyway, but as this can happen
321  * in practice, we must deal with that. */
322  if (*p != '\n')
323  putc((unsigned char) *p, fp);
324  }
325  fputs("|\n", fp);
326 
327  mutt_file_fclose(&fp);
328  FREE(&tmp);
329 
330  if (--n < 0)
331  {
332  n = C_SaveHistory;
333  shrink_histfile();
334  }
335 }
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:754
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
short C_SaveHistory
Config: Number of history entries to save per category.
Definition: config.c:39
int n
Definition: acutest.h:492
char * C_HistoryFile
Config: File to save history in.
Definition: config.c:37
#define FREE(x)
Definition: memory.h:40
static void shrink_histfile(void)
Read, de-dupe and write the history file.
Definition: history.c:194
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ 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 347 of file history.c.

348 {
349  struct History *h = get_history(hclass);
350  if (!h)
351  return; /* disabled */
352 
353  /* Remove dups from 0..last-1 compacting up. */
354  int source = 0;
355  int dest = 0;
356  while (source < h->last)
357  {
358  if (mutt_str_equal(h->hist[source], str))
359  FREE(&h->hist[source++]);
360  else
361  h->hist[dest++] = h->hist[source++];
362  }
363 
364  /* Move 'last' entry up. */
365  h->hist[dest] = h->hist[source];
366  int old_last = h->last;
367  h->last = dest;
368 
369  /* Fill in moved entries with NULL */
370  while (source > h->last)
371  h->hist[source--] = NULL;
372 
373  /* Remove dups from last+1 .. C_History compacting down. */
374  source = C_History;
375  dest = C_History;
376  while (source > old_last)
377  {
378  if (mutt_str_equal(h->hist[source], str))
379  FREE(&h->hist[source--]);
380  else
381  h->hist[dest--] = h->hist[source--];
382  }
383 
384  /* Fill in moved entries with NULL */
385  while (dest > old_last)
386  h->hist[dest--] = NULL;
387 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
short C_History
Config: Number of history entries to keep in memory per category.
Definition: config.c:36
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 last
Definition: history.c:90
#define FREE(x)
Definition: memory.h:40
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:36
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:661
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_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 (C_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:36
Saved list of user-entered commands/searches.
Definition: history.c:86
HistoryClass
Type to differentiate different histories.
Definition: lib.h:51
#define FREE(x)
Definition: memory.h:40
char ** hist
Definition: history.c:88
Definition: lib.h:60
+ 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:36
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:51
Definition: lib.h:60
+ 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 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:876
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:36
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:39
short cur
Definition: history.c:89
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:451
char * C_HistoryFile
Config: File to save history in.
Definition: config.c:37
bool C_HistoryRemoveDups
Config: Remove duplicate entries from the history.
Definition: config.c:38
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_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:36
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:36
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_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_read_file()

void mutt_hist_read_file ( void  )

Read the History from a file.

The file C_HistoryFile 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:375
#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:37
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
int const char int line
Definition: acutest.h:617
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Definition: lib.h:60
+ 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_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:451
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:

Variable Documentation

◆ Histories

struct History Histories[HC_MAX]
static

Definition at line 95 of file history.c.

◆ OldSize

int OldSize = 0
static

Definition at line 96 of file history.c.