mirror of
https://github.com/neovim/neovim.git
synced 2025-11-03 09:14:24 +00:00
eval: Move remaining get_tv_string* functions to eval/typval.c
This commit is contained in:
@@ -20,15 +20,13 @@
|
|||||||
#define BS '\010'
|
#define BS '\010'
|
||||||
#define TAB '\011'
|
#define TAB '\011'
|
||||||
#define NL '\012'
|
#define NL '\012'
|
||||||
#define NL_STR (char_u *)"\012"
|
#define NL_STR "\012"
|
||||||
#define FF '\014'
|
#define FF '\014'
|
||||||
#define CAR '\015' /* CR is used by Mac OS X */
|
#define CAR '\015' /* CR is used by Mac OS X */
|
||||||
#define ESC '\033'
|
#define ESC '\033'
|
||||||
#define ESC_STR (char_u *)"\033"
|
#define ESC_STR "\033"
|
||||||
#define ESC_STR_nc "\033"
|
|
||||||
#define DEL 0x7f
|
#define DEL 0x7f
|
||||||
#define DEL_STR (char_u *)"\177"
|
#define CSI 0x9b // Control Sequence Introducer
|
||||||
#define CSI 0x9b /* Control Sequence Introducer */
|
|
||||||
#define CSI_STR "\233"
|
#define CSI_STR "\233"
|
||||||
#define DCS 0x90 /* Device Control String */
|
#define DCS 0x90 /* Device Control String */
|
||||||
#define STERM 0x9c /* String Terminator */
|
#define STERM 0x9c /* String Terminator */
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ int buf_init_chartab(buf_T *buf, int global)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int c2;
|
int c2;
|
||||||
char_u *p;
|
|
||||||
int i;
|
int i;
|
||||||
bool tilde;
|
bool tilde;
|
||||||
bool do_isalpha;
|
bool do_isalpha;
|
||||||
@@ -144,7 +143,8 @@ int buf_init_chartab(buf_T *buf, int global)
|
|||||||
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
|
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
|
||||||
// options Each option is a list of characters, character numbers or
|
// options Each option is a list of characters, character numbers or
|
||||||
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
|
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
|
||||||
for (i = global ? 0 : 3; i <= 3; ++i) {
|
for (i = global ? 0 : 3; i <= 3; i++) {
|
||||||
|
const char_u *p;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// first round: 'isident'
|
// first round: 'isident'
|
||||||
p = p_isi;
|
p = p_isi;
|
||||||
@@ -169,7 +169,7 @@ int buf_init_chartab(buf_T *buf, int global)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ascii_isdigit(*p)) {
|
if (ascii_isdigit(*p)) {
|
||||||
c = getdigits_int(&p);
|
c = getdigits_int((char_u **)&p);
|
||||||
} else {
|
} else {
|
||||||
c = mb_ptr2char_adv(&p);
|
c = mb_ptr2char_adv(&p);
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ int buf_init_chartab(buf_T *buf, int global)
|
|||||||
++p;
|
++p;
|
||||||
|
|
||||||
if (ascii_isdigit(*p)) {
|
if (ascii_isdigit(*p)) {
|
||||||
c2 = getdigits_int(&p);
|
c2 = getdigits_int((char_u **)&p);
|
||||||
} else {
|
} else {
|
||||||
c2 = mb_ptr2char_adv(&p);
|
c2 = mb_ptr2char_adv(&p);
|
||||||
}
|
}
|
||||||
|
|||||||
204
src/nvim/edit.c
204
src/nvim/edit.c
@@ -1423,7 +1423,7 @@ static void ins_ctrl_v(void)
|
|||||||
edit_putchar('^', TRUE);
|
edit_putchar('^', TRUE);
|
||||||
did_putchar = TRUE;
|
did_putchar = TRUE;
|
||||||
}
|
}
|
||||||
AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
|
AppendToRedobuff(CTRL_V_STR);
|
||||||
|
|
||||||
add_to_showcmd_c(Ctrl_V);
|
add_to_showcmd_c(Ctrl_V);
|
||||||
|
|
||||||
@@ -1977,7 +1977,6 @@ static bool ins_compl_accept_char(int c)
|
|||||||
*/
|
*/
|
||||||
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
|
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
|
||||||
{
|
{
|
||||||
char_u *p;
|
|
||||||
int i, c;
|
int i, c;
|
||||||
int actual_len; /* Take multi-byte characters */
|
int actual_len; /* Take multi-byte characters */
|
||||||
int actual_compl_length; /* into account. */
|
int actual_compl_length; /* into account. */
|
||||||
@@ -1987,11 +1986,11 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||||||
int was_letter = FALSE;
|
int was_letter = FALSE;
|
||||||
|
|
||||||
if (p_ic && curbuf->b_p_inf && len > 0) {
|
if (p_ic && curbuf->b_p_inf && len > 0) {
|
||||||
/* Infer case of completed part. */
|
// Infer case of completed part.
|
||||||
|
|
||||||
/* Find actual length of completion. */
|
// Find actual length of completion.
|
||||||
if (has_mbyte) {
|
if (has_mbyte) {
|
||||||
p = str;
|
const char_u *p = str;
|
||||||
actual_len = 0;
|
actual_len = 0;
|
||||||
while (*p != NUL) {
|
while (*p != NUL) {
|
||||||
mb_ptr_adv(p);
|
mb_ptr_adv(p);
|
||||||
@@ -2002,7 +2001,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||||||
|
|
||||||
/* Find actual length of original text. */
|
/* Find actual length of original text. */
|
||||||
if (has_mbyte) {
|
if (has_mbyte) {
|
||||||
p = compl_orig_text;
|
const char_u *p = compl_orig_text;
|
||||||
actual_compl_length = 0;
|
actual_compl_length = 0;
|
||||||
while (*p != NUL) {
|
while (*p != NUL) {
|
||||||
mb_ptr_adv(p);
|
mb_ptr_adv(p);
|
||||||
@@ -2018,27 +2017,35 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||||||
|
|
||||||
/* Allocate wide character array for the completion and fill it. */
|
/* Allocate wide character array for the completion and fill it. */
|
||||||
wca = xmalloc(actual_len * sizeof(*wca));
|
wca = xmalloc(actual_len * sizeof(*wca));
|
||||||
p = str;
|
{
|
||||||
for (i = 0; i < actual_len; ++i)
|
const char_u *p = str;
|
||||||
if (has_mbyte)
|
for (i = 0; i < actual_len; i++) {
|
||||||
wca[i] = mb_ptr2char_adv(&p);
|
if (has_mbyte) {
|
||||||
else
|
wca[i] = mb_ptr2char_adv(&p);
|
||||||
wca[i] = *(p++);
|
} else {
|
||||||
|
wca[i] = *(p++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Rule 1: Were any chars converted to lower? */
|
// Rule 1: Were any chars converted to lower?
|
||||||
p = compl_orig_text;
|
{
|
||||||
for (i = 0; i < min_len; ++i) {
|
const char_u *p = compl_orig_text;
|
||||||
if (has_mbyte)
|
for (i = 0; i < min_len; i++) {
|
||||||
c = mb_ptr2char_adv(&p);
|
if (has_mbyte) {
|
||||||
else
|
c = mb_ptr2char_adv(&p);
|
||||||
c = *(p++);
|
} else {
|
||||||
if (vim_islower(c)) {
|
c = *(p++);
|
||||||
has_lower = TRUE;
|
}
|
||||||
if (vim_isupper(wca[i])) {
|
if (vim_islower(c)) {
|
||||||
/* Rule 1 is satisfied. */
|
has_lower = true;
|
||||||
for (i = actual_compl_length; i < actual_len; ++i)
|
if (vim_isupper(wca[i])) {
|
||||||
wca[i] = vim_tolower(wca[i]);
|
// Rule 1 is satisfied.
|
||||||
break;
|
for (i = actual_compl_length; i < actual_len; i++) {
|
||||||
|
wca[i] = vim_tolower(wca[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2048,49 +2055,57 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
|
|||||||
* upper case.
|
* upper case.
|
||||||
*/
|
*/
|
||||||
if (!has_lower) {
|
if (!has_lower) {
|
||||||
p = compl_orig_text;
|
const char_u *p = compl_orig_text;
|
||||||
for (i = 0; i < min_len; ++i) {
|
for (i = 0; i < min_len; i++) {
|
||||||
if (has_mbyte)
|
if (has_mbyte) {
|
||||||
c = mb_ptr2char_adv(&p);
|
c = mb_ptr2char_adv(&p);
|
||||||
else
|
} else {
|
||||||
c = *(p++);
|
c = *(p++);
|
||||||
|
}
|
||||||
if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
|
if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
|
||||||
/* Rule 2 is satisfied. */
|
// Rule 2 is satisfied.
|
||||||
for (i = actual_compl_length; i < actual_len; ++i)
|
for (i = actual_compl_length; i < actual_len; i++) {
|
||||||
wca[i] = vim_toupper(wca[i]);
|
wca[i] = vim_toupper(wca[i]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
was_letter = vim_islower(c) || vim_isupper(c);
|
was_letter = vim_islower(c) || vim_isupper(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the original case of the part we typed. */
|
// Copy the original case of the part we typed.
|
||||||
p = compl_orig_text;
|
{
|
||||||
for (i = 0; i < min_len; ++i) {
|
const char_u *p = compl_orig_text;
|
||||||
if (has_mbyte)
|
for (i = 0; i < min_len; i++) {
|
||||||
c = mb_ptr2char_adv(&p);
|
if (has_mbyte) {
|
||||||
else
|
c = mb_ptr2char_adv(&p);
|
||||||
c = *(p++);
|
} else {
|
||||||
if (vim_islower(c))
|
c = *(p++);
|
||||||
wca[i] = vim_tolower(wca[i]);
|
}
|
||||||
else if (vim_isupper(c))
|
if (vim_islower(c)) {
|
||||||
wca[i] = vim_toupper(wca[i]);
|
wca[i] = vim_tolower(wca[i]);
|
||||||
|
} else if (vim_isupper(c)) {
|
||||||
|
wca[i] = vim_toupper(wca[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Generate encoding specific output from wide character array.
|
||||||
* Generate encoding specific output from wide character array.
|
// Multi-byte characters can occupy up to five bytes more than
|
||||||
* Multi-byte characters can occupy up to five bytes more than
|
// ASCII characters, and we also need one byte for NUL, so stay
|
||||||
* ASCII characters, and we also need one byte for NUL, so stay
|
// six bytes away from the edge of IObuff.
|
||||||
* six bytes away from the edge of IObuff.
|
{
|
||||||
*/
|
char_u *p = IObuff;
|
||||||
p = IObuff;
|
i = 0;
|
||||||
i = 0;
|
while (i < actual_len && (p - IObuff + 6) < IOSIZE) {
|
||||||
while (i < actual_len && (p - IObuff + 6) < IOSIZE)
|
if (has_mbyte) {
|
||||||
if (has_mbyte)
|
p += (*mb_char2bytes)(wca[i++], p);
|
||||||
p += (*mb_char2bytes)(wca[i++], p);
|
} else {
|
||||||
else
|
*(p++) = wca[i++];
|
||||||
*(p++) = wca[i++];
|
}
|
||||||
*p = NUL;
|
}
|
||||||
|
*p = NUL;
|
||||||
|
}
|
||||||
|
|
||||||
xfree(wca);
|
xfree(wca);
|
||||||
|
|
||||||
@@ -3594,7 +3609,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir)
|
|||||||
adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup");
|
adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup");
|
||||||
aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty");
|
aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty");
|
||||||
} else {
|
} else {
|
||||||
word = (const char *)get_tv_string_chk(tv);
|
word = (const char *)tv_get_string_chk(tv);
|
||||||
memset(cptext, 0, sizeof(cptext));
|
memset(cptext, 0, sizeof(cptext));
|
||||||
}
|
}
|
||||||
if (word == NULL || (!aempty && *word == NUL)) {
|
if (word == NULL || (!aempty && *word == NUL)) {
|
||||||
@@ -5785,15 +5800,16 @@ comp_textwidth (
|
|||||||
*/
|
*/
|
||||||
static void redo_literal(int c)
|
static void redo_literal(int c)
|
||||||
{
|
{
|
||||||
char_u buf[10];
|
char buf[10];
|
||||||
|
|
||||||
/* Only digits need special treatment. Translate them into a string of
|
// Only digits need special treatment. Translate them into a string of
|
||||||
* three digits. */
|
// three digits.
|
||||||
if (ascii_isdigit(c)) {
|
if (ascii_isdigit(c)) {
|
||||||
vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
|
vim_snprintf(buf, sizeof(buf), "%03d", c);
|
||||||
AppendToRedobuff(buf);
|
AppendToRedobuff(buf);
|
||||||
} else
|
} else {
|
||||||
AppendCharToRedobuff(c);
|
AppendCharToRedobuff(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start_arrow() is called when an arrow key is used in insert mode.
|
// start_arrow() is called when an arrow key is used in insert mode.
|
||||||
@@ -5822,8 +5838,8 @@ static void start_arrow_common(pos_T *end_insert_pos, bool end_change)
|
|||||||
{
|
{
|
||||||
if (!arrow_used && end_change) { // something has been inserted
|
if (!arrow_used && end_change) { // something has been inserted
|
||||||
AppendToRedobuff(ESC_STR);
|
AppendToRedobuff(ESC_STR);
|
||||||
stop_insert(end_insert_pos, FALSE, FALSE);
|
stop_insert(end_insert_pos, false, false);
|
||||||
arrow_used = TRUE; /* this means we stopped the current insert */
|
arrow_used = true; // This means we stopped the current insert.
|
||||||
}
|
}
|
||||||
check_spell_redraw();
|
check_spell_redraw();
|
||||||
}
|
}
|
||||||
@@ -5880,7 +5896,7 @@ int stop_arrow(void)
|
|||||||
vr_lines_changed = 1;
|
vr_lines_changed = 1;
|
||||||
}
|
}
|
||||||
ResetRedobuff();
|
ResetRedobuff();
|
||||||
AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */
|
AppendToRedobuff("1i"); // Pretend we start an insertion.
|
||||||
new_insert_skip = 2;
|
new_insert_skip = 2;
|
||||||
} else if (ins_need_undo) {
|
} else if (ins_need_undo) {
|
||||||
if (u_save_cursor() == OK)
|
if (u_save_cursor() == OK)
|
||||||
@@ -6345,12 +6361,13 @@ stuff_inserted (
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
stuffReadbuff(ptr);
|
stuffReadbuff((const char *)ptr);
|
||||||
/* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
|
// A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
|
||||||
if (last)
|
if (last) {
|
||||||
stuffReadbuff((char_u *)(last == '0'
|
stuffReadbuff((last == '0'
|
||||||
? "\026\060\064\070"
|
? "\026\060\064\070"
|
||||||
: "\026^"));
|
: "\026^"));
|
||||||
|
}
|
||||||
} while (--count > 0);
|
} while (--count > 0);
|
||||||
|
|
||||||
if (last)
|
if (last)
|
||||||
@@ -7143,13 +7160,12 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
|
|||||||
disabled_redraw = false;
|
disabled_redraw = false;
|
||||||
}
|
}
|
||||||
if (!arrow_used) {
|
if (!arrow_used) {
|
||||||
/*
|
// Don't append the ESC for "r<CR>" and "grx".
|
||||||
* Don't append the ESC for "r<CR>" and "grx".
|
// When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
|
||||||
* When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
|
// when "count" is non-zero.
|
||||||
* when "count" is non-zero.
|
if (cmdchar != 'r' && cmdchar != 'v') {
|
||||||
*/
|
AppendToRedobuff(p_im ? "\014" : ESC_STR);
|
||||||
if (cmdchar != 'r' && cmdchar != 'v')
|
}
|
||||||
AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Repeating insert may take a long time. Check for
|
* Repeating insert may take a long time. Check for
|
||||||
@@ -7303,7 +7319,8 @@ static bool ins_start_select(int c)
|
|||||||
// Execute the key in (insert) Select mode.
|
// Execute the key in (insert) Select mode.
|
||||||
stuffcharReadbuff(Ctrl_O);
|
stuffcharReadbuff(Ctrl_O);
|
||||||
if (mod_mask) {
|
if (mod_mask) {
|
||||||
char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
|
const char buf[] = { (char)K_SPECIAL, (char)KS_MODIFIER,
|
||||||
|
(char)(uint8_t)mod_mask, NUL };
|
||||||
stuffReadbuff(buf);
|
stuffReadbuff(buf);
|
||||||
}
|
}
|
||||||
stuffcharReadbuff(c);
|
stuffcharReadbuff(c);
|
||||||
@@ -8111,11 +8128,11 @@ static bool ins_tab(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
did_ai = FALSE;
|
did_ai = false;
|
||||||
did_si = FALSE;
|
did_si = false;
|
||||||
can_si = FALSE;
|
can_si = false;
|
||||||
can_si_back = FALSE;
|
can_si_back = false;
|
||||||
AppendToRedobuff((char_u *)"\t");
|
AppendToRedobuff("\t");
|
||||||
|
|
||||||
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
|
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
|
||||||
temp = get_sw_value(curbuf);
|
temp = get_sw_value(curbuf);
|
||||||
@@ -8380,8 +8397,8 @@ static int ins_digraph(void)
|
|||||||
edit_unputchar();
|
edit_unputchar();
|
||||||
}
|
}
|
||||||
if (cc != ESC) {
|
if (cc != ESC) {
|
||||||
AppendToRedobuff((char_u *)CTRL_V_STR);
|
AppendToRedobuff(CTRL_V_STR);
|
||||||
c = getdigraph(c, cc, TRUE);
|
c = getdigraph(c, cc, true);
|
||||||
clear_showcmd();
|
clear_showcmd();
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -8443,12 +8460,13 @@ static int ins_ctrl_ey(int tc)
|
|||||||
if (c != NUL) {
|
if (c != NUL) {
|
||||||
long tw_save;
|
long tw_save;
|
||||||
|
|
||||||
/* The character must be taken literally, insert like it
|
// The character must be taken literally, insert like it
|
||||||
* was typed after a CTRL-V, and pretend 'textwidth'
|
// was typed after a CTRL-V, and pretend 'textwidth'
|
||||||
* wasn't set. Digits, 'o' and 'x' are special after a
|
// wasn't set. Digits, 'o' and 'x' are special after a
|
||||||
* CTRL-V, don't use it for these. */
|
// CTRL-V, don't use it for these.
|
||||||
if (c < 256 && !isalnum(c))
|
if (c < 256 && !isalnum(c)) {
|
||||||
AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
|
AppendToRedobuff(CTRL_V_STR);
|
||||||
|
}
|
||||||
tw_save = curbuf->b_p_tw;
|
tw_save = curbuf->b_p_tw;
|
||||||
curbuf->b_p_tw = -1;
|
curbuf->b_p_tw = -1;
|
||||||
insert_special(c, TRUE, FALSE);
|
insert_special(c, TRUE, FALSE);
|
||||||
|
|||||||
1280
src/nvim/eval.c
1280
src/nvim/eval.c
File diff suppressed because it is too large
Load Diff
@@ -796,7 +796,7 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
|
|||||||
// of the string means it should match everything up to the '*' instead of the
|
// of the string means it should match everything up to the '*' instead of the
|
||||||
// whole string.
|
// whole string.
|
||||||
const size_t len = strlen(watcher->key_pattern);
|
const size_t len = strlen(watcher->key_pattern);
|
||||||
if (watcher->key_pattern[len - 1] == '*') {
|
if (len && watcher->key_pattern[len - 1] == '*') {
|
||||||
return strncmp(key, watcher->key_pattern, len - 1) == 0;
|
return strncmp(key, watcher->key_pattern, len - 1) == 0;
|
||||||
} else {
|
} else {
|
||||||
return strcmp(key, watcher->key_pattern) == 0;
|
return strcmp(key, watcher->key_pattern) == 0;
|
||||||
@@ -2020,7 +2020,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
|
|||||||
///
|
///
|
||||||
/// @return true if everything is OK, false otherwise.
|
/// @return true if everything is OK, false otherwise.
|
||||||
bool tv_check_str_or_nr(const typval_T *const tv)
|
bool tv_check_str_or_nr(const typval_T *const tv)
|
||||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
@@ -2072,7 +2072,7 @@ static const char *const num_errors[] = {
|
|||||||
|
|
||||||
/// Check that given value is a number or can be converted to it
|
/// Check that given value is a number or can be converted to it
|
||||||
///
|
///
|
||||||
/// Error messages are compatible with tv_get_number() previously used for
|
/// Error messages are compatible with tv_get_number_chk() previously used for
|
||||||
/// the same purpose.
|
/// the same purpose.
|
||||||
///
|
///
|
||||||
/// @param[in] tv Value to check.
|
/// @param[in] tv Value to check.
|
||||||
@@ -2101,6 +2101,50 @@ bool tv_check_num(const typval_T *const tv)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FUNC_ERROR "E729: using Funcref as a String"
|
||||||
|
|
||||||
|
static const char *const str_errors[] = {
|
||||||
|
[VAR_PARTIAL]=N_(FUNC_ERROR),
|
||||||
|
[VAR_FUNC]=N_(FUNC_ERROR),
|
||||||
|
[VAR_LIST]=N_("E730: using List as a String"),
|
||||||
|
[VAR_DICT]=N_("E731: using Dictionary as a String"),
|
||||||
|
[VAR_FLOAT]=((const char *)e_float_as_string),
|
||||||
|
[VAR_UNKNOWN]=N_("E908: using an invalid value as a String"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef FUNC_ERROR
|
||||||
|
|
||||||
|
/// Check that given value is a string or can be converted to it
|
||||||
|
///
|
||||||
|
/// Error messages are compatible with tv_get_string_chk() previously used for
|
||||||
|
/// the same purpose.
|
||||||
|
///
|
||||||
|
/// @param[in] tv Value to check.
|
||||||
|
///
|
||||||
|
/// @return true if everything is OK, false otherwise.
|
||||||
|
bool tv_check_str(const typval_T *const tv)
|
||||||
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
switch (tv->v_type) {
|
||||||
|
case VAR_NUMBER:
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
case VAR_STRING: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case VAR_PARTIAL:
|
||||||
|
case VAR_FUNC:
|
||||||
|
case VAR_LIST:
|
||||||
|
case VAR_DICT:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_UNKNOWN: {
|
||||||
|
EMSG(_(str_errors[tv->v_type]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//{{{2 Get
|
//{{{2 Get
|
||||||
|
|
||||||
/// Get the number value of a VimL object
|
/// Get the number value of a VimL object
|
||||||
@@ -2245,6 +2289,48 @@ float_T tv_get_float(const typval_T *const tv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the string value of a VimL object
|
||||||
|
///
|
||||||
|
/// @param[in] tv Object to get value of.
|
||||||
|
/// @param buf Buffer used to hold numbers and special variables converted to
|
||||||
|
/// string. When function encounters one of these stringified value
|
||||||
|
/// will be written to buf and buf will be returned.
|
||||||
|
///
|
||||||
|
/// Buffer must have NUMBUFLEN size.
|
||||||
|
///
|
||||||
|
/// @return Object value if it is VAR_STRING object, number converted to
|
||||||
|
/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
|
||||||
|
const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
|
||||||
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
switch (tv->v_type) {
|
||||||
|
case VAR_NUMBER: {
|
||||||
|
snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
case VAR_STRING: {
|
||||||
|
if (tv->vval.v_string != NULL) {
|
||||||
|
return (const char *)tv->vval.v_string;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
case VAR_SPECIAL: {
|
||||||
|
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
case VAR_PARTIAL:
|
||||||
|
case VAR_FUNC:
|
||||||
|
case VAR_LIST:
|
||||||
|
case VAR_DICT:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_UNKNOWN: {
|
||||||
|
EMSG(_(str_errors[tv->v_type]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the string value of a VimL object
|
/// Get the string value of a VimL object
|
||||||
///
|
///
|
||||||
/// @warning For number and special values it uses a single, static buffer. It
|
/// @warning For number and special values it uses a single, static buffer. It
|
||||||
@@ -2252,7 +2338,26 @@ float_T tv_get_float(const typval_T *const tv)
|
|||||||
/// tv_get_string_buf() if you need to use tv_get_string() output after
|
/// tv_get_string_buf() if you need to use tv_get_string() output after
|
||||||
/// calling it again.
|
/// calling it again.
|
||||||
///
|
///
|
||||||
/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but
|
/// @param[in] tv Object to get value of.
|
||||||
|
///
|
||||||
|
/// @return Object value if it is VAR_STRING object, number converted to
|
||||||
|
/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
|
||||||
|
const char *tv_get_string_chk(const typval_T *const tv)
|
||||||
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
static char mybuf[NUMBUFLEN];
|
||||||
|
|
||||||
|
return tv_get_string_buf_chk(tv, mybuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the string value of a VimL object
|
||||||
|
///
|
||||||
|
/// @warning For number and special values it uses a single, static buffer. It
|
||||||
|
/// may be used only once, next call to get_tv_string may reuse it. Use
|
||||||
|
/// tv_get_string_buf() if you need to use tv_get_string() output after
|
||||||
|
/// calling it again.
|
||||||
|
///
|
||||||
|
/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
|
||||||
/// return NULL on error.
|
/// return NULL on error.
|
||||||
///
|
///
|
||||||
/// @param[in] tv Object to get value of.
|
/// @param[in] tv Object to get value of.
|
||||||
@@ -2269,7 +2374,7 @@ const char *tv_get_string(const typval_T *const tv)
|
|||||||
|
|
||||||
/// Get the string value of a VimL object
|
/// Get the string value of a VimL object
|
||||||
///
|
///
|
||||||
/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but
|
/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
|
||||||
/// return NULL on error.
|
/// return NULL on error.
|
||||||
///
|
///
|
||||||
/// @param[in] tv Object to get value of.
|
/// @param[in] tv Object to get value of.
|
||||||
@@ -2285,8 +2390,7 @@ const char *tv_get_string(const typval_T *const tv)
|
|||||||
const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
|
const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
const char *const res = (const char *)get_tv_string_buf_chk(
|
const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);
|
||||||
(typval_T *)tv, (char_u *)buf);
|
|
||||||
|
|
||||||
return res != NULL ? res : "";
|
return res != NULL ? res : "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ typedef double float_T;
|
|||||||
|
|
||||||
/// Mimimal possible value of varnumber_T variable
|
/// Mimimal possible value of varnumber_T variable
|
||||||
#define VARNUMBER_MIN INT_MIN
|
#define VARNUMBER_MIN INT_MIN
|
||||||
|
#define PRIdVARNUMBER "d"
|
||||||
|
|
||||||
/// %d printf format specifier for varnumber_T
|
/// %d printf format specifier for varnumber_T
|
||||||
#define PRIdVARNUMBER "d"
|
#define PRIdVARNUMBER "d"
|
||||||
|
|||||||
@@ -1008,8 +1008,8 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
|
|||||||
|
|
||||||
AppendToRedobuffLit(cmd, -1);
|
AppendToRedobuffLit(cmd, -1);
|
||||||
xfree(cmd);
|
xfree(cmd);
|
||||||
AppendToRedobuff((char_u *)"\n");
|
AppendToRedobuff("\n");
|
||||||
bangredo = FALSE;
|
bangredo = false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Add quotes around the command, for shells that need them.
|
* Add quotes around the command, for shells that need them.
|
||||||
|
|||||||
@@ -6794,7 +6794,7 @@ do_exedit (
|
|||||||
int ms = msg_scroll;
|
int ms = msg_scroll;
|
||||||
|
|
||||||
if (eap->nextcmd != NULL) {
|
if (eap->nextcmd != NULL) {
|
||||||
stuffReadbuff(eap->nextcmd);
|
stuffReadbuff((const char *)eap->nextcmd);
|
||||||
eap->nextcmd = NULL;
|
eap->nextcmd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2554,19 +2554,22 @@ void cmdline_paste_str(char_u *s, int literally)
|
|||||||
else
|
else
|
||||||
while (*s != NUL) {
|
while (*s != NUL) {
|
||||||
cv = *s;
|
cv = *s;
|
||||||
if (cv == Ctrl_V && s[1])
|
if (cv == Ctrl_V && s[1]) {
|
||||||
++s;
|
s++;
|
||||||
if (has_mbyte)
|
}
|
||||||
c = mb_cptr2char_adv(&s);
|
if (has_mbyte) {
|
||||||
else
|
c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
|
} else {
|
||||||
c = *s++;
|
c = *s++;
|
||||||
|
}
|
||||||
if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|
if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|
||||||
|| c == CAR || c == NL || c == Ctrl_L
|
|| c == CAR || c == NL || c == Ctrl_L
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
|| c == intr_char
|
|| c == intr_char
|
||||||
#endif
|
#endif
|
||||||
|| (c == Ctrl_BSL && *s == Ctrl_N))
|
|| (c == Ctrl_BSL && *s == Ctrl_N)) {
|
||||||
stuffcharReadbuff(Ctrl_V);
|
stuffcharReadbuff(Ctrl_V);
|
||||||
|
}
|
||||||
stuffcharReadbuff(c);
|
stuffcharReadbuff(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4636,7 +4639,7 @@ in_history (
|
|||||||
///
|
///
|
||||||
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
|
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
|
||||||
/// return HIST_DEFAULT unless return_default is true.
|
/// return HIST_DEFAULT unless return_default is true.
|
||||||
HistoryType get_histtype(const char_u *const name, const size_t len,
|
HistoryType get_histtype(const char *const name, const size_t len,
|
||||||
const bool return_default)
|
const bool return_default)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
@@ -5029,7 +5032,7 @@ void ex_history(exarg_T *eap)
|
|||||||
while (ASCII_ISALPHA(*end)
|
while (ASCII_ISALPHA(*end)
|
||||||
|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
|
|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
|
||||||
end++;
|
end++;
|
||||||
histype1 = get_histtype(arg, end - arg, false);
|
histype1 = get_histtype((const char *)arg, end - arg, false);
|
||||||
if (histype1 == HIST_INVALID) {
|
if (histype1 == HIST_INVALID) {
|
||||||
if (STRNICMP(arg, "all", end - arg) == 0) {
|
if (STRNICMP(arg, "all", end - arg) == 0) {
|
||||||
histype1 = 0;
|
histype1 = 0;
|
||||||
@@ -5288,18 +5291,18 @@ static int ex_window(void)
|
|||||||
cmdwin_result = Ctrl_C;
|
cmdwin_result = Ctrl_C;
|
||||||
/* Set the new command line from the cmdline buffer. */
|
/* Set the new command line from the cmdline buffer. */
|
||||||
xfree(ccline.cmdbuff);
|
xfree(ccline.cmdbuff);
|
||||||
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { /* :qa[!] typed */
|
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
|
||||||
char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
|
const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
|
||||||
|
|
||||||
if (histtype == HIST_CMD) {
|
if (histtype == HIST_CMD) {
|
||||||
/* Execute the command directly. */
|
// Execute the command directly.
|
||||||
ccline.cmdbuff = vim_strsave((char_u *)p);
|
ccline.cmdbuff = (char_u *)xstrdup(p);
|
||||||
cmdwin_result = CAR;
|
cmdwin_result = CAR;
|
||||||
} else {
|
} else {
|
||||||
/* First need to cancel what we were doing. */
|
// First need to cancel what we were doing.
|
||||||
ccline.cmdbuff = NULL;
|
ccline.cmdbuff = NULL;
|
||||||
stuffcharReadbuff(':');
|
stuffcharReadbuff(':');
|
||||||
stuffReadbuff((char_u *)p);
|
stuffReadbuff(p);
|
||||||
stuffcharReadbuff(CAR);
|
stuffcharReadbuff(CAR);
|
||||||
}
|
}
|
||||||
} else if (cmdwin_result == K_XF2) { /* :qa typed */
|
} else if (cmdwin_result == K_XF2) { /* :qa typed */
|
||||||
|
|||||||
@@ -614,10 +614,12 @@ readfile (
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
/* Set swap file protection bits after creating it. */
|
// Set swap file protection bits after creating it.
|
||||||
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
|
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
|
||||||
&& curbuf->b_ml.ml_mfp->mf_fname != NULL)
|
&& curbuf->b_ml.ml_mfp->mf_fname != NULL) {
|
||||||
(void)os_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
|
(void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname,
|
||||||
|
(long)swap_mode);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2870,9 +2872,9 @@ buf_write (
|
|||||||
xfree(backup);
|
xfree(backup);
|
||||||
backup = NULL;
|
backup = NULL;
|
||||||
} else {
|
} else {
|
||||||
/* set file protection same as original file, but
|
// set file protection same as original file, but
|
||||||
* strip s-bit */
|
// strip s-bit.
|
||||||
(void)os_setperm(backup, perm & 0777);
|
(void)os_setperm((const char *)backup, perm & 0777);
|
||||||
|
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
/*
|
/*
|
||||||
@@ -2883,7 +2885,8 @@ buf_write (
|
|||||||
*/
|
*/
|
||||||
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
|
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
|
||||||
&& os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) {
|
&& os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) {
|
||||||
os_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
|
os_setperm((const char *)backup,
|
||||||
|
(perm & 0707) | ((perm & 07) << 3));
|
||||||
}
|
}
|
||||||
# ifdef HAVE_SELINUX
|
# ifdef HAVE_SELINUX
|
||||||
mch_copy_sec(fname, backup);
|
mch_copy_sec(fname, backup);
|
||||||
@@ -3037,8 +3040,8 @@ nobackup:
|
|||||||
&& file_info_old.stat.st_uid == getuid()
|
&& file_info_old.stat.st_uid == getuid()
|
||||||
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
|
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
|
||||||
perm |= 0200;
|
perm |= 0200;
|
||||||
(void)os_setperm(fname, perm);
|
(void)os_setperm((const char *)fname, perm);
|
||||||
made_writable = TRUE;
|
made_writable = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3402,8 +3405,9 @@ restore_backup:
|
|||||||
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|
||||||
|| file_info.stat.st_gid != file_info_old.stat.st_gid) {
|
|| file_info.stat.st_gid != file_info_old.stat.st_gid) {
|
||||||
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
|
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
|
||||||
if (perm >= 0) /* set permission again, may have changed */
|
if (perm >= 0) { // Set permission again, may have changed.
|
||||||
(void)os_setperm(wfname, perm);
|
(void)os_setperm((const char *)wfname, perm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf_set_file_id(buf);
|
buf_set_file_id(buf);
|
||||||
} else if (!buf->file_id_valid) {
|
} else if (!buf->file_id_valid) {
|
||||||
@@ -3421,8 +3425,9 @@ restore_backup:
|
|||||||
if (made_writable)
|
if (made_writable)
|
||||||
perm &= ~0200; /* reset 'w' bit for security reasons */
|
perm &= ~0200; /* reset 'w' bit for security reasons */
|
||||||
#endif
|
#endif
|
||||||
if (perm >= 0) /* set perm. of new file same as old file */
|
if (perm >= 0) { // Set perm. of new file same as old file.
|
||||||
(void)os_setperm(wfname, perm);
|
(void)os_setperm((const char *)wfname, perm);
|
||||||
|
}
|
||||||
#ifdef HAVE_ACL
|
#ifdef HAVE_ACL
|
||||||
/* Probably need to set the ACL before changing the user (can't set the
|
/* Probably need to set the ACL before changing the user (can't set the
|
||||||
* ACL on a file the user doesn't own). */
|
* ACL on a file the user doesn't own). */
|
||||||
@@ -3628,7 +3633,7 @@ restore_backup:
|
|||||||
close(empty_fd);
|
close(empty_fd);
|
||||||
}
|
}
|
||||||
if (org != NULL) {
|
if (org != NULL) {
|
||||||
os_setperm((char_u *)org, os_getperm((const char *)fname) & 0777);
|
os_setperm(org, os_getperm((const char *)fname) & 0777);
|
||||||
xfree(org);
|
xfree(org);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4690,8 +4695,8 @@ int vim_rename(const char_u *from, const char_u *to)
|
|||||||
errmsg = _("E210: Error reading \"%s\"");
|
errmsg = _("E210: Error reading \"%s\"");
|
||||||
to = from;
|
to = from;
|
||||||
}
|
}
|
||||||
#ifndef UNIX /* for Unix os_open() already set the permission */
|
#ifndef UNIX // For Unix os_open() already set the permission.
|
||||||
os_setperm(to, perm);
|
os_setperm((const char *)to, perm);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ACL
|
#ifdef HAVE_ACL
|
||||||
mch_set_acl(to, acl);
|
mch_set_acl(to, acl);
|
||||||
|
|||||||
@@ -235,19 +235,18 @@ 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
|
||||||
* Add string "s" after the current block of buffer "buf".
|
///
|
||||||
* K_SPECIAL and CSI should have been escaped already.
|
/// K_SPECIAL and CSI should have been escaped already.
|
||||||
*/
|
///
|
||||||
static void
|
/// @param[out] buf Buffer to add to.
|
||||||
add_buff (
|
/// @param[in] s String to add.
|
||||||
buffheader_T *buf,
|
/// @param[in] slen String length or -1 for NUL-terminated string.
|
||||||
char_u *s,
|
static void add_buff(buffheader_T *const buf, const char *const s,
|
||||||
ssize_t slen // length of "s" or -1
|
ptrdiff_t slen)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (slen < 0) {
|
if (slen < 0) {
|
||||||
slen = (ssize_t)STRLEN(s);
|
slen = (ptrdiff_t)strlen(s);
|
||||||
}
|
}
|
||||||
if (slen == 0) { // don't add empty strings
|
if (slen == 0) { // don't add empty strings
|
||||||
return;
|
return;
|
||||||
@@ -292,9 +291,8 @@ add_buff (
|
|||||||
*/
|
*/
|
||||||
static void add_num_buff(buffheader_T *buf, long n)
|
static void add_num_buff(buffheader_T *buf, long n)
|
||||||
{
|
{
|
||||||
char_u number[32];
|
char number[32];
|
||||||
|
snprintf(number, sizeof(number), "%ld", n);
|
||||||
sprintf((char *)number, "%" PRId64, (int64_t)n);
|
|
||||||
add_buff(buf, number, -1L);
|
add_buff(buf, number, -1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,27 +302,29 @@ static void add_num_buff(buffheader_T *buf, long n)
|
|||||||
*/
|
*/
|
||||||
static void add_char_buff(buffheader_T *buf, int c)
|
static void add_char_buff(buffheader_T *buf, int c)
|
||||||
{
|
{
|
||||||
char_u bytes[MB_MAXBYTES + 1];
|
char bytes[MB_MAXBYTES + 1];
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
int i;
|
if (IS_SPECIAL(c)) {
|
||||||
char_u temp[4];
|
|
||||||
|
|
||||||
if (IS_SPECIAL(c))
|
|
||||||
len = 1;
|
len = 1;
|
||||||
else
|
} else {
|
||||||
len = (*mb_char2bytes)(c, bytes);
|
len = (*mb_char2bytes)(c, (char_u *)bytes);
|
||||||
for (i = 0; i < len; ++i) {
|
}
|
||||||
if (!IS_SPECIAL(c))
|
|
||||||
c = bytes[i];
|
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (!IS_SPECIAL(c)) {
|
||||||
|
c = bytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[4];
|
||||||
if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
|
if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
|
||||||
/* translate special key code into three byte sequence */
|
// Translate special key code into three byte sequence.
|
||||||
temp[0] = K_SPECIAL;
|
temp[0] = (char)K_SPECIAL;
|
||||||
temp[1] = (char_u)K_SECOND(c);
|
temp[1] = (char)K_SECOND(c);
|
||||||
temp[2] = (char_u)K_THIRD(c);
|
temp[2] = (char)K_THIRD(c);
|
||||||
temp[3] = NUL;
|
temp[3] = NUL;
|
||||||
} else {
|
} else {
|
||||||
temp[0] = (char_u)c;
|
temp[0] = (char)c;
|
||||||
temp[1] = NUL;
|
temp[1] = NUL;
|
||||||
}
|
}
|
||||||
add_buff(buf, temp, -1L);
|
add_buff(buf, temp, -1L);
|
||||||
@@ -479,16 +479,14 @@ static int save_level = 0;
|
|||||||
|
|
||||||
void saveRedobuff(void)
|
void saveRedobuff(void)
|
||||||
{
|
{
|
||||||
char_u *s;
|
|
||||||
|
|
||||||
if (save_level++ == 0) {
|
if (save_level++ == 0) {
|
||||||
save_redobuff = redobuff;
|
save_redobuff = redobuff;
|
||||||
redobuff.bh_first.b_next = NULL;
|
redobuff.bh_first.b_next = NULL;
|
||||||
save_old_redobuff = old_redobuff;
|
save_old_redobuff = old_redobuff;
|
||||||
old_redobuff.bh_first.b_next = NULL;
|
old_redobuff.bh_first.b_next = NULL;
|
||||||
|
|
||||||
/* Make a copy, so that ":normal ." in a function works. */
|
// Make a copy, so that ":normal ." in a function works.
|
||||||
s = get_buffcont(&save_redobuff, FALSE);
|
char *const s = (char *)get_buffcont(&save_redobuff, false);
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
add_buff(&redobuff, s, -1L);
|
add_buff(&redobuff, s, -1L);
|
||||||
xfree(s);
|
xfree(s);
|
||||||
@@ -514,10 +512,11 @@ void restoreRedobuff(void)
|
|||||||
* Append "s" to the redo buffer.
|
* Append "s" to the redo buffer.
|
||||||
* K_SPECIAL and CSI should already have been escaped.
|
* K_SPECIAL and CSI should already have been escaped.
|
||||||
*/
|
*/
|
||||||
void AppendToRedobuff(char_u *s)
|
void AppendToRedobuff(const char *s)
|
||||||
{
|
{
|
||||||
if (!block_redo)
|
if (!block_redo) {
|
||||||
add_buff(&redobuff, s, -1L);
|
add_buff(&redobuff, (const char *)s, -1L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -530,44 +529,47 @@ AppendToRedobuffLit (
|
|||||||
int len /* length of "str" or -1 for up to the NUL */
|
int len /* length of "str" or -1 for up to the NUL */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char_u *s = str;
|
if (block_redo) {
|
||||||
int c;
|
|
||||||
char_u *start;
|
|
||||||
|
|
||||||
if (block_redo)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (len < 0 ? *s != NUL : s - str < len) {
|
const char *s = (const char *)str;
|
||||||
/* Put a string of normal characters in the redo buffer (that's
|
while (len < 0 ? *s != NUL : s - (const char *)str < len) {
|
||||||
* faster). */
|
// Put a string of normal characters in the redo buffer (that's
|
||||||
start = s;
|
// faster).
|
||||||
while (*s >= ' ' && *s < DEL && (len < 0 || s - str < len))
|
const char *start = s;
|
||||||
++s;
|
while (*s >= ' ' && *s < DEL && (len < 0 || s - (const char *)str < len)) {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't put '0' or '^' as last character, just in case a CTRL-D is
|
// Don't put '0' or '^' as last character, just in case a CTRL-D is
|
||||||
* typed next. */
|
// typed next.
|
||||||
if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
|
if (*s == NUL && (s[-1] == '0' || s[-1] == '^')) {
|
||||||
--s;
|
s--;
|
||||||
if (s > start)
|
}
|
||||||
|
if (s > start) {
|
||||||
add_buff(&redobuff, start, (long)(s - start));
|
add_buff(&redobuff, start, (long)(s - start));
|
||||||
|
}
|
||||||
|
|
||||||
if (*s == NUL || (len >= 0 && s - str >= len))
|
if (*s == NUL || (len >= 0 && s - (const char *)str >= len)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle a special or multibyte character. */
|
// Handle a special or multibyte character.
|
||||||
if (has_mbyte)
|
// Composing chars separately are handled separately.
|
||||||
/* Handle composing chars separately. */
|
const int c = (has_mbyte
|
||||||
c = mb_cptr2char_adv(&s);
|
? mb_cptr2char_adv((const char_u **)&s)
|
||||||
else
|
: (uint8_t)(*s++));
|
||||||
c = *s++;
|
if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
|
||||||
if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
|
|
||||||
add_char_buff(&redobuff, Ctrl_V);
|
add_char_buff(&redobuff, Ctrl_V);
|
||||||
|
}
|
||||||
|
|
||||||
/* CTRL-V '0' must be inserted as CTRL-V 048 */
|
// CTRL-V '0' must be inserted as CTRL-V 048.
|
||||||
if (*s == NUL && c == '0')
|
if (*s == NUL && c == '0') {
|
||||||
add_buff(&redobuff, (char_u *)"048", 3L);
|
add_buff(&redobuff, "048", 3L);
|
||||||
else
|
} else {
|
||||||
add_char_buff(&redobuff, c);
|
add_char_buff(&redobuff, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,19 +596,19 @@ void AppendNumberToRedobuff(long n)
|
|||||||
* Append string "s" to the stuff buffer.
|
* Append string "s" to the stuff buffer.
|
||||||
* CSI and K_SPECIAL must already have been escaped.
|
* CSI and K_SPECIAL must already have been escaped.
|
||||||
*/
|
*/
|
||||||
void stuffReadbuff(char_u *s)
|
void stuffReadbuff(const char *s)
|
||||||
{
|
{
|
||||||
add_buff(&readbuf1, s, -1L);
|
add_buff(&readbuf1, s, -1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append string "s" to the redo stuff buffer.
|
/// Append string "s" to the redo stuff buffer.
|
||||||
/// @remark CSI and K_SPECIAL must already have been escaped.
|
/// @remark CSI and K_SPECIAL must already have been escaped.
|
||||||
void stuffRedoReadbuff(char_u *s)
|
void stuffRedoReadbuff(const char *s)
|
||||||
{
|
{
|
||||||
add_buff(&readbuf2, s, -1L);
|
add_buff(&readbuf2, s, -1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stuffReadbuffLen(char_u *s, long len)
|
void stuffReadbuffLen(const char *s, long len)
|
||||||
{
|
{
|
||||||
add_buff(&readbuf1, s, len);
|
add_buff(&readbuf1, s, len);
|
||||||
}
|
}
|
||||||
@@ -616,19 +618,18 @@ void stuffReadbuffLen(char_u *s, long len)
|
|||||||
* escaping other K_SPECIAL and CSI bytes.
|
* escaping other K_SPECIAL and CSI bytes.
|
||||||
* Change CR, LF and ESC into a space.
|
* Change CR, LF and ESC into a space.
|
||||||
*/
|
*/
|
||||||
void stuffReadbuffSpec(char_u *s)
|
void stuffReadbuffSpec(const char *s)
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
|
|
||||||
while (*s != NUL) {
|
while (*s != NUL) {
|
||||||
if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
|
if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
|
||||||
/* Insert special key literally. */
|
// Insert special key literally.
|
||||||
stuffReadbuffLen(s, 3L);
|
stuffReadbuffLen(s, 3);
|
||||||
s += 3;
|
s += 3;
|
||||||
} else {
|
} else {
|
||||||
c = mb_ptr2char_adv(&s);
|
int c = mb_ptr2char_adv((const char_u **)&s);
|
||||||
if (c == CAR || c == NL || c == ESC)
|
if (c == CAR || c == NL || c == ESC) {
|
||||||
c = ' ';
|
c = ' ';
|
||||||
|
}
|
||||||
stuffcharReadbuff(c);
|
stuffcharReadbuff(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -747,8 +748,8 @@ int start_redo(long count, int old_redo)
|
|||||||
|
|
||||||
/* copy the buffer name, if present */
|
/* copy the buffer name, if present */
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
add_buff(&readbuf2, (char_u *)"\"", 1L);
|
add_buff(&readbuf2, "\"", 1L);
|
||||||
c = read_redo(FALSE, old_redo);
|
c = read_redo(false, old_redo);
|
||||||
|
|
||||||
/* if a numbered buffer is used, increment the number */
|
/* if a numbered buffer is used, increment the number */
|
||||||
if (c >= '1' && c < '9')
|
if (c >= '1' && c < '9')
|
||||||
@@ -1091,21 +1092,19 @@ static void gotchars(char_u *chars, size_t len)
|
|||||||
{
|
{
|
||||||
char_u *s = chars;
|
char_u *s = chars;
|
||||||
int c;
|
int c;
|
||||||
char_u buf[2];
|
|
||||||
|
|
||||||
// remember how many chars were last recorded
|
// remember how many chars were last recorded
|
||||||
if (Recording) {
|
if (Recording) {
|
||||||
last_recorded_len += len;
|
last_recorded_len += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[1] = NUL;
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
// Handle one byte at a time; no translation to be done.
|
// Handle one byte at a time; no translation to be done.
|
||||||
c = *s++;
|
c = *s++;
|
||||||
updatescript(c);
|
updatescript(c);
|
||||||
|
|
||||||
if (Recording) {
|
if (Recording) {
|
||||||
buf[0] = (char_u)c;
|
char buf[2] = { (char)c, NUL };
|
||||||
add_buff(&recordbuff, buf, 1L);
|
add_buff(&recordbuff, buf, 1L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1199,6 +1199,7 @@ EXTERN char_u e_dirnotf[] INIT(= N_(
|
|||||||
"E919: Directory not found in '%s': \"%s\""));
|
"E919: Directory not found in '%s': \"%s\""));
|
||||||
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
|
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
|
||||||
EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
|
EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
|
||||||
|
EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
|
||||||
|
|
||||||
|
|
||||||
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
|
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
|
||||||
|
|||||||
@@ -625,7 +625,7 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n)
|
|||||||
* Get character at **pp and advance *pp to the next character.
|
* Get character at **pp and advance *pp to the next character.
|
||||||
* Note: composing characters are skipped!
|
* Note: composing characters are skipped!
|
||||||
*/
|
*/
|
||||||
int mb_ptr2char_adv(char_u **pp)
|
int mb_ptr2char_adv(const char_u **const pp)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@@ -638,7 +638,7 @@ int mb_ptr2char_adv(char_u **pp)
|
|||||||
* Get character at **pp and advance *pp to the next character.
|
* Get character at **pp and advance *pp to the next character.
|
||||||
* Note: composing characters are returned as separate characters.
|
* Note: composing characters are returned as separate characters.
|
||||||
*/
|
*/
|
||||||
int mb_cptr2char_adv(char_u **pp)
|
int mb_cptr2char_adv(const char_u **pp)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
|||||||
@@ -1155,7 +1155,7 @@ static void normal_check_stuff_buffer(NormalState *s)
|
|||||||
|
|
||||||
if (need_start_insertmode && goto_im() && !VIsual_active) {
|
if (need_start_insertmode && goto_im() && !VIsual_active) {
|
||||||
need_start_insertmode = false;
|
need_start_insertmode = false;
|
||||||
stuffReadbuff((uint8_t *)"i"); // start insert mode next
|
stuffReadbuff("i"); // start insert mode next
|
||||||
// skip the fileinfo message now, because it would be shown
|
// skip the fileinfo message now, because it would be shown
|
||||||
// after insert mode finishes!
|
// after insert mode finishes!
|
||||||
need_fileinfo = false;
|
need_fileinfo = false;
|
||||||
@@ -1469,8 +1469,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
* If 'cpoptions' does not contain 'r', insert the search
|
* If 'cpoptions' does not contain 'r', insert the search
|
||||||
* pattern to really repeat the same command.
|
* pattern to really repeat the same command.
|
||||||
*/
|
*/
|
||||||
if (vim_strchr(p_cpo, CPO_REDO) == NULL)
|
if (vim_strchr(p_cpo, CPO_REDO) == NULL) {
|
||||||
AppendToRedobuffLit(cap->searchbuf, -1);
|
AppendToRedobuffLit(cap->searchbuf, -1);
|
||||||
|
}
|
||||||
AppendToRedobuff(NL_STR);
|
AppendToRedobuff(NL_STR);
|
||||||
} else if (cap->cmdchar == ':') {
|
} else if (cap->cmdchar == ':') {
|
||||||
/* do_cmdline() has stored the first typed line in
|
/* do_cmdline() has stored the first typed line in
|
||||||
@@ -1853,10 +1854,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_FILTER:
|
case OP_FILTER:
|
||||||
if (vim_strchr(p_cpo, CPO_FILTER) != NULL)
|
if (vim_strchr(p_cpo, CPO_FILTER) != NULL) {
|
||||||
AppendToRedobuff((char_u *)"!\r"); /* use any last used !cmd */
|
AppendToRedobuff("!\r"); // Use any last used !cmd.
|
||||||
else
|
} else {
|
||||||
bangredo = true; /* do_bang() will put cmd in redo buffer */
|
bangredo = true; // do_bang() will put cmd in redo buffer.
|
||||||
|
}
|
||||||
|
|
||||||
case OP_INDENT:
|
case OP_INDENT:
|
||||||
case OP_COLON:
|
case OP_COLON:
|
||||||
@@ -2026,43 +2028,44 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
static void op_colon(oparg_T *oap)
|
static void op_colon(oparg_T *oap)
|
||||||
{
|
{
|
||||||
stuffcharReadbuff(':');
|
stuffcharReadbuff(':');
|
||||||
if (oap->is_VIsual)
|
if (oap->is_VIsual) {
|
||||||
stuffReadbuff((char_u *)"'<,'>");
|
stuffReadbuff("'<,'>");
|
||||||
else {
|
} else {
|
||||||
/*
|
// Make the range look nice, so it can be repeated.
|
||||||
* Make the range look nice, so it can be repeated.
|
if (oap->start.lnum == curwin->w_cursor.lnum) {
|
||||||
*/
|
|
||||||
if (oap->start.lnum == curwin->w_cursor.lnum)
|
|
||||||
stuffcharReadbuff('.');
|
stuffcharReadbuff('.');
|
||||||
else
|
} else {
|
||||||
stuffnumReadbuff((long)oap->start.lnum);
|
stuffnumReadbuff((long)oap->start.lnum);
|
||||||
|
}
|
||||||
if (oap->end.lnum != oap->start.lnum) {
|
if (oap->end.lnum != oap->start.lnum) {
|
||||||
stuffcharReadbuff(',');
|
stuffcharReadbuff(',');
|
||||||
if (oap->end.lnum == curwin->w_cursor.lnum)
|
if (oap->end.lnum == curwin->w_cursor.lnum) {
|
||||||
stuffcharReadbuff('.');
|
stuffcharReadbuff('.');
|
||||||
else if (oap->end.lnum == curbuf->b_ml.ml_line_count)
|
} else if (oap->end.lnum == curbuf->b_ml.ml_line_count) {
|
||||||
stuffcharReadbuff('$');
|
stuffcharReadbuff('$');
|
||||||
else if (oap->start.lnum == curwin->w_cursor.lnum) {
|
} else if (oap->start.lnum == curwin->w_cursor.lnum) {
|
||||||
stuffReadbuff((char_u *)".+");
|
stuffReadbuff(".+");
|
||||||
stuffnumReadbuff(oap->line_count - 1);
|
stuffnumReadbuff(oap->line_count - 1);
|
||||||
} else
|
} else {
|
||||||
stuffnumReadbuff((long)oap->end.lnum);
|
stuffnumReadbuff((long)oap->end.lnum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oap->op_type != OP_COLON)
|
if (oap->op_type != OP_COLON) {
|
||||||
stuffReadbuff((char_u *)"!");
|
stuffReadbuff("!");
|
||||||
|
}
|
||||||
if (oap->op_type == OP_INDENT) {
|
if (oap->op_type == OP_INDENT) {
|
||||||
stuffReadbuff(get_equalprg());
|
stuffReadbuff((const char *)get_equalprg());
|
||||||
stuffReadbuff((char_u *)"\n");
|
stuffReadbuff("\n");
|
||||||
} else if (oap->op_type == OP_FORMAT) {
|
} else if (oap->op_type == OP_FORMAT) {
|
||||||
if (*curbuf->b_p_fp != NUL) {
|
if (*curbuf->b_p_fp != NUL) {
|
||||||
stuffReadbuff(curbuf->b_p_fp);
|
stuffReadbuff((const char *)curbuf->b_p_fp);
|
||||||
} else if (*p_fp != NUL) {
|
} else if (*p_fp != NUL) {
|
||||||
stuffReadbuff(p_fp);
|
stuffReadbuff((const char *)p_fp);
|
||||||
} else {
|
} else {
|
||||||
stuffReadbuff((char_u *)"fmt");
|
stuffReadbuff("fmt");
|
||||||
}
|
}
|
||||||
stuffReadbuff((char_u *)"\n']");
|
stuffReadbuff("\n']");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2304,7 +2307,7 @@ do_mouse (
|
|||||||
if (VIsual_active) {
|
if (VIsual_active) {
|
||||||
if (VIsual_select) {
|
if (VIsual_select) {
|
||||||
stuffcharReadbuff(Ctrl_G);
|
stuffcharReadbuff(Ctrl_G);
|
||||||
stuffReadbuff((char_u *)"\"+p");
|
stuffReadbuff("\"+p");
|
||||||
} else {
|
} else {
|
||||||
stuffcharReadbuff('y');
|
stuffcharReadbuff('y');
|
||||||
stuffcharReadbuff(K_MIDDLEMOUSE);
|
stuffcharReadbuff(K_MIDDLEMOUSE);
|
||||||
@@ -4476,7 +4479,7 @@ static void nv_colon(cmdarg_T *cap)
|
|||||||
/* translate "count:" into ":.,.+(count - 1)" */
|
/* translate "count:" into ":.,.+(count - 1)" */
|
||||||
stuffcharReadbuff('.');
|
stuffcharReadbuff('.');
|
||||||
if (cap->count0 > 1) {
|
if (cap->count0 > 1) {
|
||||||
stuffReadbuff((char_u *)",.+");
|
stuffReadbuff(",.+");
|
||||||
stuffnumReadbuff(cap->count0 - 1L);
|
stuffnumReadbuff(cap->count0 - 1L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6156,17 +6159,15 @@ static void nv_abbrev(cmdarg_T *cap)
|
|||||||
*/
|
*/
|
||||||
static void nv_optrans(cmdarg_T *cap)
|
static void nv_optrans(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh",
|
static const char *(ar[]) = { "dl", "dh", "d$", "c$", "cl", "cc", "yy",
|
||||||
(char_u *)"d$", (char_u *)"c$",
|
":s\r" };
|
||||||
(char_u *)"cl", (char_u *)"cc",
|
static const char *str = "xXDCsSY&";
|
||||||
(char_u *)"yy", (char_u *)":s\r"};
|
|
||||||
static char_u *str = (char_u *)"xXDCsSY&";
|
|
||||||
|
|
||||||
if (!checkclearopq(cap->oap)) {
|
if (!checkclearopq(cap->oap)) {
|
||||||
if (cap->count0) {
|
if (cap->count0) {
|
||||||
stuffnumReadbuff(cap->count0);
|
stuffnumReadbuff(cap->count0);
|
||||||
}
|
}
|
||||||
stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]);
|
stuffReadbuff(ar[strchr(str, (char)cap->cmdchar) - str]);
|
||||||
}
|
}
|
||||||
cap->opcount = 0;
|
cap->opcount = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1109,7 +1109,6 @@ int insert_reg(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int retval = OK;
|
int retval = OK;
|
||||||
char_u *arg;
|
|
||||||
int allocated;
|
int allocated;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1125,21 +1124,24 @@ int insert_reg(
|
|||||||
if (regname != NUL && !valid_yank_reg(regname, false))
|
if (regname != NUL && !valid_yank_reg(regname, false))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
if (regname == '.') /* insert last inserted text */
|
char_u *arg;
|
||||||
retval = stuff_inserted(NUL, 1L, TRUE);
|
if (regname == '.') { // Insert last inserted text.
|
||||||
else if (get_spec_reg(regname, &arg, &allocated, TRUE)) {
|
retval = stuff_inserted(NUL, 1L, true);
|
||||||
if (arg == NULL)
|
} else if (get_spec_reg(regname, &arg, &allocated, true)) {
|
||||||
|
if (arg == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
stuffescaped(arg, literally);
|
}
|
||||||
if (allocated)
|
stuffescaped((const char *)arg, literally);
|
||||||
|
if (allocated) {
|
||||||
xfree(arg);
|
xfree(arg);
|
||||||
} else { /* name or number register */
|
}
|
||||||
|
} else { // Name or number register.
|
||||||
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
|
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
|
||||||
if (reg->y_array == NULL) {
|
if (reg->y_array == NULL) {
|
||||||
retval = FAIL;
|
retval = FAIL;
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < reg->y_size; i++) {
|
for (size_t i = 0; i < reg->y_size; i++) {
|
||||||
stuffescaped(reg->y_array[i], literally);
|
stuffescaped((const char *)reg->y_array[i], literally);
|
||||||
// Insert a newline between lines and after last line if
|
// Insert a newline between lines and after last line if
|
||||||
// y_type is kMTLineWise.
|
// y_type is kMTLineWise.
|
||||||
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
||||||
@@ -1156,29 +1158,29 @@ int insert_reg(
|
|||||||
* Stuff a string into the typeahead buffer, such that edit() will insert it
|
* Stuff a string into the typeahead buffer, such that edit() will insert it
|
||||||
* literally ("literally" TRUE) or interpret is as typed characters.
|
* literally ("literally" TRUE) or interpret is as typed characters.
|
||||||
*/
|
*/
|
||||||
static void stuffescaped(char_u *arg, int literally)
|
static void stuffescaped(const char *arg, int literally)
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
char_u *start;
|
|
||||||
|
|
||||||
while (*arg != NUL) {
|
while (*arg != NUL) {
|
||||||
/* Stuff a sequence of normal ASCII characters, that's fast. Also
|
// Stuff a sequence of normal ASCII characters, that's fast. Also
|
||||||
* stuff K_SPECIAL to get the effect of a special key when "literally"
|
// stuff K_SPECIAL to get the effect of a special key when "literally"
|
||||||
* is TRUE. */
|
// is TRUE.
|
||||||
start = arg;
|
const char *const start = arg;
|
||||||
while ((*arg >= ' ' && *arg < DEL) || (*arg == K_SPECIAL && !literally))
|
while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
|
||||||
++arg;
|
&& !literally)) {
|
||||||
if (arg > start)
|
arg++;
|
||||||
|
}
|
||||||
|
if (arg > start) {
|
||||||
stuffReadbuffLen(start, (long)(arg - start));
|
stuffReadbuffLen(start, (long)(arg - start));
|
||||||
|
}
|
||||||
|
|
||||||
/* stuff a single special character */
|
/* stuff a single special character */
|
||||||
if (*arg != NUL) {
|
if (*arg != NUL) {
|
||||||
if (has_mbyte)
|
const int c = (has_mbyte
|
||||||
c = mb_cptr2char_adv(&arg);
|
? mb_cptr2char_adv((const char_u **)&arg)
|
||||||
else
|
: (uint8_t)(*arg++));
|
||||||
c = *arg++;
|
if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
|
||||||
if (literally && ((c < ' ' && c != TAB) || c == DEL))
|
|
||||||
stuffcharReadbuff(Ctrl_V);
|
stuffcharReadbuff(Ctrl_V);
|
||||||
|
}
|
||||||
stuffcharReadbuff(c);
|
stuffcharReadbuff(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2663,7 +2665,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
// back to the previous line in the case of 'noautoindent' and
|
// back to the previous line in the case of 'noautoindent' and
|
||||||
// 'backspace' includes "eol". So we insert a dummy space for Ctrl_U
|
// 'backspace' includes "eol". So we insert a dummy space for Ctrl_U
|
||||||
// to consume.
|
// to consume.
|
||||||
stuffReadbuff((char_u *)"\n ");
|
stuffReadbuff("\n ");
|
||||||
stuffcharReadbuff(Ctrl_U);
|
stuffcharReadbuff(Ctrl_U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2675,7 +2677,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
// character. Simulate it with motion commands after the insert.
|
// character. Simulate it with motion commands after the insert.
|
||||||
if (flags & PUT_CURSEND) {
|
if (flags & PUT_CURSEND) {
|
||||||
if (flags & PUT_LINE) {
|
if (flags & PUT_LINE) {
|
||||||
stuffReadbuff((char_u *)"j0");
|
stuffReadbuff("j0");
|
||||||
} else {
|
} else {
|
||||||
// Avoid ringing the bell from attempting to move into the space after
|
// Avoid ringing the bell from attempting to move into the space after
|
||||||
// the current line. We can stuff the readbuffer with "l" if:
|
// the current line. We can stuff the readbuffer with "l" if:
|
||||||
@@ -2705,7 +2707,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (flags & PUT_LINE) {
|
} else if (flags & PUT_LINE) {
|
||||||
stuffReadbuff((char_u *)"g'[");
|
stuffReadbuff("g'[");
|
||||||
}
|
}
|
||||||
|
|
||||||
// So the 'u' command restores cursor position after ".p, save the cursor
|
// So the 'u' command restores cursor position after ".p, save the cursor
|
||||||
@@ -4981,7 +4983,7 @@ void write_reg_contents(int name, const char_u *str, ssize_t len,
|
|||||||
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
|
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_reg_contents_lst(int name, char_u **strings, int maxlen,
|
void write_reg_contents_lst(int name, char_u **strings,
|
||||||
bool must_append, MotionType yank_type,
|
bool must_append, MotionType yank_type,
|
||||||
colnr_T block_len)
|
colnr_T block_len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3419,15 +3419,18 @@ static char_u *set_chars_option(char_u **varp)
|
|||||||
&& p[len] == ':'
|
&& p[len] == ':'
|
||||||
&& p[len + 1] != NUL) {
|
&& p[len + 1] != NUL) {
|
||||||
s = p + len + 1;
|
s = p + len + 1;
|
||||||
c1 = mb_ptr2char_adv(&s);
|
c1 = mb_ptr2char_adv((const char_u **)&s);
|
||||||
if (mb_char2cells(c1) > 1)
|
if (mb_char2cells(c1) > 1) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (tab[i].cp == &lcs_tab2) {
|
if (tab[i].cp == &lcs_tab2) {
|
||||||
if (*s == NUL)
|
if (*s == NUL) {
|
||||||
continue;
|
continue;
|
||||||
c2 = mb_ptr2char_adv(&s);
|
}
|
||||||
if (mb_char2cells(c2) > 1)
|
c2 = mb_ptr2char_adv((const char_u **)&s);
|
||||||
|
if (mb_char2cells(c2) > 1) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (*s == ',' || *s == NUL) {
|
if (*s == ',' || *s == NUL) {
|
||||||
if (round) {
|
if (round) {
|
||||||
@@ -6887,8 +6890,8 @@ void set_fileformat(int eol_style, int opt_flags)
|
|||||||
need_maketitle = true; // Set window title later.
|
need_maketitle = true; // Set window title later.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skip to next part of an option argument: Skip space and comma.
|
/// Skip to next part of an option argument: skip space and comma
|
||||||
char_u *skip_to_option_part(char_u *p)
|
char_u *skip_to_option_part(const char_u *p)
|
||||||
{
|
{
|
||||||
if (*p == ',') {
|
if (*p == ',') {
|
||||||
p++;
|
p++;
|
||||||
@@ -6896,7 +6899,7 @@ char_u *skip_to_option_part(char_u *p)
|
|||||||
while (*p == ' ') {
|
while (*p == ' ') {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return p;
|
return (char_u *)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Isolate one part of a string option separated by `sep_chars`.
|
/// Isolate one part of a string option separated by `sep_chars`.
|
||||||
|
|||||||
@@ -622,11 +622,11 @@ int32_t os_getperm(const char *name)
|
|||||||
/// Set the permission of a file.
|
/// Set the permission of a file.
|
||||||
///
|
///
|
||||||
/// @return `OK` for success, `FAIL` for failure.
|
/// @return `OK` for success, `FAIL` for failure.
|
||||||
int os_setperm(const char_u *name, int perm)
|
int os_setperm(const char *const name, int perm)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
RUN_UV_FS_FUNC(r, uv_fs_chmod, (const char *)name, perm, NULL);
|
RUN_UV_FS_FUNC(r, uv_fs_chmod, name, perm, NULL);
|
||||||
return (r == kLibuvSuccess ? OK : FAIL);
|
return (r == kLibuvSuccess ? OK : FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2221,10 +2221,11 @@ collection:
|
|||||||
if (*regparse == '[')
|
if (*regparse == '[')
|
||||||
endc = get_coll_element(®parse);
|
endc = get_coll_element(®parse);
|
||||||
if (endc == 0) {
|
if (endc == 0) {
|
||||||
if (has_mbyte)
|
if (has_mbyte) {
|
||||||
endc = mb_ptr2char_adv(®parse);
|
endc = mb_ptr2char_adv((const char_u **)®parse);
|
||||||
else
|
} else {
|
||||||
endc = *regparse++;
|
endc = *regparse++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle \o40, \x20 and \u20AC style sequences */
|
/* Handle \o40, \x20 and \u20AC style sequences */
|
||||||
@@ -6271,8 +6272,8 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
|
|||||||
str2 = s2;
|
str2 = s2;
|
||||||
c1 = c2 = 0;
|
c1 = c2 = 0;
|
||||||
while ((int)(str1 - s1) < *n) {
|
while ((int)(str1 - s1) < *n) {
|
||||||
c1 = mb_ptr2char_adv(&str1);
|
c1 = mb_ptr2char_adv((const char_u **)&str1);
|
||||||
c2 = mb_ptr2char_adv(&str2);
|
c2 = mb_ptr2char_adv((const char_u **)&str2);
|
||||||
|
|
||||||
/* decompose the character if necessary, into 'base' characters
|
/* decompose the character if necessary, into 'base' characters
|
||||||
* because I don't care about Arabic, I will hard-code the Hebrew
|
* because I don't care about Arabic, I will hard-code the Hebrew
|
||||||
@@ -6586,7 +6587,6 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
|
|||||||
if (expr != NULL) {
|
if (expr != NULL) {
|
||||||
typval_T argv[2];
|
typval_T argv[2];
|
||||||
int dummy;
|
int dummy;
|
||||||
char_u buf[NUMBUFLEN];
|
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
staticList10_T matchList;
|
staticList10_T matchList;
|
||||||
|
|
||||||
@@ -6616,7 +6616,8 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
|
|||||||
clear_submatch_list(&matchList);
|
clear_submatch_list(&matchList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eval_result = get_tv_string_buf_chk(&rettv, buf);
|
char buf[NUMBUFLEN];
|
||||||
|
eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
|
||||||
if (eval_result != NULL) {
|
if (eval_result != NULL) {
|
||||||
eval_result = vim_strsave(eval_result);
|
eval_result = vim_strsave(eval_result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3141,7 +3141,7 @@ win_line (
|
|||||||
|
|
||||||
p_extra = extra;
|
p_extra = extra;
|
||||||
c = *p_extra;
|
c = *p_extra;
|
||||||
mb_c = mb_ptr2char_adv(&p_extra);
|
mb_c = mb_ptr2char_adv((const char_u **)&p_extra);
|
||||||
mb_utf8 = (c >= 0x80);
|
mb_utf8 = (c >= 0x80);
|
||||||
n_extra = (int)STRLEN(p_extra);
|
n_extra = (int)STRLEN(p_extra);
|
||||||
c_extra = NUL;
|
c_extra = NUL;
|
||||||
|
|||||||
@@ -2309,10 +2309,11 @@ int captype(char_u *word, char_u *end)
|
|||||||
for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
|
for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
|
||||||
if (end == NULL ? *p == NUL : p >= end)
|
if (end == NULL ? *p == NUL : p >= end)
|
||||||
return 0; // only non-word characters, illegal word
|
return 0; // only non-word characters, illegal word
|
||||||
if (has_mbyte)
|
if (has_mbyte) {
|
||||||
c = mb_ptr2char_adv(&p);
|
c = mb_ptr2char_adv((const char_u **)&p);
|
||||||
else
|
} else {
|
||||||
c = *p++;
|
c = *p++;
|
||||||
|
}
|
||||||
firstcap = allcap = SPELL_ISUPPER(c);
|
firstcap = allcap = SPELL_ISUPPER(c);
|
||||||
|
|
||||||
// Need to check all letters to find a word with mixed upper/lower.
|
// Need to check all letters to find a word with mixed upper/lower.
|
||||||
@@ -2607,14 +2608,15 @@ static bool spell_iswordp(char_u *p, win_T *wp)
|
|||||||
|
|
||||||
// Returns true if "p" points to a word character.
|
// Returns true if "p" points to a word character.
|
||||||
// Unlike spell_iswordp() this doesn't check for "midword" characters.
|
// Unlike spell_iswordp() this doesn't check for "midword" characters.
|
||||||
bool spell_iswordp_nmw(char_u *p, win_T *wp)
|
bool spell_iswordp_nmw(const char_u *p, win_T *wp)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (has_mbyte) {
|
if (has_mbyte) {
|
||||||
c = mb_ptr2char(p);
|
c = mb_ptr2char(p);
|
||||||
if (c > 255)
|
if (c > 255) {
|
||||||
return spell_mb_isword_class(mb_get_class(p), wp);
|
return spell_mb_isword_class(mb_get_class(p), wp);
|
||||||
|
}
|
||||||
return spelltab.st_isw[c];
|
return spelltab.st_isw[c];
|
||||||
}
|
}
|
||||||
return spelltab.st_isw[*p];
|
return spelltab.st_isw[*p];
|
||||||
@@ -2675,7 +2677,7 @@ int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
|
|||||||
buf[outi] = NUL;
|
buf[outi] = NUL;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
c = mb_cptr2char_adv(&p);
|
c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
|
outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
|
||||||
}
|
}
|
||||||
buf[outi] = NUL;
|
buf[outi] = NUL;
|
||||||
@@ -2937,7 +2939,7 @@ void spell_suggest(int count)
|
|||||||
|
|
||||||
// For redo we use a change-word command.
|
// For redo we use a change-word command.
|
||||||
ResetRedobuff();
|
ResetRedobuff();
|
||||||
AppendToRedobuff((char_u *)"ciw");
|
AppendToRedobuff("ciw");
|
||||||
AppendToRedobuffLit(p + c,
|
AppendToRedobuffLit(p + c,
|
||||||
stp->st_wordlen + sug.su_badlen - stp->st_orglen);
|
stp->st_wordlen + sug.su_badlen - stp->st_orglen);
|
||||||
AppendCharToRedobuff(ESC);
|
AppendCharToRedobuff(ESC);
|
||||||
@@ -3406,17 +3408,19 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper)
|
|||||||
int l;
|
int l;
|
||||||
|
|
||||||
p = word;
|
p = word;
|
||||||
if (has_mbyte)
|
if (has_mbyte) {
|
||||||
c = mb_cptr2char_adv(&p);
|
c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
else
|
} else {
|
||||||
c = *p++;
|
c = *p++;
|
||||||
if (upper)
|
}
|
||||||
|
if (upper) {
|
||||||
c = SPELL_TOUPPER(c);
|
c = SPELL_TOUPPER(c);
|
||||||
else
|
} else {
|
||||||
c = SPELL_TOFOLD(c);
|
c = SPELL_TOFOLD(c);
|
||||||
if (has_mbyte)
|
}
|
||||||
|
if (has_mbyte) {
|
||||||
l = mb_char2bytes(c, wcopy);
|
l = mb_char2bytes(c, wcopy);
|
||||||
else {
|
} else {
|
||||||
l = 1;
|
l = 1;
|
||||||
wcopy[0] = c;
|
wcopy[0] = c;
|
||||||
}
|
}
|
||||||
@@ -3433,10 +3437,11 @@ static void allcap_copy(char_u *word, char_u *wcopy)
|
|||||||
|
|
||||||
d = wcopy;
|
d = wcopy;
|
||||||
for (s = word; *s != NUL; ) {
|
for (s = word; *s != NUL; ) {
|
||||||
if (has_mbyte)
|
if (has_mbyte) {
|
||||||
c = mb_cptr2char_adv(&s);
|
c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
else
|
} else {
|
||||||
c = *s++;
|
c = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == 0xdf) {
|
if (c == 0xdf) {
|
||||||
c = 'S';
|
c = 'S';
|
||||||
@@ -5938,12 +5943,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
|
|||||||
// The sl_sal_first[] table contains the translation for chars up to
|
// The sl_sal_first[] table contains the translation for chars up to
|
||||||
// 255, sl_sal the rest.
|
// 255, sl_sal the rest.
|
||||||
for (s = inword; *s != NUL; ) {
|
for (s = inword; *s != NUL; ) {
|
||||||
c = mb_cptr2char_adv(&s);
|
c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c))
|
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
|
||||||
c = ' ';
|
c = ' ';
|
||||||
else if (c < 256)
|
} else if (c < 256) {
|
||||||
c = slang->sl_sal_first[c];
|
c = slang->sl_sal_first[c];
|
||||||
else {
|
} else {
|
||||||
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
|
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
|
||||||
if (ip == NULL) // empty list, can't match
|
if (ip == NULL) // empty list, can't match
|
||||||
c = NUL;
|
c = NUL;
|
||||||
@@ -6228,9 +6233,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
|
|||||||
int word[MAXWLEN];
|
int word[MAXWLEN];
|
||||||
int wres[MAXWLEN];
|
int wres[MAXWLEN];
|
||||||
int l;
|
int l;
|
||||||
char_u *s;
|
|
||||||
int *ws;
|
int *ws;
|
||||||
char_u *t;
|
|
||||||
int *pf;
|
int *pf;
|
||||||
int i, j, z;
|
int i, j, z;
|
||||||
int reslen;
|
int reslen;
|
||||||
@@ -6250,9 +6253,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
|
|||||||
// Remove accents, if wanted. We actually remove all non-word characters.
|
// Remove accents, if wanted. We actually remove all non-word characters.
|
||||||
// But keep white space.
|
// But keep white space.
|
||||||
wordlen = 0;
|
wordlen = 0;
|
||||||
for (s = inword; *s != NUL; ) {
|
for (const char_u *s = inword; *s != NUL; ) {
|
||||||
t = s;
|
const char_u *t = s;
|
||||||
c = mb_cptr2char_adv(&s);
|
c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
if (slang->sl_rem_accents) {
|
if (slang->sl_rem_accents) {
|
||||||
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
|
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
|
||||||
if (did_white)
|
if (did_white)
|
||||||
@@ -6261,8 +6264,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
|
|||||||
did_white = true;
|
did_white = true;
|
||||||
} else {
|
} else {
|
||||||
did_white = false;
|
did_white = false;
|
||||||
if (!spell_iswordp_nmw(t, curwin))
|
if (!spell_iswordp_nmw(t, curwin)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
word[wordlen++] = c;
|
word[wordlen++] = c;
|
||||||
@@ -6309,7 +6313,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
|
|||||||
continue;
|
continue;
|
||||||
++k;
|
++k;
|
||||||
}
|
}
|
||||||
s = smp[n].sm_rules;
|
char_u *s = smp[n].sm_rules;
|
||||||
pri = 5; // default priority
|
pri = 5; // default priority
|
||||||
|
|
||||||
p0 = *s;
|
p0 = *s;
|
||||||
@@ -6708,25 +6712,30 @@ soundalike_score (
|
|||||||
// support multi-byte characters.
|
// support multi-byte characters.
|
||||||
static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
||||||
{
|
{
|
||||||
int *cnt;
|
int *cnt;
|
||||||
int badlen, goodlen; // lengths including NUL
|
|
||||||
int j, i;
|
int j, i;
|
||||||
int t;
|
int t;
|
||||||
int bc, gc;
|
int bc, gc;
|
||||||
int pbc, pgc;
|
int pbc, pgc;
|
||||||
char_u *p;
|
|
||||||
int wbadword[MAXWLEN];
|
int wbadword[MAXWLEN];
|
||||||
int wgoodword[MAXWLEN];
|
int wgoodword[MAXWLEN];
|
||||||
const bool l_has_mbyte = has_mbyte;
|
const bool l_has_mbyte = has_mbyte;
|
||||||
|
|
||||||
|
// Lengths with NUL.
|
||||||
|
int badlen;
|
||||||
|
int goodlen;
|
||||||
if (l_has_mbyte) {
|
if (l_has_mbyte) {
|
||||||
// Get the characters from the multi-byte strings and put them in an
|
// Get the characters from the multi-byte strings and put them in an
|
||||||
// int array for easy access.
|
// int array for easy access.
|
||||||
for (p = badword, badlen = 0; *p != NUL; )
|
badlen = 0;
|
||||||
|
for (const char_u *p = badword; *p != NUL; ) {
|
||||||
wbadword[badlen++] = mb_cptr2char_adv(&p);
|
wbadword[badlen++] = mb_cptr2char_adv(&p);
|
||||||
|
}
|
||||||
wbadword[badlen++] = 0;
|
wbadword[badlen++] = 0;
|
||||||
for (p = goodword, goodlen = 0; *p != NUL; )
|
goodlen = 0;
|
||||||
|
for (const char_u *p = goodword; *p != NUL; ) {
|
||||||
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
|
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
|
||||||
|
}
|
||||||
wgoodword[goodlen++] = 0;
|
wgoodword[goodlen++] = 0;
|
||||||
} else {
|
} else {
|
||||||
badlen = (int)STRLEN(badword) + 1;
|
badlen = (int)STRLEN(badword) + 1;
|
||||||
@@ -6960,19 +6969,20 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
|
|||||||
int score_off;
|
int score_off;
|
||||||
int minscore;
|
int minscore;
|
||||||
int round;
|
int round;
|
||||||
char_u *p;
|
|
||||||
int wbadword[MAXWLEN];
|
int wbadword[MAXWLEN];
|
||||||
int wgoodword[MAXWLEN];
|
int wgoodword[MAXWLEN];
|
||||||
|
|
||||||
// Get the characters from the multi-byte strings and put them in an
|
// Get the characters from the multi-byte strings and put them in an
|
||||||
// int array for easy access.
|
// int array for easy access.
|
||||||
bi = 0;
|
bi = 0;
|
||||||
for (p = badword; *p != NUL; )
|
for (const char_u *p = badword; *p != NUL; ) {
|
||||||
wbadword[bi++] = mb_cptr2char_adv(&p);
|
wbadword[bi++] = mb_cptr2char_adv(&p);
|
||||||
|
}
|
||||||
wbadword[bi++] = 0;
|
wbadword[bi++] = 0;
|
||||||
gi = 0;
|
gi = 0;
|
||||||
for (p = goodword; *p != NUL; )
|
for (const char_u *p = goodword; *p != NUL; ) {
|
||||||
wgoodword[gi++] = mb_cptr2char_adv(&p);
|
wgoodword[gi++] = mb_cptr2char_adv(&p);
|
||||||
|
}
|
||||||
wgoodword[gi++] = 0;
|
wgoodword[gi++] = 0;
|
||||||
|
|
||||||
// The idea is to go from start to end over the words. So long as
|
// The idea is to go from start to end over the words. So long as
|
||||||
|
|||||||
@@ -1435,7 +1435,7 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
|
|||||||
// First count the number of items for each list. Temporarily use
|
// First count the number of items for each list. Temporarily use
|
||||||
// sl_sal_first[] for this.
|
// sl_sal_first[] for this.
|
||||||
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
||||||
c = mb_cptr2char_adv(&p);
|
c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
mb_cptr_adv(s);
|
mb_cptr_adv(s);
|
||||||
if (c >= 256)
|
if (c >= 256)
|
||||||
++lp->sl_sal_first[c & 0xff];
|
++lp->sl_sal_first[c & 0xff];
|
||||||
@@ -1455,8 +1455,8 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
|
|||||||
// list.
|
// list.
|
||||||
memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
|
memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
|
||||||
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
||||||
c = mb_cptr2char_adv(&p);
|
c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
i = mb_cptr2char_adv(&s);
|
i = mb_cptr2char_adv((const char_u **)&s);
|
||||||
if (c >= 256) {
|
if (c >= 256) {
|
||||||
// Append the from-to chars at the end of the list with
|
// Append the from-to chars at the end of the list with
|
||||||
// the low byte.
|
// the low byte.
|
||||||
@@ -1542,8 +1542,9 @@ static int *mb_str2wide(char_u *s)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
|
int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
|
||||||
for (char_u *p = s; *p != NUL; )
|
for (char_u *p = s; *p != NUL; ) {
|
||||||
res[i++] = mb_ptr2char_adv(&p);
|
res[i++] = mb_ptr2char_adv((const char_u **)&p);
|
||||||
|
}
|
||||||
res[i] = NUL;
|
res[i] = NUL;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -2486,13 +2487,14 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|
|||||||
|
|
||||||
// Check that every character appears only once.
|
// Check that every character appears only once.
|
||||||
for (p = items[1]; *p != NUL; ) {
|
for (p = items[1]; *p != NUL; ) {
|
||||||
c = mb_ptr2char_adv(&p);
|
c = mb_ptr2char_adv((const char_u **)&p);
|
||||||
if ((!GA_EMPTY(&spin->si_map)
|
if ((!GA_EMPTY(&spin->si_map)
|
||||||
&& vim_strchr(spin->si_map.ga_data, c)
|
&& vim_strchr(spin->si_map.ga_data, c)
|
||||||
!= NULL)
|
!= NULL)
|
||||||
|| vim_strchr(p, c) != NULL)
|
|| vim_strchr(p, c) != NULL) {
|
||||||
smsg(_("Duplicate character in MAP in %s line %d"),
|
smsg(_("Duplicate character in MAP in %s line %d"),
|
||||||
fname, lnum);
|
fname, lnum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We simply concatenate all the MAP strings, separated by
|
// We simply concatenate all the MAP strings, separated by
|
||||||
@@ -2717,12 +2719,12 @@ static unsigned get_affitem(int flagtype, char_u **pp)
|
|||||||
}
|
}
|
||||||
res = getdigits_int(pp);
|
res = getdigits_int(pp);
|
||||||
} else {
|
} else {
|
||||||
res = mb_ptr2char_adv(pp);
|
res = mb_ptr2char_adv((const char_u **)pp);
|
||||||
if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
|
if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
|
||||||
&& res >= 'A' && res <= 'Z')) {
|
&& res >= 'A' && res <= 'Z')) {
|
||||||
if (**pp == NUL)
|
if (**pp == NUL)
|
||||||
return 0;
|
return 0;
|
||||||
res = mb_ptr2char_adv(pp) + (res << 16);
|
res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@@ -2823,12 +2825,14 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
|
|||||||
case AFT_CAPLONG:
|
case AFT_CAPLONG:
|
||||||
case AFT_LONG:
|
case AFT_LONG:
|
||||||
for (p = afflist; *p != NUL; ) {
|
for (p = afflist; *p != NUL; ) {
|
||||||
n = mb_ptr2char_adv(&p);
|
n = mb_ptr2char_adv((const char_u **)&p);
|
||||||
if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
|
if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
|
||||||
&& *p != NUL)
|
&& *p != NUL) {
|
||||||
n = mb_ptr2char_adv(&p) + (n << 16);
|
n = mb_ptr2char_adv((const char_u **)&p) + (n << 16);
|
||||||
if (n == flag)
|
}
|
||||||
|
if (n == flag) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -5436,9 +5440,10 @@ static void init_spellfile(void)
|
|||||||
fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
|
fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
|
||||||
->lp_slang->sl_fname;
|
->lp_slang->sl_fname;
|
||||||
vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
|
vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
|
||||||
fname != NULL
|
((fname != NULL
|
||||||
&& strstr((char *)path_tail(fname), ".ascii.") != NULL
|
&& strstr((char *)path_tail(fname), ".ascii.") != NULL)
|
||||||
? (char_u *)"ascii" : spell_enc());
|
? "ascii"
|
||||||
|
: (const char *)spell_enc()));
|
||||||
set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL);
|
set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5465,9 +5470,9 @@ static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
|
|||||||
EMSG(_(e_affform));
|
EMSG(_(e_affform));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
f = mb_ptr2char_adv(&pf);
|
f = mb_ptr2char_adv((const char_u **)&pf);
|
||||||
l = mb_ptr2char_adv(&pl);
|
l = mb_ptr2char_adv((const char_u **)&pl);
|
||||||
u = mb_ptr2char_adv(&pu);
|
u = mb_ptr2char_adv((const char_u **)&pu);
|
||||||
// Every character that appears is a word character.
|
// Every character that appears is a word character.
|
||||||
if (f < 256)
|
if (f < 256)
|
||||||
new_st.st_isw[f] = true;
|
new_st.st_isw[f] = true;
|
||||||
@@ -5532,7 +5537,7 @@ set_spell_charflags (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*p != NUL) {
|
if (*p != NUL) {
|
||||||
c = mb_ptr2char_adv(&p);
|
c = mb_ptr2char_adv((const char_u **)&p);
|
||||||
new_st.st_fold[i + 128] = c;
|
new_st.st_fold[i + 128] = c;
|
||||||
if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
|
if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
|
||||||
new_st.st_upper[c] = i + 128;
|
new_st.st_upper[c] = i + 128;
|
||||||
@@ -5619,12 +5624,13 @@ static void set_map_str(slang_T *lp, char_u *map)
|
|||||||
// "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
|
// "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
|
||||||
// before the same slash. For characters above 255 sl_map_hash is used.
|
// before the same slash. For characters above 255 sl_map_hash is used.
|
||||||
for (p = map; *p != NUL; ) {
|
for (p = map; *p != NUL; ) {
|
||||||
c = mb_cptr2char_adv(&p);
|
c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
if (c == '/')
|
if (c == '/') {
|
||||||
headc = 0;
|
headc = 0;
|
||||||
else {
|
} else {
|
||||||
if (headc == 0)
|
if (headc == 0) {
|
||||||
headc = c;
|
headc = c;
|
||||||
|
}
|
||||||
|
|
||||||
// Characters above 255 don't fit in sl_map_array[], put them in
|
// Characters above 255 don't fit in sl_map_array[], put them in
|
||||||
// the hash table. Each entry is the char, a NUL the headchar and
|
// the hash table. Each entry is the char, a NUL the headchar and
|
||||||
|
|||||||
@@ -598,22 +598,21 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp)
|
|||||||
/// free "*tofree".
|
/// free "*tofree".
|
||||||
///
|
///
|
||||||
/// @return String value or NULL in case of error.
|
/// @return String value or NULL in case of error.
|
||||||
static char *tv_str(typval_T *tvs, int *idxp, char ** const tofree)
|
static const char *tv_str(typval_T *tvs, int *idxp, char **const tofree)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
int idx = *idxp - 1;
|
int idx = *idxp - 1;
|
||||||
char *s = NULL;
|
const char *s = NULL;
|
||||||
|
|
||||||
if (tvs[idx].v_type == VAR_UNKNOWN) {
|
if (tvs[idx].v_type == VAR_UNKNOWN) {
|
||||||
EMSG(_(e_printf));
|
EMSG(_(e_printf));
|
||||||
} else {
|
} else {
|
||||||
(*idxp)++;
|
(*idxp)++;
|
||||||
if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) {
|
if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) {
|
||||||
s = (char *)get_tv_string_chk(&tvs[idx]);
|
s = tv_get_string_chk(&tvs[idx]);
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
} else {
|
} else {
|
||||||
s = encode_tv2echo(&tvs[idx], NULL);
|
s = *tofree = encode_tv2echo(&tvs[idx], NULL);
|
||||||
*tofree = s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -953,7 +952,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
|
|||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
|
str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
|
||||||
: va_arg(ap, char *);
|
: va_arg(ap, const char *);
|
||||||
if (!str_arg) {
|
if (!str_arg) {
|
||||||
str_arg = "[NULL]";
|
str_arg = "[NULL]";
|
||||||
str_arg_l = 6;
|
str_arg_l = 6;
|
||||||
|
|||||||
@@ -1140,7 +1140,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
|
|||||||
EMSG2(_(e_not_open), file_name);
|
EMSG2(_(e_not_open), file_name);
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
(void)os_setperm((char_u *)file_name, perm);
|
(void)os_setperm(file_name, perm);
|
||||||
if (p_verbose > 0) {
|
if (p_verbose > 0) {
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
smsg(_("Writing undo file: %s"), file_name);
|
smsg(_("Writing undo file: %s"), file_name);
|
||||||
@@ -1165,7 +1165,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
|
|||||||
&& os_fileinfo(file_name, &file_info_new)
|
&& os_fileinfo(file_name, &file_info_new)
|
||||||
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid
|
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid
|
||||||
&& os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) {
|
&& os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) {
|
||||||
os_setperm((char_u *)file_name, (perm & 0707) | ((perm & 07) << 3));
|
os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
|
||||||
}
|
}
|
||||||
# ifdef HAVE_SELINUX
|
# ifdef HAVE_SELINUX
|
||||||
if (buf->b_ffname != NULL)
|
if (buf->b_ffname != NULL)
|
||||||
|
|||||||
38
test/functional/eval/input_spec.lua
Normal file
38
test/functional/eval/input_spec.lua
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
|
local Screen = require('test.functional.ui.screen')
|
||||||
|
|
||||||
|
local feed = helpers.feed
|
||||||
|
local clear = helpers.clear
|
||||||
|
local command = helpers.command
|
||||||
|
|
||||||
|
local screen
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
screen = Screen.new(25, 5)
|
||||||
|
screen:attach()
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe('input()', function()
|
||||||
|
it('works correctly with multiline prompts', function()
|
||||||
|
feed([[:call input("Test\nFoo")<CR>]])
|
||||||
|
screen:expect([[
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
Test |
|
||||||
|
Foo^ |
|
||||||
|
]], {{bold=true, foreground=Screen.colors.Blue}})
|
||||||
|
end)
|
||||||
|
it('works correctly with multiline prompts and :echohl', function()
|
||||||
|
command('hi Test ctermfg=Red guifg=Red term=bold')
|
||||||
|
feed([[:echohl Test | call input("Test\nFoo")<CR>]])
|
||||||
|
screen:expect([[
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{2:Test} |
|
||||||
|
{2:Foo}^ |
|
||||||
|
]], {{bold=true, foreground=Screen.colors.Blue}, {foreground=Screen.colors.Red}})
|
||||||
|
end)
|
||||||
|
end)
|
||||||
@@ -44,3 +44,18 @@ describe('setmatches()', function()
|
|||||||
eq({}, funcs.getmatches())
|
eq({}, funcs.getmatches())
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('matchadd()', function()
|
||||||
|
it('correctly works when first two arguments and conceal are numbers at once',
|
||||||
|
function()
|
||||||
|
command('hi def link 1 PreProc')
|
||||||
|
eq(4, funcs.matchadd(1, 2, 3, 4, {conceal=5}))
|
||||||
|
eq({{
|
||||||
|
group='1',
|
||||||
|
pattern='2',
|
||||||
|
priority=3,
|
||||||
|
id=4,
|
||||||
|
conceal='5',
|
||||||
|
}}, funcs.getmatches())
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ local eval = helpers.eval
|
|||||||
describe('dictionary change notifications', function()
|
describe('dictionary change notifications', function()
|
||||||
local channel
|
local channel
|
||||||
|
|
||||||
setup(function()
|
before_each(function()
|
||||||
clear()
|
clear()
|
||||||
channel = nvim('get_api_info')[1]
|
channel = nvim('get_api_info')[1]
|
||||||
nvim('set_var', 'channel', channel)
|
nvim('set_var', 'channel', channel)
|
||||||
@@ -18,19 +18,15 @@ describe('dictionary change notifications', function()
|
|||||||
-- the same set of tests are applied to top-level dictionaries(g:, b:, w: and
|
-- the same set of tests are applied to top-level dictionaries(g:, b:, w: and
|
||||||
-- t:) and a dictionary variable, so we generate them in the following
|
-- t:) and a dictionary variable, so we generate them in the following
|
||||||
-- function.
|
-- function.
|
||||||
local function gentests(dict_expr, dict_expr_suffix, dict_init)
|
local function gentests(dict_expr, dict_init)
|
||||||
if not dict_expr_suffix then
|
|
||||||
dict_expr_suffix = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update(opval, key)
|
local function update(opval, key)
|
||||||
if not key then
|
if not key then
|
||||||
key = 'watched'
|
key = 'watched'
|
||||||
end
|
end
|
||||||
if opval == '' then
|
if opval == '' then
|
||||||
nvim('command', "unlet "..dict_expr..dict_expr_suffix..key)
|
command(('unlet %s[\'%s\']'):format(dict_expr, key))
|
||||||
else
|
else
|
||||||
nvim('command', "let "..dict_expr..dict_expr_suffix..key.." "..opval)
|
command(('let %s[\'%s\'] %s'):format(dict_expr, key, opval))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -50,7 +46,7 @@ describe('dictionary change notifications', function()
|
|||||||
|
|
||||||
describe(dict_expr .. ' watcher', function()
|
describe(dict_expr .. ' watcher', function()
|
||||||
if dict_init then
|
if dict_init then
|
||||||
setup(function()
|
before_each(function()
|
||||||
source(dict_init)
|
source(dict_init)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -143,6 +139,32 @@ describe('dictionary change notifications', function()
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('is triggered for empty keys', function()
|
||||||
|
command([[
|
||||||
|
call dictwatcheradd(]]..dict_expr..[[, "", "g:Changed")
|
||||||
|
]])
|
||||||
|
update('= 1', '')
|
||||||
|
verify_value({new = 1}, '')
|
||||||
|
update('= 2', '')
|
||||||
|
verify_value({old = 1, new = 2}, '')
|
||||||
|
command([[
|
||||||
|
call dictwatcherdel(]]..dict_expr..[[, "", "g:Changed")
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('is triggered for empty keys when using catch-all *', function()
|
||||||
|
command([[
|
||||||
|
call dictwatcheradd(]]..dict_expr..[[, "*", "g:Changed")
|
||||||
|
]])
|
||||||
|
update('= 1', '')
|
||||||
|
verify_value({new = 1}, '')
|
||||||
|
update('= 2', '')
|
||||||
|
verify_value({old = 1, new = 2}, '')
|
||||||
|
command([[
|
||||||
|
call dictwatcherdel(]]..dict_expr..[[, "*", "g:Changed")
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
-- test a sequence of updates of different types to ensure proper memory
|
-- test a sequence of updates of different types to ensure proper memory
|
||||||
-- management(with ASAN)
|
-- management(with ASAN)
|
||||||
local function test_updates(tests)
|
local function test_updates(tests)
|
||||||
@@ -190,10 +212,10 @@ describe('dictionary change notifications', function()
|
|||||||
gentests('b:')
|
gentests('b:')
|
||||||
gentests('w:')
|
gentests('w:')
|
||||||
gentests('t:')
|
gentests('t:')
|
||||||
gentests('g:dict_var', '.', 'let g:dict_var = {}')
|
gentests('g:dict_var', 'let g:dict_var = {}')
|
||||||
|
|
||||||
describe('multiple watchers on the same dict/key', function()
|
describe('multiple watchers on the same dict/key', function()
|
||||||
setup(function()
|
before_each(function()
|
||||||
source([[
|
source([[
|
||||||
function! g:Watcher1(dict, key, value)
|
function! g:Watcher1(dict, key, value)
|
||||||
call rpcnotify(g:channel, '1', a:key, a:value)
|
call rpcnotify(g:channel, '1', a:key, a:value)
|
||||||
@@ -213,6 +235,9 @@ describe('dictionary change notifications', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('only removes watchers that fully match dict, key and callback', function()
|
it('only removes watchers that fully match dict, key and callback', function()
|
||||||
|
nvim('command', 'let g:key = "value"')
|
||||||
|
eq({'notification', '1', {'key', {new = 'value'}}}, next_msg())
|
||||||
|
eq({'notification', '2', {'key', {new = 'value'}}}, next_msg())
|
||||||
nvim('command', 'call dictwatcherdel(g:, "key", "g:Watcher1")')
|
nvim('command', 'call dictwatcherdel(g:, "key", "g:Watcher1")')
|
||||||
nvim('command', 'let g:key = "v2"')
|
nvim('command', 'let g:key = "v2"')
|
||||||
eq({'notification', '2', {'key', {old = 'value', new = 'v2'}}}, next_msg())
|
eq({'notification', '2', {'key', {old = 'value', new = 'v2'}}}, next_msg())
|
||||||
@@ -220,6 +245,17 @@ describe('dictionary change notifications', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
describe('errors', function()
|
describe('errors', function()
|
||||||
|
before_each(function()
|
||||||
|
source([[
|
||||||
|
function! g:Watcher1(dict, key, value)
|
||||||
|
call rpcnotify(g:channel, '1', a:key, a:value)
|
||||||
|
endfunction
|
||||||
|
function! g:Watcher2(dict, key, value)
|
||||||
|
call rpcnotify(g:channel, '2', a:key, a:value)
|
||||||
|
endfunction
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
-- WARNING: This suite depends on the above tests
|
-- WARNING: This suite depends on the above tests
|
||||||
it('fails to remove if no watcher with matching callback is found', function()
|
it('fails to remove if no watcher with matching callback is found', function()
|
||||||
eq("Vim(call):Couldn't find a watcher matching key and callback",
|
eq("Vim(call):Couldn't find a watcher matching key and callback",
|
||||||
@@ -236,15 +272,10 @@ describe('dictionary change notifications', function()
|
|||||||
command('call dictwatcherdel(g:, "key", "g:InvalidCb")')
|
command('call dictwatcherdel(g:, "key", "g:InvalidCb")')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('fails with empty keys', function()
|
|
||||||
eq("Vim(call):E713: Cannot use empty key for Dictionary",
|
|
||||||
exc_exec('call dictwatcheradd(g:, "", "g:Watcher1")'))
|
|
||||||
eq("Vim(call):E713: Cannot use empty key for Dictionary",
|
|
||||||
exc_exec('call dictwatcherdel(g:, "", "g:Watcher1")'))
|
|
||||||
end)
|
|
||||||
|
|
||||||
it('does not fail to replace a watcher function', function()
|
it('does not fail to replace a watcher function', function()
|
||||||
source([[
|
source([[
|
||||||
|
let g:key = 'v2'
|
||||||
|
call dictwatcheradd(g:, "key", "g:Watcher2")
|
||||||
function! g:ReplaceWatcher2()
|
function! g:ReplaceWatcher2()
|
||||||
function! g:Watcher2(dict, key, value)
|
function! g:Watcher2(dict, key, value)
|
||||||
call rpcnotify(g:channel, '2b', a:key, a:value)
|
call rpcnotify(g:channel, '2b', a:key, a:value)
|
||||||
|
|||||||
Reference in New Issue
Block a user