NeoMutt  2024-11-14-34-g5aaf0d
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 <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "lib.h"
#include "functions.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_EXT_COMMAND
 

Functions

static struct Historyget_history (enum HistoryClass hclass)
 Get a particular history.
 
static void init_history (struct History *h)
 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 HistoryArray *matches)
 Find matches in a history list.
 
void mutt_hist_cleanup (void)
 Free all the history lists.
 
void mutt_hist_init (void)
 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 -.
 

Variables

static struct History Histories [HC_MAX]
 Command histories, one for each HistoryClass.
 
static int OldSize = 0
 The previous number of history entries to save.
 

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

114{
115 const short c_history = cs_subset_number(NeoMutt->sub, "history");
116 if ((hclass >= HC_MAX) || (c_history == 0))
117 return NULL;
118
119 struct History *hist = &Histories[hclass];
120 return hist->hist ? hist : NULL;
121}
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:61
static struct History Histories[HC_MAX]
Command histories, one for each HistoryClass.
Definition: history.c:103
Saved list of user-entered commands/searches.
Definition: history.c:94
char ** hist
Array of history items.
Definition: history.c:95
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
+ 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 129 of file history.c.

130{
131 if (OldSize != 0)
132 {
133 if (h->hist)
134 {
135 for (int i = 0; i <= OldSize; i++)
136 FREE(&h->hist[i]);
137 FREE(&h->hist);
138 }
139 }
140
141 const short c_history = cs_subset_number(NeoMutt->sub, "history");
142 if (c_history != 0)
143 h->hist = MUTT_MEM_CALLOC(c_history + 1, char *);
144
145 h->cur = 0;
146 h->last = 0;
147}
static int OldSize
The previous number of history entries to save.
Definition: history.c:106
#define FREE(x)
Definition: memory.h:55
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
short cur
Current history item.
Definition: history.c:96
short last
Last history item.
Definition: history.c:97
+ 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 159 of file history.c.

160{
161 struct HashElem *he = mutt_hash_find_elem(dup_hash, str);
162 if (!he)
163 return -1;
164
165 uintptr_t count = (uintptr_t) he->data;
166 if (count <= 1)
167 {
168 mutt_hash_delete(dup_hash, str, NULL);
169 return 0;
170 }
171
172 count--;
173 he->data = (void *) count;
174 return count;
175}
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:43
void * data
User-supplied data.
Definition: hash.h:46
+ 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 185 of file history.c.

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

207{
208 FILE *fp_tmp = NULL;
209 int n[HC_MAX] = { 0 };
210 int line, hclass = 0, read = 0;
211 char *linebuf = NULL, *p = NULL;
212 size_t buflen;
213 bool regen_file = false;
214 struct HashTable *dup_hashes[HC_MAX] = { 0 };
215
216 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
217 FILE *fp = mutt_file_fopen(c_history_file, "r");
218 if (!fp)
219 return;
220
221 const bool c_history_remove_dups = cs_subset_bool(NeoMutt->sub, "history_remove_dups");
222 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
223 if (c_history_remove_dups)
224 {
225 for (hclass = 0; hclass < HC_MAX; hclass++)
226 dup_hashes[hclass] = mutt_hash_new(MAX(10, c_save_history * 2), MUTT_HASH_STRDUP_KEYS);
227 }
228
229 line = 0;
230 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
231 {
232 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
233 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
234 {
235 mutt_error(_("%s:%d: Bad history file format"), c_history_file, line);
236 regen_file = true;
237 continue;
238 }
239 /* silently ignore too high class (probably newer neomutt) */
240 if (hclass >= HC_MAX)
241 continue;
242 *p = '\0';
243 if (c_history_remove_dups && (dup_hash_inc(dup_hashes[hclass], linebuf + read) > 1))
244 {
245 regen_file = true;
246 continue;
247 }
248 n[hclass]++;
249 }
250
251 if (!regen_file)
252 {
253 for (hclass = HC_FIRST; hclass < HC_MAX; hclass++)
254 {
255 if (n[hclass] > c_save_history)
256 {
257 regen_file = true;
258 break;
259 }
260 }
261 }
262
263 if (regen_file)
264 {
265 fp_tmp = mutt_file_mkstemp();
266 if (!fp_tmp)
267 {
268 mutt_perror(_("Can't create temporary file"));
269 goto cleanup;
270 }
271 rewind(fp);
272 line = 0;
273 while ((linebuf = mutt_file_read_line(linebuf, &buflen, fp, &line, MUTT_RL_NO_FLAGS)))
274 {
275 if ((sscanf(linebuf, "%d:%n", &hclass, &read) < 1) || (read == 0) ||
276 (*(p = linebuf + strlen(linebuf) - 1) != '|') || (hclass < 0))
277 {
278 continue;
279 }
280 if (hclass >= HC_MAX)
281 continue;
282 *p = '\0';
283 if (c_history_remove_dups && (dup_hash_dec(dup_hashes[hclass], linebuf + read) > 0))
284 {
285 continue;
286 }
287 *p = '|';
288 if (n[hclass]-- <= c_save_history)
289 fprintf(fp_tmp, "%s\n", linebuf);
290 }
291 }
292
293cleanup:
294 mutt_file_fclose(&fp);
295 FREE(&linebuf);
296 if (fp_tmp)
297 {
298 if (fflush(fp_tmp) == 0)
299 {
300 if (truncate(c_history_file, 0) < 0)
301 mutt_debug(LL_DEBUG1, "truncate: %s\n", strerror(errno));
302 fp = mutt_file_fopen(c_history_file, "w");
303 if (fp)
304 {
305 rewind(fp_tmp);
306 mutt_file_copy_stream(fp_tmp, fp);
307 mutt_file_fclose(&fp);
308 }
309 }
310 mutt_file_fclose(&fp_tmp);
311 }
312 if (c_history_remove_dups)
313 for (hclass = 0; hclass < HC_MAX; hclass++)
314 mutt_hash_free(&dup_hashes[hclass]);
315}
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:287
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:808
#define mutt_file_fclose(FP)
Definition: file.h:138
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:137
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:40
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
#define mutt_perror(...)
Definition: logging2.h:93
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:185
#define HC_FIRST
Definition: history.c:86
static int dup_hash_dec(struct HashTable *dup_hash, char *str)
Decrease the refcount of a history string.
Definition: history.c:159
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#define MAX(a, b)
Definition: memory.h:31
#define _(a)
Definition: message.h:28
A Hash Table.
Definition: hash.h:97
#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()

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

323{
324 static int n = 0;
325
326 if (!str || (*str == '\0')) // This shouldn't happen, but it's safer
327 return;
328
329 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
330 FILE *fp = mutt_file_fopen(c_history_file, "a");
331 if (!fp)
332 return;
333
334 char *tmp = mutt_str_dup(str);
336
337 // If tmp contains '\n' terminate it there.
338 char *nl = strchr(tmp, '\n');
339 if (nl)
340 *nl = '\0';
341
342 /* Format of a history item (1 line): "<histclass>:<string>|".
343 * We add a '|' in order to avoid lines ending with '\'. */
344 fprintf(fp, "%d:%s|\n", (int) hclass, tmp);
345
346 mutt_file_fclose(&fp);
347 FREE(&tmp);
348
349 if (--n < 0)
350 {
351 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
352 n = c_save_history;
354 }
355}
const char * cc_charset(void)
Get the cached value of $charset.
Definition: config_cache.c:116
static void shrink_histfile(void)
Read, de-dupe and write the history file.
Definition: history.c:206
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:831
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:64
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
+ 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 367 of file history.c.

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

418{
419 if (!find || !matches)
420 return 0;
421
422 struct History *h = get_history(hclass);
423 if (!h)
424 return 0;
425
426 int cur = h->last;
427 const short c_history = cs_subset_number(NeoMutt->sub, "history");
428
429 do
430 {
431 cur--;
432 if (cur < 0)
433 cur = c_history;
434
435 if (cur == h->last)
436 break;
437
438 if (mutt_istr_find(h->hist[cur], find))
439 ARRAY_ADD(matches, h->hist[cur]);
440
441 } while (ARRAY_SIZE(matches) < c_history);
442
443 return ARRAY_SIZE(matches);
444}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:156
#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:521
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hist_cleanup()

void mutt_hist_cleanup ( void  )

Free all the history lists.

Definition at line 449 of file history.c.

450{
451 if (!NeoMutt)
452 return;
453
454 const short c_history = cs_subset_number(NeoMutt->sub, "history");
455 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
456 {
457 struct History *h = &Histories[hclass];
458 if (!h->hist)
459 continue;
460
461 /* The array has (`$history`+1) elements */
462 for (int i = 0; i <= c_history; i++)
463 {
464 FREE(&h->hist[i]);
465 }
466 FREE(&h->hist);
467 }
468}
HistoryClass
Type to differentiate different histories.
Definition: lib.h:53
+ 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 476 of file history.c.

477{
478 const short c_history = cs_subset_number(NeoMutt->sub, "history");
479 if (c_history == OldSize)
480 return;
481
482 for (enum HistoryClass hclass = HC_FIRST; hclass < HC_MAX; hclass++)
483 init_history(&Histories[hclass]);
484
485 OldSize = c_history;
486}
static void init_history(struct History *h)
Set up a new History ring buffer.
Definition: history.c:129
+ 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 494 of file history.c.

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

535{
536 struct History *h = get_history(hclass);
537 if (!h)
538 return ""; /* disabled */
539
540 int next = h->cur;
541 const short c_history = cs_subset_number(NeoMutt->sub, "history");
542 do
543 {
544 next++;
545 if (next > c_history)
546 next = 0;
547 if (next == h->last)
548 break;
549 } while (!h->hist[next]);
550
551 h->cur = next;
552 return NONULL(h->hist[h->cur]);
553}
#define NONULL(x)
Definition: string2.h:37
+ 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 562 of file history.c.

563{
564 struct History *h = get_history(hclass);
565 if (!h)
566 return ""; /* disabled */
567
568 int prev = h->cur;
569 const short c_history = cs_subset_number(NeoMutt->sub, "history");
570 do
571 {
572 prev--;
573 if (prev < 0)
574 prev = c_history;
575 if (prev == h->last)
576 break;
577 } while (!h->hist[prev]);
578
579 h->cur = prev;
580 return NONULL(h->hist[h->cur]);
581}
+ 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 590 of file history.c.

591{
592 struct History *h = get_history(hclass);
593 if (!h)
594 return; /* disabled */
595
596 h->cur = h->last;
597}
+ 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 604 of file history.c.

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

657{
658 struct History *h = get_history(hclass);
659 if (!h)
660 return false; /* disabled */
661
662 return h->cur == h->last;
663}
+ 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 673 of file history.c.

674{
675 struct History *h = get_history(hclass);
676 if (!h)
677 return; /* disabled */
678
679 /* Don't check if str has a value because the scratch buffer may contain
680 * an old garbage value that should be overwritten */
681 mutt_str_replace(&h->hist[h->last], str);
682}
+ 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 689 of file history.c.

690{
691 struct HistoryArray matches = ARRAY_HEAD_INITIALIZER;
692
693 int match_count = mutt_hist_search(buf_string(buf), hclass, &matches);
694 if (match_count != 0)
695 {
696 if (match_count == 1)
697 {
698 const char **pstr = ARRAY_GET(&matches, 0);
699 buf_strcpy(buf, *pstr);
700 }
701 else
702 {
703 dlg_history(buf, &matches);
704 }
705 }
706
707 ARRAY_FREE(&matches);
708}
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:204
#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:395
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 HistoryArray *matches)
Select an item from a history list -.
Definition: dlg_history.c:142
int mutt_hist_search(const char *find, enum HistoryClass hclass, struct HistoryArray *matches)
Find matches in a history list.
Definition: history.c:417
+ 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 103 of file history.c.

◆ OldSize

int OldSize = 0
static

The previous number of history entries to save.

See also
$history

Definition at line 106 of file history.c.