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.c136
1 files changed, 79 insertions, 57 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 0f55158733..0a9457ef35 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -81,11 +81,9 @@ static buffheader_T readbuf2 = { { NULL, { NUL } }, NULL, 0, 0 };
static int typeahead_char = 0; // typeahead char that's not flushed
-/*
- * when block_redo is TRUE redo buffer will not be changed
- * used by edit() to repeat insertions and 'V' command for redoing
- */
-static int block_redo = FALSE;
+// when block_redo is true redo buffer will not be changed
+// used by edit() to repeat insertions and 'V' command for redoing
+static int block_redo = false;
static int KeyNoremap = 0; // remapping flags
@@ -162,7 +160,7 @@ static char_u *get_buffcont(buffheader_T *buffer, int dozero)
p2 = p;
for (const buffblock_T *bp = buffer->bh_first.b_next;
bp != NULL; bp = bp->b_next) {
- for (const char_u *str = bp->b_str; *str;) {
+ for (const char_u *str = (char_u *)bp->b_str; *str;) {
*p2++ = *str++;
}
}
@@ -179,7 +177,7 @@ char_u *get_recorded(void)
char_u *p;
size_t len;
- p = get_buffcont(&recordbuff, TRUE);
+ p = get_buffcont(&recordbuff, true);
free_buff(&recordbuff);
/*
@@ -207,7 +205,7 @@ char_u *get_recorded(void)
/// K_SPECIAL in the returned string is escaped.
char_u *get_inserted(void)
{
- return get_buffcont(&redobuff, FALSE);
+ return get_buffcont(&redobuff, false);
}
/// Add string after the current block of the given buffer
@@ -319,7 +317,7 @@ static void add_char_buff(buffheader_T *buf, int c)
/// Get one byte from the read buffers. Use readbuf1 one first, use readbuf2
/// if that one is empty.
-/// If advance == TRUE go to the next char.
+/// If advance == true go to the next char.
/// No translation is done K_SPECIAL is escaped.
static int read_readbuffers(int advance)
{
@@ -341,7 +339,7 @@ static int read_readbuf(buffheader_T *buf, int advance)
}
buffblock_T *const curr = buf->bh_first.b_next;
- c = curr->b_str[buf->bh_index];
+ c = (char_u)curr->b_str[buf->bh_index];
if (advance) {
if (curr->b_str[++buf->bh_index] == NUL) {
@@ -368,19 +366,15 @@ static void start_stuff(void)
}
}
-/*
- * Return TRUE if the stuff buffer is empty.
- */
+/// Return true if the stuff buffer is empty.
int 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.
- */
+/// Return true if readbuf1 is empty. There may still be redo characters in
+/// redbuf2.
int readbuf1_empty(void)
FUNC_ATTR_PURE
{
@@ -629,6 +623,34 @@ void stuffnumReadbuff(long n)
add_num_buff(&readbuf1, n);
}
+/// Stuff a string into the typeahead buffer, such that edit() will insert it
+/// literally ("literally" true) or interpret is as typed characters.
+void stuffescaped(const char *arg, bool literally)
+{
+ while (*arg != NUL) {
+ // Stuff a sequence of normal ASCII characters, that's fast. Also
+ // stuff K_SPECIAL to get the effect of a special key when "literally"
+ // is true.
+ const char *const start = arg;
+ while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
+ && !literally)) {
+ arg++;
+ }
+ if (arg > start) {
+ stuffReadbuffLen(start, (arg - start));
+ }
+
+ // stuff a single special character
+ if (*arg != NUL) {
+ const int c = mb_cptr2char_adv((const char_u **)&arg);
+ if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
+ stuffcharReadbuff(Ctrl_V);
+ }
+ stuffcharReadbuff(c);
+ }
+ }
+}
+
/// Read a character from the redo buffer. Translates K_SPECIAL and
/// multibyte characters.
/// The redo buffer is left as it is.
@@ -649,7 +671,7 @@ static int read_redo(bool init, bool old_redo)
if (bp == NULL) {
return FAIL;
}
- p = bp->b_str;
+ p = (char_u *)bp->b_str;
return OK;
}
if ((c = *p) == NUL) {
@@ -670,7 +692,7 @@ static int read_redo(bool init, bool old_redo)
}
if (*++p == NUL && bp->b_next != NULL) {
bp = bp->b_next;
- p = bp->b_str;
+ p = (char_u *)bp->b_str;
}
buf[i] = (char_u)c;
if (i == n - 1) { // last byte of a character
@@ -793,7 +815,7 @@ int start_redo_ins(void)
void stop_redo_ins(void)
{
- block_redo = FALSE;
+ block_redo = false;
}
/*
@@ -932,9 +954,9 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
} else {
nrm = noremap;
}
- for (i = 0; i < addlen; ++i) {
+ for (i = 0; i < addlen; i++) {
typebuf.tb_noremap[typebuf.tb_off + i + offset] =
- (char_u)((--nrm >= 0) ? val : RM_YES);
+ (uint8_t)((--nrm >= 0) ? val : RM_YES);
}
// tb_maplen and tb_silent only remember the length of mapped and/or
@@ -970,7 +992,7 @@ int ins_char_typebuf(int c, int modifiers)
return (int)len;
}
-/// Return TRUE if the typeahead buffer was changed (while waiting for a
+/// Return true if the typeahead buffer was changed (while waiting for a
/// character to arrive). Happens when a message was received from a client or
/// from feedkeys().
/// But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
@@ -986,10 +1008,8 @@ bool typebuf_changed(int tb_change_cnt)
|| typebuf_was_filled);
}
-/*
- * Return TRUE if there are no characters in the typeahead buffer that have
- * not been typed (result from a mapping or come from ":normal").
- */
+/// Return true if there are no characters in the typeahead buffer that have
+/// not been typed (result from a mapping or come from ":normal").
int typebuf_typed(void)
FUNC_ATTR_PURE
{
@@ -1260,7 +1280,7 @@ void restore_typeahead(tasave_T *tp)
/// Open a new script file for the ":source!" command.
///
/// @param directly when true execute directly
-void openscript(char_u *name, bool directly)
+void openscript(char *name, bool directly)
{
if (curscript + 1 == NSCRIPT) {
emsg(_(e_nesting));
@@ -1353,9 +1373,7 @@ void close_all_scripts(void)
#endif
-/*
- * Return TRUE when reading keys from a script file.
- */
+/// Return true when reading keys from a script file.
int using_script(void)
FUNC_ATTR_PURE
{
@@ -1686,7 +1704,7 @@ int vpeekc_any(void)
/*
* Call vpeekc() without causing anything to be mapped.
- * Return TRUE if a character is available, FALSE otherwise.
+ * Return true if a character is available, false otherwise.
*/
int char_avail(void)
{
@@ -1750,7 +1768,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
if (!ui_has_messages()) {
// redraw the screen after getchar()
- update_screen(CLEAR);
+ update_screen(UPD_NOT_VALID);
}
set_vim_var_nr(VV_MOUSE_WIN, 0);
@@ -1810,13 +1828,13 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
}
/// "getchar()" function
-void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
getchar_common(argvars, rettv);
}
/// "getcharstr()" function
-void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getcharstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
getchar_common(argvars, rettv);
@@ -1836,7 +1854,7 @@ void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "getcharmod()" function
-void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getcharmod(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->vval.v_number = mod_mask;
}
@@ -1881,7 +1899,7 @@ static bool at_ins_compl_key(void)
c = p[3] & 0x1f;
}
return (ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c))
- || ((compl_cont_status & CONT_LOCAL) && (c == Ctrl_N || c == Ctrl_P));
+ || (compl_status_local() && (c == Ctrl_N || c == Ctrl_P));
}
/// Check if typebuf.tb_buf[] contains a modifier plus key that can be changed
@@ -2047,12 +2065,11 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
// - Partly match: mlen == typebuf.tb_len
keylen = mp->m_keylen;
if (mlen == keylen || (mlen == typebuf.tb_len && typebuf.tb_len < keylen)) {
- char_u *s;
int n;
// If only script-local mappings are allowed, check if the
// mapping starts with K_SNR.
- s = typebuf.tb_noremap + typebuf.tb_off;
+ uint8_t *s = typebuf.tb_noremap + typebuf.tb_off;
if (*s == RM_SCRIPT
&& (mp->m_keys[0] != K_SPECIAL
|| mp->m_keys[1] != KS_EXTRA
@@ -2103,7 +2120,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
// Check for match with 'pastetoggle'
if (*p_pt != NUL && mp == NULL && (State & (MODE_INSERT | MODE_NORMAL))) {
- bool match = typebuf_match_len(p_pt, &mlen);
+ bool match = typebuf_match_len((char_u *)p_pt, &mlen);
if (match) {
// write chars to script file(s)
if (mlen > typebuf.tb_maplen) {
@@ -2112,7 +2129,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
}
del_typebuf(mlen, 0); // remove the chars
- set_option_value("paste", !p_paste, NULL, 0);
+ set_option_value_give_err("paste", !p_paste, NULL, 0);
if (!(State & MODE_INSERT)) {
msg_col = 0;
msg_row = Rows - 1;
@@ -2248,7 +2265,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
save_m_keys = vim_strsave(mp->m_keys);
if (save_m_luaref == LUA_NOREF) {
- save_m_str = vim_strsave(mp->m_str);
+ save_m_str = vim_strsave((char_u *)mp->m_str);
}
map_str = eval_map_expr(mp, NUL);
@@ -2280,7 +2297,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
vgetc_busy = save_vgetc_busy;
may_garbage_collect = save_may_garbage_collect;
} else {
- map_str = mp->m_str;
+ map_str = (char_u *)mp->m_str;
}
// Insert the 'to' part in the typebuf.tb_buf.
@@ -2364,8 +2381,8 @@ void check_end_reg_executing(bool advance)
///
/// if "advance" is true (vgetc()):
/// Really get the character.
-/// KeyTyped is set to TRUE in the case the user typed the key.
-/// KeyStuffed is TRUE if the character comes from the stuff buffer.
+/// KeyTyped is set to true in the case the user typed the key.
+/// KeyStuffed is true if the character comes from the stuff buffer.
/// if "advance" is false (vpeekc()):
/// Just look whether there is a character available.
/// Return NUL if not.
@@ -2452,7 +2469,7 @@ static int vgetorpeek(bool advance)
// flush all input
c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
- // If inchar() returns TRUE (script file was active) or we
+ // If inchar() returns true (script file was active) or we
// are inside a mapping, get out of Insert mode.
// Otherwise we behave like having gotten a CTRL-C.
// As a result typing CTRL-C in insert mode will
@@ -2501,7 +2518,7 @@ static int vgetorpeek(bool advance)
// write char to script file(s)
gotchars(typebuf.tb_buf + typebuf.tb_off, 1);
}
- KeyNoremap = typebuf.tb_noremap[typebuf.tb_off];
+ KeyNoremap = (unsigned char)typebuf.tb_noremap[typebuf.tb_off];
del_typebuf(1, 0);
}
break; // got character, break the for loop
@@ -2530,7 +2547,7 @@ static int vgetorpeek(bool advance)
&& (State & MODE_INSERT)
&& (p_timeout || (keylen == KEYLEN_PART_KEY && p_ttimeout))
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, 3, 25L)) == 0) {
- colnr_T col = 0, vcol;
+ colnr_T col = 0;
char_u *ptr;
if (mode_displayed) {
@@ -2548,22 +2565,27 @@ static int vgetorpeek(bool advance)
// We are expecting to truncate the trailing
// white-space, so find the last non-white
// character -- webb
- col = vcol = curwin->w_wcol = 0;
+ curwin->w_wcol = 0;
ptr = get_cursor_line_ptr();
- while (col < curwin->w_cursor.col) {
- if (!ascii_iswhite(ptr[col])) {
- curwin->w_wcol = vcol;
+ chartabsize_T cts;
+ init_chartabsize_arg(&cts, curwin,
+ curwin->w_cursor.lnum, 0, ptr, ptr);
+ while ((char_u *)cts.cts_ptr < ptr + curwin->w_cursor.col) {
+ if (!ascii_iswhite(*cts.cts_ptr)) {
+ curwin->w_wcol = cts.cts_vcol;
}
- vcol += lbr_chartabsize(ptr, ptr + col, vcol);
- col += utfc_ptr2len((char *)ptr + col);
+ cts.cts_vcol += lbr_chartabsize(&cts);
+ cts.cts_ptr += utfc_ptr2len(cts.cts_ptr);
}
+ clear_chartabsize_arg(&cts);
+
curwin->w_wrow = curwin->w_cline_row
+ curwin->w_wcol / curwin->w_width_inner;
curwin->w_wcol %= curwin->w_width_inner;
curwin->w_wcol += curwin_col_off();
col = 0; // no correction needed
} else {
- --curwin->w_wcol;
+ curwin->w_wcol--;
col = curwin->w_cursor.col - 1;
}
} else if (curwin->w_p_wrap && curwin->w_wrow) {
@@ -2866,7 +2888,7 @@ int inchar(char_u *buf, int maxlen, long wait_time)
if (read_size <= 0) { // Did not get a character from script.
// If we got an interrupt, skip all previously typed characters and
- // return TRUE if quit reading script file.
+ // return true if quit reading script file.
// Stop reading typeahead when a single CTRL-C was read,
// fill_input_buf() returns this when not able to read from stdin.
// Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
@@ -2929,7 +2951,7 @@ int fix_input_buffer(char_u *buf, int len)
// Two characters are special: NUL and K_SPECIAL.
// Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
// Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
- for (i = len; --i >= 0; ++p) {
+ for (i = len; --i >= 0; p++) {
if (p[0] == NUL
|| (p[0] == K_SPECIAL
&& (i < 2 || p[1] != KS_EXTRA))) {