|
|
@@ -279,6 +279,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
|
|
|
|
s->old_topfill = curwin->w_topfill;
|
|
|
|
s->old_topfill = curwin->w_topfill;
|
|
|
|
s->old_botline = curwin->w_botline;
|
|
|
|
s->old_botline = curwin->w_botline;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(indent >= 0);
|
|
|
|
|
|
|
|
|
|
|
|
// set some variables for redrawcmd()
|
|
|
|
// set some variables for redrawcmd()
|
|
|
|
ccline.cmdfirstc = (s->firstc == '@' ? 0 : s->firstc);
|
|
|
|
ccline.cmdfirstc = (s->firstc == '@' ? 0 : s->firstc);
|
|
|
|
ccline.cmdindent = (s->firstc > 0 ? s->indent : 0);
|
|
|
|
ccline.cmdindent = (s->firstc > 0 ? s->indent : 0);
|
|
|
@@ -294,7 +296,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
|
|
|
|
|
|
|
|
|
|
|
|
// autoindent for :insert and :append
|
|
|
|
// autoindent for :insert and :append
|
|
|
|
if (s->firstc <= 0) {
|
|
|
|
if (s->firstc <= 0) {
|
|
|
|
memset(ccline.cmdbuff, ' ', s->indent);
|
|
|
|
memset(ccline.cmdbuff, ' ', (size_t)s->indent);
|
|
|
|
ccline.cmdbuff[s->indent] = NUL;
|
|
|
|
ccline.cmdbuff[s->indent] = NUL;
|
|
|
|
ccline.cmdpos = s->indent;
|
|
|
|
ccline.cmdpos = s->indent;
|
|
|
|
ccline.cmdspos = s->indent;
|
|
|
|
ccline.cmdspos = s->indent;
|
|
|
@@ -382,7 +384,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
|
|
|
|
bool tl_ret = true;
|
|
|
|
bool tl_ret = true;
|
|
|
|
dict_T *dict = get_vim_var_dict(VV_EVENT);
|
|
|
|
dict_T *dict = get_vim_var_dict(VV_EVENT);
|
|
|
|
char firstcbuf[2];
|
|
|
|
char firstcbuf[2];
|
|
|
|
firstcbuf[0] = firstc > 0 ? firstc : '-';
|
|
|
|
firstcbuf[0] = (char)(firstc > 0 ? firstc : '-');
|
|
|
|
firstcbuf[1] = 0;
|
|
|
|
firstcbuf[1] = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (has_event(EVENT_CMDLINEENTER)) {
|
|
|
|
if (has_event(EVENT_CMDLINEENTER)) {
|
|
|
@@ -676,7 +678,7 @@ static int command_line_execute(VimState *state, int key)
|
|
|
|
// Hitting <Down> after "emenu Name.": complete submenu
|
|
|
|
// Hitting <Down> after "emenu Name.": complete submenu
|
|
|
|
if (s->c == K_DOWN && ccline.cmdpos > 0
|
|
|
|
if (s->c == K_DOWN && ccline.cmdpos > 0
|
|
|
|
&& ccline.cmdbuff[ccline.cmdpos - 1] == '.') {
|
|
|
|
&& ccline.cmdbuff[ccline.cmdpos - 1] == '.') {
|
|
|
|
s->c = p_wc;
|
|
|
|
s->c = (int)p_wc;
|
|
|
|
} else if (s->c == K_UP) {
|
|
|
|
} else if (s->c == K_UP) {
|
|
|
|
// Hitting <Up>: Remove one submenu name in front of the
|
|
|
|
// Hitting <Up>: Remove one submenu name in front of the
|
|
|
|
// cursor
|
|
|
|
// cursor
|
|
|
@@ -706,7 +708,7 @@ static int command_line_execute(VimState *state, int key)
|
|
|
|
if (i > 0) {
|
|
|
|
if (i > 0) {
|
|
|
|
cmdline_del(i);
|
|
|
|
cmdline_del(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s->c = p_wc;
|
|
|
|
s->c = (int)p_wc;
|
|
|
|
s->xpc.xp_context = EXPAND_NOTHING;
|
|
|
|
s->xpc.xp_context = EXPAND_NOTHING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -728,7 +730,7 @@ static int command_line_execute(VimState *state, int key)
|
|
|
|
|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
|
|
|
|
|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
|
|
|
|
|| ccline.cmdbuff[ccline.cmdpos - 3] != '.')) {
|
|
|
|
|| ccline.cmdbuff[ccline.cmdpos - 3] != '.')) {
|
|
|
|
// go down a directory
|
|
|
|
// go down a directory
|
|
|
|
s->c = p_wc;
|
|
|
|
s->c = (int)p_wc;
|
|
|
|
} else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0
|
|
|
|
} else if (STRNCMP(s->xpc.xp_pattern, upseg + 1, 3) == 0
|
|
|
|
&& s->c == K_DOWN) {
|
|
|
|
&& s->c == K_DOWN) {
|
|
|
|
// If in a direct ancestor, strip off one ../ to go down
|
|
|
|
// If in a direct ancestor, strip off one ../ to go down
|
|
|
@@ -748,7 +750,7 @@ static int command_line_execute(VimState *state, int key)
|
|
|
|
&& ccline.cmdbuff[j - 2] == '.'
|
|
|
|
&& ccline.cmdbuff[j - 2] == '.'
|
|
|
|
&& (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) {
|
|
|
|
&& (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) {
|
|
|
|
cmdline_del(j - 2);
|
|
|
|
cmdline_del(j - 2);
|
|
|
|
s->c = p_wc;
|
|
|
|
s->c = (int)p_wc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (s->c == K_UP) {
|
|
|
|
} else if (s->c == K_UP) {
|
|
|
|
// go up a directory
|
|
|
|
// go up a directory
|
|
|
@@ -795,7 +797,7 @@ static int command_line_execute(VimState *state, int key)
|
|
|
|
|
|
|
|
|
|
|
|
// Now complete in the new directory. Set KeyTyped in case the
|
|
|
|
// Now complete in the new directory. Set KeyTyped in case the
|
|
|
|
// Up key came from a mapping.
|
|
|
|
// Up key came from a mapping.
|
|
|
|
s->c = p_wc;
|
|
|
|
s->c = (int)p_wc;
|
|
|
|
KeyTyped = true;
|
|
|
|
KeyTyped = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1633,7 +1635,7 @@ static int command_line_handle_key(CommandLineState *s)
|
|
|
|
if (p[j] == old_firstc
|
|
|
|
if (p[j] == old_firstc
|
|
|
|
&& (j == 0 || p[j - 1] != '\\')) {
|
|
|
|
&& (j == 0 || p[j - 1] != '\\')) {
|
|
|
|
if (i > 0) {
|
|
|
|
if (i > 0) {
|
|
|
|
ccline.cmdbuff[len] = s->firstc;
|
|
|
|
ccline.cmdbuff[len] = (char_u)s->firstc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Escape new sep, unless it is already
|
|
|
|
// Escape new sep, unless it is already
|
|
|
@@ -1789,7 +1791,7 @@ static int command_line_changed(CommandLineState *s)
|
|
|
|
dict_T *dict = get_vim_var_dict(VV_EVENT);
|
|
|
|
dict_T *dict = get_vim_var_dict(VV_EVENT);
|
|
|
|
|
|
|
|
|
|
|
|
char firstcbuf[2];
|
|
|
|
char firstcbuf[2];
|
|
|
|
firstcbuf[0] = s->firstc > 0 ? s->firstc : '-';
|
|
|
|
firstcbuf[0] = (char)(s->firstc > 0 ? s->firstc : '-');
|
|
|
|
firstcbuf[1] = 0;
|
|
|
|
firstcbuf[1] = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// set v:event to a dictionary with information about the commandline
|
|
|
|
// set v:event to a dictionary with information about the commandline
|
|
|
@@ -2297,8 +2299,10 @@ add_indent:
|
|
|
|
char_u *s = skipwhite(p);
|
|
|
|
char_u *s = skipwhite(p);
|
|
|
|
|
|
|
|
|
|
|
|
// Insert spaces after leading whitespaces.
|
|
|
|
// Insert spaces after leading whitespaces.
|
|
|
|
memmove(s + num_spaces, s, line_ga.ga_len - (s - p) + 1);
|
|
|
|
long move_len = line_ga.ga_len - (s - p) + 1;
|
|
|
|
memset(s, ' ', num_spaces);
|
|
|
|
assert(move_len >= 0);
|
|
|
|
|
|
|
|
memmove(s + num_spaces, s, (size_t)move_len);
|
|
|
|
|
|
|
|
memset(s, ' ', (size_t)num_spaces);
|
|
|
|
|
|
|
|
|
|
|
|
line_ga.ga_len += num_spaces;
|
|
|
|
line_ga.ga_len += num_spaces;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2351,8 +2355,10 @@ redraw:
|
|
|
|
while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) {
|
|
|
|
while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) {
|
|
|
|
*--to = NUL;
|
|
|
|
*--to = NUL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
memmove(to, from, line_ga.ga_len - (from - p) + 1);
|
|
|
|
long move_len = line_ga.ga_len - (from - p) + 1;
|
|
|
|
line_ga.ga_len -= from - to;
|
|
|
|
assert(move_len > 0);
|
|
|
|
|
|
|
|
memmove(to, from, (size_t)move_len);
|
|
|
|
|
|
|
|
line_ga.ga_len -= (int)(from - to);
|
|
|
|
|
|
|
|
|
|
|
|
// Removed to much indentation, fix it before redrawing.
|
|
|
|
// Removed to much indentation, fix it before redrawing.
|
|
|
|
num_spaces = indent - old_indent;
|
|
|
|
num_spaces = indent - old_indent;
|
|
|
@@ -2458,7 +2464,7 @@ static void alloc_cmdbuff(int len)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
len += 20;
|
|
|
|
len += 20;
|
|
|
|
|
|
|
|
|
|
|
|
ccline.cmdbuff = xmalloc(len);
|
|
|
|
ccline.cmdbuff = xmalloc((size_t)len);
|
|
|
|
ccline.cmdbufflen = len;
|
|
|
|
ccline.cmdbufflen = len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -2535,26 +2541,28 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
|
|
|
|
size_t prev_end = 0;
|
|
|
|
size_t prev_end = 0;
|
|
|
|
for (size_t i = 0 ; i < kv_size(colors) ; i++) {
|
|
|
|
for (size_t i = 0 ; i < kv_size(colors) ; i++) {
|
|
|
|
const ParserHighlightChunk chunk = kv_A(colors, i);
|
|
|
|
const ParserHighlightChunk chunk = kv_A(colors, i);
|
|
|
|
|
|
|
|
assert(chunk.start.col < INT_MAX);
|
|
|
|
|
|
|
|
assert(chunk.end_col < INT_MAX);
|
|
|
|
if (chunk.start.col != prev_end) {
|
|
|
|
if (chunk.start.col != prev_end) {
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = prev_end,
|
|
|
|
.start = (int)prev_end,
|
|
|
|
.end = chunk.start.col,
|
|
|
|
.end = (int)chunk.start.col,
|
|
|
|
.attr = 0,
|
|
|
|
.attr = 0,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const int id = syn_name2id((const char_u *)chunk.group);
|
|
|
|
const int id = syn_name2id((const char_u *)chunk.group);
|
|
|
|
const int attr = (id == 0 ? 0 : syn_id2attr(id));
|
|
|
|
const int attr = (id == 0 ? 0 : syn_id2attr(id));
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = chunk.start.col,
|
|
|
|
.start = (int)chunk.start.col,
|
|
|
|
.end = chunk.end_col,
|
|
|
|
.end = (int)chunk.end_col,
|
|
|
|
.attr = attr,
|
|
|
|
.attr = attr,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
prev_end = chunk.end_col;
|
|
|
|
prev_end = chunk.end_col;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (prev_end < (size_t)colored_ccline->cmdlen) {
|
|
|
|
if (prev_end < (size_t)colored_ccline->cmdlen) {
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = prev_end,
|
|
|
|
.start = (int)prev_end,
|
|
|
|
.end = (size_t)colored_ccline->cmdlen,
|
|
|
|
.end = colored_ccline->cmdlen,
|
|
|
|
.attr = 0,
|
|
|
|
.attr = 0,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2719,8 +2727,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (start != prev_end) {
|
|
|
|
if (start != prev_end) {
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = prev_end,
|
|
|
|
.start = (int)prev_end,
|
|
|
|
.end = start,
|
|
|
|
.end = (int)start,
|
|
|
|
.attr = 0,
|
|
|
|
.attr = 0,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2749,15 +2757,15 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
|
|
|
const int id = syn_name2id((char_u *)group);
|
|
|
|
const int id = syn_name2id((char_u *)group);
|
|
|
|
const int attr = (id == 0 ? 0 : syn_id2attr(id));
|
|
|
|
const int attr = (id == 0 ? 0 : syn_id2attr(id));
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = start,
|
|
|
|
.start = (int)start,
|
|
|
|
.end = end,
|
|
|
|
.end = (int)end,
|
|
|
|
.attr = attr,
|
|
|
|
.attr = attr,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
i++;
|
|
|
|
i++;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (prev_end < colored_ccline->cmdlen) {
|
|
|
|
if (prev_end < colored_ccline->cmdlen) {
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
|
|
|
.start = prev_end,
|
|
|
|
.start = (int)prev_end,
|
|
|
|
.end = colored_ccline->cmdlen,
|
|
|
|
.end = colored_ccline->cmdlen,
|
|
|
|
.attr = 0,
|
|
|
|
.attr = 0,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
@@ -2835,15 +2843,16 @@ static void draw_cmdline(int start, int len)
|
|
|
|
goto draw_cmdline_no_arabicshape;
|
|
|
|
goto draw_cmdline_no_arabicshape;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int buflen = 0;
|
|
|
|
static size_t buflen = 0;
|
|
|
|
|
|
|
|
assert(len >= 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Do arabic shaping into a temporary buffer. This is very
|
|
|
|
// Do arabic shaping into a temporary buffer. This is very
|
|
|
|
// inefficient!
|
|
|
|
// inefficient!
|
|
|
|
if (len * 2 + 2 > buflen) {
|
|
|
|
if ((size_t)len * 2 + 2 > buflen) {
|
|
|
|
// Re-allocate the buffer. We keep it around to avoid a lot of
|
|
|
|
// Re-allocate the buffer. We keep it around to avoid a lot of
|
|
|
|
// alloc()/free() calls.
|
|
|
|
// alloc()/free() calls.
|
|
|
|
xfree(arshape_buf);
|
|
|
|
xfree(arshape_buf);
|
|
|
|
buflen = len * 2 + 2;
|
|
|
|
buflen = (size_t)len * 2 + 2;
|
|
|
|
arshape_buf = xmalloc(buflen);
|
|
|
|
arshape_buf = xmalloc(buflen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -2901,7 +2910,7 @@ static void draw_cmdline(int start, int len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
prev_c = u8c;
|
|
|
|
prev_c = u8c;
|
|
|
|
memmove(arshape_buf + newlen, p, mb_l);
|
|
|
|
memmove(arshape_buf + newlen, p, (size_t)mb_l);
|
|
|
|
newlen += mb_l;
|
|
|
|
newlen += mb_l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2946,8 +2955,9 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
|
|
|
|
Array item = ARRAY_DICT_INIT;
|
|
|
|
Array item = ARRAY_DICT_INIT;
|
|
|
|
ADD(item, INTEGER_OBJ(chunk.attr));
|
|
|
|
ADD(item, INTEGER_OBJ(chunk.attr));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(chunk.end >= chunk.start);
|
|
|
|
ADD(item, STRING_OBJ(cbuf_to_string((char *)line->cmdbuff + chunk.start,
|
|
|
|
ADD(item, STRING_OBJ(cbuf_to_string((char *)line->cmdbuff + chunk.start,
|
|
|
|
chunk.end-chunk.start)));
|
|
|
|
(size_t)(chunk.end-chunk.start))));
|
|
|
|
ADD(content, ARRAY_OBJ(item));
|
|
|
|
ADD(content, ARRAY_OBJ(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@@ -2968,7 +2978,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ui_ext_cmdline_block_append(int indent, const char *line)
|
|
|
|
void ui_ext_cmdline_block_append(size_t indent, const char *line)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char *buf = xmallocz(indent + strlen(line));
|
|
|
|
char *buf = xmallocz(indent + strlen(line));
|
|
|
|
memset(buf, ' ', indent);
|
|
|
|
memset(buf, ' ', indent);
|
|
|
@@ -3047,7 +3057,7 @@ void cmdline_ui_flush(void)
|
|
|
|
* right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc.
|
|
|
|
* right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc.
|
|
|
|
* "c" must be printable (fit in one display cell)!
|
|
|
|
* "c" must be printable (fit in one display cell)!
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void putcmdline(int c, int shift)
|
|
|
|
void putcmdline(char c, int shift)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (cmd_silent) {
|
|
|
|
if (cmd_silent) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@@ -3366,8 +3376,9 @@ void cmdline_paste_str(char_u *s, int literally)
|
|
|
|
/// Delete characters on the command line, from "from" to the current position.
|
|
|
|
/// Delete characters on the command line, from "from" to the current position.
|
|
|
|
static void cmdline_del(int from)
|
|
|
|
static void cmdline_del(int from)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
assert(ccline.cmdpos <= ccline.cmdlen);
|
|
|
|
memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
|
|
|
|
memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
|
|
|
|
(size_t)ccline.cmdlen - ccline.cmdpos + 1);
|
|
|
|
(size_t)ccline.cmdlen - (size_t)ccline.cmdpos + 1);
|
|
|
|
ccline.cmdlen -= ccline.cmdpos - from;
|
|
|
|
ccline.cmdlen -= ccline.cmdpos - from;
|
|
|
|
ccline.cmdpos = from;
|
|
|
|
ccline.cmdpos = from;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -3598,7 +3609,8 @@ nextwild (
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
i = (int)(xp->xp_pattern - ccline.cmdbuff);
|
|
|
|
i = (int)(xp->xp_pattern - ccline.cmdbuff);
|
|
|
|
xp->xp_pattern_len = ccline.cmdpos - i;
|
|
|
|
assert(ccline.cmdpos >= i);
|
|
|
|
|
|
|
|
xp->xp_pattern_len = (size_t)ccline.cmdpos - (size_t)i;
|
|
|
|
|
|
|
|
|
|
|
|
if (type == WILD_NEXT || type == WILD_PREV) {
|
|
|
|
if (type == WILD_NEXT || type == WILD_PREV) {
|
|
|
|
// Get next/previous match for a previous expanded pattern.
|
|
|
|
// Get next/previous match for a previous expanded pattern.
|
|
|
@@ -3618,7 +3630,7 @@ nextwild (
|
|
|
|
xfree(p1);
|
|
|
|
xfree(p1);
|
|
|
|
// Longest match: make sure it is not shorter, happens with :help.
|
|
|
|
// Longest match: make sure it is not shorter, happens with :help.
|
|
|
|
if (p2 != NULL && type == WILD_LONGEST) {
|
|
|
|
if (p2 != NULL && type == WILD_LONGEST) {
|
|
|
|
for (j = 0; j < xp->xp_pattern_len; j++) {
|
|
|
|
for (j = 0; (size_t)j < xp->xp_pattern_len; j++) {
|
|
|
|
if (ccline.cmdbuff[i + j] == '*'
|
|
|
|
if (ccline.cmdbuff[i + j] == '*'
|
|
|
|
|| ccline.cmdbuff[i + j] == '?') {
|
|
|
|
|| ccline.cmdbuff[i + j] == '?') {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@@ -3631,14 +3643,15 @@ nextwild (
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (p2 != NULL && !got_int) {
|
|
|
|
if (p2 != NULL && !got_int) {
|
|
|
|
difflen = (int)STRLEN(p2) - xp->xp_pattern_len;
|
|
|
|
difflen = (int)STRLEN(p2) - (int)xp->xp_pattern_len;
|
|
|
|
if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen) {
|
|
|
|
if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen) {
|
|
|
|
realloc_cmdbuff(ccline.cmdlen + difflen + 4);
|
|
|
|
realloc_cmdbuff(ccline.cmdlen + difflen + 4);
|
|
|
|
xp->xp_pattern = ccline.cmdbuff + i;
|
|
|
|
xp->xp_pattern = ccline.cmdbuff + i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ccline.cmdpos <= ccline.cmdlen);
|
|
|
|
memmove(&ccline.cmdbuff[ccline.cmdpos + difflen],
|
|
|
|
memmove(&ccline.cmdbuff[ccline.cmdpos + difflen],
|
|
|
|
&ccline.cmdbuff[ccline.cmdpos],
|
|
|
|
&ccline.cmdbuff[ccline.cmdpos],
|
|
|
|
(size_t)ccline.cmdlen - ccline.cmdpos + 1);
|
|
|
|
(size_t)ccline.cmdlen - (size_t)ccline.cmdpos + 1);
|
|
|
|
memmove(&ccline.cmdbuff[i], p2, STRLEN(p2));
|
|
|
|
memmove(&ccline.cmdbuff[i], p2, STRLEN(p2));
|
|
|
|
ccline.cmdlen += difflen;
|
|
|
|
ccline.cmdlen += difflen;
|
|
|
|
ccline.cmdpos += difflen;
|
|
|
|
ccline.cmdpos += difflen;
|
|
|
@@ -3835,7 +3848,7 @@ ExpandOne (
|
|
|
|
size_t len = 0;
|
|
|
|
size_t len = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) {
|
|
|
|
for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) {
|
|
|
|
mb_len = utfc_ptr2len(&xp->xp_files[0][len]);
|
|
|
|
mb_len = (size_t)utfc_ptr2len(&xp->xp_files[0][len]);
|
|
|
|
int c0 = utf_ptr2char(&xp->xp_files[0][len]);
|
|
|
|
int c0 = utf_ptr2char(&xp->xp_files[0][len]);
|
|
|
|
for (i = 1; i < xp->xp_numfiles; i++) {
|
|
|
|
for (i = 1; i < xp->xp_numfiles; i++) {
|
|
|
|
int ci = utf_ptr2char(&xp->xp_files[i][len]);
|
|
|
|
int ci = utf_ptr2char(&xp->xp_files[i][len]);
|
|
|
@@ -4107,17 +4120,19 @@ static int showmatches(expand_T *xp, int wildmenu)
|
|
|
|
|| ui_has(kUIWildmenu);
|
|
|
|
|| ui_has(kUIWildmenu);
|
|
|
|
|
|
|
|
|
|
|
|
if (compl_use_pum) {
|
|
|
|
if (compl_use_pum) {
|
|
|
|
|
|
|
|
assert(num_files >= 0);
|
|
|
|
compl_match_arraysize = num_files;
|
|
|
|
compl_match_arraysize = num_files;
|
|
|
|
compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T));
|
|
|
|
compl_match_array = xcalloc((size_t)compl_match_arraysize,
|
|
|
|
|
|
|
|
sizeof(pumitem_T));
|
|
|
|
for (i = 0; i < num_files; i++) {
|
|
|
|
for (i = 0; i < num_files; i++) {
|
|
|
|
compl_match_array[i].pum_text = L_SHOWFILE(i);
|
|
|
|
compl_match_array[i].pum_text = L_SHOWFILE(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char_u *endpos = (showtail
|
|
|
|
char_u *endpos = (showtail
|
|
|
|
? sm_gettail(xp->xp_pattern, true) : xp->xp_pattern);
|
|
|
|
? sm_gettail(xp->xp_pattern, true) : xp->xp_pattern);
|
|
|
|
if (ui_has(kUICmdline)) {
|
|
|
|
if (ui_has(kUICmdline)) {
|
|
|
|
compl_startcol = endpos - ccline.cmdbuff;
|
|
|
|
compl_startcol = (int)(endpos - ccline.cmdbuff);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
compl_startcol = cmd_screencol(endpos - ccline.cmdbuff);
|
|
|
|
compl_startcol = cmd_screencol((int)(endpos - ccline.cmdbuff));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
compl_selected = -1;
|
|
|
|
compl_selected = -1;
|
|
|
|
cmdline_pum_display(true);
|
|
|
|
cmdline_pum_display(true);
|
|
|
@@ -4306,24 +4321,20 @@ static int expand_showtail(expand_T *xp)
|
|
|
|
return TRUE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/// Prepare a string for expansion.
|
|
|
|
* Prepare a string for expansion.
|
|
|
|
///
|
|
|
|
* When expanding file names: The string will be used with expand_wildcards().
|
|
|
|
/// When expanding file names: The string will be used with expand_wildcards().
|
|
|
|
* Copy "fname[len]" into allocated memory and add a '*' at the end.
|
|
|
|
/// Copy "fname[len]" into allocated memory and add a '*' at the end.
|
|
|
|
* When expanding other names: The string will be used with regcomp(). Copy
|
|
|
|
/// When expanding other names: The string will be used with regcomp(). Copy
|
|
|
|
* the name into allocated memory and prepend "^".
|
|
|
|
/// the name into allocated memory and prepend "^".
|
|
|
|
*/
|
|
|
|
///
|
|
|
|
char_u *
|
|
|
|
/// @param context EXPAND_FILES etc.
|
|
|
|
addstar (
|
|
|
|
char_u *addstar(char_u *fname, size_t len, int context)
|
|
|
|
char_u *fname,
|
|
|
|
|
|
|
|
int len,
|
|
|
|
|
|
|
|
int context /* EXPAND_FILES etc. */
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
FUNC_ATTR_NONNULL_RET
|
|
|
|
FUNC_ATTR_NONNULL_RET
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char_u *retval;
|
|
|
|
char_u *retval;
|
|
|
|
int i, j;
|
|
|
|
size_t i, j;
|
|
|
|
int new_len;
|
|
|
|
size_t new_len;
|
|
|
|
char_u *tail;
|
|
|
|
char_u *tail;
|
|
|
|
int ends_in_star;
|
|
|
|
int ends_in_star;
|
|
|
|
|
|
|
|
|
|
|
@@ -4414,9 +4425,10 @@ addstar (
|
|
|
|
tail = path_tail(retval);
|
|
|
|
tail = path_tail(retval);
|
|
|
|
ends_in_star = (len > 0 && retval[len - 1] == '*');
|
|
|
|
ends_in_star = (len > 0 && retval[len - 1] == '*');
|
|
|
|
#ifndef BACKSLASH_IN_FILENAME
|
|
|
|
#ifndef BACKSLASH_IN_FILENAME
|
|
|
|
for (i = len - 2; i >= 0; --i) {
|
|
|
|
for (ssize_t k = (ssize_t)len - 2; k >= 0; k--) {
|
|
|
|
if (retval[i] != '\\')
|
|
|
|
if (retval[k] != '\\') {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
ends_in_star = !ends_in_star;
|
|
|
|
ends_in_star = !ends_in_star;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
@@ -4497,7 +4509,7 @@ set_cmd_context (
|
|
|
|
int use_ccline // use ccline for info
|
|
|
|
int use_ccline // use ccline for info
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int old_char = NUL;
|
|
|
|
char_u old_char = NUL;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Avoid a UMR warning from Purify, only save the character if it has been
|
|
|
|
* Avoid a UMR warning from Purify, only save the character if it has been
|
|
|
@@ -4561,8 +4573,9 @@ expand_cmdline (
|
|
|
|
return EXPAND_NOTHING;
|
|
|
|
return EXPAND_NOTHING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* add star to file name, or convert to regexp if not exp. files. */
|
|
|
|
// add star to file name, or convert to regexp if not exp. files.
|
|
|
|
xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
|
|
|
|
assert((str + col) - xp->xp_pattern >= 0);
|
|
|
|
|
|
|
|
xp->xp_pattern_len = (size_t)((str + col) - xp->xp_pattern);
|
|
|
|
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
|
|
|
|
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
|
|
|
|
|
|
|
|
|
|
|
|
if (p_wic)
|
|
|
|
if (p_wic)
|
|
|
@@ -4852,7 +4865,7 @@ void ExpandGeneric(
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|
int count = 0;
|
|
|
|
size_t count = 0;
|
|
|
|
char_u *str;
|
|
|
|
char_u *str;
|
|
|
|
|
|
|
|
|
|
|
|
// count the number of matching names
|
|
|
|
// count the number of matching names
|
|
|
@@ -4868,7 +4881,8 @@ void ExpandGeneric(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count == 0)
|
|
|
|
if (count == 0)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
*num_file = count;
|
|
|
|
assert(count < INT_MAX);
|
|
|
|
|
|
|
|
*num_file = (int)count;
|
|
|
|
*file = (char_u **)xmalloc(count * sizeof(char_u *));
|
|
|
|
*file = (char_u **)xmalloc(count * sizeof(char_u *));
|
|
|
|
|
|
|
|
|
|
|
|
// copy the matching names into allocated memory
|
|
|
|
// copy the matching names into allocated memory
|
|
|
@@ -4989,9 +5003,10 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
|
|
|
|
if (e == NULL)
|
|
|
|
if (e == NULL)
|
|
|
|
e = s + STRLEN(s);
|
|
|
|
e = s + STRLEN(s);
|
|
|
|
|
|
|
|
|
|
|
|
l = e - s;
|
|
|
|
l = (size_t)(e - s);
|
|
|
|
if (l > MAXPATHL - 5)
|
|
|
|
if (l > MAXPATHL - 5) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
STRLCPY(buf, s, l + 1);
|
|
|
|
STRLCPY(buf, s, l + 1);
|
|
|
|
add_pathsep((char *)buf);
|
|
|
|
add_pathsep((char *)buf);
|
|
|
|
l = STRLEN(buf);
|
|
|
|
l = STRLEN(buf);
|
|
|
@@ -5032,7 +5047,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
|
|
|
|
static void * call_user_expand_func(user_expand_func_T user_expand_func,
|
|
|
|
static void * call_user_expand_func(user_expand_func_T user_expand_func,
|
|
|
|
expand_T *xp, int *num_file, char_u ***file)
|
|
|
|
expand_T *xp, int *num_file, char_u ***file)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int keep = 0;
|
|
|
|
char_u keep = 0;
|
|
|
|
char_u num[50];
|
|
|
|
char_u num[50];
|
|
|
|
char_u *args[3];
|
|
|
|
char_u *args[3];
|
|
|
|
int save_current_SID = current_SID;
|
|
|
|
int save_current_SID = current_SID;
|
|
|
@@ -5094,14 +5109,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
|
|
|
|
e = vim_strchr(s, '\n');
|
|
|
|
e = vim_strchr(s, '\n');
|
|
|
|
if (e == NULL)
|
|
|
|
if (e == NULL)
|
|
|
|
e = s + STRLEN(s);
|
|
|
|
e = s + STRLEN(s);
|
|
|
|
const int keep = *e;
|
|
|
|
const char_u keep = *e;
|
|
|
|
*e = NUL;
|
|
|
|
*e = NUL;
|
|
|
|
|
|
|
|
|
|
|
|
const bool skip = xp->xp_pattern[0]
|
|
|
|
const bool skip = xp->xp_pattern[0]
|
|
|
|
&& vim_regexec(regmatch, s, (colnr_T)0) == 0;
|
|
|
|
&& vim_regexec(regmatch, s, (colnr_T)0) == 0;
|
|
|
|
*e = keep;
|
|
|
|
*e = keep;
|
|
|
|
if (!skip) {
|
|
|
|
if (!skip) {
|
|
|
|
GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s)));
|
|
|
|
GA_APPEND(char_u *, &ga, vim_strnsave(s, (size_t)(e - s)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (*e != NUL) {
|
|
|
|
if (*e != NUL) {
|
|
|
@@ -5203,7 +5218,8 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
*e = NUL;
|
|
|
|
*e = NUL;
|
|
|
|
memmove(match, s, e - s + 1);
|
|
|
|
assert((e - s) + 1 >= 0);
|
|
|
|
|
|
|
|
memmove(match, s, (size_t)(e - s) + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -5239,8 +5255,7 @@ static int ExpandPackAddDir(char_u *pat, int *num_file, char_u ***file)
|
|
|
|
for (int i = 0; i < ga.ga_len; i++) {
|
|
|
|
for (int i = 0; i < ga.ga_len; i++) {
|
|
|
|
char_u *match = ((char_u **)ga.ga_data)[i];
|
|
|
|
char_u *match = ((char_u **)ga.ga_data)[i];
|
|
|
|
s = path_tail(match);
|
|
|
|
s = path_tail(match);
|
|
|
|
char_u *e = s + STRLEN(s);
|
|
|
|
memmove(match, s, STRLEN(s)+1);
|
|
|
|
memmove(match, s, e - s + 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GA_EMPTY(&ga)) {
|
|
|
|
if (GA_EMPTY(&ga)) {
|
|
|
@@ -5384,7 +5399,9 @@ void init_history(void)
|
|
|
|
// On copying them to the new arrays, we take the chance to reorder them.
|
|
|
|
// On copying them to the new arrays, we take the chance to reorder them.
|
|
|
|
if (newlen != oldlen) {
|
|
|
|
if (newlen != oldlen) {
|
|
|
|
for (int type = 0; type < HIST_COUNT; type++) {
|
|
|
|
for (int type = 0; type < HIST_COUNT; type++) {
|
|
|
|
histentry_T *temp = newlen ? xmalloc(newlen * sizeof(*temp)) : NULL;
|
|
|
|
histentry_T *temp = (newlen
|
|
|
|
|
|
|
|
? xmalloc((size_t)newlen * sizeof(*temp))
|
|
|
|
|
|
|
|
: NULL);
|
|
|
|
|
|
|
|
|
|
|
|
int j = hisidx[type];
|
|
|
|
int j = hisidx[type];
|
|
|
|
if (j >= 0) {
|
|
|
|
if (j >= 0) {
|
|
|
@@ -5549,7 +5566,6 @@ add_to_history (
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
histentry_T *hisptr;
|
|
|
|
histentry_T *hisptr;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (hislen == 0 || histype == HIST_INVALID) { // no history
|
|
|
|
if (hislen == 0 || histype == HIST_INVALID) { // no history
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@@ -5581,12 +5597,12 @@ add_to_history (
|
|
|
|
hisptr = &history[histype][hisidx[histype]];
|
|
|
|
hisptr = &history[histype][hisidx[histype]];
|
|
|
|
hist_free_entry(hisptr);
|
|
|
|
hist_free_entry(hisptr);
|
|
|
|
|
|
|
|
|
|
|
|
/* Store the separator after the NUL of the string. */
|
|
|
|
// Store the separator after the NUL of the string.
|
|
|
|
len = (int)STRLEN(new_entry);
|
|
|
|
size_t len = STRLEN(new_entry);
|
|
|
|
hisptr->hisstr = vim_strnsave(new_entry, len + 2);
|
|
|
|
hisptr->hisstr = vim_strnsave(new_entry, len + 2);
|
|
|
|
hisptr->timestamp = os_time();
|
|
|
|
hisptr->timestamp = os_time();
|
|
|
|
hisptr->additional_elements = NULL;
|
|
|
|
hisptr->additional_elements = NULL;
|
|
|
|
hisptr->hisstr[len + 1] = sep;
|
|
|
|
hisptr->hisstr[len + 1] = (char_u)sep;
|
|
|
|
|
|
|
|
|
|
|
|
hisptr->hisnum = ++hisnum[histype];
|
|
|
|
hisptr->hisnum = ++hisnum[histype];
|
|
|
|
if (histype == HIST_SEARCH && in_map)
|
|
|
|
if (histype == HIST_SEARCH && in_map)
|
|
|
@@ -5640,7 +5656,7 @@ char_u *get_cmdline_str(void)
|
|
|
|
|
|
|
|
|
|
|
|
if (p == NULL)
|
|
|
|
if (p == NULL)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
return vim_strnsave(p->cmdbuff, p->cmdlen);
|
|
|
|
return vim_strnsave(p->cmdbuff, (size_t)p->cmdlen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@@ -5909,7 +5925,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((const char *)arg, end - arg, false);
|
|
|
|
histype1 = get_histtype((const char *)arg, (size_t)(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;
|
|
|
@@ -6115,8 +6131,8 @@ static int open_cmdwin(void)
|
|
|
|
State = NORMAL;
|
|
|
|
State = NORMAL;
|
|
|
|
setmouse();
|
|
|
|
setmouse();
|
|
|
|
|
|
|
|
|
|
|
|
/* Trigger CmdwinEnter autocommands. */
|
|
|
|
// Trigger CmdwinEnter autocommands.
|
|
|
|
typestr[0] = cmdwin_type;
|
|
|
|
typestr[0] = (char_u)cmdwin_type;
|
|
|
|
typestr[1] = NUL;
|
|
|
|
typestr[1] = NUL;
|
|
|
|
apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf);
|
|
|
|
apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf);
|
|
|
|
if (restart_edit != 0) /* autocmd with ":startinsert" */
|
|
|
|
if (restart_edit != 0) /* autocmd with ":startinsert" */
|
|
|
|