[vim/vim] Add 'cdhome' to make `:cd` go home on non-Unix system (PR #9324)

10 views
Skip to first unread message

バクダンくん

unread,
Dec 11, 2021, 12:15:58 AM12/11/21
to vim/vim, Subscribed

On Windows and other non-Unix system, :cd without an argument just prints the current working directory instead of moving to the home directory.
It is confusing and inconvenient for me using Vim on various OSs including Windows. Also, there is no reason to use :cd for this purpose because :pwd can be used on all environment.
So I added 'cdhome' option to add a way to make its behavior the same with the Unix way.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/9324

Commit Summary

File Changes

(8 files)

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

Gary Johnson

unread,
Dec 11, 2021, 12:55:02 AM12/11/21
to reply+ACY5DGF6P7LESSO4ON...@reply.github.com, vim...@googlegroups.com
On 2021-12-10, バクダンくん wrote:
> On Windows and other non-Unix system, :cd without an argument just
> prints the current working directory instead of moving to the home
> directory. It is confusing and inconvenient for me using Vim on
> various OSs including Windows. Also, there is no reason to use :cd
> for this purpose because :pwd can be used on all environment.

The reason for using :cd this way on Windows is that this is how cd
works at the Command Prompt, so it is more natural for Windows
users.

> So I added 'cdhome' option to add a way to make its behavior the
> same with the Unix way.

How about putting this in your vimrc instead. It avoids Yet Another
Option.

if has("win32")
cabbrev <expr> cd ((getcmdtype() == ':' && getcmdpos() <= 3) ? 'Cd' : 'cd')
command! -nargs=? -complete=file Cd if !empty(expand("<args>")) | cd <args> | else | cd $USERPROFILE | endif
endif

I think I got that right. I tested it on Linux, without the
outer if/endif.

Regards,
Gary

vim-dev ML

unread,
Dec 11, 2021, 12:55:18 AM12/11/21
to vim/vim, vim-dev ML, Your activity

On 2021-12-10, バクダンくん wrote:
> On Windows and other non-Unix system, :cd without an argument just
> prints the current working directory instead of moving to the home
> directory. It is confusing and inconvenient for me using Vim on
> various OSs including Windows. Also, there is no reason to use :cd
> for this purpose because :pwd can be used on all environment.

The reason for using :cd this way on Windows is that this is how cd
works at the Command Prompt, so it is more natural for Windows
users.

> So I added 'cdhome' option to add a way to make its behavior the
> same with the Unix way.

How about putting this in your vimrc instead. It avoids Yet Another
Option.

if has("win32")
cabbrev <expr> cd ((getcmdtype() == ':' && getcmdpos() <= 3) ? 'Cd' : 'cd')
command! -nargs=? -complete=file Cd if !empty(expand("<args>")) | cd <args> | else | cd $USERPROFILE | endif
endif

I think I got that right. I tested it on Linux, without the
outer if/endif.

Regards,
Gary

バクダンくん

unread,
Dec 11, 2021, 1:51:20 AM12/11/21
to vim/vim, vim-dev ML, Comment

Thank you for your comment!

The reason for using :cd this way on Windows is that this is how cd
works at the Command Prompt, so it is more natural for Windows
users.

That may be natural, but not useful. Also, Microsoft recently encourages to switch to PowerShell 7, in which cd (alias of Set-Location) command without an argument changes the working directory to the home directory.

How about putting this in your vimrc instead. It avoids Yet Another
Option.

if has("win32")
  cabbrev <expr> cd ((getcmdtype() == ':' && getcmdpos() <= 3) ? 'Cd' : 'cd')
  command! -nargs=? -complete=file Cd if !empty(expand("<args>")) | cd <args> | else | cd $USERPROFILE | endif
endif

I have tried similar solution, but it has some problems:

  • I just don't want to define a command for this simple feature that Unix version already has. Using :Cd command is weird for me.
  • Your method does not cover a feature that :cd echoes the new working directory. Somehow :cd<CR> echoes, but :Cd<CR> and :Cd Desktop do not. I want to keep this feature because it is helpful.

To meet my wants, I need to write the next script in my vimrc, but it maps <CR> on command line mode so I expect some side effects.

if has('win32')
  function! s:expand_alias() abort
    if getcmdtype() !=# ':'
      return "\<CR>"
    endif
    let cmdline = getcmdline()
    for [pattern, alias] in [
          \   ['^\s*[tl]\?cd\s*$', "$HOME\<CR>\<Cmd>pwd\<CR>"],
          \   ['^\s*[tl]\?cd\s', "\<CR>\<Cmd>pwd\<CR>"],
          \ ]
      if cmdline =~# pattern
        return alias
      endif
    endfor
    return "\<CR>"
  endfunction
  cnoremap <expr> <CR> <SID>expand_alias()
endif

The change of C code is smaller than this script, and would have less side effects.


You are receiving this because you commented.

Gary Johnson

unread,
Dec 11, 2021, 2:29:38 AM12/11/21
to reply+ACY5DGAG25JARMMGU5...@reply.github.com, vim...@googlegroups.com
On 2021-12-10, バクダンくん wrote:
> Thank you for your comment!
>
> The reason for using :cd this way on Windows is that this is how cd
> works at the Command Prompt, so it is more natural for Windows
> users.
>
> That may be natural, but not useful. Also, Microsoft recently encourages to
> switch to PowerShell 7, in which cd (alias of Set-Location) command without an
> argument changes the working directory to the home directory.

I didn't know that. Thanks. I occasionally have to use Power
Shell, but not often.

> How about putting this in your vimrc instead. It avoids Yet Another
> Option.
>
> if has("win32")
> cabbrev <expr> cd ((getcmdtype() == ':' && getcmdpos() <= 3) ? 'Cd' : 'cd')
> command! -nargs=? -complete=file Cd if !empty(expand("<args>")) | cd <args> | else | cd $USERPROFILE | endif
> endif
>
> I have tried similar solution, but it has some problems:
>
> • I just don't want to define a command for this simple feature that Unix
> version already has. Using :Cd command is weird for me.

Agreed, but that's what the abbreviation is for. It changes :cd to
:Cd automatically so you can continue to type :cd.

> • Your method does not cover a feature that :cd echoes the new working
> directory. Somehow :cd<CR> echoes, but :Cd<CR> and :Cd Desktop do not. I
> want to keep this feature because it is helpful.

I don't care about that myself--it seems redundant--but I'm sure
that a command or function could be crafted to do that.

> To meet my wants, I need to write the next script in my vimrc, but it maps <CR>
> on command line mode so I expect some side effects.
>
> if has('win32')
> function! s:expand_alias() abort
> if getcmdtype() !=# ':'
> return "\<CR>"
> endif
> let cmdline = getcmdline()
> for [pattern, alias] in [
> \ ['^\s*[tl]\?cd\s*$', "$HOME\<CR>\<Cmd>pwd\<CR>"],
> \ ['^\s*[tl]\?cd\s', "\<CR>\<Cmd>pwd\<CR>"],
> \ ]
> if cmdline =~# pattern
> return alias
> endif
> endfor
> return "\<CR>"
> endfunction
> cnoremap <expr> <CR> <SID>expand_alias()
> endif
>
> The change of C code is smaller than this script, and would have less side
> effects.

I think you could get the behavior you want by modifying my :Cd
command to call a function that would :cd and :pwd as you have done
above. That would avoid mapping <CR> and should have no side
effects.

Your proposal isn't horrible, it's just one of those things that
could be done with a script and tuned to do exactly what you want
without having to worry about what other users want.

There's usually a trade-off between adding a feature in a script or
in C, and to avoid making Vim more difficult to maintain and to
understand, I usually prefer using a script.

On the other hand, if enough users would benefit from having :cd
behave according to your patch, that would be better than all those
users having to write or copy your script.

Regards,
Gary

vim-dev ML

unread,
Dec 11, 2021, 2:29:58 AM12/11/21
to vim/vim, vim-dev ML, Your activity

バクダンくん

unread,
Dec 11, 2021, 4:57:46 AM12/11/21
to vim/vim, vim-dev ML, Push

@Bakudankun pushed 1 commit.

  • 354f5c0 Fix test where shellslash was set after evaluating $HOME


You are receiving this because you are subscribed to this thread.

View it on GitHub.

codecov[bot]

unread,
Dec 11, 2021, 5:04:51 AM12/11/21
to vim/vim, vim-dev ML, Comment

Codecov Report

Merging #9324 (354f5c0) into master (f8bc0ce) will decrease coverage by 2.38%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@

##           master    #9324      +/-   ##

==========================================

- Coverage   90.19%   87.81%   -2.39%     

==========================================

  Files         151      149       -2     

  Lines      170853   171343     +490     

==========================================

- Hits       154098   150458    -3640     

- Misses      16755    20885    +4130     
Flag Coverage Δ
huge-clang-none 89.31% <100.00%> (-0.80%) ⬇️
huge-gcc-none ?
huge-gcc-testgui ?
huge-gcc-unittests 2.46% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/ex_docmd.c 93.13% <100.00%> (-2.80%) ⬇️
src/libvterm/src/rect.h 0.00% <0.00%> (-96.56%) ⬇️
src/libvterm/src/state.c 40.00% <0.00%> (-49.44%) ⬇️
src/libvterm/src/keyboard.c 48.42% <0.00%> (-40.00%) ⬇️
src/libvterm/include/vterm.h 0.00% <0.00%> (-37.50%) ⬇️
src/libvterm/src/pen.c 47.78% <0.00%> (-36.88%) ⬇️
src/libvterm/src/encoding.c 44.55% <0.00%> (-28.72%) ⬇️
src/libvterm/src/parser.c 67.08% <0.00%> (-28.70%) ⬇️
src/if_perl.xs 63.30% <0.00%> (-27.63%) ⬇️
src/libvterm/src/vterm.c 47.03% <0.00%> (-20.41%) ⬇️
... and 127 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f8bc0ce...354f5c0. Read the comment docs.


You are receiving this because you commented.

バクダンくん

unread,
Dec 11, 2021, 5:18:56 AM12/11/21
to vim/vim, vim-dev ML, Comment

$HOME had backslashes while Windows tests because it was evaluated after set shellslash.
I fixed that, and now failing tests are flaky ones.


You are receiving this because you commented.

Bram Moolenaar

unread,
Dec 11, 2021, 5:21:40 AM12/11/21
to vim/vim, vim-dev ML, Comment

I think this is common enough to add an option for. The suggested abbreviation does it quite well, but not exactly right.
And it needs to be copy/pasted, while setting the option in your vimrc is easy.


You are receiving this because you commented.

Bram Moolenaar

unread,
Dec 11, 2021, 7:28:36 AM12/11/21
to vim/vim, vim-dev ML, Comment

Closed #9324 via 29f3a45.


You are receiving this because you commented.

バクダンくん

unread,
Dec 11, 2021, 8:14:54 AM12/11/21
to vim/vim, vim-dev ML, Comment

Hi, @brammool
Thank you for adopting this PR!
However, it seems that the document of 'cdhome' is lost in the patch 8.2.3780.
Please check the options.txt.


You are receiving this because you commented.

Bram Moolenaar

unread,
Dec 11, 2021, 12:25:19 PM12/11/21
to vim/vim, vim-dev ML, Comment

Let me update the whole file.


You are receiving this because you commented.

Reply all
Reply to author
Forward
0 new messages