NeoMutt  2024-10-02-37-gfa9146
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 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 *search_buf, enum HistoryClass hclass, char **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 (char *buf, size_t buflen, 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 85 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 112 of file history.c.

113{
114 const short c_history = cs_subset_number(NeoMutt->sub, "history");
115 if ((hclass >= HC_MAX) || (c_history == 0))
116 return NULL;
117
118 struct History *hist = &Histories[hclass];
119 return hist->hist ? hist : NULL;
120}
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:58
static struct History Histories[HC_MAX]
Command histories, one for each HistoryClass.
Definition: history.c:102
Saved list of user-entered commands/searches.
Definition: history.c:93
char ** hist
Array of history items.
Definition: history.c:94
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 128 of file history.c.

129{
130 if (OldSize != 0)
131 {
132 if (h->hist)
133 {
134 for (int i = 0; i <= OldSize; i++)
135 FREE(&h->hist[i]);
136 FREE(&h->hist);
137 }
138 }
139
140 const short c_history = cs_subset_number(NeoMutt->sub, "history");
141 if (c_history != 0)
142 h->hist = mutt_mem_calloc(c_history + 1, sizeof(char *));
143
144 h->cur = 0;
145 h->last = 0;
146}
static int OldSize
The previous number of history entries to save.
Definition: history.c:105
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
#define FREE(x)
Definition: memory.h:45
short cur
Current history item.
Definition: history.c:95
short last
Last history item.
Definition: history.c:96
+ 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 158 of file history.c.

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

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

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

322{
323 static int n = 0;
324
325 if (!str || (*str == '\0')) // This shouldn't happen, but it's safer
326 return;
327
328 const char *const c_history_file = cs_subset_path(NeoMutt->sub, "history_file");
329 FILE *fp = mutt_file_fopen(c_history_file, "a");
330 if (!fp)
331 return;
332
333 char *tmp = mutt_str_dup(str);
335
336 // If tmp contains '\n' terminate it there.
337 char *nl = strchr(tmp, '\n');
338 if (nl)
339 *nl = '\0';
340
341 /* Format of a history item (1 line): "<histclass>:<string>|".
342 * We add a '|' in order to avoid lines ending with '\'. */
343 fprintf(fp, "%d:%s|\n", (int) hclass, tmp);
344
345 mutt_file_fclose(&fp);
346 FREE(&tmp);
347
348 if (--n < 0)
349 {
350 const short c_save_history = cs_subset_number(NeoMutt->sub, "save_history");
351 n = c_save_history;
353 }
354}
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:205
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:73
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 366 of file history.c.

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

417{
418 if (!search_buf || !matches)
419 return 0;
420
421 struct History *h = get_history(hclass);
422 if (!h)
423 return 0;
424
425 int match_count = 0;
426 int cur = h->last;
427 const short c_history = cs_subset_number(NeoMutt->sub, "history");
428 do
429 {
430 cur--;
431 if (cur < 0)
432 cur = c_history;
433 if (cur == h->last)
434 break;
435 if (mutt_istr_find(h->hist[cur], search_buf))
436 matches[match_count++] = h->hist[cur];
437 } while (match_count < c_history);
438
439 return match_count;
440}
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 445 of file history.c.

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

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

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

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

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

587{
588 struct History *h = get_history(hclass);
589 if (!h)
590 return; /* disabled */
591
592 h->cur = h->last;
593}
+ 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 600 of file history.c.

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

653{
654 struct History *h = get_history(hclass);
655 if (!h)
656 return false; /* disabled */
657
658 return h->cur == h->last;
659}
+ 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 669 of file history.c.

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

◆ mutt_hist_complete()

void mutt_hist_complete ( char *  buf,
size_t  buflen,
enum HistoryClass  hclass 
)

Complete a string from a history list.

Parameters
bufBuffer in which to save string
buflenBuffer length
hclassHistory list to use

Definition at line 686 of file history.c.

687{
688 const short c_history = cs_subset_number(NeoMutt->sub, "history");
689 char **matches = mutt_mem_calloc(c_history, sizeof(char *));
690 int match_count = mutt_hist_search(buf, hclass, matches);
691 if (match_count)
692 {
693 if (match_count == 1)
694 mutt_str_copy(buf, matches[0], buflen);
695 else
696 dlg_history(buf, buflen, matches, match_count);
697 }
698 FREE(&matches);
699}
void dlg_history(char *buf, size_t buflen, char **matches, int match_count)
Select an item from a history list -.
Definition: dlg_history.c:139
int mutt_hist_search(const char *search_buf, enum HistoryClass hclass, char **matches)
Find matches in a history list.
Definition: history.c:416
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
+ 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 102 of file history.c.

◆ OldSize

int OldSize = 0
static

The previous number of history entries to save.

See also
$history

Definition at line 105 of file history.c.