NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
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 "module_data.h"
Include dependency graph for history.c:

Go to the source code of this file.

Macros

#define HC_FIRST   HC_EXT_COMMAND

Functions

static struct Historyget_history (enum HistoryClass hclass)
 Get a particular history.
static void init_history (struct History *h, int old_size)
 Set up a new History ring buffer.
static int dup_hash_dec (struct HashTable *dup_hash, char *str)
 Decrease the refcount of a history string.
static int dup_hash_inc (struct HashTable *dup_hash, char *str)
 Increase the refcount of a history string.
static void shrink_histfile (void)
 Read, de-dupe and write the history file.
static void save_history (enum HistoryClass hclass, const char *str)
 Save one history string to a file.
static void remove_history_dups (enum HistoryClass hclass, const char *str)
 De-dupe the history.
int mutt_hist_search (const char *find, enum HistoryClass hclass, struct StringArray *matches)
 Find matches in a history list.
void mutt_hist_cleanup (struct HistoryModuleData *mod_data)
 Free all the history lists.
void mutt_hist_init (struct HistoryModuleData *mod_data)
 Create a set of empty History ring buffers.
void mutt_hist_add (enum HistoryClass hclass, const char *str, bool save)
 Add a string to a history.
char * mutt_hist_next (enum HistoryClass hclass)
 Get the next string in a History.
char * mutt_hist_prev (enum HistoryClass hclass)
 Get the previous string in a History.
void mutt_hist_reset_state (enum HistoryClass hclass)
 Move the 'current' position to the end of the History.
void mutt_hist_read_file (void)
 Read the History from a file.
bool mutt_hist_at_scratch (enum HistoryClass hclass)
 Is the current History position at the 'scratch' place?
void mutt_hist_save_scratch (enum HistoryClass hclass, const char *str)
 Save a temporary string to the History.
void mutt_hist_complete (struct Buffer *buf, enum HistoryClass hclass)
 Complete a string from a history list.
int main_hist_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has change - Implements observer_t -.

Detailed Description

Read/write command history from/to a file.

Authors
  • Richard Russon
  • Pietro Cerutti
  • Dennis Schön

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_EXT_COMMAND

Definition at line 84 of file history.c.

Function Documentation

◆ get_history()

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

92{
94 const short c_history = cs_subset_number(NeoMutt->sub, "history");
95 if ((hclass >= HC_MAX) || (c_history == 0))
96 return NULL;
97
98 struct History *hist = &mod_data->histories[hclass];
99 return hist->hist ? hist : NULL;
100}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
@ HC_MAX
Definition lib.h:63
@ MODULE_ID_HISTORY
ModuleHistory, History
Definition module_api.h:70
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
History private Module data.
Definition module_data.h:44
struct History histories[HC_MAX]
Command histories, one for each HistoryClass.
Definition module_data.h:46
Saved list of user-entered commands/searches.
Definition module_data.h:34
char ** hist
Array of history items.
Definition module_data.h:35
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_history()

void init_history ( struct History * h,
int old_size )
static

Set up a new History ring buffer.

Parameters
hHistory to populate
old_sizePrevious number of history entries to save

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

Definition at line 109 of file history.c.

110{
111 if (old_size != 0)
112 {
113 if (h->hist)
114 {
115 for (int i = 0; i <= old_size; i++)
116 FREE(&h->hist[i]);
117 FREE(&h->hist);
118 }
119 }
120
121 const short c_history = cs_subset_number(NeoMutt->sub, "history");
122 if (c_history != 0)
123 h->hist = MUTT_MEM_CALLOC(c_history + 1, char *);
124
125 h->cur = 0;
126 h->last = 0;
127}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
short cur
Current history item.
Definition module_data.h:36
short last
Last history item.
Definition module_data.h:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dup_hash_dec()

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

140{
141 struct HashElem *he = mutt_hash_find_elem(dup_hash, str);
142 if (!he)
143 return -1;
144
145 uintptr_t count = (uintptr_t) he->data;
146 if (count <= 1)
147 {
148 mutt_hash_delete(dup_hash, str, NULL);
149 return 0;
150 }
151
152 count--;
153 he->data = (void *) count;
154 return count;
155}
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition hash.c:430
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:380
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()

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

166{
167 uintptr_t count;
168
169 struct HashElem *he = mutt_hash_find_elem(dup_hash, str);
170 if (!he)
171 {
172 count = 1;
173 mutt_hash_insert(dup_hash, str, (void *) count);
174 return count;
175 }
176
177 count = (uintptr_t) he->data;
178 count++;
179 he->data = (void *) count;
180 return count;
181}
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:338
Here is the call graph for this function:
Here is the caller graph for this function:

◆ shrink_histfile()

void shrink_histfile ( void )
static

Read, de-dupe and write the history file.

Definition at line 186 of file history.c.

187{
188 FILE *fp_tmp = NULL;
189 int n[HC_MAX] = { 0 };
190 int line = 0;
191 int hclass = 0;
192 int read = 0;
193 char *linebuf = NULL;
194 char *p = NULL;
195 size_t buflen = 0;
196 bool regen_file = false;
197 struct HashTable *dup_hashes[HC_MAX] = { 0 };
198
199 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
200 FILE *fp = mutt_file_fopen(c_history_file, "r");
201 if (!fp)
202 return;
203
204 /* If duplicate removal is enabled, build per-class hash tables to track
205 * how many times each history entry appears in the file */
206 const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
207 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
208 if (c_history_remove_dups)
209 {
210 for (hclass = 0; hclass < HC_MAX; hclass++)
211 dup_hashes[hclass] = mutt_hash_new(MAX(10, c_save_history * 2), MUTT_HASH_STRDUP_KEYS);
212 }
213
214 /* First pass: count entries per class, detect duplicates, and validate
215 * the file format (each line is "class:entry|") */
216 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NONE)))
217 {
218 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
219 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
220 {
221 mutt_error(_("%s:%d: Bad history file format"), c_history_file, line);
222 regen_file = true;
223 continue;
224 }
225 /* silently ignore too high class (probably newer neomutt) */
226 if (hclass >= HC_MAX)
227 continue;
228 *p = '\0';
229 if (c_history_remove_dups && (dup_hash_inc(dup_hashes[hclass], linebuf + read) > 1))
230 {
231 regen_file = true;
232 continue;
233 }
234 n[hclass]++;
235 }
236
237 if (!regen_file)
238 {
239 for (hclass = HC_FIRST; hclass < HC_MAX; hclass++)
240 {
241 if (n[hclass] > c_save_history)
242 {
243 regen_file = true;
244 break;
245 }
246 }
247 }
248
249 if (regen_file)
250 {
251 /* Second pass: rewrite the file keeping only the most recent
252 * c_save_history entries per class, omitting duplicates */
253 fp_tmp = mutt_file_mkstemp();
254 if (!fp_tmp)
255 {
256 mutt_perror(_("Can't create temporary file"));
257 goto cleanup;
258 }
259 fseek(fp, 0, SEEK_SET);
260 clearerr(fp);
261 line = 0;
262 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NONE)))
263 {
264 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
265 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
266 {
267 continue;
268 }
269 if (hclass >= HC_MAX)
270 continue;
271 *p = '\0';
272 if (c_history_remove_dups && (dup_hash_dec(dup_hashes[hclass], linebuf + read) > 0))
273 {
274 continue;
275 }
276 *p = '|';
277 if (n[hclass]-- <= c_save_history)
278 fprintf(fp_tmp, "%s\n", linebuf);
279 }
280 }
281
282cleanup:
283 mutt_file_fclose(&fp);
284 FREE(&linebuf);
285 if (fp_tmp)
286 {
287 if (fflush(fp_tmp) == 0)
288 {
289 fp = mutt_file_fopen(c_history_file, "w");
290 if (fp)
291 {
292 fseek(fp_tmp, 0, SEEK_SET);
293 clearerr(fp_tmp);
294 mutt_file_copy_stream(fp_tmp, fp);
295 mutt_file_fclose(&fp);
296 }
297 }
298 mutt_file_fclose(&fp_tmp);
299 }
300 if (c_history_remove_dups)
301 for (hclass = 0; hclass < HC_MAX; hclass++)
302 mutt_hash_free(&dup_hashes[hclass]);
303}
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition helpers.c:168
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition file.c:224
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:678
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
@ MUTT_RL_NONE
No flags are set.
Definition file.h:43
#define mutt_error(...)
Definition logging2.h:94
#define mutt_perror(...)
Definition logging2.h:95
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys).
Definition hash.c:262
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition hash.c:460
@ MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition hash.h:117
static int dup_hash_inc(struct HashTable *dup_hash, char *str)
Increase the refcount of a history string.
Definition history.c:165
#define HC_FIRST
Definition history.c:84
static int dup_hash_dec(struct HashTable *dup_hash, char *str)
Decrease the refcount of a history string.
Definition history.c:139
#define MAX(a, b)
Return the maximum of two values.
Definition memory.h:38
#define _(a)
Definition message.h:28
A Hash Table.
Definition hash.h:99
#define mutt_file_mkstemp()
Definition tmp.h:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_history()

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

311{
312 if (!str || (*str == '\0')) // This shouldn't happen, but it's safer
313 return;
314
315 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
316 FILE *fp = mutt_file_fopen(c_history_file, "a");
317 if (!fp)
318 return;
319
320 char *tmp = mutt_str_dup(str);
322
323 // If tmp contains '\n' terminate it there.
324 char *nl = strchr(tmp, '\n');
325 if (nl)
326 *nl = '\0';
327
328 /* Format of a history item (1 line): "<histclass>:<string>|".
329 * We add a '|' in order to avoid lines ending with '\'. */
330 fprintf(fp, "%d:%s|\n", (int) hclass, tmp);
331
332 mutt_file_fclose(&fp);
333 FREE(&tmp);
334
336}
const char * cc_charset(void)
Get the cached value of $charset.
static void shrink_histfile(void)
Read, de-dupe and write the history file.
Definition history.c:186
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition charset.c:819
#define MUTT_ICONV_NONE
No flags are set.
Definition charset.h:66
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_history_dups()

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

349{
350 struct History *h = get_history(hclass);
351 if (!h)
352 return; /* disabled */
353
354 /* Remove dups from 0..last-1 compacting up. */
355 int source = 0;
356 int dest = 0;
357 while (source < h->last)
358 {
359 if (mutt_str_equal(h->hist[source], str))
360 FREE(&h->hist[source++]);
361 else
362 h->hist[dest++] = h->hist[source++];
363 }
364
365 /* Move 'last' entry up. */
366 h->hist[dest] = h->hist[source];
367 int old_last = h->last;
368 h->last = dest;
369
370 /* Fill in moved entries with NULL */
371 while (source > h->last)
372 h->hist[source--] = NULL;
373
374 /* Remove dups from last+1 .. `$history` compacting down. */
375 const short c_history = cs_subset_number(NeoMutt->sub, "history");
376 source = c_history;
377 dest = c_history;
378 while (source > old_last)
379 {
380 if (mutt_str_equal(h->hist[source], str))
381 FREE(&h->hist[source--]);
382 else
383 h->hist[dest--] = h->hist[source--];
384 }
385
386 /* Fill in moved entries with NULL */
387 while (dest > old_last)
388 h->hist[dest--] = NULL;
389}
static struct History * get_history(enum HistoryClass hclass)
Get a particular history.
Definition history.c:91
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
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 * find,
enum HistoryClass hclass,
struct StringArray * matches )

Find matches in a history list.

Parameters
[in]findString to find
[in]hclassHistory list
[out]matchesAll the matching lines
Return values
numMatches found

Definition at line 398 of file history.c.

399{
400 if (!find || !matches)
401 return 0;
402
403 struct History *h = get_history(hclass);
404 if (!h)
405 return 0;
406
407 int cur = h->last;
408 const short c_history = cs_subset_number(NeoMutt->sub, "history");
409
410 do
411 {
412 cur--;
413 if (cur < 0)
414 cur = c_history;
415
416 if (cur == h->last)
417 break;
418
419 if (mutt_istr_find(h->hist[cur], find))
420 ARRAY_ADD(matches, h->hist[cur]);
421
422 } while (ARRAY_SIZE(matches) < c_history);
423
424 return ARRAY_SIZE(matches);
425}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case).
Definition string.c:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_hist_cleanup()

void mutt_hist_cleanup ( struct HistoryModuleData * mod_data)

Free all the history lists.

Parameters
mod_dataHistory module data

Definition at line 431 of file history.c.

432{
433 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
434 {
435 struct History *h = &mod_data->histories[hclass];
436 if (!h->hist)
437 continue;
438
439 /* The array has (mod_data->old_size+1) elements */
440 for (int i = 0; i <= mod_data->old_size; i++)
441 {
442 FREE(&h->hist[i]);
443 }
444 FREE(&h->hist);
445 }
446}
HistoryClass
Type to differentiate different histories.
Definition lib.h:55
int old_size
The previous number of history entries to save.
Definition module_data.h:47
Here is the caller graph for this function:

◆ mutt_hist_init()

void mutt_hist_init ( struct HistoryModuleData * mod_data)

Create a set of empty History ring buffers.

Parameters
mod_dataHistory module data

This just creates empty histories. To fill them, call mutt_hist_read_file().

Definition at line 455 of file history.c.

456{
457 const short c_history = cs_subset_number(NeoMutt->sub, "history");
458 if (c_history == mod_data->old_size)
459 return;
460
461 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
462 init_history(&mod_data->histories[hclass], mod_data->old_size);
463
464 mod_data->old_size = c_history;
465}
static void init_history(struct History *h, int old_size)
Set up a new History ring buffer.
Definition history.c:109
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 473 of file history.c.

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

514{
515 struct History *h = get_history(hclass);
516 if (!h)
517 return ""; /* disabled */
518
519 int next = h->cur;
520 const short c_history = cs_subset_number(NeoMutt->sub, "history");
521 do
522 {
523 next++;
524 if (next > c_history)
525 next = 0;
526 if (next == h->last)
527 break;
528 } while (!h->hist[next]);
529
530 h->cur = next;
531 return NONULL(h->hist[h->cur]);
532}
#define NONULL(x)
Definition string2.h:44
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 541 of file history.c.

542{
543 struct History *h = get_history(hclass);
544 if (!h)
545 return ""; /* disabled */
546
547 int prev = h->cur;
548 const short c_history = cs_subset_number(NeoMutt->sub, "history");
549 do
550 {
551 prev--;
552 if (prev < 0)
553 prev = c_history;
554 if (prev == h->last)
555 break;
556 } while (!h->hist[prev]);
557
558 h->cur = prev;
559 return NONULL(h->hist[h->cur]);
560}
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 569 of file history.c.

570{
571 struct History *h = get_history(hclass);
572 if (!h)
573 return; /* disabled */
574
575 h->cur = h->last;
576}
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 583 of file history.c.

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

639{
640 struct History *h = get_history(hclass);
641 if (!h)
642 return false; /* disabled */
643
644 return h->cur == h->last;
645}
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 655 of file history.c.

656{
657 struct History *h = get_history(hclass);
658 if (!h)
659 return; /* disabled */
660
661 /* Don't check if str has a value because the scratch buffer may contain
662 * an old garbage value that should be overwritten */
663 mutt_str_replace(&h->hist[h->last], str);
664}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_hist_complete()

void mutt_hist_complete ( struct Buffer * buf,
enum HistoryClass hclass )

Complete a string from a history list.

Parameters
bufBuffer in which to save string
hclassHistory list to use

Definition at line 671 of file history.c.

672{
673 struct StringArray matches = ARRAY_HEAD_INITIALIZER;
674
675 int match_count = mutt_hist_search(buf_string(buf), hclass, &matches);
676 if (match_count != 0)
677 {
678 if (match_count == 1)
679 {
680 const char **pstr = ARRAY_GET(&matches, 0);
681 buf_strcpy(buf, *pstr);
682 }
683 else
684 {
685 dlg_history(buf, &matches);
686 }
687 }
688
689 ARRAY_FREE(&matches);
690}
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void dlg_history(struct Buffer *buf, struct StringArray *matches)
Select an item from a history list -.
int mutt_hist_search(const char *find, enum HistoryClass hclass, struct StringArray *matches)
Find matches in a history list.
Definition history.c:398
Here is the call graph for this function:
Here is the caller graph for this function: