mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
ex_getln: refactor command line mode to use the state_enter
loop
Split `getcmdline()` into command_line_{enter,check,execute}`
This commit is contained in:
parent
52d4978b03
commit
0701e1bfa4
@ -160,32 +160,7 @@ static int hislen = 0; /* actual length of history tables */
|
|||||||
static int cmd_hkmap = 0; /* Hebrew mapping during command line */
|
static int cmd_hkmap = 0; /* Hebrew mapping during command line */
|
||||||
|
|
||||||
static int cmd_fkmap = 0; /* Farsi mapping during command line */
|
static int cmd_fkmap = 0; /* Farsi mapping during command line */
|
||||||
|
static uint8_t *command_line_enter(int firstc, long count, int indent)
|
||||||
/*
|
|
||||||
* getcmdline() - accept a command line starting with firstc.
|
|
||||||
*
|
|
||||||
* firstc == ':' get ":" command line.
|
|
||||||
* firstc == '/' or '?' get search pattern
|
|
||||||
* firstc == '=' get expression
|
|
||||||
* firstc == '@' get text for input() function
|
|
||||||
* firstc == '>' get text for debug mode
|
|
||||||
* firstc == NUL get text for :insert command
|
|
||||||
* firstc == -1 like NUL, and break on CTRL-C
|
|
||||||
*
|
|
||||||
* The line is collected in ccline.cmdbuff, which is reallocated to fit the
|
|
||||||
* command line.
|
|
||||||
*
|
|
||||||
* Careful: getcmdline() can be called recursively!
|
|
||||||
*
|
|
||||||
* Return pointer to allocated string if there is a commandline, NULL
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
char_u *
|
|
||||||
getcmdline (
|
|
||||||
int firstc,
|
|
||||||
long count, // only used for incremental search
|
|
||||||
int indent // indent for inside conditionals
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CommandLineState state, *s = &state;
|
CommandLineState state, *s = &state;
|
||||||
memset(s, 0, sizeof(CommandLineState));
|
memset(s, 0, sizeof(CommandLineState));
|
||||||
@ -298,27 +273,100 @@ getcmdline (
|
|||||||
|
|
||||||
did_emsg = false;
|
did_emsg = false;
|
||||||
got_int = false;
|
got_int = false;
|
||||||
|
s->state.check = command_line_check;
|
||||||
|
s->state.execute = command_line_execute;
|
||||||
|
state_enter(&s->state);
|
||||||
|
|
||||||
// Collect the command string, handling editing keys.
|
cmdmsg_rl = false;
|
||||||
for (;;) {
|
|
||||||
|
cmd_fkmap = 0;
|
||||||
|
|
||||||
|
ExpandCleanup(&s->xpc);
|
||||||
|
ccline.xpc = NULL;
|
||||||
|
|
||||||
|
if (s->did_incsearch) {
|
||||||
|
curwin->w_cursor = s->old_cursor;
|
||||||
|
curwin->w_curswant = s->old_curswant;
|
||||||
|
curwin->w_leftcol = s->old_leftcol;
|
||||||
|
curwin->w_topline = s->old_topline;
|
||||||
|
curwin->w_topfill = s->old_topfill;
|
||||||
|
curwin->w_botline = s->old_botline;
|
||||||
|
highlight_match = false;
|
||||||
|
validate_cursor(); // needed for TAB
|
||||||
|
redraw_later(SOME_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ccline.cmdbuff != NULL) {
|
||||||
|
// Put line in history buffer (":" and "=" only when it was typed).
|
||||||
|
if (ccline.cmdlen && s->firstc != NUL
|
||||||
|
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
||||||
|
add_to_history(s->histype, ccline.cmdbuff, true,
|
||||||
|
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
||||||
|
if (s->firstc == ':') {
|
||||||
|
xfree(new_last_cmdline);
|
||||||
|
new_last_cmdline = vim_strsave(ccline.cmdbuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->gotesc) { // abandon command line
|
||||||
|
xfree(ccline.cmdbuff);
|
||||||
|
ccline.cmdbuff = NULL;
|
||||||
|
if (msg_scrolled == 0) {
|
||||||
|
compute_cmdrow();
|
||||||
|
}
|
||||||
|
MSG("");
|
||||||
|
redraw_cmdline = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the screen was shifted up, redraw the whole screen (later).
|
||||||
|
// If the line is too long, clear it, so ruler and shown command do
|
||||||
|
// not get printed in the middle of it.
|
||||||
|
msg_check();
|
||||||
|
msg_scroll = s->save_msg_scroll;
|
||||||
|
redir_off = false;
|
||||||
|
|
||||||
|
// When the command line was typed, no need for a wait-return prompt.
|
||||||
|
if (s->some_key_typed) {
|
||||||
|
need_wait_return = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
State = s->save_State;
|
||||||
|
setmouse();
|
||||||
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
|
|
||||||
|
{
|
||||||
|
char_u *p = ccline.cmdbuff;
|
||||||
|
|
||||||
|
// Make ccline empty, getcmdline() may try to use it.
|
||||||
|
ccline.cmdbuff = NULL;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_line_check(VimState *state)
|
||||||
|
{
|
||||||
redir_off = true; // Don't redirect the typed command.
|
redir_off = true; // Don't redirect the typed command.
|
||||||
// Repeated, because a ":redir" inside
|
// Repeated, because a ":redir" inside
|
||||||
// completion may switch it on.
|
// completion may switch it on.
|
||||||
quit_more = false; // reset after CTRL-D which had a more-prompt
|
quit_more = false; // reset after CTRL-D which had a more-prompt
|
||||||
|
|
||||||
cursorcmd(); // set the cursor on the right spot
|
cursorcmd(); // set the cursor on the right spot
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a character. Ignore K_IGNORE, it should not do anything, such
|
static int command_line_execute(VimState *state, int key)
|
||||||
// as stop completion.
|
{
|
||||||
input_enable_events();
|
if (key == K_IGNORE || key == K_PASTE) {
|
||||||
do {
|
return -1; // get another key
|
||||||
s->c = safe_vgetc();
|
}
|
||||||
} while (s->c == K_IGNORE || s->c == K_PASTE);
|
|
||||||
input_disable_events();
|
CommandLineState *s = (CommandLineState *)state;
|
||||||
|
s->c = key;
|
||||||
|
|
||||||
if (s->c == K_EVENT) {
|
if (s->c == K_EVENT) {
|
||||||
queue_process_events(loop.events);
|
queue_process_events(loop.events);
|
||||||
continue;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyTyped) {
|
if (KeyTyped) {
|
||||||
@ -645,7 +693,7 @@ getcmdline (
|
|||||||
}
|
}
|
||||||
s->gotesc = true; // will free ccline.cmdbuff after putting it
|
s->gotesc = true; // will free ccline.cmdbuff after putting it
|
||||||
// in history
|
// in history
|
||||||
goto returncmd; // back to Normal mode
|
return 0; // back to Normal mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,7 +732,7 @@ getcmdline (
|
|||||||
ui_cursor_goto(msg_row, 0);
|
ui_cursor_goto(msg_row, 0);
|
||||||
ui_flush();
|
ui_flush();
|
||||||
}
|
}
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,7 +942,7 @@ getcmdline (
|
|||||||
msg_putchar(' '); // delete ':'
|
msg_putchar(' '); // delete ':'
|
||||||
}
|
}
|
||||||
redraw_cmdline = true;
|
redraw_cmdline = true;
|
||||||
goto returncmd; // back to cmd mode
|
return 0; // back to cmd mode
|
||||||
}
|
}
|
||||||
goto cmdline_changed;
|
goto cmdline_changed;
|
||||||
|
|
||||||
@ -962,7 +1010,7 @@ getcmdline (
|
|||||||
|
|
||||||
s->gotesc = true; // will free ccline.cmdbuff after
|
s->gotesc = true; // will free ccline.cmdbuff after
|
||||||
// putting it in history
|
// putting it in history
|
||||||
goto returncmd; // back to cmd mode
|
return 0; // back to cmd mode
|
||||||
|
|
||||||
case Ctrl_R: // insert register
|
case Ctrl_R: // insert register
|
||||||
putcmdline('"', true);
|
putcmdline('"', true);
|
||||||
@ -999,7 +1047,7 @@ getcmdline (
|
|||||||
if (aborting()) {
|
if (aborting()) {
|
||||||
s->gotesc = true; // will free ccline.cmdbuff after
|
s->gotesc = true; // will free ccline.cmdbuff after
|
||||||
// putting it in history
|
// putting it in history
|
||||||
goto returncmd; // back to cmd mode
|
return 0; // back to cmd mode
|
||||||
}
|
}
|
||||||
KeyTyped = false; // Don't do p_wc completion.
|
KeyTyped = false; // Don't do p_wc completion.
|
||||||
if (new_cmdpos >= 0) {
|
if (new_cmdpos >= 0) {
|
||||||
@ -1020,7 +1068,7 @@ getcmdline (
|
|||||||
}
|
}
|
||||||
|
|
||||||
redrawcmd();
|
redrawcmd();
|
||||||
continue; // don't do incremental search now
|
return 1; // don't do incremental search now
|
||||||
|
|
||||||
case K_RIGHT:
|
case K_RIGHT:
|
||||||
case K_S_RIGHT:
|
case K_S_RIGHT:
|
||||||
@ -1439,7 +1487,7 @@ getcmdline (
|
|||||||
// (Sorry for the goto's, I know it is ugly).
|
// (Sorry for the goto's, I know it is ugly).
|
||||||
cmdline_not_changed:
|
cmdline_not_changed:
|
||||||
if (!s->incsearch_postponed) {
|
if (!s->incsearch_postponed) {
|
||||||
continue;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdline_changed:
|
cmdline_changed:
|
||||||
@ -1451,7 +1499,7 @@ cmdline_changed:
|
|||||||
// if there is a character waiting, search and redraw later
|
// if there is a character waiting, search and redraw later
|
||||||
if (char_avail()) {
|
if (char_avail()) {
|
||||||
s->incsearch_postponed = true;
|
s->incsearch_postponed = true;
|
||||||
continue;
|
return 1;
|
||||||
}
|
}
|
||||||
s->incsearch_postponed = false;
|
s->incsearch_postponed = false;
|
||||||
curwin->w_cursor = s->old_cursor; // start at old position
|
curwin->w_cursor = s->old_cursor; // start at old position
|
||||||
@ -1543,75 +1591,37 @@ cmdline_changed:
|
|||||||
redrawcmd();
|
redrawcmd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
returncmd:
|
/*
|
||||||
|
* getcmdline() - accept a command line starting with firstc.
|
||||||
cmdmsg_rl = false;
|
*
|
||||||
|
* firstc == ':' get ":" command line.
|
||||||
cmd_fkmap = 0;
|
* firstc == '/' or '?' get search pattern
|
||||||
|
* firstc == '=' get expression
|
||||||
ExpandCleanup(&s->xpc);
|
* firstc == '@' get text for input() function
|
||||||
ccline.xpc = NULL;
|
* firstc == '>' get text for debug mode
|
||||||
|
* firstc == NUL get text for :insert command
|
||||||
if (s->did_incsearch) {
|
* firstc == -1 like NUL, and break on CTRL-C
|
||||||
curwin->w_cursor = s->old_cursor;
|
*
|
||||||
curwin->w_curswant = s->old_curswant;
|
* The line is collected in ccline.cmdbuff, which is reallocated to fit the
|
||||||
curwin->w_leftcol = s->old_leftcol;
|
* command line.
|
||||||
curwin->w_topline = s->old_topline;
|
*
|
||||||
curwin->w_topfill = s->old_topfill;
|
* Careful: getcmdline() can be called recursively!
|
||||||
curwin->w_botline = s->old_botline;
|
*
|
||||||
highlight_match = false;
|
* Return pointer to allocated string if there is a commandline, NULL
|
||||||
validate_cursor(); // needed for TAB
|
* otherwise.
|
||||||
redraw_later(SOME_VALID);
|
*/
|
||||||
}
|
char_u *
|
||||||
|
getcmdline (
|
||||||
if (ccline.cmdbuff != NULL) {
|
int firstc,
|
||||||
// Put line in history buffer (":" and "=" only when it was typed).
|
long count, // only used for incremental search
|
||||||
if (ccline.cmdlen && s->firstc != NUL
|
int indent // indent for inside conditionals
|
||||||
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
)
|
||||||
add_to_history(s->histype, ccline.cmdbuff, true,
|
|
||||||
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
|
||||||
if (s->firstc == ':') {
|
|
||||||
xfree(new_last_cmdline);
|
|
||||||
new_last_cmdline = vim_strsave(ccline.cmdbuff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->gotesc) { // abandon command line
|
|
||||||
xfree(ccline.cmdbuff);
|
|
||||||
ccline.cmdbuff = NULL;
|
|
||||||
if (msg_scrolled == 0) {
|
|
||||||
compute_cmdrow();
|
|
||||||
}
|
|
||||||
MSG("");
|
|
||||||
redraw_cmdline = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the screen was shifted up, redraw the whole screen (later).
|
|
||||||
// If the line is too long, clear it, so ruler and shown command do
|
|
||||||
// not get printed in the middle of it.
|
|
||||||
msg_check();
|
|
||||||
msg_scroll = s->save_msg_scroll;
|
|
||||||
redir_off = false;
|
|
||||||
|
|
||||||
// When the command line was typed, no need for a wait-return prompt.
|
|
||||||
if (s->some_key_typed) {
|
|
||||||
need_wait_return = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
State = s->save_State;
|
|
||||||
setmouse();
|
|
||||||
ui_cursor_shape(); // may show different cursor shape
|
|
||||||
|
|
||||||
{
|
{
|
||||||
char_u *p = ccline.cmdbuff;
|
return command_line_enter(firstc, count, indent);
|
||||||
|
|
||||||
// Make ccline empty, getcmdline() may try to use it.
|
|
||||||
ccline.cmdbuff = NULL;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user