mirror of
https://github.com/vim/vim
synced 2025-03-26 11:45:22 +01:00
patch 8.0.1660: the terminal API "drop" command doesn't support options
Problem: The terminal API "drop" command doesn't support options. Solution: Implement the options.
This commit is contained in:
parent
1f8495cf48
commit
333b80acf3
10 changed files with 214 additions and 31 deletions
runtime/doc
src
|
@ -25,7 +25,7 @@ If the result is "1" you have it.
|
|||
MS-Windows |terminal-ms-windows|
|
||||
2. Terminal communication |terminal-communication|
|
||||
Vim to job: term_sendkeys() |terminal-to-job|
|
||||
Job to Vim: JSON API |terminal-api|
|
||||
Job to Vim: JSON API |terminal-api|
|
||||
Using the client-server feature |terminal-client-server|
|
||||
3. Remote testing |terminal-testing|
|
||||
4. Diffing screen dumps |terminal-diff|
|
||||
|
@ -352,7 +352,7 @@ On Unix a pty is used to make it possible to run all kinds of commands. You
|
|||
can even run Vim in the terminal! That's used for debugging, see below.
|
||||
|
||||
Environment variables are used to pass information to the running job:
|
||||
TERM name of the terminal, 'term'
|
||||
TERM name of the terminal, from the 'term' option
|
||||
ROWS number of rows in the terminal initially
|
||||
LINES same as ROWS
|
||||
COLUMNS number of columns in the terminal initially
|
||||
|
@ -443,11 +443,25 @@ Currently supported commands:
|
|||
< Output from `:echo` may be erased by a redraw, use `:echomsg`
|
||||
to be able to see it with `:messages`.
|
||||
|
||||
drop {filename}
|
||||
drop {filename} [options]
|
||||
|
||||
Let Vim open a file, like the `:drop` command. If {filename}
|
||||
is already open in a window, switch to that window. Otherwise
|
||||
open a new window to edit {filename}.
|
||||
|
||||
[options] is only used when opening a new window. If present,
|
||||
it must be a Dict. Similarly to |++opt|, These entries are recognized:
|
||||
"ff" file format: "dos", "mac" or "unix"
|
||||
"fileformat" idem
|
||||
"enc" overrides 'fileencoding'
|
||||
"encoding" idem
|
||||
"bin" sets 'binary'
|
||||
"binary" idem
|
||||
"nobin" resets 'binary'
|
||||
"nobinary" idem
|
||||
"bad" specifies behavior for bad characters, see
|
||||
|++bad|
|
||||
|
||||
Example in JSON: >
|
||||
["drop", "path/file.txt", {"ff": "dos"}]
|
||||
|
||||
|
|
|
@ -6590,7 +6590,7 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||
len += 7;
|
||||
|
||||
if (eap->force_ff != 0)
|
||||
len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
|
||||
len += 10; /* " ++ff=unix" */
|
||||
# ifdef FEAT_MBYTE
|
||||
if (eap->force_enc != 0)
|
||||
len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
|
||||
|
@ -6614,7 +6614,9 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||
|
||||
if (eap->force_ff != 0)
|
||||
sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
|
||||
eap->cmd + eap->force_ff);
|
||||
eap->force_ff == 'u' ? "unix"
|
||||
: eap->force_ff == 'd' ? "dos"
|
||||
: "mac");
|
||||
#ifdef FEAT_MBYTE
|
||||
if (eap->force_enc != 0)
|
||||
sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
|
||||
|
|
|
@ -1778,7 +1778,7 @@ struct exarg
|
|||
int regname; /* register name (NUL if none) */
|
||||
int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
|
||||
int read_edit; /* ++edit argument */
|
||||
int force_ff; /* ++ff= argument (index in cmd[]) */
|
||||
int force_ff; /* ++ff= argument (first char of argument) */
|
||||
#ifdef FEAT_MBYTE
|
||||
int force_enc; /* ++enc= argument (index in cmd[]) */
|
||||
int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
|
||||
|
|
|
@ -5308,6 +5308,18 @@ skip_cmd_arg(
|
|||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
get_bad_opt(char_u *p, exarg_T *eap)
|
||||
{
|
||||
if (STRICMP(p, "keep") == 0)
|
||||
eap->bad_char = BAD_KEEP;
|
||||
else if (STRICMP(p, "drop") == 0)
|
||||
eap->bad_char = BAD_DROP;
|
||||
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
|
||||
eap->bad_char = *p;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get "++opt=arg" argument.
|
||||
* Return FAIL or OK.
|
||||
|
@ -5387,6 +5399,7 @@ getargopt(exarg_T *eap)
|
|||
#endif
|
||||
if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
|
||||
return FAIL;
|
||||
eap->force_ff = eap->cmd[eap->force_ff];
|
||||
#ifdef FEAT_MBYTE
|
||||
}
|
||||
else if (pp == &eap->force_enc)
|
||||
|
@ -5399,14 +5412,7 @@ getargopt(exarg_T *eap)
|
|||
{
|
||||
/* Check ++bad= argument. Must be a single-byte character, "keep" or
|
||||
* "drop". */
|
||||
p = eap->cmd + bad_char_idx;
|
||||
if (STRICMP(p, "keep") == 0)
|
||||
eap->bad_char = BAD_KEEP;
|
||||
else if (STRICMP(p, "drop") == 0)
|
||||
eap->bad_char = BAD_DROP;
|
||||
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
|
||||
eap->bad_char = *p;
|
||||
else
|
||||
if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
|
|
14
src/fileio.c
14
src/fileio.c
|
@ -2779,22 +2779,22 @@ readfile_linenr(
|
|||
int
|
||||
prep_exarg(exarg_T *eap, buf_T *buf)
|
||||
{
|
||||
eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
|
||||
eap->cmd = alloc(15
|
||||
#ifdef FEAT_MBYTE
|
||||
+ STRLEN(buf->b_p_fenc)
|
||||
+ (unsigned)STRLEN(buf->b_p_fenc)
|
||||
#endif
|
||||
+ 15));
|
||||
);
|
||||
if (eap->cmd == NULL)
|
||||
return FAIL;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
|
||||
eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
|
||||
sprintf((char *)eap->cmd, "e ++enc=%s", buf->b_p_fenc);
|
||||
eap->force_enc = 8;
|
||||
eap->bad_char = buf->b_bad_char;
|
||||
#else
|
||||
sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff);
|
||||
sprintf((char *)eap->cmd, "e");
|
||||
#endif
|
||||
eap->force_ff = 7;
|
||||
eap->force_ff = *buf->b_p_ff;
|
||||
|
||||
eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
|
||||
eap->read_edit = FALSE;
|
||||
|
|
|
@ -3161,7 +3161,7 @@ get_fileformat_force(
|
|||
int c;
|
||||
|
||||
if (eap != NULL && eap->force_ff != 0)
|
||||
c = eap->cmd[eap->force_ff];
|
||||
c = eap->force_ff;
|
||||
else
|
||||
{
|
||||
if ((eap != NULL && eap->force_bin != 0)
|
||||
|
|
|
@ -12,6 +12,7 @@ char_u *skip_range(char_u *cmd, int *ctx);
|
|||
void ex_ni(exarg_T *eap);
|
||||
int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp);
|
||||
void separate_nextcmd(exarg_T *eap);
|
||||
int get_bad_opt(char_u *p, exarg_T *eap);
|
||||
int ends_excmd(int c);
|
||||
char_u *find_nextcmd(char_u *p);
|
||||
char_u *check_nextcmd(char_u *p);
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
* in tl_scrollback are no longer used.
|
||||
*
|
||||
* TODO:
|
||||
* - For the "drop" command accept another argument for options.
|
||||
* - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and in
|
||||
* the GUI.
|
||||
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
|
||||
|
@ -3152,10 +3151,12 @@ init_default_colors(term_T *term)
|
|||
handle_drop_command(listitem_T *item)
|
||||
{
|
||||
char_u *fname = get_tv_string(&item->li_tv);
|
||||
listitem_T *opt_item = item->li_next;
|
||||
int bufnr;
|
||||
win_T *wp;
|
||||
tabpage_T *tp;
|
||||
exarg_T ea;
|
||||
char_u *tofree = NULL;
|
||||
|
||||
bufnr = buflist_add(fname, BLN_LISTED | BLN_NOOPT);
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
|
@ -3168,10 +3169,60 @@ handle_drop_command(listitem_T *item)
|
|||
}
|
||||
}
|
||||
|
||||
/* open in new window, like ":sbuffer N" */
|
||||
vim_memset(&ea, 0, sizeof(ea));
|
||||
ea.cmd = (char_u *)"sbuffer";
|
||||
goto_buffer(&ea, DOBUF_FIRST, FORWARD, bufnr);
|
||||
|
||||
if (opt_item != NULL && opt_item->li_tv.v_type == VAR_DICT
|
||||
&& opt_item->li_tv.vval.v_dict != NULL)
|
||||
{
|
||||
dict_T *dict = opt_item->li_tv.vval.v_dict;
|
||||
char_u *p;
|
||||
|
||||
p = get_dict_string(dict, (char_u *)"ff", FALSE);
|
||||
if (p == NULL)
|
||||
p = get_dict_string(dict, (char_u *)"fileformat", FALSE);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (check_ff_value(p) == FAIL)
|
||||
ch_log(NULL, "Invalid ff argument to drop: %s", p);
|
||||
else
|
||||
ea.force_ff = *p;
|
||||
}
|
||||
p = get_dict_string(dict, (char_u *)"enc", FALSE);
|
||||
if (p == NULL)
|
||||
p = get_dict_string(dict, (char_u *)"encoding", FALSE);
|
||||
if (p != NULL)
|
||||
{
|
||||
ea.cmd = alloc((int)STRLEN(p) + 10);
|
||||
if (ea.cmd != NULL)
|
||||
{
|
||||
sprintf((char *)ea.cmd, "sbuf ++enc=%s", p);
|
||||
ea.force_enc = 11;
|
||||
tofree = ea.cmd;
|
||||
}
|
||||
}
|
||||
|
||||
p = get_dict_string(dict, (char_u *)"bad", FALSE);
|
||||
if (p != NULL)
|
||||
get_bad_opt(p, &ea);
|
||||
|
||||
if (dict_find(dict, (char_u *)"bin", -1) != NULL)
|
||||
ea.force_bin = FORCE_BIN;
|
||||
if (dict_find(dict, (char_u *)"binary", -1) != NULL)
|
||||
ea.force_bin = FORCE_BIN;
|
||||
if (dict_find(dict, (char_u *)"nobin", -1) != NULL)
|
||||
ea.force_bin = FORCE_NOBIN;
|
||||
if (dict_find(dict, (char_u *)"nobinary", -1) != NULL)
|
||||
ea.force_bin = FORCE_NOBIN;
|
||||
}
|
||||
|
||||
/* open in new window, like ":split fname" */
|
||||
if (ea.cmd == NULL)
|
||||
ea.cmd = (char_u *)"split";
|
||||
ea.arg = fname;
|
||||
ea.cmdidx = CMD_split;
|
||||
ex_splitview(&ea);
|
||||
|
||||
vim_free(tofree);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1049,17 +1049,14 @@ func Test_terminal_dumpdiff_options()
|
|||
set laststatus&
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
func Api_drop_common(options)
|
||||
call assert_equal(1, winnr('$'))
|
||||
|
||||
" Use the title termcap entries to output the escape sequence.
|
||||
call writefile([
|
||||
\ 'set title',
|
||||
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
|
||||
\ 'let &titlestring = ''["drop","Xtextfile"]''',
|
||||
\ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''',
|
||||
\ 'redraw',
|
||||
\ "set t_ts=",
|
||||
\ ], 'Xscript')
|
||||
|
@ -1067,6 +1064,116 @@ func Test_terminal_api_drop_newwin()
|
|||
call WaitFor({-> bufnr('Xtextfile') > 0})
|
||||
call assert_equal('Xtextfile', expand('%:t'))
|
||||
call assert_true(winnr('$') >= 3)
|
||||
return buf
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common('')
|
||||
call assert_equal(0, &bin)
|
||||
call assert_equal('', &fenc)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_bin()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"bin":1}')
|
||||
call assert_equal(1, &bin)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_binary()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"binary":1}')
|
||||
call assert_equal(1, &bin)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_nobin()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
set binary
|
||||
let buf = Api_drop_common(',{"nobin":1}')
|
||||
call assert_equal(0, &bin)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
set nobinary
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_nobinary()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
set binary
|
||||
let buf = Api_drop_common(',{"nobinary":1}')
|
||||
call assert_equal(0, &bin)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
set nobinary
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_ff()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"ff":"dos"}')
|
||||
call assert_equal("dos", &ff)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_fileformat()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"fileformat":"dos"}')
|
||||
call assert_equal("dos", &ff)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_enc()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"enc":"utf-16"}')
|
||||
call assert_equal("utf-16", &fenc)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
bwipe Xtextfile
|
||||
endfunc
|
||||
|
||||
func Test_terminal_api_drop_newwin_encoding()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
let buf = Api_drop_common(',{"encoding":"utf-16"}')
|
||||
call assert_equal("utf-16", &fenc)
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xscript')
|
||||
|
|
|
@ -762,6 +762,8 @@ static char *(features[]) =
|
|||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1660,
|
||||
/**/
|
||||
1659,
|
||||
/**/
|
||||
|
|
Loading…
Add table
Reference in a new issue