To: vim_dev@googlegroups.com Subject: Patch 8.0.1660 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1660 Problem: The terminal API "drop" command doesn't support options. Solution: Implement the options. Files: src/terminal.c, src/ex_docmd.c, src/proto/ex_docmd.pro, src/ex_cmds.h, src/eval.c, src/misc2.c, src/fileio.c, src/testdir/test_terminal.vim, runtime/doc/terminal.txt *** ../vim-8.0.1659/src/terminal.c 2018-03-29 17:22:19.892974695 +0200 --- src/terminal.c 2018-04-04 22:53:33.179187225 +0200 *************** *** 38,44 **** * 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 --- 38,43 ---- *************** *** 3152,3161 **** --- 3151,3162 ---- 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,3177 **** } } - /* 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); } /* --- 3169,3228 ---- } } vim_memset(&ea, 0, sizeof(ea)); ! ! 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); } /* *** ../vim-8.0.1659/src/ex_docmd.c 2018-03-29 16:03:46.620035905 +0200 --- src/ex_docmd.c 2018-04-03 22:57:51.520883239 +0200 *************** *** 5308,5313 **** --- 5308,5325 ---- 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,5392 **** --- 5399,5405 ---- #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,5412 **** { /* 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 return FAIL; } #endif --- 5412,5418 ---- { /* Check ++bad= argument. Must be a single-byte character, "keep" or * "drop". */ ! if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL) return FAIL; } #endif *** ../vim-8.0.1659/src/proto/ex_docmd.pro 2017-09-23 16:33:40.857195233 +0200 --- src/proto/ex_docmd.pro 2018-04-03 21:38:19.922499751 +0200 *************** *** 12,17 **** --- 12,18 ---- 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); *** ../vim-8.0.1659/src/ex_cmds.h 2017-09-17 20:32:15.298326050 +0200 --- src/ex_cmds.h 2018-04-03 22:07:59.020919487 +0200 *************** *** 1778,1784 **** 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[]) */ #ifdef FEAT_MBYTE int force_enc; /* ++enc= argument (index in cmd[]) */ int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */ --- 1778,1784 ---- 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 (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 */ *** ../vim-8.0.1659/src/eval.c 2018-03-04 18:07:04.248592476 +0100 --- src/eval.c 2018-04-03 22:13:25.791206761 +0200 *************** *** 6590,6596 **** len += 7; if (eap->force_ff != 0) ! len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; # ifdef FEAT_MBYTE if (eap->force_enc != 0) len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; --- 6590,6596 ---- len += 7; if (eap->force_ff != 0) ! len += 10; /* " ++ff=unix" */ # ifdef FEAT_MBYTE if (eap->force_enc != 0) len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; *************** *** 6614,6620 **** if (eap->force_ff != 0) sprintf((char *)newval + STRLEN(newval), " ++ff=%s", ! eap->cmd + eap->force_ff); #ifdef FEAT_MBYTE if (eap->force_enc != 0) sprintf((char *)newval + STRLEN(newval), " ++enc=%s", --- 6614,6622 ---- if (eap->force_ff != 0) sprintf((char *)newval + STRLEN(newval), " ++ff=%s", ! 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", *** ../vim-8.0.1659/src/misc2.c 2018-03-20 12:34:00.138383018 +0100 --- src/misc2.c 2018-04-03 22:15:44.310482308 +0200 *************** *** 3161,3167 **** int c; if (eap != NULL && eap->force_ff != 0) ! c = eap->cmd[eap->force_ff]; else { if ((eap != NULL && eap->force_bin != 0) --- 3161,3167 ---- int c; if (eap != NULL && eap->force_ff != 0) ! c = eap->force_ff; else { if ((eap != NULL && eap->force_bin != 0) *** ../vim-8.0.1659/src/fileio.c 2018-03-11 16:55:30.008616433 +0100 --- src/fileio.c 2018-04-03 22:20:42.920920277 +0200 *************** *** 2779,2800 **** int prep_exarg(exarg_T *eap, buf_T *buf) { ! eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff) #ifdef FEAT_MBYTE ! + 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); eap->bad_char = buf->b_bad_char; #else ! sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff); #endif ! eap->force_ff = 7; eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN; eap->read_edit = FALSE; --- 2779,2800 ---- int prep_exarg(exarg_T *eap, buf_T *buf) { ! eap->cmd = alloc(15 #ifdef FEAT_MBYTE ! + (unsigned)STRLEN(buf->b_p_fenc) #endif ! ); if (eap->cmd == NULL) return FAIL; #ifdef FEAT_MBYTE ! 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"); #endif ! eap->force_ff = *buf->b_p_ff; eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN; eap->read_edit = FALSE; *** ../vim-8.0.1659/src/testdir/test_terminal.vim 2018-03-29 17:40:42.607415702 +0200 --- src/testdir/test_terminal.vim 2018-04-04 22:50:39.388223874 +0200 *************** *** 1049,1065 **** set laststatus& endfunc ! func Test_terminal_api_drop_newwin() ! if !CanRunVimInTerminal() ! return ! endif call assert_equal(1, winnr('$')) " Use the title termcap entries to output the escape sequence. call writefile([ \ 'set title', \ 'exe "set t_ts=\]51; t_fs=\x07"', ! \ 'let &titlestring = ''["drop","Xtextfile"]''', \ 'redraw', \ "set t_ts=", \ ], 'Xscript') --- 1049,1062 ---- set laststatus& endfunc ! 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=\]51; t_fs=\x07"', ! \ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''', \ 'redraw', \ "set t_ts=", \ ], 'Xscript') *************** *** 1067,1072 **** --- 1064,1179 ---- 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') *** ../vim-8.0.1659/runtime/doc/terminal.txt 2018-03-26 21:38:45.196332620 +0200 --- runtime/doc/terminal.txt 2018-04-04 21:19:21.068900274 +0200 *************** *** 25,31 **** 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| Using the client-server feature |terminal-client-server| 3. Remote testing |terminal-testing| 4. Diffing screen dumps |terminal-diff| --- 25,31 ---- 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| Using the client-server feature |terminal-client-server| 3. Remote testing |terminal-testing| 4. Diffing screen dumps |terminal-diff| *************** *** 352,358 **** 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' ROWS number of rows in the terminal initially LINES same as ROWS COLUMNS number of columns in the terminal initially --- 352,358 ---- 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, 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,453 **** < Output from `:echo` may be erased by a redraw, use `:echomsg` to be able to see it with `:messages`. ! drop {filename} 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}. Example in JSON: > ["drop", "path/file.txt", {"ff": "dos"}] --- 443,467 ---- < Output from `:echo` may be erased by a redraw, use `:echomsg` to be able to see it with `:messages`. ! 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"}] *** ../vim-8.0.1659/src/version.c 2018-04-04 21:53:06.769891319 +0200 --- src/version.c 2018-04-04 22:54:40.194795849 +0200 *************** *** 764,765 **** --- 764,767 ---- { /* Add new patch number below this line */ + /**/ + 1660, /**/ -- hundred-and-one symptoms of being an internet addict: 98. The Alta Vista administrators ask you what sites are missing in their index files. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///