Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider reinstating implicit cd in some form #22

Closed
ridiculousfish opened this issue Jun 1, 2012 · 54 comments
Closed

Consider reinstating implicit cd in some form #22

ridiculousfish opened this issue Jun 1, 2012 · 54 comments
Labels
docs An issue/PR that touches or should touch the docs

Comments

@ridiculousfish
Copy link
Member

This bug tracks reinstating implicit cd in some form. Implicit cd is where you can switch to a directory by just typing its path, without explicitly typing cd. It's as if you execute the directory.

In decreasing order of implicitness:

  1. Restore it to its state in fish trunk: implicit cd is active and respects CDPATH
  2. Implicit cd only works for the current directory. CDPATH would still be respected, but only when using cd explicitly.
  3. Implicit cd only works for paths starting with a dot, slash, or tilde
  4. Implicit cd only works for '..' (and perhaps ../.., etc.)
  5. No implicit cd.

There's also potential to make this configurable in some way.

Feel free to pile on with your desires / perspectives.

@twm
Copy link

twm commented Jun 2, 2012

I regularly use implicit cd, but I have set CDPATH to . because I found the results of combining the two confusing. I'd suggest either (1), with changing CDPATH a sufficient degree of configurability, or (2).

@shamrin
Copy link

shamrin commented Jun 6, 2012

Regardless of what you do, please don't make it configurable. Zero configurability is one of my favorite features of fish. It's super convienient to be able to just install it and not worry about configs.

@ridiculousfish
Copy link
Member Author

Agree with shamrin regarding not making it configurable.
For beta r2, I went with solution 3, but I'll leave this open for further comments

@iven
Copy link

iven commented Jun 28, 2012

Any update on this?

@ridiculousfish
Copy link
Member Author

So far I'm happy with the current behavior, which is that implicit cd works only for paths starting with one of ./~

I'm leaving this open to encourage piling-on.

@iven
Copy link

iven commented Aug 17, 2012

This is the biggest point I feel uncomforable since I switched fish to fish-shell. I don't know why I have to type a / or ./ for every directory changing.
Moreover, is that really an improvement typing "./foo" instead of "cd foo"?
I suggest switch back to (1), and leave ./
either in CDPATH or configurable.

@levantis
Copy link

In fact, ./ allows to browse the directory tree as if it were a GUI, through autocompletion.
Forcing this makes such a move more discoverable (at least, I wouldn't have thought about it, if not for the limitation)

and, if you write
cd a
cd b
cd c
cd d
often, it means you could have written
./a/b/c/d
from the start. Otherwise, the shortening doesn't save much time.

configurable CDPATH is also very convenient

@iven
Copy link

iven commented Aug 17, 2012

@levantis That's not the reason we make it forced. You can still use like that even if we make cd implicit.

@levantis
Copy link

Well, if it's program-folder name collisions, you can always write it explicitly, so forcing does nothing here, either.

Is it something else? I couldn't find it on the web...

@nagisa
Copy link
Contributor

nagisa commented Aug 29, 2012

Either 3️⃣

It looks reasonable and I can't think of any ways it could collide with anything else.

or 5️⃣

Typing cd should be a muscle memory and takes at most several milliseconds. Especially when c and d are so close to each other.


Why not 1️⃣, 2️⃣ or 4️⃣?

1️⃣ and 2️⃣ introduces some strange variable/setting and as user-friendly shell user I want to know nothing about it. 4️⃣ is something in between 3️⃣ and 5️⃣ and is inconsistent. Because then you'd be already writing cd everywhere else and why should .. be given any special treatment?

@iven
Copy link

iven commented Aug 29, 2012

@simukis

I don't think we can type three characters cd in milliseconds, especially when c and d are controlled by the same finger and you can't type them simultaneously.

When use 1, you don't have to know much new:

  • You can still use explicit cd when changing directories, nothing difference.
  • When you're using implicit cd, or typing a command, we can make the completion results seperated, instead of mixing them together(the original fish behavior), so you won't get confused.

@ridiculousfish
Is this acceptable? We can make the different completions seperated in different lines, and/or in different colors, and with different prefixes(~, ., /), that resolves the confusion problem.

@ridiculousfish
Copy link
Member Author

If we reintroduce #1, then command completions will cease to be globally unique, depending on which directory you are in. For example, say you are used to typing 'zipc' to get 'zipcloak'; introducing this change would mean that if a directory 'zipcar' happens to be present, it would break your muscle memory.

I also remember finding the sheer number of (low-quality) completions overwhelming in the original fish. Of course having ~ in CDPATH didn't help.

Lastly, I think it's confusing that under #1, you can "execute" any directory with a relative path, and execute any program with a relative path that contains a directory, but not execute a program with a relative path; i.e.:

directory             <-- works
directory/program     <-- works
directory; program    <-- fails

PATH does not contain '.' by design, and it seems strange to make it so, but only for directories.

That's my thinking at least.

@iven
Copy link

iven commented Aug 31, 2012

For me, it's worth to lose some user-friendly completion unexpectly sometimes, instead of typing cd or even ~/ every time. I also hate thinking before typing, and I expect the shell to have the similar as quick-launch applications. Now it seems not every one think so.

So can we make it configurable? We have fish_config, right? Configurability isn't evil, if you set a reasonable default behavior.

And I don't think the directory; program issue is a problem, who will execute programs like that?

@boxed
Copy link

boxed commented Oct 12, 2012

I'm with iven on this. Fish looks really cool but I'm sticking with oh-my-zsh for now because of implicit cd. Really the usability of implicit cd should be much better in fish anyway because you can see before you complete what's gonna happen.

@Soares
Copy link
Contributor

Soares commented Oct 18, 2012

I'm with @ridiculousfish on this. Let's look at how execution of files acts. Your directory structure is:

home/Soares/
  program/
    src/
    a.out

You're in the program/ directory. Let's try some commands:

> ./a.out
<works>

> /home/Soares/program/a.out
<works>

> ~/program/a.out
<works>

> cd program/
> a.out
fish: Unknown command: a.out

I like the idea that autocd works just like program execution. It's not like you can ever execute a directory anyway. What if whenever you try to execute a directory, fish cds you to that directory instead of complaining that the file doesn't have execute permissions? That would be really cool.

Note that because this works:

> cd ~
> program/a.out
<works>

this would also work:

> cd ~
> program/src
> pwd
/home/Soares/program/src

However, fish fails to autocomplete this case. Observe:

> cd ~
> mkdir Desktop
> touch Desktop/program
> chmod u+x Desktop/program
> D<tab>

Even though Desktop/program is a perfectly valid command at this juncture, fish does not autocomplete it. This is a feature. As @ridiculousfish mentioned above, most people don't want their autocomplete flow to depend upon what directory they're in. If you want file autocompletion, start the command with one of ./~.

Fish should autocd just like it executes programs: whenever a user tries to execute a directory, cd to it, but only autocomplete if it starts with ./~.

Conversely, full autocd should come with automatic execution, for consistency. It's silly and inconsistent to allow program/ to cd you in to program/ without allowing a.out to execute a.out. You can't (or, rather, shouldn't) argue for one without the other.

If any configurability is added I suggest an auto execution option, of which autocd is a subset. Some people might find that really useful. I, for one, would hate it: especially if it made autocomplete work differently depending upon my location.

@boxed
Copy link

boxed commented Oct 23, 2012

@Soares Autocd without ./~ is as you say inconsistant with non-auto-execute without ./~. But why be hung up over consistency?

Consistency is a tool used to increase usability, discoverability, memorization, etc. It is not a goal in itself. All things being equal consistency should always lose out to usability, discoverability and ease of memorization if they are actually in conflict.

@iven
Copy link

iven commented Oct 23, 2012

@Soares Note that we should have autoexecution of a.out enabled for usability. The reason why we don't allow it is its insecurity. So it's an exception. Why should we be consist with an exception?

Just think about the omni bar in Google Chrome. Do you think we should have to type search XXX for searching?

@Soares
Copy link
Contributor

Soares commented Oct 23, 2012

It's for security but it's also for usability. Let's say you have a file named ls in your current directory. If you type ls, the system command should be used. Now, if you have a directory named ls and you type ls, the system command should still be used.

Yes, it's more "dangerous" to execute a file than it is to cd to a directory, but from a user perspective it's quite surprising to have different behavior for directories and files. (And that's ignoring symlinks and other edge cases where things get wishy washy.)

Keep in mind that I'm advocating we do autocd to a directory when you just type it's name, we just don't autocomplete it (which is how programs are currently executed). Commands on the $PATH should always take precedence over directories/files present, IMHO. But I fail to see any user benefits from breaking consistency in this scenario.

@gustafj
Copy link
Contributor

gustafj commented Oct 23, 2012

Soares and ridiculousfish are spot on here, 3 is imo the way to go.
Consistency and the lack of shell "magic" are my priorities here, so complete on ./~ and autocd as the last resort to a matching directory name in current dir.

@robacarp
Copy link

robacarp commented Feb 7, 2013

I'd like to throw in that I think this is a fine feature as it is, but it should be better documented.

I spent quite a lot of time reading the extensive documentation on cd and directories and other things, and then had to try a few different searches here in the issue tracker before I could nail down what I was looking for. The problem for me was that I didn't know what to search for. Perhaps an amendment to the documentation under cd or a clarification to the FAQ at the bottom of the doxygen page that describes how to use the implicit cd command.

I'd personally never used zsh but seen my coworkers do so frequently, so perhaps I am an edge case. Or perhaps I just need better search-fu.

Cheers.

@dag
Copy link
Contributor

dag commented May 10, 2013

@iven

I don't think we can type three characters cd in milliseconds, especially when c and d are controlled by the same finger and you can't type them simultaneously.

Not true if you touch-type with qwerty or dvorak. True for colemak though.

You can always make a custom bind, for example:

bind \ec 'commandline "cd ./"; commandline -f complete'

or perhaps

bind \ec 'cd (commandline); commandline -f repaint; commandline ""'

The latter will look bad with syntax highlighting but saves one key stroke (enter). I wanted to make it ctrl-enter but seems you can't bind \c\n, at least not in my terminal.

@iven
Copy link

iven commented May 10, 2013

@dag Thanks for the tip. However, I'd like implicit cd to follow $CDPATH, so this does not work for me.

I'm currently using a version modified by myself to have implicit cd, working well so far: https://aur.archlinux.org/packages/fish-shell-implicit-cd-git/

@dag
Copy link
Contributor

dag commented May 10, 2013

@iven Another idea would be to use a fish_command_not_found event handler, but that still doesn't fix the syntax highlighting and I'm not sure how to properly disable the default event handler for that ...

@terlar
Copy link
Contributor

terlar commented May 11, 2013

@dag The reason why you can't bind \c\n. Is that the terminal usually doesn't register this. So it only sends \n. This is true for some other keys like space and backspace.

If your terminal allows you to setup keys, you could specify that ctrl+enter should send this key-sequence.

@dag
Copy link
Contributor

dag commented May 11, 2013

Ah.

@fran6co
Copy link

fran6co commented Jun 28, 2013

+1 for this feature. I would love to have the implicit cd back. If it's something that there is no agreement, at least add a way to enable it for the people that use it.

@KamilaBorowska
Copy link
Contributor

I've through of something else. No magic (well, ok, feature itself is magical, but the method I propose is logical), good error messages, and stuff like that.

me@machine /> usr/
me@machine /usr> bin/
me@machine /u/bin>

So, well, the idea is that if you end command with /, the shell assumes you meant implicit cd. IMO, it's clean, fast (typing / is like very easy, especially compared to cd or ./), and unambiguous (because if I write ./something, it isn't obvious whatever something is a directory or a binary, but something/ can only mean a directory).

Alternatively, it could apply to any path containing / (so bin/ would be just fine), while still avoiding ambiguity with global commands (or that is ~ (potentially followed by username) or .. by itself).

@SanskritFritz
Copy link
Contributor

I like @glitchmr 's idea. I never liked implicit cd but this one seems to be usable for me. So +1

@dag
Copy link
Contributor

dag commented Jul 4, 2013

I like it @glitchmr, could even work with CDPATH I imagine?

@KamilaBorowska
Copy link
Contributor

The reason why tab doesn't show slash for single dot is related to source command that should die in current form (or at least moved to source, instead of .).

@ghost
Copy link

ghost commented Jul 29, 2013

IMHO, implicit cd should work:

  1. in the case where a binary would be executed (dir/dir, ./dir, ~/dir, /dir, etc.)
  2. when the file ends with a slash (dir/)

I like the idea of having both. Currently, dir/dir doesn't work and you have to enter ./dir/dir, which seems rather silly.

Also, I think that . moving to source should happen alongside this change, and that . should simply be a no-op that changes to the current directory. If you enter . right now by accident, it waits for input and doesn't respond to ctrl-C, which is kind of unintuitive.

@anordal
Copy link
Contributor

anordal commented Oct 1, 2013

2. when the file ends with a slash (dir/)

I agree with you and GlitchMr on this, because:
a) It's no exception to the «contains slash» rule I mentioned.
b) Trailing slash is just a way to tell programs, syscalls and C library functions that «I intend this to be a directory» — typically they fail with ENOTDIR (Not a directory) if the path doesn't resolve to a directory in that case. If implicit cd is syntactically indistinguishable from executing a program, ending with slash is an obvious way to assert what you mean, and with autocompletion, distinguish what's going to happen.

From man 7 path_resolution, section Trailing slashes:

If a pathname ends in a '/' (…), it has to exist and resolve to a directory.

Most programs obey this, for example mv:

me@machine ~> touch file1
me@machine ~> mv file1 file2/
mv: cannot move «file1» to «file2/»: No such file or directory
me@machine ~> touch file2
mv: accessing «file2/»: Not a directory

For bash, trailing slash on the executable is mission impossible to begin with, since it has no notion of executing directories. Yet, bash will honor the trailing slash, and verify for you that the executable is a directory:

me@machine ~> bash
bash ~$ eject/
bash: eject/: No such file or directory
bash ~$ echo '#!/usr/bin/eject' > eject
bash ~$ chmod +x eject
bash ~$ eject/
bash: eject/: Not a directory
bash ~$ rm eject && mkdir eject
bash ~$ eject/
bash: eject/: Is a directory

Note also that by the «contains slash» rule, eject/ is not searched for in $PATH, but treated as the relative path it is.

KamilaBorowska pushed a commit that referenced this issue Oct 1, 2013
This is an experimental feature, proposed in the issue #22.
#22 (comment)
@KamilaBorowska
Copy link
Contributor

I decided to experiment with this feature, and pushed it (for now) to the fish code, in commit 6c82e7a, just to get feedback about this feature (considering the support for it). The feature is partially implemented, but basic things (like tab completion and feature itself should work). Needs documentation, and better error messages, but that will be added when it will be confirmed that this feature will appear in fish 2.1.0.

@ridiculousfish
Copy link
Member Author

My main concern here is tab completion. Will we find that tab completing commands instead accidentally completes directories? How does (should) this relate to CDPATH? I guess time will tell.

@KamilaBorowska
Copy link
Contributor

@ridiculousfish: I wouldn't worry too much about tab completion. Before improving tab completion (and tab completion was improved after 2.0), tab completion could complete directories. Besides, I don't expect directories to have lots of directories, so it's unlikely things would break too much in many cases.

As for CDPATH, I'm unsure about it. In my opinion, it's just a hack that fish simply shouldn't support, but it does. I actually wonder how often it is used (I don't use it, but I bet others do). Still, I believe that it could work with CDPATH, but what about ./ and ../?

@ghost
Copy link

ghost commented Oct 2, 2013

Changing my view on this: I think that this should require a / at the end of the directory, and whenever you type in something incorrect with a / at the end, it should say "Directory X not found" instead of "Unknown command X." This way, there's never any ambiguity whether something is a directory or an executable, and errors are consistent.

@88Alex
Copy link

88Alex commented Nov 7, 2013

IMHO Either solution 1 or 2 would be good.

  1. in the case where a binary would be executed (dir/dir, ./dir, ~/dir, /dir, etc.)
  2. when the file ends with a slash (dir/)

👍 This would be a great idea.

@ghost
Copy link

ghost commented Nov 8, 2013

The second is already implemented in fish right now.

@iven
Copy link

iven commented Nov 8, 2013

But autocompletion doesn't work for this?

@nagisa
Copy link
Contributor

nagisa commented Nov 8, 2013

@iven it does?

@ridiculousfish
Copy link
Member Author

By autocompletion, do you mean tab completion or autosuggestions? What's not working specifically?

@iven
Copy link

iven commented Nov 9, 2013

@ridiculousfish
I've set CDPATH as ~ ., and I have a directory Workspace in my Home directory. When I type Work in other directories, neithor tab completion or autosuggestions works.

@ridiculousfish
Copy link
Member Author

I think we deliberately do not respect CDPATH for implicit cd.

@SanskritFritz
Copy link
Contributor

... which is a very good choice IMO!

@iven
Copy link

iven commented Nov 11, 2013

@ridiculousfish But when I type the whole Workspace/ in any directory, it works. So why we have such a function, while don't support autocompletion?

@ridiculousfish
Copy link
Member Author

Well then maybe I'm wrong :)

@berkus
Copy link

berkus commented Jun 11, 2014

3 works just fine.

@88Alex
Copy link

88Alex commented Jun 11, 2014

@berkus 👍, I agree.

@faho
Copy link
Member

faho commented Jul 14, 2015

Is this still an issue? For me, typing "directory/" works and respects CDPATH.

@ridiculousfish
Copy link
Member Author

The current rules are that it has to lead with dots, a slash, or have a trailing slash.

@faho
Copy link
Member

faho commented Sep 17, 2015

From the docs for the cd builtin:

Note that the shell will attempt to change directory without requiring cd if the name of a directory is provided (starting with ., / or ~, or ending with /).

I'm not sure where else it should be documented, so I'm closing this now.

@faho faho closed this as completed Sep 17, 2015
@faho faho removed this from the fish-future milestone Feb 8, 2016
@fjolnir
Copy link

fjolnir commented Jan 2, 2018

It would be nice if the following worked:

> set icloud "/Users/me/Library/Mobile Documents/com~apple~CloudDocs/"
> $icloud/Subdir/
fish: Variables may not be used as commands. In fish, please define a function or use 'eval $icloud/Development/'.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
docs An issue/PR that touches or should touch the docs
Projects
None yet
Development

No branches or pull requests