Powershell: Add support for 'cd +'

Created on 26 Jun 2018  路  11Comments  路  Source: PowerShell/PowerShell

Now that PR 5051 has implemented issue 2188 (cd - support), we are ready to start thinking about adding cd + support, i.e. not only can one go back in the location history, one should also be able to go forward as well. The behaviour should behave as in the following example and support a similar history range like the cd - operation, which can go back the last 20 history locations

C:\foo> cd C:\bar
C:\bar> cd -
C:\foo> cd +
C:\bar

Currently a stack is used for the location history of cd -, this will need to be changed/adapted to allow for this new scenario, it could possibly be something similar to a circular buffer.

To be clear, this issue is just to discuss and track this feature as I don't have time to implement it now (but might come back to it in the future), so anyone can pick it up.

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.1.0-preview.721
PSEdition                      Core
GitCommitId                    v6.1.0-preview.721
OS                             Microsoft Windows 10.0.17134
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Management Issue-Enhancement Resolution-Fixed

Most helpful comment

Not a parser trick but a use of ValueFromRemainingArguments - https://github.com/Pscx/Pscx/blob/master/Src/Pscx/Modules/CD/Pscx.CD.psm1#L78 Yeah, that breaks down if there are multiple spaces between tokens but the common cases have a single space like in Program Files. Perhaps there is a better way to do this with $MyInvocation?

It's just that as I have moved folks from CMD to PowerShell, they inevitably try this and when it doesn't work it's a bit of a bummer. Not huge but if it can be solved easily (and robustly) it eliminates one source of paper cuts. :-)

All 11 comments

While you are at it, please consider adding support for some syntax to display the current stack. This is what we do in PSCX. Maybe use cd ? to display something like this:

06-26 15:55:12 9> cd

     # Directory Stack:
   --- ----------------
     0 C:\Users\hillr
     1 C:\Windows
     2 C:\Git
->   3 C:\Users\hillr\GitHub
     4 C:\Bin
     5 C:\temp

Also, and this is probably an aside but Set-Location really should be designed to not require quotes. For instance, if I fire up CMD.exe I can do this:

C:\Users\hillr>cd c:\program files

c:\Program Files>

but in PS Core this fails:

06-26 15:56:33 1> cd c:\program files
Set-Location : A positional parameter cannot be found that accepts argument 'files'.

In PSCX, we have a wrapper command that cd is aliased to called Set-LocationEx and it allows two nice features. First, you don't have to quote:

06-26 15:59:29 13> cd c:\program files
C:\program files

Second, if the path is a file path then it will cd to the directory containing the file which is nice for:

06-26 15:59:33 14> cd $profile
~\Documents\WindowsPowerShell

This last feature would be a breaking change I suppose so may not be viable but I can tell you that for interactive use, it is very nice. :-)

@rkeithhill You know you can do

 cd c:\program` files

It's considerably less annoying than quoting at each end. To get rid of quotes are you suggesting parser magic? Or simply making Set-Location varags and concatenating the strings with a space between them? (Which will work in most cases but not all). With respect to parent directory vs leaf, in my cd function, I have a switch -Parent that lops of the leaf node of the path. It's handy.

Not a parser trick but a use of ValueFromRemainingArguments - https://github.com/Pscx/Pscx/blob/master/Src/Pscx/Modules/CD/Pscx.CD.psm1#L78 Yeah, that breaks down if there are multiple spaces between tokens but the common cases have a single space like in Program Files. Perhaps there is a better way to do this with $MyInvocation?

It's just that as I have moved folks from CMD to PowerShell, they inevitably try this and when it doesn't work it's a bit of a bummer. Not huge but if it can be solved easily (and robustly) it eliminates one source of paper cuts. :-)

@rkeithhill Do you want to open a separate issue for the cd c:\program files feature?

Yes, I can do that.

cd -, cd + and cd ? all make great additions.

Syntax-wise I'm a little concerned about edge cases:

Given that - and + are legal directory names, I'm hoping that these magic symbols bind to -Path only, so that -LiteralPath can be used to target - and + as literals. Is that how - is already implemented?

(On a side note: bash, dash, ksh, and zsh surprisingly do _not_ support targeting a directory _literally_ named - - even though they could use the presence or absence of quoting to distinguish between the magic symbol and the literal.)

The same distinction won't work with ?, because binding ? to -Path takes away the ability to target a single-character directory name with a wildcard.
However, given that Set-Location only works with wildcards that resolve to a _single_ container, that is even more of an edge case, so perhaps not worth worrying about.

@mklement0 One can still use -Path and -LiteralPath for absolute and relative paths where the directory is just named -.
For relative paths one would need to change scripts though from cd - to something like cd '.\-' but tab completion helps getting there automatically.

Ah, of course, thanks @bergmeister - for some reason I didn't think about the ./ prefix.

(I doubt that tab completion will be of much help, though: if you don't know about the need to ./-prefix, you'll likely just try - without attempting tab completion, and if you do know, you're likely to just type ./- in full; attempting to tab-complete on - alone will not work, as it will complete _parameter names_.)

Tab completion will only help if you start with .\- and then tab (either with or without single or double quotes). But I think overall this special case for relative directories can be neglected IMHO, as long as it still works

But I think overall this special case for relative directories can be neglected IMHO

Agreed, now that we've established that it will continue to be possible to change to directories literally named - and + with relative paths (too).

(Just to bring closure to this: My point was that if your intent is to target a directory named + and -, you won't use tab completion (on the last or only path component), because there's nothing to complete. _Afterthought_: But, yes, you can type ./<tab> in order to have _all_ directories listed / cycled through, which would include the dir. of interest.)

Was this page helpful?
0 / 5 - 0 ratings