summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-04-04 22:57:29 +0200
committerBram Moolenaar <Bram@vim.org>2018-04-04 22:57:29 +0200
commit333b80acf3a44e462456e6d5730e47ffa449c83d (patch)
tree24070cc76ef5b978aabc38db366e04e0dbed591d
parent1f8495cf48888ff3a8ab3d0eb22db92389191a60 (diff)
downloadvim-git-333b80acf3a44e462456e6d5730e47ffa449c83d.tar.gz
patch 8.0.1660: the terminal API "drop" command doesn't support optionsv8.0.1660
Problem: The terminal API "drop" command doesn't support options. Solution: Implement the options.
-rw-r--r--runtime/doc/terminal.txt20
-rw-r--r--src/eval.c6
-rw-r--r--src/ex_cmds.h2
-rw-r--r--src/ex_docmd.c22
-rw-r--r--src/fileio.c14
-rw-r--r--src/misc2.c2
-rw-r--r--src/proto/ex_docmd.pro1
-rw-r--r--src/terminal.c59
-rw-r--r--src/testdir/test_terminal.vim117
-rw-r--r--src/version.c2
10 files changed, 214 insertions, 31 deletions
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index 54c7e1f04..f575c82d1 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -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"}]
diff --git a/src/eval.c b/src/eval.c
index 2da56a47a..c965d64f2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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",
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 41c7c80cb..48b025315 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -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 */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 3a6c7cfb1..b0130046e 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -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
diff --git a/src/fileio.c b/src/fileio.c
index 05c3df50b..e2fa3e22b 100644
--- a/src/fileio.c
+++ b/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;
diff --git a/src/misc2.c b/src/misc2.c
index cd1dcf054..9127e669a 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -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)
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 381953192..0eace6222 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -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);
diff --git a/src/terminal.c b/src/terminal.c
index b60799d7f..326806205 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -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);
}
/*
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index eac54c1d6..218b4ca6f 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -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')
diff --git a/src/version.c b/src/version.c
index cdd8b418d..2d566ca14 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1660,
+/**/
1659,
/**/
1658,