NeoMutt  2025-12-11-769-g906513
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
window.c File Reference

GUI ask the user to enter a string. More...

#include "config.h"
#include <stdbool.h>
#include <string.h>
#include <wchar.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "color/lib.h"
#include "complete/lib.h"
#include "history/lib.h"
#include "key/lib.h"
#include "functions.h"
#include "module_data.h"
#include "muttlib.h"
#include "state.h"
#include "wdata.h"
+ Include dependency graph for window.c:

Go to the source code of this file.

Functions

static int my_addwch (struct MuttWindow *win, wchar_t wc)
 Display one wide character on screen.
 
bool self_insert (struct EnterWindowData *wdata, int ch)
 Insert a normal character.
 
static int enter_recalc (struct MuttWindow *win)
 Recalculate the Window data - Implements MuttWindow::recalc() -.
 
static int enter_repaint (struct MuttWindow *win)
 Repaint the Window - Implements MuttWindow::repaint() -.
 
static bool enter_recursor (struct MuttWindow *win)
 Recursor the Window - Implements MuttWindow::recursor() -.
 
int mw_get_field_notify (const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata, get_field_callback_t callback, void *cb_data, const struct MenuDefinition *md, function_dispatcher_t fn_disp)
 Ask the user for a string and call a notify function on keypress.
 
int mw_get_field (const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
 Ask the user for a string -.
 

Variables

static const struct Mapping EditorHelp []
 Help Bar for the Command Line Editor.
 

Detailed Description

GUI ask the user to enter a string.

Authors
  • Richard Russon

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 window.c.

Function Documentation

◆ my_addwch()

static int my_addwch ( struct MuttWindow * win,
wchar_t wc )
static

Display one wide character on screen.

Parameters
winWindow
wcCharacter to display
Return values
OKSuccess
ERRFailure

Definition at line 70 of file window.c.

71{
72 int n = wcwidth(wc);
73 if (IsWPrint(wc) && (n > 0))
74 return mutt_addwch(win, wc);
75 if (!(wc & ~0x7f))
76 return mutt_window_printf(win, "^%c", ((int) wc + 0x40) & 0x7f);
77 if (!(wc & ~0xffff))
78 return mutt_window_printf(win, "\\u%04x", (int) wc);
79 return mutt_window_printf(win, "\\u%08x", (int) wc);
80}
int mutt_addwch(struct MuttWindow *win, wchar_t wc)
Addwch would be provided by an up-to-date curses library.
Definition curs_lib.c:321
#define IsWPrint(wc)
Definition mbyte.h:40
int mutt_window_printf(struct MuttWindow *win, const char *fmt,...)
Write a formatted string to a Window.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ self_insert()

bool self_insert ( struct EnterWindowData * wdata,
int ch )

Insert a normal character.

Parameters
wdataEnter window data
chRaw keypress
Return values
trueIf done (enter pressed)

Definition at line 88 of file window.c.

89{
90 if (!wdata)
91 return true;
92
93 wdata->tabs = 0;
94 wchar_t wc = 0;
95
96 /* quietly ignore all other function keys */
97 if (ch & ~0xff)
98 return false;
99
100 /* gather the bytes into a wide character */
101 {
102 char c = ch;
103 size_t k = mbrtowc(&wc, &c, 1, wdata->mbstate);
104 if (k == ICONV_BUF_TOO_SMALL)
105 {
106 return false;
107 }
108 else if ((k != 0) && (k != 1))
109 {
110 memset(wdata->mbstate, 0, sizeof(*wdata->mbstate));
111 return false;
112 }
113 }
114
115 if (wdata->first && (wdata->flags & MUTT_COMP_CLEAR))
116 {
117 wdata->first = false;
118 if (IsWPrint(wc)) /* why? */
119 {
120 wdata->state->curpos = 0;
121 wdata->state->lastchar = 0;
122 }
123 }
124
125 if ((wc == '\r') || (wc == '\n'))
126 {
127 /* Convert from wide characters */
128 buf_mb_wcstombs(wdata->buffer, wdata->state->wbuf, wdata->state->lastchar);
129 if (!wdata->pass)
130 mutt_hist_add(wdata->hclass, buf_string(wdata->buffer), true);
131
132 if (wdata->cdata)
133 {
134 struct FileCompletionData *cdata = wdata->cdata;
135 if (cdata->multiple)
136 {
137 char **tfiles = NULL;
138 *cdata->numfiles = 1;
139 tfiles = MUTT_MEM_CALLOC(*cdata->numfiles, char *);
140 expand_path(wdata->buffer, false);
141 tfiles[0] = buf_strdup(wdata->buffer);
142 *cdata->files = tfiles;
143 }
144 }
145 return true;
146 }
147 else if (wc && ((wc < ' ') || IsWPrint(wc))) /* why? */
148 {
149 enter_state_resize(wdata->state, wdata->state->lastchar + 1);
150 memmove(wdata->state->wbuf + wdata->state->curpos + 1,
151 wdata->state->wbuf + wdata->state->curpos,
152 (wdata->state->lastchar - wdata->state->curpos) * sizeof(wchar_t));
153 wdata->state->wbuf[wdata->state->curpos++] = wc;
154 wdata->state->lastchar++;
155 }
156 else
157 {
159 mutt_beep(false);
160 }
161
162 return false;
163}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void mutt_beep(bool force)
Irritate the user.
Definition curs_lib.c:69
void enter_state_resize(struct EnterState *es, size_t num)
Make the buffer bigger.
Definition state.c:54
#define MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition wdata.h:43
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:60
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition history.c:469
void buf_mb_wcstombs(struct Buffer *dest, const wchar_t *wstr, size_t wlen)
Convert a string from wide to multibyte characters.
Definition mbyte.c:257
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition charset.h:116
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
size_t curpos
Position of the cursor.
Definition state.h:36
wchar_t * wbuf
Buffer for the string being entered.
Definition state.h:33
size_t lastchar
Position of the last character.
Definition state.h:35
bool pass
Password mode, conceal characters.
Definition wdata.h:63
int tabs
Number of times the user has hit tab.
Definition wdata.h:68
void * cdata
Auto-Completion private data.
Definition wdata.h:58
CompletionFlags flags
Flags, see CompletionFlags.
Definition wdata.h:54
struct Buffer * buffer
struct Buffer for the result
Definition wdata.h:53
bool first
First time through, no input yet.
Definition wdata.h:64
struct EnterState * state
Current state of text entry.
Definition wdata.h:55
mbstate_t * mbstate
Multi-byte state.
Definition wdata.h:67
enum HistoryClass hclass
History to use, e.g. HC_NEO_COMMAND.
Definition wdata.h:56
Input for the file completion function.
Definition curs_lib.h:39
char *** files
List of files selected.
Definition curs_lib.h:42
bool multiple
Allow multiple selections.
Definition curs_lib.h:40
int * numfiles
Number of files selected.
Definition curs_lib.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mw_get_field_notify()

int mw_get_field_notify ( const char * prompt,
struct Buffer * buf,
CompletionFlags complete,
enum HistoryClass hclass,
const struct CompleteOps * comp_api,
void * cdata,
get_field_callback_t callback,
void * cb_data,
const struct MenuDefinition * md,
function_dispatcher_t fn_disp )

Ask the user for a string and call a notify function on keypress.

Parameters
[in]promptPrompt
[in]bufBuffer for the result
[in]hclassHistory class to use
[in]completeFlags, see CompletionFlags
[in]comp_apiAuto-completion API
[in]cdataAuto-completion private data
[in]callbackCallback function used for notification
[in]cb_dataData to pass to callback function
[in]mdMenu Definition
[in]fn_dispFunction dispatcher
Return values
0Selection made
-1Aborted

Definition at line 266 of file window.c.

270{
272 ASSERT(mod_data);
273
276
278 if (complete & MUTT_COMP_UNBUFFERED)
279 flags = GETCH_IGNORE_MACRO;
280
281 struct Buffer *cbuf = NULL;
282 if (callback)
283 cbuf = buf_pool_get();
284
285 if (!md)
286 md = mod_data->md_editor;
287
288 int rc = 0;
289
290 struct EnterState *es = enter_state_new();
291
292 win->help_data = EditorHelp;
293 win->help_md = mod_data->md_editor;
294
296 struct MuttWindow *old_focus = window_set_focus(win);
297
298 mbstate_t mbstate = { 0 };
299 // clang-format off
300 struct EnterWindowData wdata = { buf, complete, es, hclass, comp_api, cdata, prompt, ENTER_REDRAW_NONE, (complete & MUTT_COMP_PASS), true, NULL, 0, &mbstate, 0, false, NULL, 0, 0 };
301 // clang-format on
302
303 win->wdata = &wdata;
304 win->wdata_free = NULL; // No need, we hold the data
305 win->recalc = enter_recalc;
306 win->repaint = enter_repaint;
308
309 window_redraw(win);
310
311 if (es->wbuf[0] == L'\0')
312 {
313 /* Initialise wbuf from buf */
314 wdata.state->wbuflen = 0;
315 wdata.state->lastchar = mutt_mb_mbstowcs(&wdata.state->wbuf, &wdata.state->wbuflen,
316 0, buf_string(wdata.buffer));
318 }
319 else
320 {
322 wdata.first = false;
323 }
324
325 do
326 {
327 memset(&mbstate, 0, sizeof(mbstate));
328
329 do
330 {
331 if (wdata.redraw != ENTER_REDRAW_NONE)
332 win->actions |= WA_REPAINT;
333
335 window_redraw(NULL);
337 struct KeyEvent event = km_dokey(md, flags);
338 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
339 {
340 continue;
341 }
342
343 if (event.op == OP_ABORT)
344 {
345 rc = -1;
346 goto bye;
347 }
348
349 if (event.op == OP_NULL)
350 {
351 if (complete & MUTT_COMP_PASS)
352 mutt_debug(LL_DEBUG5, "Got char *\n");
353 else
354 mutt_debug(LL_DEBUG5, "Got char %c (0x%02x)\n", event.ch, event.ch);
355
356 if (self_insert(&wdata, event.ch))
357 {
358 rc = 0;
359 goto bye;
360 }
361 win->actions |= WA_REPAINT;
362 goto notify;
363 }
364 else
365 {
366 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(event.op),
367 event.op);
368 }
369
370 wdata.first = false;
371 if ((event.op != OP_EDITOR_COMPLETE) && (event.op != OP_EDITOR_COMPLETE_QUERY))
372 wdata.tabs = 0;
373
375
376 int rc_disp = FR_UNKNOWN;
377 if (fn_disp)
378 {
379 rc_disp = fn_disp(cb_data, &event);
380 if (rc_disp == FR_SUCCESS)
381 rc_disp = FR_CONTINUE;
382 }
383
384 if (rc_disp == FR_UNKNOWN)
385 rc_disp = enter_function_dispatcher(win, &event);
386
387 switch (rc_disp)
388 {
389 case FR_NO_ACTION:
390 {
391 if (self_insert(&wdata, event.ch))
392 {
393 rc = 0;
394 goto bye;
395 }
396 break;
397 }
398 case FR_CONTINUE: // repaint
399 rc = 1;
400 goto bye;
401
402 case FR_DONE:
403 wdata.done = true;
404 rc = 0;
405 break;
406
407 case FR_SUCCESS:
408 rc = 0;
409 break;
410
411 case FR_UNKNOWN:
412 case FR_ERROR:
413 default:
414 mutt_beep(false);
415 }
416
417 notify:
418 if (callback)
419 {
420 buf_mb_wcstombs(cbuf, wdata.state->wbuf, wdata.state->lastchar);
421 callback(buf_string(cbuf), cb_data);
422 }
423
424 } while (!wdata.done);
425
426 bye:
428 FREE(&wdata.tempbuf);
429 } while (rc == 1);
430
431 completion_data_free(&wdata.cd);
433 window_set_focus(old_focus);
434 mutt_window_free(&win);
435
436 if (rc == 0)
437 buf_fix_dptr(buf);
438 else
439 buf_reset(buf);
440
441 buf_pool_release(&cbuf);
442
443 enter_state_free(&es);
444
445 return rc;
446}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:182
void completion_data_free(struct CompletionData **ptr)
Free the Completion Data.
Definition data.c:53
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
@ FR_CONTINUE
Remain in the Dialog.
Definition dispatcher.h:35
@ FR_NO_ACTION
Valid function - no action performed.
Definition dispatcher.h:38
struct EnterState * enter_state_new(void)
Create a new EnterState.
Definition state.c:74
void enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition state.c:38
#define MUTT_COMP_PASS
Password mode (no echo)
Definition wdata.h:44
#define MUTT_COMP_UNBUFFERED
Ignore macro buffer.
Definition wdata.h:45
@ ENTER_REDRAW_NONE
Nothing to redraw.
Definition wdata.h:36
@ ENTER_REDRAW_LINE
Redraw entire line.
Definition wdata.h:38
@ ENTER_REDRAW_INIT
Go to end of line and redraw.
Definition wdata.h:37
static const struct Mapping EditorHelp[]
Help Bar for the Command Line Editor.
Definition window.c:48
bool self_insert(struct EnterWindowData *wdata, int ch)
Insert a normal character.
Definition window.c:88
struct KeyEvent km_dokey(const struct MenuDefinition *md, GetChFlags flags)
Determine what a keypress should do.
Definition get.c:437
uint8_t GetChFlags
Flags for mutt_getch(), e.g. GETCH_NO_FLAGS.
Definition get.h:33
#define GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition get.h:35
#define GETCH_NO_FLAGS
No flags are set.
Definition get.h:34
int enter_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform an Enter function - Implements function_dispatcher_t -.
Definition functions.c:532
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
static int enter_recalc(struct MuttWindow *win)
Recalculate the Window data - Implements MuttWindow::recalc() -.
Definition window.c:170
static bool enter_recursor(struct MuttWindow *win)
Recursor the Window - Implements MuttWindow::recursor() -.
Definition window.c:243
static int enter_repaint(struct MuttWindow *win)
Repaint the Window - Implements MuttWindow::repaint() -.
Definition window.c:181
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the 'current' position to the end of the History.
Definition history.c:565
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, const char *buf)
Convert a string from multibyte to wide characters.
Definition mbyte.c:292
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
@ MODULE_ID_EDITOR
ModuleEditor, Edit a string
Definition module_api.h:63
void msgcont_push_window(struct MuttWindow *win)
Add a window to the Container Stack.
Definition msgcont.c:105
struct MuttWindow * msgcont_pop_window(void)
Remove the last Window from the Container Stack.
Definition msgcont.c:60
enum MuttCursorState mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition mutt_curses.c:94
@ MUTT_CURSOR_INVISIBLE
Hide the cursor.
Definition mutt_curses.h:65
@ MUTT_CURSOR_VISIBLE
Display a normal cursor.
Definition mutt_curses.h:66
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
@ WT_CUSTOM
Window with a custom drawing function.
Definition mutt_window.h:94
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition mutt_window.h:38
#define WA_REPAINT
Redraw the contents of the Window.
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition mutt_window.h:52
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition mutt_window.h:47
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
#define OP_TIMEOUT
1 second with no events
Definition opcodes.h:35
#define OP_REPAINT
Repaint is needed.
Definition opcodes.h:34
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition opcodes.h:36
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define ASSERT(COND)
Definition signal2.h:59
String manipulation buffer.
Definition buffer.h:36
Editor private Module data.
Definition module_data.h:30
struct MenuDefinition * md_editor
Editor Menu Definition.
Definition module_data.h:32
Keep our place when entering a string.
Definition state.h:32
size_t wbuflen
Length of buffer.
Definition state.h:34
Data to fill the Enter Window.
Definition wdata.h:51
struct CompletionData * cd
Auto-completion state data.
Definition wdata.h:72
bool done
Is text-entry done?
Definition wdata.h:70
wchar_t * tempbuf
Buffer used by completion.
Definition wdata.h:65
const struct CompleteOps * comp_api
Auto-Completion API.
Definition wdata.h:57
const char * prompt
Prompt.
Definition wdata.h:61
enum EnterRedrawFlags redraw
What needs redrawing? See EnterRedrawFlags.
Definition wdata.h:62
An event such as a keypress.
Definition get.h:50
int op
Function opcode, e.g. OP_HELP.
Definition get.h:52
int ch
Raw key pressed.
Definition get.h:51
const struct Mapping * help_data
Data for the Help Bar.
const struct MenuDefinition * help_md
Menu Definition for key bindings.
int(* repaint)(struct MuttWindow *win)
void * wdata
Private data.
int(* recalc)(struct MuttWindow *win)
void(* wdata_free)(struct MuttWindow *win, void **ptr)
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
bool(* recursor)(struct MuttWindow *win)
Container for Accounts, Notifications.
Definition neomutt.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ EditorHelp

const struct Mapping EditorHelp[]
static
Initial value:
= {
{ N_("Help"), OP_HELP },
{ N_("Complete"), OP_EDITOR_COMPLETE },
{ N_("Hist Up"), OP_EDITOR_HISTORY_UP },
{ N_("Hist Down"), OP_EDITOR_HISTORY_DOWN },
{ N_("Hist Search"), OP_EDITOR_HISTORY_SEARCH },
{ N_("Begin Line"), OP_EDITOR_BOL },
{ N_("End Line"), OP_EDITOR_EOL },
{ N_("Kill Line"), OP_EDITOR_KILL_LINE },
{ N_("Kill Word"), OP_EDITOR_KILL_WORD },
{ NULL, 0 },
}
#define N_(a)
Definition message.h:32

Help Bar for the Command Line Editor.

Definition at line 48 of file window.c.

48 {
49 // clang-format off
50 { N_("Help"), OP_HELP },
51 { N_("Complete"), OP_EDITOR_COMPLETE },
52 { N_("Hist Up"), OP_EDITOR_HISTORY_UP },
53 { N_("Hist Down"), OP_EDITOR_HISTORY_DOWN },
54 { N_("Hist Search"), OP_EDITOR_HISTORY_SEARCH },
55 { N_("Begin Line"), OP_EDITOR_BOL },
56 { N_("End Line"), OP_EDITOR_EOL },
57 { N_("Kill Line"), OP_EDITOR_KILL_LINE },
58 { N_("Kill Word"), OP_EDITOR_KILL_WORD },
59 { NULL, 0 },
60 // clang-format on
61};