NeoMutt  2023-05-17-56-ga67199
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]
 Command histories, one for each HistoryClass. More...
 
static int OldSize = 0
 The previous number of history entries to save. 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 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 108 of file history.c.

109{
110 const short c_history = cs_subset_number(NeoMutt->sub, "history");
111 if ((hclass >= HC_MAX) || (c_history == 0))
112 return NULL;
113
114 struct History *hist = &Histories[hclass];
115 return hist->hist ? hist : NULL;
116}
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]
Command histories, one for each HistoryClass.
Definition: history.c:98
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 124 of file history.c.

125{
126 if (OldSize != 0)
127 {
128 if (h->hist)
129 {
130 for (int i = 0; i <= OldSize; i++)
131 FREE(&h->hist[i]);
132 FREE(&h->hist);
133 }
134 }
135
136 const short c_history = cs_subset_number(NeoMutt->sub, "history");
137 if (c_history != 0)
138 h->hist = mutt_mem_calloc(c_history + 1, sizeof(char *));
139
140 h->cur = 0;
141 h->last = 0;
142}
static int OldSize
The previous number of history entries to save.
Definition: history.c:101
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 154 of file history.c.

155{
156 struct HashElem *he = mutt_hash_find_elem(dup_hash, str);
157 if (!he)
158 return -1;
159
160 uintptr_t count = (uintptr_t) he->data;
161 if (count <= 1)
162 {
163 mutt_hash_delete(dup_hash, str, NULL);
164 return 0;
165 }
166
167 count--;
168 he->data = (void *) count;
169 return count;
170}
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 180 of file history.c.

181{
182 uintptr_t count;
183
184 struct HashElem *he = mutt_hash_find_elem(dup_hash, str);
185 if (!he)
186 {
187 count = 1;
188 mutt_hash_insert(dup_hash, str, (void *) count);
189 return count;
190 }
191
192 count = (uintptr_t) he->data;
193 count++;
194 he->data = (void *) count;
195 return count;
196}
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 201 of file history.c.

202{
203 FILE *fp_tmp = NULL;
204 int n[HC_MAX] = { 0 };
205 int line, hclass, read;
206 char *linebuf = NULL, *p = NULL;
207 size_t buflen;
208 bool regen_file = false;
209 struct HashTable *dup_hashes[HC_MAX] = { 0 };
210
211 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
212 FILE *fp = mutt_file_fopen(c_history_file, "r");
213 if (!fp)
214 return;
215
216 const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
217 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
218 if (c_history_remove_dups)
219 {
220 for (hclass = 0; hclass < HC_MAX; hclass++)
221 dup_hashes[hclass] = mutt_hash_new(MAX(10, c_save_history * 2), MUTT_HASH_STRDUP_KEYS);
222 }
223
224 line = 0;
225 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
226 {
227 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
228 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
229 {
230 mutt_error(_("Bad history file format (line %d)"), line);
231 goto cleanup;
232 }
233 /* silently ignore too high class (probably newer neomutt) */
234 if (hclass >= HC_MAX)
235 continue;
236 *p = '\0';
237 if (c_history_remove_dups && (dup_hash_inc(dup_hashes[hclass], linebuf + read) > 1))
238 {
239 regen_file = true;
240 continue;
241 }
242 n[hclass]++;
243 }
244
245 if (!regen_file)
246 {
247 for (hclass = HC_FIRST; hclass < HC_MAX; hclass++)
248 {
249 if (n[hclass] > c_save_history)
250 {
251 regen_file = true;
252 break;
253 }
254 }
255 }
256
257 if (regen_file)
258 {
259 fp_tmp = mutt_file_mkstemp();
260 if (!fp_tmp)
261 {
262 mutt_perror(_("Can't create temporary file"));
263 goto cleanup;
264 }
265 rewind(fp);
266 line = 0;
267 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
268 {
269 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
270 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
271 {
272 mutt_error(_("Bad history file format (line %d)"), line);
273 goto cleanup;
274 }
275 if (hclass >= HC_MAX)
276 continue;
277 *p = '\0';
278 if (c_history_remove_dups && (dup_hash_dec(dup_hashes[hclass], linebuf + read) > 0))
279 {
280 continue;
281 }
282 *p = '|';
283 if (n[hclass]-- <= c_save_history)
284 fprintf(fp_tmp, "%s\n", linebuf);
285 }
286 }
287
288cleanup:
289 mutt_file_fclose(&fp);
290 FREE(&linebuf);
291 if (fp_tmp)
292 {
293 if ((fflush(fp_tmp) == 0) && (fp = fopen(NONULL(c_history_file), "w")))
294 {
295 rewind(fp_tmp);
296 mutt_file_copy_stream(fp_tmp, fp);
297 mutt_file_fclose(&fp);
298 }
299 mutt_file_fclose(&fp_tmp);
300 }
301 if (c_history_remove_dups)
302 for (hclass = 0; hclass < HC_MAX; hclass++)
303 mutt_hash_free(&dup_hashes[hclass]);
304}
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
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:738
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
#define mutt_error(...)
Definition: logging2.h:90
#define mutt_perror(...)
Definition: logging2.h:91
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:112
static int dup_hash_inc(struct HashTable *dup_hash, char *str)
Increase the refcount of a history string.
Definition: history.c:180
#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:154
#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:98
#define mutt_file_mkstemp()
Definition: tmp.h:40
+ 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 311 of file history.c.

312{
313 static int n = 0;
314 char *tmp = NULL;
315
316 if (!str || (*str == '\0')) /* This shouldn't happen, but it's safer. */
317 return;
318
319 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
320 FILE *fp = mutt_file_fopen(c_history_file, "a");
321 if (!fp)
322 return;
323
324 tmp = mutt_str_dup(str);
326
327 /* Format of a history item (1 line): "<histclass>:<string>|".
328 * We add a '|' in order to avoid lines ending with '\'. */
329 fprintf(fp, "%d:", (int) hclass);
330 for (char *p = tmp; *p; p++)
331 {
332 /* Don't copy \n as a history item must fit on one line. The string
333 * shouldn't contain such a character anyway, but as this can happen
334 * in practice, we must deal with that. */
335 if (*p != '\n')
336 putc((unsigned char) *p, fp);
337 }
338 fputs("|\n", fp);
339
340 mutt_file_fclose(&fp);
341 FREE(&tmp);
342
343 if (--n < 0)
344 {
345 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
346 n = c_save_history;
348 }
349}
const char * cc_charset(void)
Get the cached value of $charset.
Definition: cache.c:106
static void shrink_histfile(void)
Read, de-dupe and write the history file.
Definition: history.c:201
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:822
#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:251
+ 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 361 of file history.c.

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

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

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

468{
469 const short c_history = cs_subset_number(NeoMutt->sub, "history");
470 if (c_history == OldSize)
471 return;
472
473 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
474 init_history(&Histories[hclass]);
475
476 OldSize = c_history;
477}
static void init_history(struct History *h)
Set up a new History ring buffer.
Definition: history.c:124
+ 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 485 of file history.c.

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

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

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

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

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

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

665{
666 struct History *h = get_history(hclass);
667 if (!h)
668 return; /* disabled */
669
670 /* Don't check if str has a value because the scratch buffer may contain
671 * an old garbage value that should be overwritten */
672 mutt_str_replace(&h->hist[h->last], str);
673}
+ 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

Command histories, one for each HistoryClass.

Definition at line 98 of file history.c.

◆ OldSize

int OldSize = 0
static

The previous number of history entries to save.

See also
$history

Definition at line 101 of file history.c.