Skip to content

Commit 333b80a

Browse files
committed
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.
1 parent 1f8495c commit 333b80a

File tree

10 files changed

+214
-31
lines changed

10 files changed

+214
-31
lines changed

runtime/doc/terminal.txt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ If the result is "1" you have it.
2525
MS-Windows |terminal-ms-windows|
2626
2. Terminal communication |terminal-communication|
2727
Vim to job: term_sendkeys() |terminal-to-job|
28-
Job to Vim: JSON API |terminal-api|
28+
Job to Vim: JSON API |terminal-api|
2929
Using the client-server feature |terminal-client-server|
3030
3. Remote testing |terminal-testing|
3131
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
352352
can even run Vim in the terminal! That's used for debugging, see below.
353353

354354
Environment variables are used to pass information to the running job:
355-
TERM name of the terminal, 'term'
355+
TERM name of the terminal, from the 'term' option
356356
ROWS number of rows in the terminal initially
357357
LINES same as ROWS
358358
COLUMNS number of columns in the terminal initially
@@ -443,11 +443,25 @@ Currently supported commands:
443443
< Output from `:echo` may be erased by a redraw, use `:echomsg`
444444
to be able to see it with `:messages`.
445445

446-
drop {filename}
446+
drop {filename} [options]
447447

448448
Let Vim open a file, like the `:drop` command. If {filename}
449449
is already open in a window, switch to that window. Otherwise
450450
open a new window to edit {filename}.
451+
452+
[options] is only used when opening a new window. If present,
453+
it must be a Dict. Similarly to |++opt|, These entries are recognized:
454+
"ff" file format: "dos", "mac" or "unix"
455+
"fileformat" idem
456+
"enc" overrides 'fileencoding'
457+
"encoding" idem
458+
"bin" sets 'binary'
459+
"binary" idem
460+
"nobin" resets 'binary'
461+
"nobinary" idem
462+
"bad" specifies behavior for bad characters, see
463+
|++bad|
464+
451465
Example in JSON: >
452466
["drop", "path/file.txt", {"ff": "dos"}]
453467

src/eval.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6590,7 +6590,7 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
65906590
len += 7;
65916591

65926592
if (eap->force_ff != 0)
6593-
len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
6593+
len += 10; /* " ++ff=unix" */
65946594
# ifdef FEAT_MBYTE
65956595
if (eap->force_enc != 0)
65966596
len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
@@ -6614,7 +6614,9 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
66146614

66156615
if (eap->force_ff != 0)
66166616
sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
6617-
eap->cmd + eap->force_ff);
6617+
eap->force_ff == 'u' ? "unix"
6618+
: eap->force_ff == 'd' ? "dos"
6619+
: "mac");
66186620
#ifdef FEAT_MBYTE
66196621
if (eap->force_enc != 0)
66206622
sprintf((char *)newval + STRLEN(newval), " ++enc=%s",

src/ex_cmds.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,7 @@ struct exarg
17781778
int regname; /* register name (NUL if none) */
17791779
int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
17801780
int read_edit; /* ++edit argument */
1781-
int force_ff; /* ++ff= argument (index in cmd[]) */
1781+
int force_ff; /* ++ff= argument (first char of argument) */
17821782
#ifdef FEAT_MBYTE
17831783
int force_enc; /* ++enc= argument (index in cmd[]) */
17841784
int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */

src/ex_docmd.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5308,6 +5308,18 @@ skip_cmd_arg(
53085308
return p;
53095309
}
53105310

5311+
int
5312+
get_bad_opt(char_u *p, exarg_T *eap)
5313+
{
5314+
if (STRICMP(p, "keep") == 0)
5315+
eap->bad_char = BAD_KEEP;
5316+
else if (STRICMP(p, "drop") == 0)
5317+
eap->bad_char = BAD_DROP;
5318+
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
5319+
eap->bad_char = *p;
5320+
return FAIL;
5321+
}
5322+
53115323
/*
53125324
* Get "++opt=arg" argument.
53135325
* Return FAIL or OK.
@@ -5387,6 +5399,7 @@ getargopt(exarg_T *eap)
53875399
#endif
53885400
if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
53895401
return FAIL;
5402+
eap->force_ff = eap->cmd[eap->force_ff];
53905403
#ifdef FEAT_MBYTE
53915404
}
53925405
else if (pp == &eap->force_enc)
@@ -5399,14 +5412,7 @@ getargopt(exarg_T *eap)
53995412
{
54005413
/* Check ++bad= argument. Must be a single-byte character, "keep" or
54015414
* "drop". */
5402-
p = eap->cmd + bad_char_idx;
5403-
if (STRICMP(p, "keep") == 0)
5404-
eap->bad_char = BAD_KEEP;
5405-
else if (STRICMP(p, "drop") == 0)
5406-
eap->bad_char = BAD_DROP;
5407-
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
5408-
eap->bad_char = *p;
5409-
else
5415+
if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL)
54105416
return FAIL;
54115417
}
54125418
#endif

src/fileio.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,22 +2779,22 @@ readfile_linenr(
27792779
int
27802780
prep_exarg(exarg_T *eap, buf_T *buf)
27812781
{
2782-
eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
2782+
eap->cmd = alloc(15
27832783
#ifdef FEAT_MBYTE
2784-
+ STRLEN(buf->b_p_fenc)
2784+
+ (unsigned)STRLEN(buf->b_p_fenc)
27852785
#endif
2786-
+ 15));
2786+
);
27872787
if (eap->cmd == NULL)
27882788
return FAIL;
27892789

27902790
#ifdef FEAT_MBYTE
2791-
sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
2792-
eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
2791+
sprintf((char *)eap->cmd, "e ++enc=%s", buf->b_p_fenc);
2792+
eap->force_enc = 8;
27932793
eap->bad_char = buf->b_bad_char;
27942794
#else
2795-
sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff);
2795+
sprintf((char *)eap->cmd, "e");
27962796
#endif
2797-
eap->force_ff = 7;
2797+
eap->force_ff = *buf->b_p_ff;
27982798

27992799
eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
28002800
eap->read_edit = FALSE;

src/misc2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3161,7 +3161,7 @@ get_fileformat_force(
31613161
int c;
31623162

31633163
if (eap != NULL && eap->force_ff != 0)
3164-
c = eap->cmd[eap->force_ff];
3164+
c = eap->force_ff;
31653165
else
31663166
{
31673167
if ((eap != NULL && eap->force_bin != 0)

src/proto/ex_docmd.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ char_u *skip_range(char_u *cmd, int *ctx);
1212
void ex_ni(exarg_T *eap);
1313
int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp);
1414
void separate_nextcmd(exarg_T *eap);
15+
int get_bad_opt(char_u *p, exarg_T *eap);
1516
int ends_excmd(int c);
1617
char_u *find_nextcmd(char_u *p);
1718
char_u *check_nextcmd(char_u *p);

src/terminal.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
* in tl_scrollback are no longer used.
3939
*
4040
* TODO:
41-
* - For the "drop" command accept another argument for options.
4241
* - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and in
4342
* the GUI.
4443
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
@@ -3152,10 +3151,12 @@ init_default_colors(term_T *term)
31523151
handle_drop_command(listitem_T *item)
31533152
{
31543153
char_u *fname = get_tv_string(&item->li_tv);
3154+
listitem_T *opt_item = item->li_next;
31553155
int bufnr;
31563156
win_T *wp;
31573157
tabpage_T *tp;
31583158
exarg_T ea;
3159+
char_u *tofree = NULL;
31593160

31603161
bufnr = buflist_add(fname, BLN_LISTED | BLN_NOOPT);
31613162
FOR_ALL_TAB_WINDOWS(tp, wp)
@@ -3168,10 +3169,60 @@ handle_drop_command(listitem_T *item)
31683169
}
31693170
}
31703171

3171-
/* open in new window, like ":sbuffer N" */
31723172
vim_memset(&ea, 0, sizeof(ea));
3173-
ea.cmd = (char_u *)"sbuffer";
3174-
goto_buffer(&ea, DOBUF_FIRST, FORWARD, bufnr);
3173+
3174+
if (opt_item != NULL && opt_item->li_tv.v_type == VAR_DICT
3175+
&& opt_item->li_tv.vval.v_dict != NULL)
3176+
{
3177+
dict_T *dict = opt_item->li_tv.vval.v_dict;
3178+
char_u *p;
3179+
3180+
p = get_dict_string(dict, (char_u *)"ff", FALSE);
3181+
if (p == NULL)
3182+
p = get_dict_string(dict, (char_u *)"fileformat", FALSE);
3183+
if (p != NULL)
3184+
{
3185+
if (check_ff_value(p) == FAIL)
3186+
ch_log(NULL, "Invalid ff argument to drop: %s", p);
3187+
else
3188+
ea.force_ff = *p;
3189+
}
3190+
p = get_dict_string(dict, (char_u *)"enc", FALSE);
3191+
if (p == NULL)
3192+
p = get_dict_string(dict, (char_u *)"encoding", FALSE);
3193+
if (p != NULL)
3194+
{
3195+
ea.cmd = alloc((int)STRLEN(p) + 10);
3196+
if (ea.cmd != NULL)
3197+
{
3198+
sprintf((char *)ea.cmd, "sbuf ++enc=%s", p);
3199+
ea.force_enc = 11;
3200+
tofree = ea.cmd;
3201+
}
3202+
}
3203+
3204+
p = get_dict_string(dict, (char_u *)"bad", FALSE);
3205+
if (p != NULL)
3206+
get_bad_opt(p, &ea);
3207+
3208+
if (dict_find(dict, (char_u *)"bin", -1) != NULL)
3209+
ea.force_bin = FORCE_BIN;
3210+
if (dict_find(dict, (char_u *)"binary", -1) != NULL)
3211+
ea.force_bin = FORCE_BIN;
3212+
if (dict_find(dict, (char_u *)"nobin", -1) != NULL)
3213+
ea.force_bin = FORCE_NOBIN;
3214+
if (dict_find(dict, (char_u *)"nobinary", -1) != NULL)
3215+
ea.force_bin = FORCE_NOBIN;
3216+
}
3217+
3218+
/* open in new window, like ":split fname" */
3219+
if (ea.cmd == NULL)
3220+
ea.cmd = (char_u *)"split";
3221+
ea.arg = fname;
3222+
ea.cmdidx = CMD_split;
3223+
ex_splitview(&ea);
3224+
3225+
vim_free(tofree);
31753226
}
31763227

31773228
/*

src/testdir/test_terminal.vim

Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,24 +1049,131 @@ func Test_terminal_dumpdiff_options()
10491049
set laststatus&
10501050
endfunc
10511051

1052-
func Test_terminal_api_drop_newwin()
1053-
if !CanRunVimInTerminal()
1054-
return
1055-
endif
1052+
func Api_drop_common(options)
10561053
call assert_equal(1, winnr('$'))
10571054

10581055
" Use the title termcap entries to output the escape sequence.
10591056
call writefile([
10601057
\ 'set title',
10611058
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1062-
\ 'let &titlestring = ''["drop","Xtextfile"]''',
1059+
\ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''',
10631060
\ 'redraw',
10641061
\ "set t_ts=",
10651062
\ ], 'Xscript')
10661063
let buf = RunVimInTerminal('-S Xscript', {})
10671064
call WaitFor({-> bufnr('Xtextfile') > 0})
10681065
call assert_equal('Xtextfile', expand('%:t'))
10691066
call assert_true(winnr('$') >= 3)
1067+
return buf
1068+
endfunc
1069+
1070+
func Test_terminal_api_drop_newwin()
1071+
if !CanRunVimInTerminal()
1072+
return
1073+
endif
1074+
let buf = Api_drop_common('')
1075+
call assert_equal(0, &bin)
1076+
call assert_equal('', &fenc)
1077+
1078+
call StopVimInTerminal(buf)
1079+
call delete('Xscript')
1080+
bwipe Xtextfile
1081+
endfunc
1082+
1083+
func Test_terminal_api_drop_newwin_bin()
1084+
if !CanRunVimInTerminal()
1085+
return
1086+
endif
1087+
let buf = Api_drop_common(',{"bin":1}')
1088+
call assert_equal(1, &bin)
1089+
1090+
call StopVimInTerminal(buf)
1091+
call delete('Xscript')
1092+
bwipe Xtextfile
1093+
endfunc
1094+
1095+
func Test_terminal_api_drop_newwin_binary()
1096+
if !CanRunVimInTerminal()
1097+
return
1098+
endif
1099+
let buf = Api_drop_common(',{"binary":1}')
1100+
call assert_equal(1, &bin)
1101+
1102+
call StopVimInTerminal(buf)
1103+
call delete('Xscript')
1104+
bwipe Xtextfile
1105+
endfunc
1106+
1107+
func Test_terminal_api_drop_newwin_nobin()
1108+
if !CanRunVimInTerminal()
1109+
return
1110+
endif
1111+
set binary
1112+
let buf = Api_drop_common(',{"nobin":1}')
1113+
call assert_equal(0, &bin)
1114+
1115+
call StopVimInTerminal(buf)
1116+
call delete('Xscript')
1117+
bwipe Xtextfile
1118+
set nobinary
1119+
endfunc
1120+
1121+
func Test_terminal_api_drop_newwin_nobinary()
1122+
if !CanRunVimInTerminal()
1123+
return
1124+
endif
1125+
set binary
1126+
let buf = Api_drop_common(',{"nobinary":1}')
1127+
call assert_equal(0, &bin)
1128+
1129+
call StopVimInTerminal(buf)
1130+
call delete('Xscript')
1131+
bwipe Xtextfile
1132+
set nobinary
1133+
endfunc
1134+
1135+
func Test_terminal_api_drop_newwin_ff()
1136+
if !CanRunVimInTerminal()
1137+
return
1138+
endif
1139+
let buf = Api_drop_common(',{"ff":"dos"}')
1140+
call assert_equal("dos", &ff)
1141+
1142+
call StopVimInTerminal(buf)
1143+
call delete('Xscript')
1144+
bwipe Xtextfile
1145+
endfunc
1146+
1147+
func Test_terminal_api_drop_newwin_fileformat()
1148+
if !CanRunVimInTerminal()
1149+
return
1150+
endif
1151+
let buf = Api_drop_common(',{"fileformat":"dos"}')
1152+
call assert_equal("dos", &ff)
1153+
1154+
call StopVimInTerminal(buf)
1155+
call delete('Xscript')
1156+
bwipe Xtextfile
1157+
endfunc
1158+
1159+
func Test_terminal_api_drop_newwin_enc()
1160+
if !CanRunVimInTerminal()
1161+
return
1162+
endif
1163+
let buf = Api_drop_common(',{"enc":"utf-16"}')
1164+
call assert_equal("utf-16", &fenc)
1165+
1166+
call StopVimInTerminal(buf)
1167+
call delete('Xscript')
1168+
bwipe Xtextfile
1169+
endfunc
1170+
1171+
func Test_terminal_api_drop_newwin_encoding()
1172+
if !CanRunVimInTerminal()
1173+
return
1174+
endif
1175+
let buf = Api_drop_common(',{"encoding":"utf-16"}')
1176+
call assert_equal("utf-16", &fenc)
10701177

10711178
call StopVimInTerminal(buf)
10721179
call delete('Xscript')

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,8 @@ static char *(features[]) =
762762

763763
static int included_patches[] =
764764
{ /* Add new patch number below this line */
765+
/**/
766+
1660,
765767
/**/
766768
1659,
767769
/**/

0 commit comments

Comments
 (0)