aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/getchar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/getchar.c')
-rw-r--r--src/nvim/getchar.c187
1 files changed, 98 insertions, 89 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 73af78d3e2..64c9c5a8c3 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -22,37 +22,42 @@
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
+#include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
-#include "nvim/func_attr.h"
#include "nvim/garray.h"
+#include "nvim/garray_defs.h"
#include "nvim/getchar.h"
-#include "nvim/gettext.h"
+#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
#include "nvim/input.h"
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
#include "nvim/lua/executor.h"
-#include "nvim/macros_defs.h"
#include "nvim/main.h"
#include "nvim/mapping.h"
+#include "nvim/mapping_defs.h"
#include "nvim/mbyte.h"
+#include "nvim/mbyte_defs.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
+#include "nvim/normal_defs.h"
#include "nvim/ops.h"
#include "nvim/option_vars.h"
#include "nvim/os/fileio.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
#include "nvim/plines.h"
#include "nvim/pos_defs.h"
#include "nvim/state.h"
+#include "nvim/state_defs.h"
#include "nvim/strings.h"
#include "nvim/types_defs.h"
#include "nvim/ui.h"
@@ -60,8 +65,9 @@
#include "nvim/vim_defs.h"
/// Index in scriptin
-static int curscript = 0;
-FileDescriptor *scriptin[NSCRIPT] = { NULL };
+static int curscript = -1;
+/// Streams to read script from
+static FileDescriptor scriptin[NSCRIPT] = { 0 };
// These buffers are used for storing:
// - stuffed characters: A command that is translated into another command.
@@ -92,7 +98,7 @@ static int typeahead_char = 0; ///< typeahead char that's not flushed
/// When block_redo is true the redo buffer will not be changed.
/// Used by edit() to repeat insertions.
-static int block_redo = false;
+static bool block_redo = false;
static int KeyNoremap = 0; ///< remapping flags
@@ -190,15 +196,12 @@ static char *get_buffcont(buffheader_T *buffer, int dozero)
/// K_SPECIAL in the returned string is escaped.
char *get_recorded(void)
{
- char *p;
- size_t len;
-
- p = get_buffcont(&recordbuff, true);
+ char *p = get_buffcont(&recordbuff, true);
free_buff(&recordbuff);
// Remove the characters that were added the last time, these must be the
// (possibly mapped) characters that stopped the recording.
- len = strlen(p);
+ size_t len = strlen(p);
if (len >= last_recorded_len) {
len -= last_recorded_len;
p[len] = NUL;
@@ -274,12 +277,10 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle
/// Only works when it was just added.
static void delete_buff_tail(buffheader_T *buf, int slen)
{
- int len;
-
if (buf->bh_curr == NULL) {
return; // nothing to delete
}
- len = (int)strlen(buf->bh_curr->b_str);
+ int len = (int)strlen(buf->bh_curr->b_str);
if (len < slen) {
return;
}
@@ -333,18 +334,16 @@ static void add_char_buff(buffheader_T *buf, int c)
/// if that one is empty.
/// If advance == true go to the next char.
/// No translation is done K_SPECIAL is escaped.
-static int read_readbuffers(int advance)
+static int read_readbuffers(bool advance)
{
- int c;
-
- c = read_readbuf(&readbuf1, advance);
+ int c = read_readbuf(&readbuf1, advance);
if (c == NUL) {
c = read_readbuf(&readbuf2, advance);
}
return c;
}
-static int read_readbuf(buffheader_T *buf, int advance)
+static int read_readbuf(buffheader_T *buf, bool advance)
{
if (buf->bh_first.b_next == NULL) { // buffer is empty
return NUL;
@@ -376,16 +375,16 @@ static void start_stuff(void)
}
}
-/// Return true if the stuff buffer is empty.
-int stuff_empty(void)
+/// @return true if the stuff buffer is empty.
+bool stuff_empty(void)
FUNC_ATTR_PURE
{
return (readbuf1.bh_first.b_next == NULL && readbuf2.bh_first.b_next == NULL);
}
-/// Return true if readbuf1 is empty. There may still be redo characters in
-/// redbuf2.
-int readbuf1_empty(void)
+/// @return true if readbuf1 is empty. There may still be redo characters in
+/// redbuf2.
+bool readbuf1_empty(void)
FUNC_ATTR_PURE
{
return (readbuf1.bh_first.b_next == NULL);
@@ -1002,7 +1001,7 @@ int ins_char_typebuf(int c, int modifiers)
unsigned len = special_to_buf(c, modifiers, true, buf);
assert(len < sizeof(buf));
buf[len] = NUL;
- (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
+ ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
return (int)len;
}
@@ -1148,10 +1147,10 @@ static void gotchars(const uint8_t *chars, size_t len)
maptick++;
}
-/// Record a <Nop> key.
-void gotchars_nop(void)
+/// Record an <Ignore> key.
+void gotchars_ignore(void)
{
- uint8_t nop_buf[3] = { K_SPECIAL, KS_EXTRA, KE_NOP };
+ uint8_t nop_buf[3] = { K_SPECIAL, KS_EXTRA, KE_IGNORE };
gotchars(nop_buf, 3);
}
@@ -1178,7 +1177,7 @@ void ungetchars(int len)
void may_sync_undo(void)
{
if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used)
- && scriptin[curscript] == NULL) {
+ && curscript < 0) {
u_sync(false);
}
}
@@ -1218,8 +1217,9 @@ void free_typebuf(void)
/// restored when "file" has been read completely.
static typebuf_T saved_typebuf[NSCRIPT];
-void save_typebuf(void)
+static void save_typebuf(void)
{
+ assert(curscript >= 0);
init_typebuf();
saved_typebuf[curscript] = typebuf;
alloc_typebuf();
@@ -1294,18 +1294,13 @@ void openscript(char *name, bool directly)
return;
}
- if (scriptin[curscript] != NULL) { // already reading script
- curscript++;
- }
+ curscript++;
// use NameBuff for expanded name
expand_env(name, NameBuff, MAXPATHL);
- int error;
- if ((scriptin[curscript] = file_open_new(&error, NameBuff,
- kFileReadOnly, 0)) == NULL) {
+ int error = file_open(&scriptin[curscript], NameBuff, kFileReadOnly, 0);
+ if (error) {
semsg(_(e_notopen_2), name, os_strerror(error));
- if (curscript) {
- curscript--;
- }
+ curscript--;
return;
}
save_typebuf();
@@ -1316,7 +1311,6 @@ void openscript(char *name, bool directly)
// always, "make test" would fail.
if (directly) {
oparg_T oa;
- int oldcurscript;
int save_State = State;
int save_restart_edit = restart_edit;
int save_finish_op = finish_op;
@@ -1328,12 +1322,12 @@ void openscript(char *name, bool directly)
clear_oparg(&oa);
finish_op = false;
- oldcurscript = curscript;
+ int oldcurscript = curscript;
do {
update_topline_cursor(); // update cursor position and topline
normal_cmd(&oa, false); // execute one command
- (void)vpeekc(); // check for end of file
- } while (scriptin[oldcurscript] != NULL);
+ vpeekc(); // check for end of file
+ } while (curscript >= oldcurscript);
State = save_State;
msg_scroll = save_msg_scroll;
@@ -1345,31 +1339,53 @@ void openscript(char *name, bool directly)
/// Close the currently active input script.
static void closescript(void)
{
+ assert(curscript >= 0);
free_typebuf();
typebuf = saved_typebuf[curscript];
- file_free(scriptin[curscript], false);
- scriptin[curscript] = NULL;
- if (curscript > 0) {
- curscript--;
- }
+ file_close(&scriptin[curscript], false);
+ curscript--;
}
#if defined(EXITFREE)
void close_all_scripts(void)
{
- while (scriptin[0] != NULL) {
+ while (curscript >= 0) {
closescript();
}
}
#endif
+bool open_scriptin(char *scriptin_name)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(curscript == -1);
+ curscript++;
+
+ int error;
+ if (strequal(scriptin_name, "-")) {
+ error = file_open_stdin(&scriptin[0]);
+ } else {
+ error = file_open(&scriptin[0], scriptin_name,
+ kFileReadOnly|kFileNonBlocking, 0);
+ }
+ if (error) {
+ fprintf(stderr, _("Cannot open for reading: \"%s\": %s\n"),
+ scriptin_name, os_strerror(error));
+ curscript--;
+ return false;
+ }
+ save_typebuf();
+
+ return true;
+}
+
/// Return true when reading keys from a script file.
int using_script(void)
FUNC_ATTR_PURE
{
- return scriptin[curscript] != NULL;
+ return curscript >= 0;
}
/// This function is called just before doing a blocking wait. Thus after
@@ -1452,8 +1468,6 @@ int vgetc(void)
mouse_row = old_mouse_row;
mouse_col = old_mouse_col;
} else {
- int c2;
- int n;
// number of characters recorded from the last vgetc() call
static size_t last_vgetc_recorded_len = 0;
@@ -1483,7 +1497,7 @@ int vgetc(void)
int save_allow_keys = allow_keys;
no_mapping++;
allow_keys = 0; // make sure BS is not found
- c2 = vgetorpeek(true); // no mapping for these chars
+ int c2 = vgetorpeek(true); // no mapping for these chars
c = vgetorpeek(true);
no_mapping--;
allow_keys = save_allow_keys;
@@ -1576,6 +1590,7 @@ int vgetc(void)
// For a multi-byte character get all the bytes and return the
// converted character.
// Note: This will loop until enough bytes are received!
+ int n;
if ((n = MB_BYTE2LEN_CHECK(c)) > 1) {
no_mapping++;
buf[0] = (uint8_t)c;
@@ -1584,8 +1599,8 @@ int vgetc(void)
if (buf[i] == K_SPECIAL) {
// Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
// which represents a K_SPECIAL (0x80).
- (void)vgetorpeek(true); // skip KS_SPECIAL
- (void)vgetorpeek(true); // skip KE_FILLER
+ vgetorpeek(true); // skip KS_SPECIAL
+ vgetorpeek(true); // skip KE_FILLER
}
}
no_mapping--;
@@ -1607,7 +1622,7 @@ int vgetc(void)
&& !is_mouse_key(c)) {
mod_mask = 0;
int len = ins_char_typebuf(c, 0);
- (void)ins_char_typebuf(ESC, 0);
+ ins_char_typebuf(ESC, 0);
ungetchars(len + 3); // K_SPECIAL KS_MODIFIER MOD_MASK_ALT takes 3 more bytes
continue;
}
@@ -1639,9 +1654,7 @@ int vgetc(void)
/// directly from the user (ignoring typeahead).
int safe_vgetc(void)
{
- int c;
-
- c = vgetc();
+ int c = vgetc();
if (c == NUL) {
c = get_keystroke(NULL);
}
@@ -1679,9 +1692,7 @@ int vpeekc(void)
/// buffer, it must be an ESC that is recognized as the start of a key code.
int vpeekc_any(void)
{
- int c;
-
- c = vpeekc();
+ int c = vpeekc();
if (c == NUL && typebuf.tb_len > 0) {
c = ESC;
}
@@ -1692,10 +1703,8 @@ int vpeekc_any(void)
/// @return true if a character is available, false otherwise.
bool char_avail(void)
{
- int retval;
-
no_mapping++;
- retval = vpeekc();
+ int retval = vpeekc();
no_mapping--;
return retval != NUL;
}
@@ -1721,7 +1730,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
if (!char_avail()) {
// Flush screen updates before blocking.
ui_flush();
- (void)os_inchar(NULL, 0, -1, typebuf.tb_change_cnt, main_loop.events);
+ os_inchar(NULL, 0, -1, typebuf.tb_change_cnt, main_loop.events);
if (!multiqueue_empty(main_loop.events)) {
state_handle_k_event();
continue;
@@ -1794,7 +1803,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
if (win == NULL) {
return;
}
- (void)mouse_comp_pos(win, &row, &col, &lnum);
+ mouse_comp_pos(win, &row, &col, &lnum);
for (wp = firstwin; wp != win; wp = wp->w_next) {
winnr++;
}
@@ -1950,7 +1959,6 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
mapblock_T *mp_match;
int mp_match_len = 0;
int max_mlen = 0;
- int tb_c1;
int keylen = *keylenp;
int local_State = get_real_state();
bool is_plug_map = false;
@@ -1974,7 +1982,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
// - waiting for "hit return to continue" and CR or SPACE typed
// - waiting for a char with --more--
// - in Ctrl-X mode, and we get a valid char for that mode
- tb_c1 = typebuf.tb_buf[typebuf.tb_off];
+ int tb_c1 = typebuf.tb_buf[typebuf.tb_off];
if (no_mapping == 0
&& (no_zero_mapping == 0 || tb_c1 != '0')
&& (typebuf.tb_maplen == 0 || is_plug_map
@@ -2190,7 +2198,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
// mode temporarily. Append K_SELECT to switch back to Select mode.
if (VIsual_active && VIsual_select && (mp->m_mode & MODE_VISUAL)) {
VIsual_select = false;
- (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE, 0, true, false);
+ ins_typebuf(K_SELECT_STRING, REMAP_NONE, 0, true, false);
}
// Copy the values from *mp that are used, because evaluating the
@@ -2513,20 +2521,22 @@ static int vgetorpeek(bool advance)
// we are expecting to truncate the trailing
// white-space, so find the last non-white
// character -- webb
- if (did_ai
- && *skipwhite(get_cursor_line_ptr() + curwin->w_cursor.col) == NUL) {
+ if (did_ai && *skipwhite(get_cursor_line_ptr() + curwin->w_cursor.col) == NUL) {
curwin->w_wcol = 0;
ptr = get_cursor_line_ptr();
- chartabsize_T cts;
- init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, 0, ptr, ptr);
- while (cts.cts_ptr < ptr + curwin->w_cursor.col) {
- if (!ascii_iswhite(*cts.cts_ptr)) {
- curwin->w_wcol = cts.cts_vcol;
+ char *endptr = ptr + curwin->w_cursor.col;
+
+ CharsizeArg csarg;
+ CSType cstype = init_charsize_arg(&csarg, curwin, curwin->w_cursor.lnum, ptr);
+ StrCharInfo ci = utf_ptr2StrCharInfo(ptr);
+ int vcol = 0;
+ while (ci.ptr < endptr) {
+ if (!ascii_iswhite(ci.chr.value)) {
+ curwin->w_wcol = vcol;
}
- cts.cts_vcol += lbr_chartabsize(&cts);
- cts.cts_ptr += utfc_ptr2len(cts.cts_ptr);
+ vcol += win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width;
+ ci = utfc_next(ci);
}
- clear_chartabsize_arg(&cts);
curwin->w_wrow = curwin->w_cline_row
+ curwin->w_wcol / curwin->w_width_inner;
@@ -2654,7 +2664,7 @@ static int vgetorpeek(bool advance)
showcmd_idx = typebuf.tb_len - SHOWCMD_COLS;
}
while (showcmd_idx < typebuf.tb_len) {
- (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off + showcmd_idx++]);
+ add_to_showcmd(typebuf.tb_buf[typebuf.tb_off + showcmd_idx++]);
}
curwin->w_wcol = old_wcol;
curwin->w_wrow = old_wrow;
@@ -2755,9 +2765,9 @@ static int vgetorpeek(bool advance)
}
if (timedout && c == ESC) {
- // When recording there will be no timeout. Add a <Nop> after the ESC
- // to avoid that it forms a key code with following characters.
- gotchars_nop();
+ // When recording there will be no timeout. Add an <Ignore> after the
+ // ESC to avoid that it forms a key code with following characters.
+ gotchars_ignore();
}
vgetc_busy--;
@@ -2810,10 +2820,10 @@ int inchar(uint8_t *buf, int maxlen, long wait_time)
// Get a character from a script file if there is one.
// If interrupted: Stop reading script files, close them all.
ptrdiff_t read_size = -1;
- while (scriptin[curscript] != NULL && read_size <= 0 && !ignore_script) {
+ while (curscript >= 0 && read_size <= 0 && !ignore_script) {
char script_char;
if (got_int
- || (read_size = file_read(scriptin[curscript], &script_char, 1)) != 1) {
+ || (read_size = file_read(&scriptin[curscript], &script_char, 1)) != 1) {
// Reached EOF or some error occurred.
// Careful: closescript() frees typebuf.tb_buf[] and buf[] may
// point inside typebuf.tb_buf[]. Don't use buf[] after this!
@@ -2920,7 +2930,6 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
{
garray_T line_ga;
int c1 = -1;
- int c2;
int cmod = 0;
bool aborted = false;
@@ -2947,7 +2956,7 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
// Get two extra bytes for special keys
if (c1 == K_SPECIAL) {
c1 = vgetorpeek(true);
- c2 = vgetorpeek(true);
+ int c2 = vgetorpeek(true);
if (c1 == KS_MODIFIER) {
cmod = c2;
continue;
@@ -3037,7 +3046,7 @@ bool map_execute_lua(bool may_repeat)
Error err = ERROR_INIT;
Array args = ARRAY_DICT_INIT;
- nlua_call_ref(ref, NULL, args, false, &err);
+ nlua_call_ref(ref, NULL, args, kRetNilBool, NULL, &err);
if (err.type != kErrorTypeNone) {
semsg_multiline("E5108: %s", err.msg);
api_clear_error(&err);