15 ms·
Show HN: tere – A Faster Alternative to cd+ls
Hi HN!
I wrote a small program to browse folders in the terminal. The main inspiration was type-ahead search in GUI file managers. There exist several programs that are similar (see the listing in the README), but none of them do it quite the way I like, and often they have a very complex UI and a ton of features. I tried to make something that is obvious how to use and gets out of your way. (I also wanted an excuse to learn Rust.)
Let me know what you think!
- mwexler 4y agoOne of the better demo gifs: clever naming, clear utility, clear understanding of how to use the tool.
- rebanevapustus 4y agoA Small bit of trivia: tere means hi in Estonian.
- taskforcegemini 4y agotere (or "dere") is used in austrian colloquial german for helo as well (but also for "bye"). Seems TIL where it comes from
- mgunyho 4y agoThat's mentioned in the readme! :) I'm pretty happy with the name choice, it's short, doesn't seem to clash with other CLI tools, it can be interpreted as "terminal explorer", and has a kind of cute meaning as you say.
- notpushkin 4y agoTere from Tallinn here! :-)
- the_alchemist 4y ago> "Tere" means "hello" in Estonian. It also feels nice to type. On qwerty I think that's the case :)
- mgunyho 4y agoTrue, it's not a very smooth experience on non-qwerty keyboards, and the keyboard shortcuts can't be customized yet. But it's high on the todo list!
- fnord123 4y agoIt feels bad to type on qwerty. Alternating hands feels nicer to type. That's part of why ls is so hard to remove from peoples' muscle memory.
- deleted 4y ago[deleted]
- mgunyho 4y agoNote that setting up tere requires defining an alias in your shell config anyway, so you can choose any name you want with basically zero extra effort! Except for coming up with an abbreviation you remember, of course. But I agree, it is faster to type with alternating hands.
- chungus 4y agoCool! Also, I really like your demo gif! Super effective and fun way to go through all the features.
- enriquto 4y agocurl https://raw.githubusercontent.com/mgunyho/tere/master/Cargo.lock | grep source | wc -l 51 How come that such a simple tool has more than half a century of dependencies? This is terrifying.
- bowsamic 4y agoSome Rust dependency bloat is pretty common, because a lot of idiomatic approaches are hidden behind dependencies. I don't think it's particularly crazy in this situation. The actual dependencies directly used are relatively lean: crossterm = "0.24.0" dirs = "4.0.0" regex = "1.5.4" serde_json = "1.0" serde = { version = "1.0", features = ["rc"] } textwrap = "0.14" unicode-segmentation = "1.7" I guess one could write their own textwrap and probably also dirs, but other than that they all are probably vital to this tool. The only reason this wouldn't be a problem in another language would be because that language already includes the functionality of such libraries
- chrismorgan 4y agoYou missed clap for the CLI because it was written in table form: [dependencies.clap] version = "3" default-features = false features = ["wrap_help", "suggestions", "std"]
- chrismorgan 4y ago`cargo tree` output: tere v1.0.0 ├── clap v3.0.10 │ ├── bitflags v1.3.2 │ ├── indexmap v1.8.0 │ │ └── hashbrown v0.11.2 │ │ [build-dependencies] │ │ └── autocfg v1.1.0 │ ├── os_str_bytes v6.0.0 │ │ └── memchr v2.4.1 │ ├── strsim v0.10.0 │ ├── terminal_size v0.1.17 │ │ └── libc v0.2.126 │ └── textwrap v0.14.2 │ ├── smawk v0.3.1 │ ├── terminal_size v0.1.17 (*) │ ├── unicode-linebreak v0.1.2 │ │ [build-dependencies] │ │ └── regex v1.5.4 │ │ ├── aho-corasick v0.7.18 │ │ │ └── memchr v2.4.1 │ │ ├── memchr v2.4.1 │ │ └── regex-syntax v0.6.25 │ └── unicode-width v0.1.9 ├── crossterm v0.24.0 │ ├── bitflags v1.3.2 │ ├── libc v0.2.126 │ ├── mio v0.8.4 │ │ ├── libc v0.2.126 │ │ └── log v0.4.14 │ │ └── cfg-if v1.0.0 │ ├── parking_lot v0.12.1 │ │ ├── lock_api v0.4.7 │ │ │ └── scopeguard v1.1.0 │ │ │ [build-dependencies] │ │ │ └── autocfg v1.1.0 │ │ └── parking_lot_core v0.9.3 │ │ ├── cfg-if v1.0.0 │ │ ├── libc v0.2.126 │ │ └── smallvec v1.8.0 │ ├── signal-hook v0.3.13 │ │ ├── libc v0.2.126 │ │ └── signal-hook-registry v1.4.0 │ │ └── libc v0.2.126 │ └── signal-hook-mio v0.2.3 │ ├── libc v0.2.126 │ ├── mio v0.8.4 (*) │ └── signal-hook v0.3.13 (*) ├── dirs v4.0.0 │ └── dirs-sys v0.3.6 │ └── libc v0.2.126 ├── regex v1.5.4 (*) ├── serde v1.0.134 ├── serde_json v1.0.75 │ ├── itoa v1.0.1 │ ├── ryu v1.0.9 │ └── serde v1.0.134 ├── textwrap v0.14.2 (*) └── unicode-segmentation v1.8.0 I can easily look at each one of these and understand why it’s there, save only a few: most of crossterm’s recursive dependencies, which are fairly involved but the immediate dependencies at least are clearly explained in its README (and you could probably remove one or two of them at minor performance or similar costs); mio’s use of log, which I believe should be optional and I would say not enabled by default, but I’d rather use it with log than miss out on it, where it’s useful; uses of autocfg, which are build-time implementation detail for taking advantage of rustc features where available and readily understood on analysis; and I was going to say cfg-if, which I have a minor personal vendetta against due to extensive unnecessary use, but after looking at parking_lot_core’s src/thread_parker/mod.rs I will begrudgingly admit this is one of the rare cases where it is fairly well-justified. All up, none of the dependencies are in any way unreasonable. Having over fifty dependencies for something like this is not in any way terrifying—you’re just starting with a different set of expectations and understandings of how things are done. It’s a natural and reasonable outworking of (a) using the right tools for the job, (b) doing things properly rather than half-heartedly (most obviously where terminal interactions are involved), and (c) Rust’s deliberately thin standard library.
- tempusr 4y agoI'm going to be a dick here, because someone will say it anyways, but how is this different from VIM's directory browser? Essentially the same UI. I do think your program does add some features not found in VIM.
- mgunyho 4y agoIt's true that vim probably contains all of the functionality of tere, but IME browsing with vim is still a bit more cumbersome (and I'm not sure if you can configure it to print the cwd on exit, though probably you can). The extra '/' keystroke in each subdirectory for type to search, and the auto-cd really does make tere feel smoother.
- kiwijamo 4y agoHow do you get vim to output the path to the directory you want?
- Beltalowda 4y agoNot everyone uses Vim. Also netrw is a bit of a mess; I once found a bug and thought "I'll write a patch". After five minutes of browsing through the code ([insert Eddie Murphy meme]): "yeah, never mind".
- taskforcegemini 4y agosome people have been using vim on a daily basis for years but have never used any directory functionality, only the text editing bits
- progx 4y agoLol, ~30 years ago a created such a tool for DOS in Turbo Pascal for my own usage. Later i "upgrade" it to a Star Trek LCARS Design.... i have to look if i still had the sources. History repeats.
- p4bl0 4y ago> "Tere" means "hello" in Estonian. It also feels nice to type. I really thought it was initially a typo on "tree" (the tool's purpose is to navigate the folder tree) that the author decided to keep.
- maybevain 4y agoI think the origin might be ”[ter]minal file [e]xplorer”, though the author might correct me here. ”Tere” is also, perhaps unsurprisingly, used in Finnish.
- mgunyho 4y agoI would say that terminal explorer is what I had in mind initially (and incidentally, I also speak Finnish, heh). But a misspelling of tree is certainly a valid interpretation as well :)
- 3r8riacz 4y ago"there" would also be a nice alternative explanation
- sileht 4y agoLooks like builtin in zsh autoload -Uz compinit compinit zstyle ':completion:*' menu select Then ‘cd <tab>’
- mgunyho 4y agoTab completion with these settings takes some extra keystrokes: if there's only one match, you have to press tab twice to see what's in the subfolder. If you have several matches, you have to press tab, then enter to select the one you want, and then tab again to show the subfolder contents. And going up (especially several) folders is also quite a bit of typing. It might sound like splitting hairs to shave off less than five keystrokes, but it really does make a difference in how smooth the browsing feels.
- freedomben 4y agoI'm blown away at the quality of the readme :-) In the demo, how did you get the key press indicator to show? I haven't seen that before, but it's a wonderful addition. And may I ask what you used to record it?
- mgunyho 4y agoFunny, to me showing the keystrokes felt like a cliche in "modern"/flashy CLI app readmes :) I guess it's more often used in youtube videos. I used screenkey to display the keystrokes and Peek to record the gif. I actually wrote some instructions for myself so I remember how I did it if I want to update the gif: https://github.com/mgunyho/tere/blob/master/demo/README.md https://github.com/mgunyho/tere/blob/master/demo/README.md
- divbzero 4y agoEchoing neighbor comments that the README is very well done. I specifically searched through this thread to learn how you displayed those keystrokes in the demo.
- tommiegannert 4y agoI was thinking the same. Building something without sharing is one thing. Dumping code on GitHub is second level. Third is building a good README. Fourth is building a good README and announcing it to the right audience. Very well executed. I'm not sure there's a level between fifth and "being obnoxiously pushy," but if there's such a thing, I'd be interested to know. :)
- codecurve 4y agoThis feels a lot like Vim's built in file explorer (netrw). I find these kinds of text based, keyboard centric explorers to be far superior for navigating around a codebase, then giving you back your screen space as soon as you're found what you're looking for. I implemented something similar but for VSCode: https://github.com/danprince/vsnetrw https://github.com/danprince/vsnetrw
- iso1631 4y agoI hit ~ expecting to go to my home directory, which was a bit odd Once I select a directory I want to dump myself back out into a command line in that directory, I couldn't see the key for that? Or am I misunderstanding the purpose?
- mgunyho 4y agoTo end up in the directory where you are, you just have to exit using esc or alt-q, assuming you have set up your shell config. I'll add ~ as a shortcut for the home directory, thanks for the good idea! (It conflicts with type-to-search for folders starting with '~', but I think that's much less common than cding to home.)
- p6way 4y agoNot bad, my old stuff the same but c++/X11lib: https://youtu.be/2l7cIc4INAs?t=89 https://youtu.be/2l7cIc4INAs?t=89
- chrismorgan 4y agoI strongly dislike the idea of automatically jumping into a folder when there’s only one match: it feels like a feature optimised for very slow typers that actively penalises fast typers, because it makes things generally unpredictable: will one character be enough to navigate, or two, or three? It depends on the siblings, and if you type more characters than are required, you will be penalised by ending up somewhere else as the remaining letters are fed to the next level down that you haven’t even seen yet. My general habit in navigating is to type three characters and press Tab, because that’s almost always sufficient, and is plenty fast. I have a very few places where I’ve learned to do other things. Under my habit, I could end up as much as two levels down from where I wanted to be.
- mgunyho 4y agoI'm a fast typer, and I understand where you're coming from! But note how there's a small (200ms by default but can be configured) delay when the auto-cd happens. This is actually pretty important, because otherwise it's impossible to see where you cd'd to. Importantly, during this delay, the keystrokes are eaten (so they are not fed down to the next level), and from my experience this is enough to basically never accidentally cd in the lower level. The auto-cd can also be turned off with a CLI option.
- chrismorgan 4y agoOK, delay sounds good.
- jonnycomputer 4y agoI think you were highlighting an important potential usability issue; the delay might be ok, but I still prefer a keystroke, such as enter, to confirm selection.
- mynameisvlad 4y ago> The auto-cd can also be turned off with a CLI option. Which was seemingly addressed as well, no?
- zelphirkalt 4y agoLooks like Emacs built-in dired, except, that it is not integrated into Emacs.
- fouric 4y agoIt has fuzzy-filtering and auto-select - does dired have those? I think it's closer to helm-find-file.
- asib 4y agoIs cd+ls a common pattern for people? I tend to just use double tab to browse folders, combined with a file separator-aware "delete word" keybinding when I want to go back up one level.
- memorable 4y agoI don't know about other people, but I use the combo almost all the time when I need to `cd`.
- p4bl0 4y agoSame here, I use ls when I'm where I want to be, but for navigating the filesystem to there, I use cd and TAB TAB autocompletion (which is smart enough to only suggest directories).
- Cthulhu_ 4y agoI've got ZSH or a ZSH plugin that shows me a list of possible files in a folder I'm cd-ing into, without going into a different 'terminal mode'. Works for things like vim as well.
- divbzero 4y agoI use cd+ls all the time even though double tab or fzf [1] work better in theory. [1]: https://github.com/junegunn/fzf#key-bindings-for-command-line https://github.com/junegunn/fzf#key-bindings-for-command-lin...
- lloeki 4y agoCongrats for getting this out! > I also wanted an excuse to learn This is the best reason ever, and not just for you: seeing your GIF I thought "could I achieve that with fzf?". Turns out, yes I can: function fcd() { local dir; while true; do # exit with ^D dir="$(ls -a1p | grep '/$' | grep -v '^./$' | fzf --height 40% --reverse --no-multi --preview 'pwd' --preview-window=up,1,border-none --no-info)" if [[ -z "${dir}" ]]; then break else cd "${dir}" fi done } Certainly not the best code (and definitely not a jab at your implementation!) but, hey, it was purely for the heck of it. Lately I've been trying to find the joy in programming again, these kind of fun little challenges help a lot, so thanks for sharing, enthusiasm and creativity is contaminating :)
- mgunyho 4y agoThanks for the kind words! :) While digging up alternatives (of course after I had already written most of the functionality), I briefly tried out fzf. I think at that time I couldn't find an example snippet like yours to do the cding, so I didn't look into it much more. With some basic settings, it was also not easy (or even possible?) to go up in the folder tree, but I see that your example handles that. If you're unfamiliar with a big folder tree, fzf (or another very similar tool that is designed for this purpose, broot) can be more efficient. But it might take a while for it to scan all subfolders.
- lloeki 4y ago> fzf (or another very similar tool that is designed for this purpose, broot) can be more efficient Well, fzf is only a selection tool, it's more about the tool that feeds fzf data ;) That's why I used a dumb ls in my example. Maybe a difference with yours is that it does perform cd on each loop, and there's no way to bail out and not cd. > it might take a while for it to scan all subfolders. Haha yeah, for recursive cases I was using ripgrep as fzf default command: rg --files --no-ignore --hidden --follow --glob "!{.git,node_modules}/*" | fzf And now I just discovered fd[0]: fd --no-ignore --hidden --follow --strip-cwd-prefix | fzf (...at least essentially, my setup is a bit more tunable and complex, I have a few of these with varying flags depending on the situation and goal) [0]: https://github.com/sharkdp/fd#using-fd-with-fzf https://github.com/sharkdp/fd#using-fd-with-fzf
- medv 4y agoI also created a such tool llama: https://github.com/antonmedv/llama https://github.com/antonmedv/llama But with fuzzy searching.
- mgunyho 4y agoNice, looks like this is indeed very similar to tere! I guess the biggest difference is that the current search is not as "sticky", looks like it's cleared automatically after a while, which is similar to the behavior of the windows file explorer. I added it to the list of similar programs in the README (it's in the develop branch for now).
- a3w 4y agoNice of the readme to mention broot et al.
- smartmic 4y agoDefinitely worth to check out sdn which also serves perfectly as cd+ls replacement: https://git.janouch.name/p/sdn https://git.janouch.name/p/sdn I also submitted few days ago here on HN: https://news.ycombinator.com/item?id=32081263 https://news.ycombinator.com/item?id=32081263
- mgunyho 4y agoIndeed, this looks very similar! I added it to the list in the README. To compile it, I had to sudo apt-get install libacl1-dev, which was not mentioned in the instructions.
- premysl 4y agoAuthor here, this is implied from runtime dependencies, it's in generic packager speak. Ideally, I would provide pre-built packages from CI, of course.
- IshKebab 4y agoThis looks very cool. The demo has convinced me to try it, well done! Also typical hacker news - "why don't you just use Vim"? Ha. Ignore the naysayers.
- mgunyho 4y agoI was well prepared mentally for the HN cynicism, and I did spend quite a bit of mental energy to justify the existence of tere to myself. Luckily I have a good rebuttal: I already use vim! :)
- thyrox 4y agoSorry for being dense but I thought when I entered into a directory and pressed Esc it would pwd into that directory. But in my case, entering the dir and pressing esc just prints the dir name and doesn't pwd into it. I did the cargo install.. What am I missing?
- mgunyho 4y agoYou need to configure a shell function to actually do the cd (see the snippets in the README). It has to be done this way because a subprocess cannot change the pwd of the parent.
- ducktective 4y agoNice project! Kudos! BTW, checkout `nnn` search-as-you-type and cd-on-quit features. I think its similar in scope to this project. https://github.com/jarun/nnn https://github.com/jarun/nnn https://github.com/jarun/nnn/wiki/Basic-use-cases#configure-cd-on-quit https://github.com/jarun/nnn/wiki/Basic-use-cases#configure-...
- hnlmorg 4y agoAppreciate this is a hobby project to learn Rust in, but for those who want similar functionality without installing additional dependencies, you can already do this in `vim` by selecting a directory to open instead of a file. For example vim ~ vim /etc It has more or less the same UI as the one in this Show HN but with the added feature of opening any files you select.
- mgunyho 4y agoAs mentioned in another comment, vim doesn't provide exactly the same experience: navigation is more cumbersome because you need extra keystrokes for type-to-search and to cd a folder. It also requires some extra tinkering for vim to print out the cwd when you exit.
- hnlmorg 4y agoClearly it's not going to be functionally identical, which is why I said it might interest people who are after something similar "without installing additional dependencies". That said, I do think your reply here is a little disingenuous because one extra key stroke is hardly "cumbersome". Especially when you advertise your tool as having VIM bindings and then criticise VIM for the same thing. I have no issues with you promoting your tool but lets be pragmatic about our comparisons here. You also overlooked the fact that VIM will open any documents from within in. Which would save you a lot more key strokes than tere due to not having to `$EDITOR $file` after the whole (tere|vim) {navigate} process. As for automatically changing directory. Lets be clear, `tere` doesn't either. You need to configure your shell to do that. Granted you provide the code to set that up but there's nothing stopping someone from writing a similar script for VIM (there's a VimLeave event so you could do something like :autocmd VimLeave * and the path would be stored in expand('%:p:h') so it's certainly doable to replicate the same behaviour in VIM. In fact I might even knock up a working script if anything wants it? I'm honestly not saying any of this to be negative about your project here though. It's a nice little tool and I'm sure some people will find it very useful. It's just a common problem so you'll probably find a lot of of people have already solved this with other tools. But there's absolutely nothing wrong with having another tool out there :)
- tipsytoad 4y agoLooks great! I was thinking of a rusty pet project for the same thing :) I haven't seen it mentioned yet, but Ranger is a great alternative tool, it can even be integrated into vim [0]: https://github.com/ranger/ranger https://github.com/ranger/ranger
- andai 4y agoSee also lf, inspired by ranger. https://github.com/gokcehan/lf https://github.com/gokcehan/lf
- sayanarijit 4y agoxplr author here (xplr.dev). Nice tool. Note that there's a plugin https://github.com/sayanarijit/type-to-nav.xplr https://github.com/sayanarijit/type-to-nav.xplr that does something similar. But I just realized that tere can also be used as a more generic type-to-nav helper for xplr. xplr.config.modes.builtin.default.key_bindings.on_key.T = { help = "tere nav", messages = { { BashExec = [[echo ChangeDirectory: "'"$(tere)"'" >> "$XPLR_PIPE_MSG_IN"]] }, }, }
- mgunyho 4y agoNice! Looks like xplr can indeed "integrate them all", as you say in the readme.
- deleted 4y ago[deleted]
- post-factum 4y agoNow in AUR too [1]. [1] https://aur.archlinux.org/packages/tere https://aur.archlinux.org/packages/tere
- protonbob 4y agoI really like the animated gif. It really is useful to show how the program works.
- jhgb 4y agoWell, what I think... It looks cool, but fish already includes similar functionality in its directory completion, so no external program required. So I suspect this is useful for people using bash and such?
- amelius 4y agoMakes me think of Norton commander.
- pehtran 4y agoReminds me a bit of Helm mode in Emacs, nice!
- fouric 4y agoThis appears to be "helm-find-file" for those who want to use bash, and not Emacs.
- syntaxfree 4y agoI alias cd to pushd but half the time I forget to popd. It would be cool if there was a tool like this that would produce a menu from my pushd queue.
- tsujp 4y agoSimilar but in pure Bash: https://github.com/dylanaraps/fff https://github.com/dylanaraps/fff
- j1elo 4y agoOne thing I'd like is a cd command incantation that when given a file path, it just changes to the dir containing such file. It is such a common need (for me at least) that I'm surprised the standard cd doesn't do it already. I find myself using find or locate, then wanting to change to some file's directory, thus needing to manually delete the file's name before hitting enter. When you do that enough times you start to wish it worked automatically :-)
- Tepix 4y agoThis reminds me of "ncdu" which has the main task to let you know where your disk space has gone, but you can also use it to navigate folders and even delete stuff.
- realyashnag 4y agoThe reason devs still use `cd+ls` is because they're ubiquitous. But always great to learn new stuff like this (:
- seligman99 4y agoSimilar idea for Windows: https://github.com/seligman/ccd https://github.com/seligman/ccd ccd is more concerned with an edge-first search, and since it's Windows, actually changing the directory involves a thread insertion in the cmd process to do the work ... which somehow works.
- StillBored 4y agoInteresting. OTOH, people have named a number of similar tools, and I'm going to point out 'mc' aka Midnight Commander, which is part of most linux distro's, and is a clone of the 1980's Norton commander. Its designed to be a command line TUI helper, sorta like the project here, with not only cursor/etc based directory navigation but copy/rename/delete/etc functionality just a keystroke away. Its fairly convenient because it overlays the command line rather than replacing it.
- sillycube 4y ago
- ghostly_s 4y agoDo people actually still use cd + ls? At least in bash, you get a similar experience just typing a cd command and tab-completing the path elements - bash shows a listing of matches when your command is ambiguous, no `ls` required.I'll still check it out as I can see fuzzy-search being more useful but muscle memory is hard to change.
- tux2bsd 4y agonot entirely. e.g. cd tab tab directories listed cat tab tab files listed (this^^ is on Debian, it can probably be changed but I've not looked into it) it's pretty annoying when I'm halfway through and want to use tab tab as a periscope to see all file+dirs
- kleer001 4y agoLooks like fun to use and it was fun to create. I don't see a use case for myself. I use cd with TAB autocomplete and I'm set. I'm old enough and lazy enough.
- deleted 4y ago[deleted]
- bradwood 4y agoOne of my pet peeves is CLI newbies who always have the need to cd into some directory before running a command. I learnt pretty early on that this was stupid. Just run your command from the repo root or $HOME.
- taskforcegemini 4y agoimho that is not a bad habit to have, what's the harm? you don't always know how the script/application behaves. sometimes they do things in relation to where you are standing. if you mean the newbies cd into a location in $PATH though, i.e.: cd /bin, cd /usr/bin etcetera I agree, that doesn't make sense usually
- eikenberry 4y agoTo be fair most of those newbies are probably writing scripts that use relative directories so they require them being run in the same directory. Newbies tend to reinforce bad habits like that which makes it harder to break out of those ruts.
- bradwood 4y ago(cd ./some/path; ./script.sh)
- eikenberry 4y agoIMO it's easier just to write your scripts so they don't rely on the directory context for running correctly. Usually it's just a matter of taking your relative path using script and sticking something like this at the top and you're good. cd "$(dirname $0)"
- mixmastamyk 4y agoThis is quite neat so I feel slightly embarrassed to share my low-tech solution. Just run a "dir" after each "cd" (which is my alias for "ls -l --si ..."). It's written for fish, but could be ported to bash easily: # cat ~/.config/fish/functions/cd.fish function cd builtin cd $argv; if test $status -gt 0 # there was an error, stop return end # auto print dir info if test "$argv" != "" # not home though dir end end There's probably a way to optimize out the "test " call as well, but I haven't got around to it.
- fouric 4y agoHeh, I implemented almost exactly this same thing several years ago in Python[1], with the main difference just being the amount of polish and feature set. (I was, and continue to be, a very distractible person) Good to see the idea getting more traction! [1] https://github.com/fouric/lightning-cd https://github.com/fouric/lightning-cd
- mrtweetyhack 4y ago