Hacker News new | comments | ask | show | jobs | submit login
Z.lua – A new cd command that navigates faster by learning your habits (github.com)
163 points by skywind3000 11 days ago | hide | past | web | favorite | 58 comments





Hopefully they have read the Jargon File:

http://www.catb.org/jargon/html/D/DWIM.html

> Warren Teitelman originally wrote DWIM to fix his typos and spelling errors, so it was somewhat idiosyncratic to his style, and would often make hash of anyone else's typos if they were stylistically different. Some victims of DWIM thus claimed that the acronym stood for 'Damn Warren’s Infernal Machine!'.

> In one notorious incident, Warren added a DWIM feature to the command interpreter used at Xerox PARC. One day another hacker there typed delete * $ to free up some disk space. (The editor there named backup files by appending $ to the original file name, so he was trying to delete any backup files left over from old editing sessions.) It happened that there weren't any editor backup files, so DWIM helpfully reported * $ not found, assuming you meant 'delete * '. It then started to delete all the files on the disk! The hacker managed to stop it with a Vulcan nerve pinch after only a half dozen or so files were lost.

> The disgruntled victim later said he had been sorely tempted to go to Warren's office, tie Warren down in his chair in front of his workstation, and then type delete * $ twice.


We don't need to be quite as paranoid about the plainness of a directory navigation tool, as needed for a command interpreters path selector. It would need to be combined with potentially destructive operations in a script to be dangerous, so then on thy own head be it.

Such things have happened: https://www.slashgear.com/steam-on-linux-bug-can-delete-all-...

The problem is that shell is so sloppy it's hard to know what will happen. Of course, that's not unique to a new mechanism for navigating directories. It's scary stuff no matter what.


That was an unbound variable, not due to a tool for predicting what directories you typically navigate to. Who in their right mind would use that in a shell script? (Actually, nevermind, if github had decent code search I'll bet you could find rm -rf --no-preserve-root `fasd somefile` somewhere in there.)

I use the version available for zsh (cdr) for folders that I very recently and infrequently accessed, as well as z (https://github.com/rupa/z works with bash and zsh). It seems like this z.lua and z are in some way related?

It feels far more intuitive and it's so incredibly convenient to be able to jump between folders I'm working in without having to traverse an entire tree. The shell used to feel so constraining for me, but tools like this are making me enjoy it so much more.


This is an excellent layer on top of bash and has some overlap with concepts in other tools like fish shell, but it has me wondering, are we really at the end of the evolution of shells, so that we're now focused on making tools that improve shells? Or can we evolve the very concept of shells even further, making zsh and fish look like assembly language in comparison to Haskell?

We can definitely evolve shells more.

Most shells offer a convenient syntax around a lot of (fantastic) utilities that often mirror C libraries (notably posix). When we were working in C, having our shell mirror parts of that at times while being a very dynamic language at other times sounds great.

But we have a much more varied landscape of language and library options now, and many developers haven’t ever used C or posix.

So my thought is: what if we had a shell that was designed to interop with JS (or python, or ideally a language the user knows well), instead of C/posix. What if, instead of having to remember bash’s for loop syntax (or xargs), you could just write .map() and iterate over lines/execute commands that way?


Totally agree with this. We need to create shells based popular languages so language syntax stops being a barrier to entry for new people. How many times do we search for "if statement bash" or "function bash" because the if and function syntax isn't modern and isn't easy to remember?

Transforming the shell is a great opportunity for a new project, and as you said should probably should be done in Python or JS. Lua is a good option as well for its elegance, though it's a bit less popular than the others.

As for Z.lua, this is an interesting project and I really like seeing modern languages enriching what we do every day on the command line. Very cool!


That's the motivation behind my Oil project:

Why Create a New Unix Shell? http://www.oilshell.org/blog/2018/01/28.html

I took a very long route to doing it though, first implementing OSH (which will run existing shell scripts, which is close to done, but slow) and then Oil (a new language, not implemented).

This is because POSIX shell/bash has a really strong network effect. zsh and fish are better in many respects, but people are locked into bash because that's what "everybody else uses".

It's analogous to how C has a really strong network effect because e.g. every kernel is written in C. So C++ became a popular language in a large part because it's compatible with C. (Though the analogy breaks down because the Oil language isn't a superset of bash, so we can break free of legacy. The project is though.)

In my mind, I think of Oil as a mix between Python and shell, with some elements of Ruby and JS (blocks, function literals, etc.)


I love what you're doing with Oil! Looking forward to trying the interactive version in the future :)

And yes, network effects are so important—your C++ example is spot on. One recent example that comes to mind is the adoption from python2 to python3, showing just how big a barrier those network effects are to adopting something incompatible.


Thanks! I'm writing a blog post now about how I got the majority of bash-completion running, so I'm now using OSH myself. This is the biggest milestone in a long time!

It exposed the slowness issue though. I have a plan for that, but it's a bunch of work.

It will help me if people try it and give feedback -- I'll give details in the post.

I definitely agree about Python 2/3. I think you basically can't overestimate the amount of inertia a popular language has. I'm sure there will be patches floating around for Python 2 for a long time after the core team stops maintaining it next year.

Another example is all the compile-to-JS languages. I think TypeScript is the most popular in part because its transition path is the easiest, i.e. it's a superset of JS.


That’s awesome! I’d love to try it; details in an upcoming blog post?

how's oil going? I haven't looked into it in about a year or so, but it seemed like a cool project

There will be a big status update in a few days here: http://www.oilshell.org/blog/

Or you can subscribe in one of these places :)

https://www.reddit.com/r/oilshell

https://twitter.com/oilshellblog


> How many times do we search for "if statement bash" or "function bash" because the if and function syntax isn't modern and isn't easy to remember?

The number of times I've used a for loop in shell is roughly equal to the number of times I've had to look up how to use a for loop in shell. Relatedly, I generally switch to Ruby when my scripts get complex enough to require control flow.


For some tasks I find myself writing my scripts in bash with a bunch of python herefiles. Bash is pretty straight forward when it comes to text stream processing and tool integration but for anything more the herefiles are a good way to avoid figuring out bash control flow and messing with list delimiters

Agreed, I always feel like there is so much great shell-related code scattered all over people's dotfiles and we could all benefit from a kind of modernization you and the parent are mentioning.

This is my attempt so solve a small personal pain point in the shell while trying to keep track of various commands: https://github.com/bonidjukic/aka

It definitely comes nothing close to the Z.lua, but the enjoyment generated from getting to write the thing which optimizes even the tiniest parts of your daily tasks is quite wonderful.


If you're using bash, there's a usable help builtin.

    help
    help if
    help function
etc.

Oh right, I forgot lua! I love lua and would enjoy that shell (and the metaprogramming available makes it much easier to let unknown commands call programs, which I've tried once).

But I expect for adoption it'll need to be a more widely-used langauge


#!/bin/env/poplang

That is the fundamental idea behind powershell. PS accesses the .NET world kinda like that. Many people love it. I would want one similar for JS and mainly fixated on the linux world (but works in Windows). Whereas PS works in Linux, I would say .NET isn't a great target for the linux audience.

I code a crapload of PowerShell and I've come to hate it. It's the most inconsistent language I've ever used, and the docs always bury the lede about the format of the returned object-stream, leaving me grasping to find the types and properties of everything where more text-oriented consoles would be far more wsiwyg.

Yeah, it's a great idea but terribly executed.

They could have just used F# as the new shell language, the interpreter already exists, the syntax is clean and concise, etc.


I joked about this years ago. I'm not a Javascript fan, so really, I lamented that in a few years time, someone would make a CoffeeScript REPL[1] with built-in functions mirroring the Linux shell[2]. Call it jssh or sh.js.

Just a few days ago, I saw a shell interpreter that had a method for bouncing in and out of Python with ease.[3] I'm sure the Javascript version isn't long behind.

[1] https://coffeescript.org/#overview

[2] https://www.npmjs.com/package/shelljs

[3] https://xon.sh/tutorial.html#python-mode-vs-subprocess-mode


> What if, instead of having to remember bash’s for loop syntax (or xargs), you could just write .map() and iterate over lines/execute commands that way?

But you can! The dot is spelled '|' of course, and 'map' for historical reason is called 'xarg'. There is no real lambda syntax nor closures though, everything is stringly typed.


Check out xonsh. I haven’t used it but it’s supposed to be a python/bash hybrid shell.

Xonsh is good, I’ve used it for a bit. I loved customizing but in the end I found the reliance on prompt toolkit unfortunate. It’s significantly slower than fish for example. Trying to hook into how search and similar stuff works is really hard — you end up having to hook into xonsh and then into prompt toolkit, and a lot of the source feels like it was cobbled together with a bunch of libraries.

But it’s fun to use, still. I might come back to it a few versions down the road.


eshell (https://www.gnu.org/software/emacs/manual/html_mono/eshell.h...) is a bit like that, but with Lisp.

You have not because you ask not.

https://xon.sh/


We can improve shells and terminals a lot.

Shell:

Currently shell code is limited to one language. If you have bash, you can only do bash. But we could imagine a shell that understands webassembly, and hence we can use it with many languages. We could even imagine tools to inline webassembly generation, so that you can code directly in your favorite language in the shell, and it gets transparently compiled and executed.

Terminals:

I use a combination of GUI and TUI all the time. I like my mouse. I wish there were a terminal that behaves more like a file browser, with back and next button, an address bar, and a way to temporarily switch the view from text to icons to select files with the mouse then enter a command for thoses. Some file operation should also be available from a right click on a file path.

Not every shell lover wants his hands on the keyboard all the time.


> Currently shell code is limited to one language. If you have bash, you can only do bash. But we could imagine a shell that understands webassembly, and hence we can use it with many languages. We could even imagine tools to inline webassembly generation, so that you can code directly in your favorite language in the shell, and it gets transparently compiled and executed.

We might even compile directly to native code, nay, automatically identify the format and pass it to the appropriate interpreter, and then provide an interface to call arbitrary modules that conform to a particular interface―

... and then expose it as a library function so the shell can use it, let's call it execve().


Since so many languages use # for comments, we could even have a special comment that finds the interpreter for you! If only we had something like that.

> I wish there were a terminal that behaves more like a file browser

Oh man, you are gonna love this. In Plasma 5, hitting F4 in a file browser toggles a pop-up terminal in the folder you're in. As you navigate the directory tree, the shell actually follows you - and vice versa when you type `cd`! Working directory is always kept synchronized. If you split the file manager into a two-pane layout (another great feature), the terminal working directory follows whichever pane has focus. And of course you can drag files into the terminal and it pastes the path.

It's basically exactly what you asked for, and it is indeed fantastic. Plasma 5 is fantastic. Light years ahead.


Nautilus in Gnome used to have that 8 years ago (https://launchpad.net/nautilus-terminal) so Plasma didn't invent anything here.

But unfortunaly they discontinued it, which is a shame because indeed it's a nice feature.

However there is a limit to this conccept:

- no quake mode

- no horizontal split

- no way to manipulate the terminal shape and sessions from another terminal

- keyboard shortcuts and config options are file explorer first, terminal second

- no way to hide the explorer part. I don't want the files to always be here.

- no shell integration. I want some status such as the git repot state or the virtualenv name to appear in the bar, and the shell to remove it automatically from the prompt if I'm in GUI mode.

All in all, I'd prefer a specialized terminal, that have some file explorer features, and a real file explorer on the side, without the terminal features.

But yes, it is a good start.


Sounds a lot like Norton commander - I think it also did the 'change directory without clearing the command line' trick

For the UNIX world you'd have Midnight Commander

> But we could imagine a shell that understands webassembly, and hence we can use it with many languages. We could even imagine tools to inline webassembly generation, so that you can code directly in your favorite language in the shell, and it gets transparently compiled and executed.

For a shell as an interactive command interpreter, I don't see the point of it. For the shell as a programming language, you can already use any other language in its place.

> I wish there were a terminal that behaves more like a file browser, with back and next button, an address bar, and a way to temporarily switch the view from text to icons to select files with the mouse then enter a command for thoses. Some file operation should also be available from a right click on a file path.

This sounds more like the domain of a shell than a terminal. A terminal has no concept of what's generating the stream of control codes. A shell on the other hand could easily implement functionality like this.


I remember there being this shell/terminal hybrid that was a really advanced TUI. The best way I can describe it is, it was a blackboard/whiteboard you could run commands on. So you could have multiple commands running, and see their outputs scattered across the board (you could move things around with the mouse). Also had features like exploring filesystem trees, and inline images (I think). Can't remember what it was called and Google isn't helping :(

The Acme editor is sort of like that. Text frames you can drag around and organize with the mouse. You can run commands that get their own frame for output, you can launch a shell in a frame and interact that way, you can browse directory structures, and of course you can edit files. I don't think it's what you're thinking of (Oberon, maybe?) but you might find it interesting: https://research.swtch.com/acme

There have been several attempts at merge GUI and TUI, but I can't remember any that looks like the one you describes appart from the inline images and fs tree exploring.


Why is web assembly a desirable target? Wouldn't it make more sense to use LLVM IR or something that can go down to native? It don't get why, if you're compiling down to such a low level anyway, you'd want to target a bulkier runtime like wasm.

I also don't really understand why you'd want more than one language in the shell, but I guess if you wa


There are a lot of things the address bar on my web browser does that would be useful in an interactive shell, I think.

This looks nice! I'm especially interested in the claims of performance.

I've also written an autojumper[0] (in rust) after being frustrated by performance issues in other autojumpers, among other reasons.

For mine, I've gone to the effort to write a test and benchmark harness, and I also ended up with about 10x faster than fasd/autojump[1].

I'm excited to benchmark pazi against z.lua, and if needed take some ideas to be even faster :)

[0]: https://github.com/euank/pazi

[1]: https://github.com/euank/pazi/blob/v0.2.0/docs/Benchmarks.md...


How does it differ from https://github.com/xen0n/autojump-rs ?

Fair question! I didn't know a rust rewrite of autojump existed!

I already benchmark pazi against autojump by itself, so adding in a benchmark against autojump-rs will basically be drop-in, and I do expect pazi will still be faster, but I'll see.

At a glance, the differences I see are the following:

* pazi has extensive integration tests and benchmark code

* pazi doesn't fork processes into the background like autojump's shell scripts do (and therefore autojump-rs does), which avoids a few races

* pazi's interactive selection (z -i) makes use of the terminal's alternate buffer to avoid blowing away your scrollback, which most jumpers don't bother with.

* pazi has a cooler name in my opinion :)

These differences are not all that major. pazi is definitely short on some features, and I don't blame you if you wish to use one of the others. I'll keep working on pazi because I like using it and I'm having fun working on it / optimizing it / testing it.


It's cool, but does the extra speed matter? My eyeballs cannot differentiate 0.5ms vs 5 ms. That said, I'm pretty happy with fasd.

Does pazi work on windows? That's a big benefit I see in Z.lua: cross platform/shell support.

It does not currently (only linux and macOS), but porting it over should be really easy!

The cross platform story for rust isn't as seamless as an interpreted language like lua, but it's still good enough that it's not a huge effort to support another platform or shell.

> cross platform/shell support

Shell support should be fairly similarly easy or hard between most autojump implementations.


Shells could be even more powerfull if recipes- aka workflows and troubleshooting would be shared as if learned.

You want to install something troublesome, and the shell suggests a solution command- or even several solution commands, mechanical turked away from other linux users.


Here is a step in that direction: https://github.com/tldr-pages/tldr

Since op is the github owner I guess this should be a Show HN? I'm not sure if this is anything for me. I guess I would have to put in more effort remembering if I accessed a directory before than to simply be able to use this... But have to take a look how fast this thing really is and what it can do and how it compares to ctrl+r and globbing

I tried it and it seems indeed faster than autojumper on my Macbook Air with bash. However, visually I don't see any difference, probably because other tools run on cd'ing to the next folder (probably git).

Also when I do `z doc` I expect to go to `~/Documents` like in autojumper, but in z.lua it jumps to a subfolder `~/Documents/projects`, which is annoying. Finally it does not seem to cycle through all matches when I repeatedly do `z proj` -- I like that about autojumper.


z.lua has multiple matching algorithms, the default one is simiar to z.sh, in your case, you may look into the enhanced matching mode, by:

    eval "$(lua /path/to/z.lua --init bash enhanced once)"
FYI: https://github.com/skywind3000/z.lua#enhanced-matching

Ah, great!

I can confirm z.lua feels really snappy compared to autojumper after disabling the git related stuff! :) So now I should find a way to make the git prompt faster.


I like this in principal. I’m pretty damn predictable at the command line and far too lazy to make shortcuts.

Same. I do make some aliases like status instead of git status but use them like 10% of the time. I mean I already know all the commands I need for my work, it seems like memorizing their short forms is the same amount of mental load. Also completions exist.

zsh has named directories:

  somedir=~/Development/subdir1/subdir2
  cd ~somedir



Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: