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=\<Esc>]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=\<Esc>]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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui