]> granicus.if.org Git - neomutt/blob - mutt_history.c
Fix mutt_write_mime_body() application/pgp-encrypted handling
[neomutt] / mutt_history.c
1 /**
2  * @file
3  * Read/write command history from/to a file
4  *
5  * @authors
6  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 /**
24  * @page mutt_history Read/write command history from/to a file
25  *
26  * Read/write command history from/to a file
27  */
28
29 #include "config.h"
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include "mutt/mutt.h"
33 #include "config/lib.h"
34 #include "mutt.h"
35 #include "curs_lib.h"
36 #include "format_flags.h"
37 #include "keymap.h"
38 #include "mutt_menu.h"
39 #include "mutt_window.h"
40 #include "muttlib.h"
41 #include "opcodes.h"
42
43 static const struct Mapping HistoryHelp[] = {
44   { N_("Exit"), OP_EXIT },
45   { N_("Select"), OP_GENERIC_SELECT_ENTRY },
46   { N_("Search"), OP_SEARCH },
47   { N_("Help"), OP_HELP },
48   { NULL, 0 },
49 };
50
51 /**
52  * history_format_str - Format a string for the history list - Implements ::format_t
53  *
54  * | Expando | Description
55  * |:--------|:--------------
56  * | \%s     | History match
57  */
58 static const char *history_format_str(char *buf, size_t buflen, size_t col, int cols,
59                                       char op, const char *src, const char *prec,
60                                       const char *if_str, const char *else_str,
61                                       unsigned long data, MuttFormatFlags flags)
62 {
63   char *match = (char *) data;
64
65   switch (op)
66   {
67     case 's':
68       mutt_format_s(buf, buflen, prec, match);
69       break;
70   }
71
72   return src;
73 }
74
75 /**
76  * history_make_entry - Format a menu item for the history list - Implements Menu::menu_make_entry()
77  */
78 static void history_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
79 {
80   char *entry = ((char **) menu->data)[line];
81
82   mutt_expando_format(buf, buflen, 0, menu->indexwin->cols, "%s", history_format_str,
83                       (unsigned long) entry, MUTT_FORMAT_ARROWCURSOR);
84 }
85
86 /**
87  * history_menu - Select an item from a history list
88  * @param[in]  buf         Buffer in which to save string
89  * @param[in]  buflen      Buffer length
90  * @param[out] matches     Items to choose from
91  * @param[in]  match_count Number of items
92  */
93 static void history_menu(char *buf, size_t buflen, char **matches, int match_count)
94 {
95   bool done = false;
96   char helpstr[1024];
97   char title[256];
98
99   snprintf(title, sizeof(title), _("History '%s'"), buf);
100
101   struct Menu *menu = mutt_menu_new(MENU_GENERIC);
102   menu->menu_make_entry = history_make_entry;
103   menu->title = title;
104   menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_GENERIC, HistoryHelp);
105   mutt_menu_push_current(menu);
106
107   menu->max = match_count;
108   menu->data = matches;
109
110   while (!done)
111   {
112     switch (mutt_menu_loop(menu))
113     {
114       case OP_GENERIC_SELECT_ENTRY:
115         mutt_str_strfcpy(buf, matches[menu->current], buflen);
116         /* fall through */
117
118       case OP_EXIT:
119         done = true;
120         break;
121     }
122   }
123
124   mutt_menu_pop_current(menu);
125   mutt_menu_free(&menu);
126 }
127
128 /**
129  * mutt_hist_complete - Complete a string from a history list
130  * @param buf    Buffer in which to save string
131  * @param buflen Buffer length
132  * @param hclass History list to use
133  */
134 void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass)
135 {
136   char **matches = mutt_mem_calloc(C_History, sizeof(char *));
137   int match_count = mutt_hist_search(buf, hclass, matches);
138   if (match_count)
139   {
140     if (match_count == 1)
141       mutt_str_strfcpy(buf, matches[0], buflen);
142     else
143       history_menu(buf, buflen, matches, match_count);
144   }
145   FREE(&matches);
146 }
147
148 /**
149  * mutt_hist_observer - Listen for config changes affecting the history - Implements ::observer_t()
150  */
151 int mutt_hist_observer(struct NotifyCallback *nc)
152 {
153   if (!nc)
154     return -1;
155
156   struct EventConfig *ec = (struct EventConfig *) nc->event;
157
158   if (mutt_str_strcmp(ec->name, "history") != 0)
159     return 0;
160
161   mutt_hist_init();
162   return 0;
163 }