Patch 8.2.2675
Problem:    Directory change in a terminal window shell is not followed.
Solution:   Add the 'autoshelldir' option. (closes #6290)
Files:      runtime/doc/options.txt, runtime/doc/quickref.txt,
            runtime/optwin.vim, src/charset.c, src/feature.h, src/option.h,
            src/optiondefs.h, src/terminal.c, src/testdir/check.vim,
            src/testdir/test_terminal3.vim


*** ../vim-8.2.2674/runtime/doc/options.txt     2021-03-04 21:55:54.601235264 
+0100
--- runtime/doc/options.txt     2021-03-29 20:38:32.031640025 +0200
***************
*** 749,754 ****
--- 749,763 ----
        or selected.
        Note: When this option is on some plugins may not work.
  
+                       *'autoshelldir'* *'asd'* *'noautoshelldir'* *'noasd'*
+ 'autoshelldir' 'asd'  boolean (default off)
+                       global
+       When on, Vim will change the current working directory whenever you
+       change the directory of the shell running in a terminal window. You
+       need proper setting-up, so whenever the shell's pwd changes an OSC 7
+       escape sequence will be emitted. For example, on Linux, you can source
+       /etc/profile.d/vte.sh in your shell profile if you use bash or zsh.
+ 
                                *'arabic'* *'arab'* *'noarabic'* *'noarab'*
  'arabic' 'arab'               boolean (default off)
                        local to window
*** ../vim-8.2.2674/runtime/doc/quickref.txt    2021-01-31 17:02:06.258490157 
+0100
--- runtime/doc/quickref.txt    2021-03-29 20:39:10.695540234 +0200
***************
*** 605,610 ****
--- 605,611 ----
  'ambiwidth'     'ambw'    what to do with Unicode chars of ambiguous width
  'antialias'     'anti'    Mac OS X: use smooth, antialiased fonts
  'autochdir'     'acd'     change directory to the file in the current window
+ 'autoshelldir'          'asd'     change directory to the shell's current 
directory
  'arabic'        'arab'    for Arabic as a default second language
  'arabicshape'   'arshape' do shaping for Arabic characters
  'autoindent'    'ai'      take indent for new line from previous line
*** ../vim-8.2.2674/runtime/optwin.vim  2020-09-20 21:31:59.634692878 +0200
--- runtime/optwin.vim  2021-03-29 20:35:13.384153457 +0200
***************
*** 266,271 ****
--- 266,273 ----
    call <SID>AddOption("autochdir", gettext("change to directory of file in 
buffer"))
    call <SID>BinOptionG("acd", &acd)
  endif
+ call <SID>AddOption("autoshelldir", gettext("change to pwd of shell in 
terminal buffer"))
+ call <SID>BinOptionG("asd", &asd)
  call <SID>AddOption("wrapscan", gettext("search commands wrap around the end 
of the buffer"))
  call <SID>BinOptionG("ws", &ws)
  call <SID>AddOption("incsearch", gettext("show match for partly typed search 
command"))
*** ../vim-8.2.2674/src/charset.c       2021-02-15 20:37:58.453374547 +0100
--- src/charset.c       2021-03-29 20:35:13.384153457 +0200
***************
*** 2005,2011 ****
      return c - '0';
  }
  
! #if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) || defined(PROTO)
  /*
   * Convert two hex characters to a byte.
   * Return -1 if one of the characters is not hex.
--- 2005,2012 ----
      return c - '0';
  }
  
! #if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) \
!         || defined(PROTO) || defined(FEAT_AUTOSHELLDIR)
  /*
   * Convert two hex characters to a byte.
   * Return -1 if one of the characters is not hex.
*** ../vim-8.2.2674/src/feature.h       2020-12-18 19:49:52.341571870 +0100
--- src/feature.h       2021-03-29 20:35:13.384153457 +0200
***************
*** 1148,1153 ****
--- 1148,1159 ----
  #endif
  
  /*
+  * +autoshelldir          'autoshelldir' option.
+  */
+ #if defined(FEAT_TERMINAL)
+ # define FEAT_AUTOSHELLDIR
+ #endif
+ /*
   * +textprop and +popupwin    Text PROPerties and POPUP windows
   */
  #if defined(FEAT_EVAL) && defined(FEAT_SYN_HL)
*** ../vim-8.2.2674/src/option.h        2021-02-15 20:37:58.457374538 +0100
--- src/option.h        2021-03-29 20:35:13.384153457 +0200
***************
*** 383,388 ****
--- 383,391 ----
  #ifdef FEAT_AUTOCHDIR
  EXTERN int    p_acd;          // 'autochdir'
  #endif
+ #ifdef FEAT_AUTOSHELLDIR
+ EXTERN int    p_asd;          // 'autoshelldir'
+ #endif
  EXTERN int    p_ai;           // 'autoindent'
  EXTERN int    p_bin;          // 'binary'
  EXTERN int    p_bomb;         // 'bomb'
*** ../vim-8.2.2674/src/optiondefs.h    2021-02-15 20:37:58.457374538 +0100
--- src/optiondefs.h    2021-03-29 20:35:13.384153457 +0200
***************
*** 372,377 ****
--- 372,386 ----
                            {(char_u *)0L, (char_u *)0L}
  #endif
                            SCTX_INIT},
+     {"autoshelldir",  "asd",   P_BOOL|P_VI_DEF,
+ #ifdef FEAT_AUTOSHELLDIR
+                           (char_u *)&p_asd, PV_NONE,
+                           {(char_u *)FALSE, (char_u *)0L}
+ #else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
+ #endif
+                           SCTX_INIT},
      {"autoindent",  "ai",   P_BOOL|P_VI_DEF,
                            (char_u *)&p_ai, PV_AI,
                            {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
*** ../vim-8.2.2674/src/terminal.c      2021-02-23 17:47:20.078181103 +0100
--- src/terminal.c      2021-03-29 20:45:42.646551274 +0200
***************
*** 4293,4298 ****
--- 4293,4365 ----
  }
  
  /*
+  * URL decoding (also know as Percent-encoding).
+  *
+  * Note this function currently is only used for decoding shell's
+  * OSC 7 escape sequence which we can assume all bytes are valid
+  * UTF-8 bytes. Thus we don't need to deal with invalid UTF-8
+  * encoding bytes like 0xfe, 0xff.
+  */
+     static size_t
+ url_decode(const char *src, const size_t len, char_u *dst)
+ {
+     size_t i = 0, j = 0;
+ 
+     while (i < len)
+     {
+       if (src[i] == '%' && i + 2 < len)
+       {
+           dst[j] = hexhex2nr((char_u *)&src[i + 1]);
+           j++;
+           i += 3;
+       }
+       else
+       {
+           dst[j] = src[i];
+           i++;
+           j++;
+       }
+     }
+     dst[j] = '\0';
+     return j;
+ }
+ 
+ /*
+  * Sync terminal buffer's cwd with shell's pwd with the help of OSC 7.
+  *
+  * The OSC 7 sequence has the format of
+  * "\033]7;file://HOSTNAME/CURRENT/DIR\033\\"
+  * and what VTerm provides via VTermStringFragment is
+  * "file://HOSTNAME/CURRENT/DIR"
+  */
+     static void
+ sync_shell_dir(VTermStringFragment *frag)
+ {
+     int       offset = 7; // len of "file://" is 7
+     char      *pos = (char *)frag->str + offset;
+     char_u    *new_dir;
+ 
+     // remove HOSTNAME to get PWD
+     while (*pos != '/' && offset < frag->len)
+     {
+         offset += 1;
+         pos += 1;
+     }
+ 
+     if (offset >= frag->len)
+     {
+         semsg(_(e_failed_to_extract_pwd_from_str_check_your_shell_config),
+                                                                   frag->str);
+         return;
+     }
+ 
+     new_dir = alloc(frag->len - offset + 1);
+     url_decode(pos, frag->len-offset, new_dir);
+     changedir_func(new_dir, TRUE, CDSCOPE_WINDOW);
+     vim_free(new_dir);
+ }
+ 
+ /*
   * Called by libvterm when it cannot recognize an OSC sequence.
   * We recognize a terminal API command.
   */
***************
*** 4306,4312 ****
                                                    : term->tl_job->jv_channel;
      garray_T  *gap = &term->tl_osc_buf;
  
!     // We recognize only OSC 5 1 ; {command}
      if (command != 51)
        return 0;
  
--- 4373,4385 ----
                                                    : term->tl_job->jv_channel;
      garray_T  *gap = &term->tl_osc_buf;
  
!     // We recognize only OSC 5 1 ; {command} and OSC 7 ; {command}
!     if (p_asd && command == 7)
!     {
!       sync_shell_dir(&frag);
!       return 1;
!     }
! 
      if (command != 51)
        return 0;
  
*** ../vim-8.2.2674/src/testdir/check.vim       2021-03-20 12:49:12.078222904 
+0100
--- src/testdir/check.vim       2021-03-29 20:35:13.384153457 +0200
***************
*** 92,97 ****
--- 92,105 ----
    endif
  endfunc
  
+ " Command to check for not running on a BSD system.
+ command CheckNotBSD call CheckNotBSD()
+ func CheckNotBSD()
+   if has('bsd')
+     throw 'Skipped: does not work on BSD'
+   endif
+ endfunc
+ 
  " Command to check that making screendumps is supported.
  " Caller must source screendump.vim
  command CheckScreendump call CheckScreendump()
*** ../vim-8.2.2674/src/testdir/test_terminal3.vim      2021-02-20 
19:21:31.955986987 +0100
--- src/testdir/test_terminal3.vim      2021-03-29 20:46:24.430447428 +0200
***************
*** 475,480 ****
--- 475,509 ----
    call delete('Xbuf')
  endfunc
  
+ " Test for sync buffer cwd with shell's pwd
+ func Test_terminal_sync_shell_dir()
+   CheckUnix
+   " The test always use sh (see src/testdir/unix.vim).
+   " However, BSD's sh doesn't seem to play well with OSC 7 escape sequence.
+   CheckNotBSD
+ 
+   set asd
+   " , is
+   "  1. a valid character for directory names
+   "  2. a reserved character in url-encoding
+   let chars = ",a"
+   " "," is url-encoded as '%2C'
+   let chars_url = "%2Ca"
+   let tmpfolder = fnamemodify(tempname(),':h').'/'.chars
+   let tmpfolder_url = fnamemodify(tempname(),':h').'/'.chars_url
+   call mkdir(tmpfolder, "p")
+   let buf = Run_shell_in_terminal({})
+   call term_sendkeys(buf, "echo -ne 
$'\\e\]7;file://".tmpfolder_url."\\a'\<CR>")
+   "call term_sendkeys(buf, "cd ".tmpfolder."\<CR>")
+   call TermWait(buf)
+   if has("mac")
+     let expected = "/private".tmpfolder
+   else
+     let expected = tmpfolder
+   endif
+   call assert_equal(expected, getcwd(winnr()))
+ endfunc
+ 
  " Test for modeless selection in a terminal
  func Test_term_modeless_selection()
    CheckUnix
*** ../vim-8.2.2674/src/version.c       2021-03-29 20:10:23.152204702 +0200
--- src/version.c       2021-03-29 20:46:45.218395670 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2675,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
34. You laugh at people with a 10 Mbit connection.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202103291849.12TInVdw1221781%40masaka.moolenaar.net.

Raspunde prin e-mail lui