Hacker News new | past | comments | ask | show | jobs | submit login
Eza: A modern, maintained replacement for ls (github.com/eza-community)
291 points by alexzeitler 4 months ago | hide | past | favorite | 238 comments



One pet peeve of mine is "human readable dates", especially for a directory listing. If I'm scanning for something I copied into a folder yesterday amongst other things, I don't want everything to show "1 day ago" if I'm looking for something I did around 11am. I want the dates and times. That goes for forums like HN. Show me the date/time and also "7 hours ago" or whatever if you have to.

I've never understood taking that information away. I wonder if it's a consequence of infinite scroll or something.


I agree. GitHub does this too on commits. "foo.cpp modified last year." It makes no sense, at least without the ability to view additional datetime information.


You can hover over the date for an exact timestamp. Maybe someone can write a userscript to replace the relative dates to exact ones.


This bookmarklet (I prefer to do it on purpose, not by default) would do this on a GitHub page. It is easy to convert it to a userscript.

javascript:(function () { document.querySelectorAll("relative-time").forEach(function (el) { var p = el.parentNode; var t = el.title; var s = document.createElement("span"); s.innerHTML = t; p.removeChild(el); p.appendChild(s); }); })();


Shorter version

javascript:(()=> {document.querySelectorAll("relative-time").forEach((el)=> el.format="datetime")})()

based on docs at https://github.com/github/relative-time-element

you can also do other formats like

document.querySelectorAll("relative-time").forEach((el)=> {el.format= "datetime"; el.year ="numeric"; el.weekday=undefined;})


shortened version still using <span>, as that has better line wrapping:

document.querySelectorAll("relative-time").forEach((el)=>el.replaceWith(document.createElement("span").innerHTML = el.title))


Can’t hover on mobile


You can hover with a pen like the Galaxy S Ultra has. But it doesn't work.


the point is that you should not need to hover over the dates to get the exact ones.

it hinders fast viewing of the data, when it is more than a small amount.


Depends on the application and your personal preference. It's way "faster" for me to see a HN comment was posted "1 hour ago" than it is for me to see the absolute time string and do the math myself. Further, I don't care about the exact time a HN comment was made. I care about roughly how long ago it was posted so I know if the conversation is still going.


But if exact dates/time is shown you have the possibility to mentally subtract one hour from what the time is, and look for that.

With 1 hour/week/month/year you cannot go the other way, it is too vague.

But web pages and apps should provide a quick and easy way of changing between the too formats.


>With 1 hour/week/month/year you cannot go the other way, it is too vague.

It's not just too vague, it's impossible in general.

think about it, first, those who disagree.


yes, that's exactly what I said here:

https://news.ycombinator.com/item?id=41039675


> the point is that you should not need to hover over the dates to get the exact ones.

For you. For some, you should not need to hover over exact dates to get humanized relative deltas.


I’ve never looked at a datetime and thought to myself “if only I knew how long ago that was.” Are there really people like that?

And actually, if I saw the date of “2023-12-07,” knowing it was last December actually gives me more information than “eight months ago” — because I know that means around Christmas time last year, and I know what other things happened last December, such as what features we were launching, who the product manager was at the time, etc. If you just shouted a random number of months ago, I would then have to stop and think about the answers to those questions. Lots of my memories could be placed in an approximate month or at least a season, and those never change after the fact. Relative dates are constantly changing and my memory does not increment all its records every month (e.g. “I’ve now worked here 9 months. I’ve now worked here 10 months.” But I can tell you the month and the year I started working here.)

Relative dates are definitely a case of “just because we can do this doesn’t mean we should force everyone to use it”


so those of us who think differently from you are inhuman?

/jk

humans from long back, could, and still very much can, easily parse / grok those exact dates and do the trivial date arithmetic needed (just mentally, without even pen and paper, forget a calculator), in seconds, to figure out the deltas nearly perfectly, or at least close enough for their needs.

just because you cannot do it, don't think that plenty of others cannot (analogous to what you said to me above). I have interacted with different types and categories of people, of various educational levels and socio-economic backgrounds, from so-called "low" to so-called quite "high", for many years now, and I can tell you that even uneducated farmers, fishermen, bike and car mechanics, and other kinds of manual labourers that I have met and interacted with a good amount, can easily do these kind of calculations in just a few seconds, mentally. not necessarily all, but many of them can.


Huh, I never noticed that. There is a lot of sublety in HN's minimal formatting.


Yeah this makes it better, but I've found some sites that don't do that, blogs and news articles where it's impossible to find the date of published... Is it a SEO trick to make your content always relevant?


Well it will definitely help with caching. You only need to update the article every year or so.


That's still more than just using an exact date that never needs to be updated. Also that seems like something you would do client side anyway. ie. you send a timestamp that never changes and then have the client convert it to "X years/days ago."


Most people render the html on the server side and then you can just cache it wholesale.

You could cache the page itself or even the article itself (I'm not talking about browser cache, I'm talking about caching on the web server).

The idea being that you don't have to keep rendering or even hitting your DB for the content you just have a html fragment that you create once and cache and then serve. You'll only need to rebuild the content when the date expires so when "one year ago" becomes "two years ago" .


Often I want to see exact what time I made a commit to correlate it with some error code and it’s only giving it by day. Such a bummern


Particularly when many systems I've seen group the past three years into last year.

It feels like the categories are:

"Today, Yesterday, This Week, This Month, Last Year, Big Bang"


Gitlab considers everything older than 0.49 years to be "a year ago". Since it's July, that means commits from January 2024 are "a year ago" now!


So annoying, I wrote this extension some time ago to get rid of relative dates in github

https://addons.mozilla.org/en-US/firefox/addon/yyyy-mm-dd-gi...


Yes. If we are in the middle of the current year, modified last year could mean anything from half a year ago to one and a half years ago.


I wonder if sites could use the HTML <time> tag for this. They could choose the human readable format but still give us the time so that it could be replaced or overlayed with some extension.

I always try to use it when writing HTML.

(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ti...)


Yeah that is such an amazing anti-feature. And how do you deal with changes? Like, when does 1 day ago become 2 days ago? According to google it becomes two days ago after 48 hours. That means if you look at your phone after 47 hours it will say 1 day ago and you'll be tricked into it happening yesterday. Human readable my ass.

Or, you know the specific day because it was the day after your friends birthday or whatever. And you try to find a specific item, but you have to sift through an entire months of shit because all the information you get is "three months ago".


The intent make sense (humans are better at durations than with absolute timestamps), but the lack of granularity is ridiculous. It should be "1d 20h ago" or based on the dates in question maybe more or less granual. (It's a hard UX problem, but that just means that the program ought to know what the user wants. What's important to them. Are the searching for something? What patterns to highlight? Ie. if there's a directory with a 1000 files but only 2 old ones maybe put some emphasis on them, etc.)


I utterly hate this on iOS. Suddenly after an hour or something, you irretrievably lose the time on a notification. There’s not even some fiddly power user way to force it to show you.


This is a setting, you can change it to any other date format you want.


Yep, `--time-style`.


Yes, I hate that approach too. I think it started with either Web 2.0 startups (I was working with one at the time, that implemented that in their product), or with Google and suchlike companies around that time, in their general web apps or social media web apps.

I agree, they should provide the detailed time, then provide the days ago thing too, if they want to.


The same I feel, so I didn't bother to print human readable dates in my open source mlops project. xvc file list[0] prints times in the same format even if it changed a minute or a year ago.

[0]: https://docs.xvc.dev/ref/xvc-file-list


You can hover over the time on HN and get a timestamp.


Not if you are on a phone or similar device, which lots of people are. Important info like that should never be only accessible by hovering a mouse pointer that may or may not exist.


One thing I really like about all of the ago formats:

- What it says: 1 year ago

- What it is: 1 year and 10 months ago


There is also 'lsd' but I still prefer eza.

For everyone interested there is a lot of modern command line tools I nowadays prefer over the old stuff:

  bat - cat with highlight
  difftastic - better diff
  gdu - ncdu for ssds (disk space analyser)
  zoxide - modern cd
  fd - find alternative
  rg - ripgrep (grep)
  fzf - fuzzy finder
  jless - json viewer with mouse folding
  dra - download and install release assets
  lazygit - git TUI
  lazydocker - docker TUI
  yazi - file manager with image preview
  zellij - better tmux / screen
  starship - cross shell prompt config
Have fun


4 additional tools I use regularly:

- task, a Makefile alternative

- hyperfine, a benchmark tool

- vegeta, a load testing tool

- sd, a better, more intuitive sed

There’s also the JSON trinity:

- jq, the well know JSON processor

- jc, convert the output of many CLI tools to JSON

- gron, make JSON greppable


Task is _amazing_

I tried magefiles[0] for a while, but Task just works so much better and isn't Go-specific as heavily.

[0] https://github.com/magefile/mage


Justfile is my favorite. Anything that requires complexity I just use Zig build. I hate make with a passion. I could see why people stick with it after learning it for decades, but for the rest of us it is a nightmare.


I looked, just now, at all the Make alternatives mentioned: Task, Mage and Just.

Those first two are nowhere near as easy to read as Makefiles. The last one, Just, looks good, though.

At least Cmake files are easy to read, but many of these alternatives are just poor UI, compared to Makefiles. I mean, using YAML of all things and thinking it's some sort of improvement over Make syntax?

1. Mage is just insane. In what world is this:

    func Build() error {
        if err := sh.Run("go", "mod", "download"); err != nil {
            return err
        }
        return sh.Run("go", "install", "./...")
    }
More readable than this:

    build:
        go mod download
        go install ./...

2. Task - not just significant whitespace, but significant whitespace everywhere, due to a poor format (YAML). Look at the example given:

   version: '3'

   tasks:
     build:
       deps: [assets]
       cmds:
         - go build -v -i main.go

     assets:
       cmds:
         - esbuild --bundle --minify css/index.css > public/bundle.css

Compare with Makefile that does exactly the same thing:

    build: assets
        go build -v -i main.go

    assets:
        esbuild --bundle --minify css/index.css > public/bundle.css
These alternatives to "Make an easier Make" appear to not know about Make in the first place.


> due to a poor format (YAML).

That's just your opinion. I'll take YAML whitespaces over Makefile whitespaces any day.

> Compare with Makefile that does exactly the same thing

Good example in favor of Task, I prefer the explicitness :) Especially when the file starts to get big. You forgot the .PHONY by the way, I hope for you there's no build/ or assets/ folder where your Makefile is.

For a more useful comparison, with actual source dependencies and build target:

Makefile:

    GO_FILES = $(shell find . -type f -name '*.go')

    ./myapp: $(GO_FILES)
        go build -trimpath -o $@

    .PHONY: build
    build: ./myapp
Taskfile:

    tasks:
      build:
        cmds:
          - go build -trimpath -o ./myapp
        sources:
          - '**/*.go'
        generates:
          - ./myapp
Makefiles are incredibly terse, but that's not an advantage. I read my code more than I write it, so I favor explicitness .


> For a more useful comparison, with actual source dependencies and build target:

Makefile:

     GO_FILES = $(shell find . -type f -name '*.go')

     ./myapp: $(GO_FILES)
         go build -trimpath -o $@

     .PHONY: build
     build: ./myapp

 Taskfile:

     tasks:
       build:
         cmds:
           - go build -trimpath -o ./myapp
         sources:
           - '\*/*.go'
         generates:
           - ./myapp

Even in this example, what is PHONY needed for?

    GO_FILES = $(shell find . -type f -name '*.go')

    ./myapp: $(GO_FILES)
        go build -trimpath -o $@

Honestly, it's still simpler to read.

> Makefiles are incredibly terse, but that's not an advantage.

Brevity is not why I prefer Makefile syntax over YAML, readability is. The minute you start trying to do anything large in a YAML definition you're going to need special editor help to keep track of indentation, and even with that, a large tree is still going to be lost off-screen because the context of any node in the tree depends on seeing the lines immediately above.

With Makefiles, any node in the tree has immediate context on the same line (the dependencies) which makes it very readable to me. I really prefer:

    target: dep1 dep2 dep3 dep4
compared to:

    tasks:
      dep3:
        cmds:
          - ...
        sources:
          - ...
        generates:
          - ...
      dep2:
        cmds:
          - ...
        sources:
          - ...
        generates:
          - ...
      dep1:
        cmds:
          - ...
        sources:
          - ...
        generates:
          - ...
      target:
        cmds:
          - ...
        sources:
          - ...
        generates:
          - ...


One day I decided to design a Makefile alternative, but I wanted to use YAML to benefit from the standard syntax and JSON schemas. I quickly realized I was just reimplementing Taskfile with different key names.

I love Task because it completely fits my mental model, I can use all the Makefile features I like without relying on arcane syntax.


Those are all very nice! I've come to be a huge fan of just as a Makefile replacement for the common case where I'm not actually computing vast build dependencies.


hyperfine is absolutely brilliant. My go-to replacement for time.


Cool. Some new ones there. I usually use a script with dra to download my release assets to `$HOME/bin`

I also use `oha` (Load Testing), `btop` (better top), `rmlint` (find duplicates) and `cheat` (similar to tldr - short manpages).

There is a blog post / video that shows how to integrate fzf with git, bat etc... it's one of the best videos I've ever seen on terminal productivity:

https://www.youtube.com/watch?v=mmqDYw9C30I

This guy is bonkers - take a look at his other videos, too


  >   fd - find alternative
  >   rg - ripgrep (grep)
NOTE OF WARNING:

BY DEFAULT these ignores anything included in your `.gitignore` folder. So if you think it is a straight find replacement, you'll likely be surprised. fd discussion here[0]

Just make sure that when recommending people these tools that this is clear because if they don't read the docs (lol who does) they'll miss this part.

This is a pet peeve of mine. I wish the people that make these replacement coreutils (and others) would leave the defaults as very similar to the original tool. I do really like the new functionalities but if you market it as "an alternative" ("It is a simple, fast and user-friendly alternative to find") then they should respect the defaults of the original because it reduces new user surprise. I mean aliases exist... So it is better to have in your ~/.${SHELL##*/}rc file to have `alias fd='fd --ignore'` than `alias fd='fd --no-ignore'`.

Side note/pro tip: use `\command` if you want to use an unaliased version. An example of this is that I have `alias grep='grep --color=always --no-messages --binary-files=without-match` but this can sometimes be problematic because the color option can change the character representation so if you pipe this into `curl` you will get errors. This is not the case in all piping, but it is a shocking and confusing experience when you first encounter it. You can validate this by `echo "Hello world" | \grep --color=always "Hello" | hexdump` and then `!!:s^always^never`

[0] https://github.com/sharkdp/fd/issues/612


> I wish the people that make these replacement coreutils (and others) would leave the defaults as very similar to the original tool. I do really like the new functionalities but if you market it as "an alternative" ("It is a simple, fast and user-friendly alternative to find") then they should respect the defaults of the original because it reduces new user surprise. I mean aliases exist... So it is better to have in your ~/.${SHELL##*/}rc file to have `alias fd='fd --ignore'` than `alias fd='fd --no-ignore'`.

I never marketed ripgrep explicitly as an "alternative." But it would be entirely appropriate to do so. An "alternative" does not mean "has exactly the same behavior." You're confusing that with, "drop-in replacement that is bug-for-bug compatible."

If people such as myself working on these new tools had your mindset, then there would literally never be any room for improving the default behavior. Which just seems like a wild position to stake out to me. Defaults really matter, and other than performance, ripgrep's default ignore behavior is far and away the thing people consistently remark as their favorite feature.


This link also has a large list of additional tools I hadn't heard of but look interesting.

https://github.com/ibraheemdev/modern-unix



Gotta love Rust (in which most if not all of these tools are written).


I didn't find zellij to be better than screen. The tabs/screens are not numbered correctly so switching directly to them requires manually counting. A non-starter for me.


If you don't like the default tab bar, you can use the zjstatus plugin (https://github.com/dj95/zjstatus) to replace it with a customizable one that can show the tab index.


From memory the index is different to the position, so if you rearrange our delete tabs the numbers become meaningless. I submitted a PR but the developers wanted it to be a separate plugin for just this. I decided it wasn't for me.


As someone who defaults to lsd, is there any reason why you prefer eza to it?


I use du-dust over gdu, but otherwise my list is almost identical to yours.


Thanks. I will definitely try that out.


Great list! I would also add:

   viddy, a replacement for watch that includes history


GNU ls is maintained. I see commits affecting the ls.c file from 2024-06-24 and 2024-06-27; less than a month ago.

The GNU Coreutils mailing list is fairly busy also.

This project seems to be using the word maintained for the meaning of actively developed.


This is referencing 'exa', of which eza is a fork. Exa was unmaintained for about a year before it was marked officially deprecated by the only person with write permissions on the repository.

It has definitely been long enough now since the forking, where not everyone is aware of exa, and this language/intent is now far less clear. I see you are not the only one to comment on this, so I think it's time to update the phrasing.


No the maintained here means it is a maintained (replacment) with reference that it is a fork of exa which was a ls replacment that is not maintained anymore. It does not say that ls is not maintained.


Look at the title above. It only says Eza and ls. It says eza is maintained, which tells me the other,ls, is not maintained.

Doesn’t mention exa.

Yes it’s missing nuance if you don’t click through, but that’s a complete statement, and I wouldn’t expect people to click through to get more context


It's saying "modern, maintained", implying that ls is either not maintained (wrong), or ls is not modern (can be argued to be true). Only one of those two properties need to hold for the entire label to fit.


I agree with you that their usage of language is ambiguous and should be clear. I was just explaining the situation not defending the description.


Yes title is not clear so parent was just clarifying.


Side note: the English language is a dumpster fire, and it’s easy for these issues to happen.


I strongly suspect the title could be translated into numerous languages verbatim, without losing the unintended interpretation. It is so for a few languages I know.

You can try it with translation tools.

The problem is semantic: in any language whatsoever (I suspect) if we express the idea that X is a replacement for Y, and in the same sentence mention some attributes of X, it means that those attributes are relevant to qualifying X as a replacement, which implies that those attributes are lacking or inadequately present in Y.

Without heaps of prior context, it is an impossible interpretation that the X attributes are not actually lacking in Y, but in a previously attempted replacement Z.


Absolutely nothing in the confusion here is specific to English.

I don't know why you would try to take this opportunity to criticize English when this misunderstanding could be present in literally every other language.

Because there is nothing whatsoever here that is a case of linguistic confusion or vagueness -- it is a conceptual issue of comparing two items, applying an adjective to one, and leaving the reader to wonder what that implies about the other item.

And no, English is not a "dumpster fire". Every language has its pros and cons. But there is no language on Earth that is a "dumpster fire". There is absolutely nothing productive or good that can come out of blanket, utterly unfounded statements like that.


Correction: the English language is a dumpster.


Don’t comment based on just the title, please.


I clicked through the title, but mostly looked at code and example invocations and output.


My ls usage went down 100% after I switched to fish shell. The built in Alt + l command lists the directory contents. Very helpful! And also results in a cleaner shell history.


> And also results in a cleaner shell history

In Bash you can also keep the history cleaner by adding ls (or other commands) to the HISTIGNORE env var: https://superuser.com/questions/232885/can-you-share-wisdom-...


Nice tip. What got rid of most of my use of `ls` in fish was running `ls` automatically when you changed directories:

  function ls_on_cd --on-variable PWD
      ls
  end


Seems like that would strongly encourage me to keep my directories tidier.


It absolutely did for me.

Sadly, it also serves as constant reminder that ~ is a bloody mess because people still can't get used to .local/.share/.config.


Taking this opportunity to remind folks: if you're going to emit a config file from your program, check for $XDG_CONFIG_HOME and use what you find by preference. ~/.config is a decent fallback. Sticking it in ~? It's not the 1980s anymore, please, don't.


Config files are the lesser problem, although it's really, really, really useful for programs to realize that $XDG_CONFIG_HOME exists.

More importantly, please put your caches under $XDG_CACHE_HOME so they don't trash up my backups or git.

And if you're feeling really fancy, put all your runtime stuff in a separate dir in $XDG_RUNTIME_DIR so /tmp doesn't look like someone detonated a zip bomb in there. I want to use it for my temporary files and still find them, thank you very much.


So it's OK to hide the mess, by throwing everything from the living room into the closet, I guess?

Not to mention, in the old days, that stuff was modtly in dot files.

(Users install graphical file manager. User has file manager set to bizarrely show dotfiles by default. User gets mad at prior hidden "clutter". Now dotfiles hidden one dir down.)


> So it's OK to hide the mess, by throwing everything from the living room into the closet, I guess?

Yes? This is literally how every human in the world does it. You put your things, according to catrgories, into their respective room/cabinet. If somebody asks you where your sweaters are, you don't say "just search the ground", you say " in the closet".

Same thing here. You don't have to guess where files are, you know by convention.


My counterpoint was merely that ~/.<programname> hid things, unless you did weird things. Like explicitly ask to see all hidden things.

Having a file manager set to see all dotfiles by default, is like ripping all the doors off your closets.


I don't think it's all that weird, it's one of the first things I'd do in any file manager and I make sure Windows Explorer shows me system files too. If never had to interact with the hidden config it would be one thing, but I very often do and I don't want extra friction in getting to them.


You're completely missing the point.

~/.programname is an unorganized mess, where someone stuff their dirty laundry, their trash, their food and their passport into the same closet. It doesn't matter if the closet is open or not, nobody but the mentally ill hoarder who created the mess can navigate it.

~/.(local|share|cache) means people put their food in the fridge, their trash into the bin and their sensitive documents in a fire proof safe. Which means other people can take care of basic tasks like taking out the trash and creating backups of their sensitive documents.


~/.(local|share|whatever) means I have to search both the basement, the attic and the garage. For stuff i rarely need to touch so I forget every time where it was placed.

If it was only one place it would be great. If it was truly separated by config vs cache it would be great. The reality know though is that you have at least three locations where important config are stored, not counting those from package managers that have their own idea of this concept. Still, this mess is preferable to the even worse mess of hundred plumbing files spread on the living room floor.


The one thing I despise about local|share|config is I never know which one they're using or what kind of nested hierarchy they're using that means I might have to search for the company name first.

At least with the ~/.whatever system I can just start typing ~/.tool-name, hit tab and it'll show me the thing if it exists. If it's somewhere else I have to look it up.


It's not like ~/.whatever has ever been used consistently:

- ~/.mozilla/firefox, but: ~/.thunderbird and ~/.pki/nssdb (gonna keep you on your toes!)

- Java defaults to .full.package.name (on top of using .java, .openjfx, and others)

- Fontconfig uses `fc-*` for its tools. Naturally, its config file used to be in ~/.fonts.conf.d before they finally accepted standard directories

- arandr, as the name implies, uses .screenlayout

- The sooner the .net ecosystem decides if it wants to use ~/.dotnet or ~/.mono, the better (humble suggestion: ~/..net)


> The one thing I despise about local|share|config is I never know which one they're using or what kind of nested hierarchy they're using that means I might have to search for the company name first.

This really only applies to badly ported Windows software like Unity engine games. There should be no hierarchy, just ~/.{local/share,config,etc.}/$application And nothing stops badly behaved software from deciding to use ~/.$CompanyName or heck I have even seen ~/My\ Documents/$CompanyName


But that's disorganized!

I have a real filing cabinet. In it, I have folders.

I don't keep my backup car dongle in one folder, my car invoice in another, my warranty and info from dealer all in different folders. They're all in a folder with the car name on it.

The same for my fridge. The invoice, the manual, the warranty info, all in one folder.

It is much more disorganized to have a folder for manuals and put them all there. I have to find the one I want out of 50 such manuals. And if it is a warranty thing, then I need the invoice, and other papers.

Why would I want to keep associated things in different folders?!

You think it's a mess, but really it's not. It's organized for humans to find related things.

Before, I'd uninstall a program and delete its single dotdir. Done.

Now I have to hunt in a maze of madness to "get it all".

You cite some programs that didn't properly keep their data in a single dotdir, and use that as a reason why a single dotdir was bad?!


> You cite some programs that didn't properly keep their data in a single dotdir, and use that as a reason why a single dotdir was bad?!

No. It's literally the other way around. It's bad that they keep everything in a single dotdir, because now I have to poke through dozens of folders to see where they hide their caches and other bloated garbage that shouldn't be backed up or kept in git, and where between all that garbage they're hiding their config files.

If all caches go to ~/.cache, I can exclude them all with a single setting, and I can put all my configurations in git/backups by adding ~/.config.

Same as with /var/tmp vs /etc vs /var/lib; if I want everything thrown together into a single folder I can just go use Windows.


Unsettling concept tbh


> people still can't get used to .local/.share/.config

I'm one of those people... I don't want yet more hidden stuff in my home dir; I want less. My dream is to have zero hidden directories in my home. What I want is something really clean like this:

    $ ls -a ~
    . .. config fun local pro tmp
This is almost possible, thanks to XDG_ environment variables. But unfortunately many programs still use hardcoded names for the local userdirs.

If you want to get closer to that goal, the xdg-ninja [0] package can help you. Also, do something like "touch ~/.local ; chmod 000 ~/.local" to force programs that use hardcoded names to fail spectacularly (instead of recreating the hidden dir).

[0] https://github.com/b3nj5m1n/xdg-ninja


I do the same in bash, but it's a bit wordier:

  _chpwd_hook() {
    if [[ "$PWD" != "$PREVPWD" ]]; then
      ls
      PREVPWD="$PWD"
    fi
  }

  PROMPT_COMMAND=(_chpwd_hook)
Goes well with

  shopt -s autocd
  alias r='cd -'


Not strictly equivalent, but shorter (and should work with multiple shells):

  $ cd() { builtin cd $* && ls; }
  $ cd /
  bin  boot cdrom  dev  etc  home  lib  lib64 [...]


$* will break on directory names containing spaces and other bash "word" delimiters, use "$@":

    cd() { builtin cd "$@" && ls; }


Neat idea, thanks! So obvious in hindsight... Just need to add some logic to it so it doesn't output more than N files.

For others (like me) who use zsh:

    function chpwd() {
      ls
    }


Oh cool idea! But gosh I think I would hate that.. I typically know what files are in directories that I'm working in, and usually care more about the output of previous commands I've run. I feel like this would teach me to never change directories


When I want to cd I usually don't type cd. I use zoxide which is a modern autojump.

In fish shell you can also just type the directory path and press enter and it will change the working directory.


Also good practice


A word of a warning if you have folders with _a lot_ of files.


Ooo! Thank you! That is a nice tip! Stealing it right now. :)


Bash users: FYI you can bind shortcuts like this, too. I have my right hand home row keys bound to __bash_ctrl_n() (for e.g.), and various tools in my dotfiles override these functions (git, if installed, sets up __bash_ctrl_e() to run git status and git log).


Neat. Can you share the source of any of the functions you've bound to some of your keys?


Apologies for the slow response. They're not really interesting:

- ctrl+j => equivalent of 'ls -la' using exa/eza

- ctrl+k => git status followed by git log showing only current branch's commits (vs. tracked)

- ctrl+l => sometimes I'll manually bind this to 'git reset @~'

- ctrl+; => thinking I'll use this for calling fzf through my wrapper which sets up hotkeys for either `cd`/`$EDITOR`-ing the selected item

Point is to reduce typing of the commonly-used commands.

Somewhere in my shell profile/rc setup (I'm on Workman, not Qwerty, hence NEOK instead of JKL;):

    bash_functions=(
      "__bash_ctrl_n"
      "__bash_ctrl_e"
      "__bash_ctrl_o"
      "__bash_ctrl_k"
    )
    
    for bash_function in "${bash_functions[@]}"
    do
      if ! type -t "$bash_function" 1> /dev/null
      then
        eval "$bash_function() { echo \"$bash_function(): This function should be overridden/aliased\"; }"
      fi
    done
Then in my .bashrc (Note the leading space prior to `__bash_ctrl_x` - with Bash's `HISTCONTROL=ignorespace`, these keybinds won't pollute your history):

    bind '"\C-n": "\C-u __bash_ctrl_n\C-j"'
    bind '"\C-e": "\C-u __bash_ctrl_e\C-j"'
    bind '"\C-o": "\C-u __bash_ctrl_o\C-j"'
    bind '"\C-k": "\C-u __bash_ctrl_k\C-j"'
Then in my app-specific configs/dotfiles:

    __bash_ctrl_n() { git status; git log ..; }
Bonus: these Bash bindings can be cool for little QoL tricks, e.g. Ctrl+Y to rerun the last command with sudo.

    bind '"\e\C-y": "\C-usudo !! \C-j"'
Other good ones:

- Append `--help | $PAGER` and run

- Rerun last command and pipe into $PAGER (some terminals support viewing last command output in a pager without re-running it, e.g. Kitty)

Hope that helps.


This appears to run eza for me, probably because I've aliased ls to eza. So I'm guessing it's just running `ls`.


I realized most of my ls runs come right after `cd`, so I added these to my startup files. Now almost every `cd` does `ls` automatically:

    # bash, simple
    function cd() {
        builtin cd "$@" && ls -l
    }

    # fish, a bit more sophisticated
    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  # aka ls -l ...
        end
    end


I just use bash and tab tab all the time.


Yes! one full hand of mine is kept in reserve to keep hitting tab


For me, there are two principal cases of sorting in `ls` output: alphabetical when I'm trying to find something I don't know/ remember exactly, and mtime-based when I want to see the latest (or oldest) in a group of related files. I don't see how it could work with one shortcut.

Another thing is `ls -l` that's important when I need to understand file sizes and especially how symlinks are set up. Yet another is `ls -ld` which explains details about directories.

All these cases could be made more ergonomic, and maybe partly merged. But I don't see how I could compress them into one type of output that fits all purposes.

(My current fancy version of `ls` is `lsd`, but I still use the built-in `ls` a lot.)


To this end I made a simple script, `latest`, which is, essentially, `ls -lt $@ | head`.

So, `latest *.log`, etc.

Other than that, simple autocomplete does a lot of my ls work for me.


I know you're showing a rough example, but others might want to throw a `-d` in there so that folders don't get expanded. And put `$@` in quotations so spaced file names don't get interpreted as separate arguments.

i.e.:

    ls -ltd "$@" | head
edit: `-d` may be a bad choice. It also results in directories being listed first on my system, even with `-t` passed.

edit 2: That was an alias I had setup. Carry on with the `-d`.


    find -type f -printf '%M@ %p\0' | sort -zn | tail -z | sed -z 's/^[0-9.]* //' | ...
Ugh.. so unixy


I cannot find this shortcut in https://fishshell.com/docs/current/interactive.html.

Do you know where it's documented by any chance?


It's there, in Shared bindings: "Alt+L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed."


Ah, it was an L, I thought it was an I (eye). Thanks


I have been using fish for a long time and I didn't know about this. Thanks.


TIL! great tip, thanks. Now I just need to wire that shortcut up to `lsd` instead of `ls`.

Update: the ls command is stored at __fish_ls_command, so this is a `set -g __fish_ls_command lsd` in `config.fish`.


Also many shells come with greatly improved ls implementations built in, like that of nushell.


yes, but the good thing is that you don't have switch shells with this. I'm running nushell on windows, which is nice, but I haven't got it as concise with $env.config.table.mode = "none", it also doesn't feature the tree display


I just use mc and ctrl-O, to switch between shell and listing.


In bash/zsh you can easily setup fzf completions ctrl-r (for directory) and ctrl-t (for shell history)


history? atuin has been great.


I have a problem with all terminal tools that insist on using colors to distinguish between various file types or attributes etc ('ls' is often set up like that too for distros, but I simply delete the config which sets that, the default doesn't). I use a terminal background which is easy on my eyes, and those color schemes always include colors which clash with the background or makes them hard to see in other ways. In short - I don't want colors in my 'ls' or 'ls' equivalent output. I'm fine with what ls with '-AFC' gives me.


If tooling would simply use the Base16 Framework[0] instead of arbitrary colors from “256 color” or “RGB” color modes, this would be much less of a problem: the output would always be displayed with (presumably) readable colors defined by your terminal.

[0] https://github.com/chriskempson/base16

[1] https://tinted-theming.github.io/base16-gallery/


> the output would always be displayed with (presumably) readable colors

There are several obstacles that make this not the case in practice, unfortunately. Black on white and white on black (whatever hex colors those actually are) will look fine. But different applications will use the accent colors differently. For example, some might use black text on a colored background, and others may use colored text on a black background. Some tools even use “bright” colored text on a different colored background. This is masked in most cases by iTerm2’s “Minimum contrast” setting, but when I tried to design a color palette with good contrast with that setting off, I found it to be very difficult.


As a CLI tool author, I don't understand how I can use base16 to "theme" my tool's output. Can you point to some resources?


I'm not sure if eddyg had a different idea, but I think the following sums it up:

  - base16 is a specification of how different UI elements map to colors [1], and also some tooling, configuration files, etc. to automate setting this up for many different applications.
  - For a user to be able to use base16 with a tool, either:
    - Allow the user to set their preferred colors for UI elements at a semantic level, preferrably in a config file, and even more preferrably in a separate file that can be included into the main config file so that it's easier to automate (i.e. I have a separate `colors.sh` that is loaded in my `.zshrc`).
    - Let the user set their shell colors however they want (presumably using [2]), and use the ANSI shell colors (and a few more) according to the base16 style guide [1]. Some translation between shell colors and base16 colors will be necessary, e.g. base16 says that a language keyword should use the color base0E, which in [2] corresponds to ANSI shell color 13.
My impression is that the base16 specification is not sufficiently general for most tools to implement it in a totally unbambiguous way, but if users can set their own colorschemes with a config file, it's not hard for a user to come up with a base16-approximating colorscheme template file, from which other users can generate a config file that sets a specific base16 colorscheme.

[1]: https://github.com/chriskempson/base16/blob/main/styling.md [2]: https://github.com/chriskempson/base16-shell


I'm not sure that I fully understood the theming aspect but one point I think is that the standard 8/8 ANSI colors are presumably picked to be readable by the terminal theme itself, independent from your application.

So if you just use those in your application you don't know the actual colors that the user will see on their screen but you know that they will be something readable.


It’s the first 16 colors of the 256 set. Most current graphical terminals support the latter, but they only expose the first 16 in their configuration. So using them makes your software completely customizable. I believe the tty console only use the first 8.


I'm totally the other way around, I rely on colorized output heavily.

But! There's supposed to be a solution to this, set $NO_COLOR to some value. https://no-color.org

Totally reasonable to file a bug report against tools which don't check and respect that env variable.


30-odd years of using ls and this comment is finally the catalyst for me to start using -A instead of -a. Thank you!



You can use vivid [1], choose a proper theme that works for your terminal background and load the generated LS_COLORS variable into your shell.

[1]: https://github.com/sharkdp/vivid/


I work on VS Code. We have a feature for this exact problem that enforces a minimum contrast ratio of 4.5:1 via shifting the luminance of the foreground text by default https://code.visualstudio.com/docs/terminal/appearance#_mini... . This feature's in xterm.js so any terminal based on xterm.js can leverage this.

We actually got a bit of push back when this was released but I haven't heard anything for quite a while now that some time has passed and we have a FAQ for colors not being "correct".


Solarized is easy on the eyes and the colours are chosen for readability.

https://ethanschoonover.com/solarized/

The list on the site lacks some entries. Konsole has it built in and i bet Gnome Terminal too.


Pet peeve, Solarized makes no sense as a terminal color scheme, because it maps brgreen, brblue, bryellow, and brcyan to barely-distinguishable shades of gray. It just doesn't have enough colors in its palette to cover the range of colors that the authors of CLI tools expect your terminal to be able to display.

Also, Solarized's whole trick is that its colors are perceptually uniform in terms of lightness, and I think the results speak for themselves why we don't do this in practice. If you want a yellow that actually looks yellow and not a shade of puke brown, it needs to be brighter than the other colors (especially red, which needs to be darker than the other colors if you don't want it to look pink).


I’ve used solarised-light in my terminal for a few years. I really enjoy the colours, but you’re absolutely right, it is not actually terminal friendly. Many programs just write invisible text.


It also makes the baffling decision to make "bright black" darker than "black." Pretty much every other terminal colorscheme renders brightblack as a dark gray.

It's fine as an editor colorscheme, but nearly unusable as a terminal scheme.


It's not easy on my eyes. It looks washed out with too low contrast.


--color=never


I find it strange that the README does not mention at that `eza` is a fork of `exa`.


> eza features not in exa (non-exhaustive):

It at least mentions it's existence (though no link or context)


contributions welcome


Crediting people becomes awkward when it's done by outsiders though.


What’s with all these new versions of GNU utilities being built with the MIT license? Seems like there are a lot of them.


Rust users tend to permissively-license their code in general. I don't know if there are easily available statistics but almost everything on the Rust package repository (crates.io) is MIT or Apache-2.0; certainly the most popular libraries are.


The GNU project didn't invent ls. The GNU coreutils (including ls) were originally new versions of either proprietary (AT&T) or BSD licensed utilities.


Related: https://github.com/uutils/coreutils "Cross-platform Rust rewrite of the GNU coreutils"


Why `ls` replacement needs kerberos and ssh?

  ldd /usr/bin/eza
        linux-vdso.so.1 (0x00007f5238f5e000)
        libgit2.so.1.7 => /lib/x86_64-linux-gnu/libgit2.so.1.7 (0x00007f5238cfd000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5238cd0000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5238bee000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5238a09000)
        libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f52389b5000)
        libmbedtls.so.14 => /lib/x86_64-linux-gnu/libmbedtls.so.14 (0x00007f523897f000)
        libmbedx509.so.1 => /lib/x86_64-linux-gnu/libmbedx509.so.1 (0x00007f523895e000)
        libmbedcrypto.so.7 => /lib/x86_64-linux-gnu/libmbedcrypto.so.7 (0x00007f52388d3000)
        libhttp_parser.so.2.9 => /lib/x86_64-linux-gnu/libhttp_parser.so.2.9 (0x00007f52388c8000)
        libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f523882d000)
        libssh2.so.1 => /lib/x86_64-linux-gnu/libssh2.so.1 (0x00007f52387e6000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f52387c5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5238f60000)
        libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f52386ef000)
        libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f52386c2000)
        libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f52386bc000)
        libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f52386af000)
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007f5238000000)
        libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f52386a6000)
        libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f5238695000)
        libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f52385cd000)


That's a lot of dependencies for ls of all things


Typing eza is a pretty horrible three character combination on a qwerty keyboard. One advantage of ls is it’s a lightning fast set of key strokes. I guess you can alias, but that’s kind of weird (compatibility, etc).


I’ve had eza (and formally exa) aliased as ls, ll and lll since around 2015 and never hit a compatibility issue.

I also have sl installed to encourage accuracy when running it…


What is 'sl' ?


Steam Locomotive, an annoying little ASCII art film to punish you for typos. Funny exactly once.


As a Dvorak user, ‘eza’ seems like an improvement! (‘ls’ on a Dvorak layout is ‘p-’ on QWERTY; both keys on the right little finger.)


Can you elaborate on why aliasing is kind of weird?


You can alias it to whatever you want though.


You can, but that's a pain to set up and maintain everywhere. I avoid using aliases for that reason, it just makes me annoyed when I ssh into a machine and it's not there.

I'm not sure the meaning behind the name, but maybe they should have picked `eya` instead, that's nice and satisfying rather than the double pinky move :D


This is where an azerty keyboard shines.


I was a former exa user, and the z is next to x on my keyboard, wasn't a huge hassle for me


`command -v eza >/dev/null && alias ls="eza"`


this was my first reaction too


Who uses ls anyway? I tab-complete until it lists the files I need.

Just kidding. But on a more serious note, why does he claim ls is not maintained anymore?


I think they are not referring to ls, but to exa [0], which is not maintained anymore.

[0]https://github.com/ogham/exa


No, they definitely mean "ls":

> By deliberately making some decisions differently, eza attempts to be a more featureful, more user-friendly version of ls.


Yes, it is marketed as a better “ls”. I was commenting regarding “maintained” in:

> A modern, maintained replacement for ls.

“Maintained” is referring to exa I think.


Yes, exactly this. The original `exa`'s description is

> exa is a modern replacement for `ls`

and it seems `eza` very recently changed the README to match that, given the confusion.

At the time, emphasizing it was actively maintained (in comparison to `exa`) made sense, but by now, `eza` has about 5x more daily downloads than `exa`:

- https://crates.io/crates/eza

- https://crates.io/crates/exa


Right; since the sentence mentions ls, of course, it must be referring to something other than ls.

Like when your wife finds a sexier, more romantic replacement for you, of course she's not comparing anyone to you. (Nobody is sexier or more romantic than you.) She means sexier and more romantic replacement compared to the previous lover she's just broken up with.


We do not


> A modern, maintained replacement for ls.

The tag line certainly reads that way

(first line in the readme)


For some reason it became the norm to think that if some piece of software isn't updated regularly that it's inherently out of date.


For statically built executables, this might just be true.

Since when you give up shared libraries, you give up on security upgrades without needing to rebuild the world.


Or dynamically-linked binaries that are distributed via containers.


Professional Linux masters just use the `echo *` shell built-in


Of course `ls` is maintained, as a part of your shell or of coreutils.

But `eza` is a variation of `exa`, and the latter is no longer maintained, AFAICT.


Because he's deliberately confusing "maintained" with "actively developed" in order to insinuate that the existing tools is unmaintained.


The "maintained" refers to `exa`, which is also written in Rust.

Rust binaries are static, which means they need to be rebuilt when security fixes are published on one of their dependencies.

Without active development to at least update, the static binary becomes a liability.

On another note, the developers on exa did explicitly say the project was unmaintained:

https://github.com/ogham/exa/commit/fb05c421ae98e076989eb6e8...


IMO the killer feature of eza/exa is not the pretty colors but the git integration - being able to see the git status of individual files in a listing (ignored, modified, etc) is pretty handy.


Totally —- any idea why eza claims exa doesn’t support it? I know that’s wrong.


I don't know, I do recall exa was a little finicky about linking with libgit2 - maybe some distros didn't come with it linked by default.


Ah, good point.


Tangentially, does anyone know what happened to Ben Sago, the author of exa?


For a long time now, I have wanted all command line utilities to consider options --exclude <regex> and --include <regex> options, where the regex refers to paths. This is applied before they do any displaying or evaluation.

So much more convenient than xargs.


You can get something similar with shell globs, and ~not in zsh. e.g. *~*.c(.) to exclude all .c files (and only list files, not directories or anything else).

Looks a bit obscure at a glance due to lack of spaces, but it's not that different from -exclude or "| grep -v".


À la powershell’s Get-ChildItems!

It’s a good point, as the shell glob syntax is too limited.


For people reading this and trying it for the first time and going through nix problems (well I did at least), check your distro package repo instead for eza. You probably already have it.


Visually fancy, but personally it's way too "busy" for my brain.


Can definitely recommend eza (prev. exa). I've used it as an ls replacement for a long time with zero problems. If anyone's using nix home-manager, here's my config for inspiration:

    programs.eza = {
      enable = true;

      # In list view, include a column with each file's git status.
      git = true;
    };

    programs.bash.shellAliases = {
      ks = "eza";
      sl = "eza";
      l = "eza";
      ls = "eza";
      ll = "eza -l";
      la = "eza -a";
      lt = "eza --tree";
      lla = "eza -la";
    };


I will join others here to point out that information in readme is not presented the best way.

I am developer so I understand this, if you just take feedback from this post here and apply it, it will be much better.

- It is not fair to say ls is not maintained

- Clarify this is for of exa, I am familiar with exa, I wasn't sure what eza was.

- Give example how it can be used, alias ls="exa " for example, give few example of usage, not everyone is following your repo every day.

Thank you for work you've put into this.


It’s not saying that ls is not maintained.


    ls -lrt
    eza -lrt (broken)
I wish it's 100% compatible to ls


I keep `ls` un-aliased precisely because of this. I do keep these two aliases around:

    alias l="eza --all"
    alias ll="eza --long --all --time-style=long-iso --group"


Yeah that one's annoying.

I got used to a "recent" alias (Zsh):

  if (( $+commands[eza] )) {
    alias recent="eza --binary --octal-permissions --no-permissions --git -snew --icons=always"
  } else {
    alias recent="ls -rt"
  }


I just found this after I noticed support had stopped for exa.


Why is why I’ll never be using any of these as the default.

ls works, is not mission critical (you know what I mean), and will always be around.


How are people paging with these ls replacements? I wish with all the features it includes some guidance about which pager is suitable. more? less? something else? how does the pretty colors work with paging?


I use the --color=always option with eza. This allows it to be piped through less and still maintain the color.

To avoid having to type that option every time, I have a bash alias for ls:

  alias ls='eza -F --color=always'


I am gonna pioneering using this as a drop in replacement for "ls". If i am not back in some days, remember me as a pioneer.

Btw good work, i always like modern gnu compatible tools


Neat, it also works on termux, I like the tree output. Is there a parameter to just display the size, name and date format YYMMDD or rickdate for even shorter display, or can I hack it in the rust code? The permission and user column output distract me and take up space. With rust it can also be compiled to wasm and run on ios a-shell (which runs vim and python wasm and other smallish wasm's).


eza -l --time-style=+%Y%m%d --no-user --no-permissions


It looks like the nu-ansi-term crate hardcodes escape sequences. It would be more reliable to use terminfo or termcap as the sources of truth for which ones the tty supports.


I use lsd, because I like the name and it does what I want so far.


I actually installed it a few days ago, which is rare for me, I tend to be restrictive to a fault with configuring my environment these days.

Happy so far.

Difftastic was another gem for me.


Hints on bare ls, either GNU or BSD: - the -F flag give hints on items. Man ls. - never parse ls's output - color isn't always needed, see -F


MIT - immediate nope from me for my gnu/linux stacks, but it seems well made and I wish you well!


What's the point, though?

You still have to rely on POSIX and / or GNU tools in most scenarios, and if already knowing / using those, then why bother to switch to anything else?


I don't know how common my situation is, but I don't have any of those constraints. I have eza aliased to ls both on my daily driver and all of my work servers and it hasn't caused me a single problem.


The only time you have to care about GNU tools vs your own preference of tool is when writing scripts to run on computers running some Linux distributions, and per [1] you shouldn’t be using ls for that.

[1]: https://www.shellcheck.net/wiki/SC2045


Yes but if you work professionally as a software engineer, chances are that you don't only use your PC. Being that a server that you connect remotely to develop on, or a production system where you connect to investigate a bug, or the PC of a coworker you are helping, or getting inside a container, etc.

Getting to know and use a standard setup makes you efficient in that situations, that is also the reason why I learned to use vim (since vim or at least vi you can take for granted there is on every system).

The only concession that I make is the shell, since zsh is much more convenient to use than bash, even if every time I use a system with bash I of course write some code that works in zsh and have to remember that in bash you can't do it. That is annoying, but to me it's worth it to use a better shell, not worth probably for an `ls` clone.


My setup does not deviate from that. As the sibling comment points out, `ls` responds everywhere (even powershell on Windows), it's just nicer on my local machine.

Coworker machines are whole different issue though - most of them have American keyboards (I do not), most of them do not use editors with vim bindings etc.


I just type `ls, which uses eza when I’m on my own device and ls when I’m on an SSH server. What’s the problem with that?


Use cases are different. I bet I'm not the only one who runs ls manually on my command line a LOT more than I ever use it in scripts.


Seems quite similar to https://github.com/lsd-rs/lsd . How do they compare?

I know though lsd has one annoying bug when using it for grepping: https://github.com/lsd-rs/lsd/issues/1052



Well, eza certainly seems faster on my micro-benchmark as well, though in general I never have any performance issues with these tools. Btw, ls beats them both easily (in my single-directory test).

So features would be my main criteria, I guess. At least eza doesn't have that annoying bug I linked :).

Short comparison: - Eza doesn't have the lsd's piping bug - Eza has more different output from ls than I would like (by default) - Both have git support - Eza --hyperlink doesn't have "auto" mode so if I alias ls to it, ls | sed hacks will likely behave unexpectedly if I enable it: https://github.com/eza-community/eza/issues/703 and this also seems like an instance of it: https://github.com/eza-community/eza/issues/693 - Eza is slower to write than lsd :) - Eza has more options to change its behaviour than lsd

Overall I think the hyperlink issue is more severe than lsd's piping one, so I think I'll just keep using lsd for the time being.


I've used both, but settled on using `lsd`. While eza has slightly better performance, that difference doesn't usually matter for a `ls` alternative (unless you operate on very large directories) and `lsd` is nicer and feature rich.


Eza: A modern, maintained replacement for Exa ;-)


Not at three key strokes, it isn't!


`alias ls = "exa"`

Problem solved.


This also works on Windows, fwiw.


What happened to Exa?


I'm under the impression that ls doesn't do very much. I'd expect it to be a small wrapper around libc.

This is thousands of lines of rust with emphasis on community building and ongoing development.

There seems to be a disconnect between engineering effort and product here which doesn't totally make sense to me. I think I'll stay with ls.


eza's scope is much larger than ls's, and has tons of additional features.

And IMO, that's sensible: ls is primarily an interactive tool (basically all uses of it in shell scripts are wrong), so adding more features that help users to better/more easily make sense of their directory listings is a net benefit, even if it makes the tool somewhat slower.

Folder icons in the terminal may sound silly, but eza uses them to indicate empty folders, among others. Colour-coded file age/size columns make parsing a directory list faster. Git columns saved my many trips through gitignore / git status. And so on.

And even through not particularly fast fuse-over-network connections it's still faster than I can type, which is more than good enough for an interactive CLI tool.


Challenge: which of the letters a to z and A to Z are NOT switches that modify the behavior of ls?

I would guess that ls has at least 50 different behaviors based on the switches.


> which of the letters a to z and A to Z are NOT switches that modify the behavior of ls?

For GNU ls: e/E, j/J, V, K, M, O, P, W, y/Y and z are not used

It uses all the other upper and lower case letters, along with digit 1 and has a hand full of long options without a corresponding short one.

Edit: I double-checked the man page, I'm surprised how many are unused, I would have guessed that it uses all of them by now.


> For GNU ls: e/E, j/J, V, K, M, O, P, W, y/Y and z are not used

Challenge accepted!


> emphasis on community building

Probably the first time ever I hear about a community built on a freaking directory listing tool.


Definitely the first time I've heard ambition, features & especially community used as a slight.

Generally I think of most engineers I know in person as people receptive to improvements & gains. Yes they looks at costs/tradeoffs. But there feels like some strong rejectionistic / contrarianism / negativity that I wasn't expecting, that seems bizarre & antisocial to me, especially here as the top post.


ls is the archetypical example of unix gone wrong, and I think this was already widely discussed (and joked) about in early 90s (iirc unix haters had something about that). It should be just simple wrapper for readdir, but it grew into sprawling mess when it learned to stat the files too, which snowballed ls to have gazillion ways to handle all sorts of metadata


[flagged]


This is unnecessary, it's not advertising on Rust. The README directly explains why they describe `eza` as modern. It makes no mention of Rust or memory safety.

Personally, I use eza because of `--tree` and `--git`.


[flagged]


That reaction was your choice, not the project's.


fwiw we're glad we're scaring people like that away :p


You really shouldn't. You're adding to the stereotype that Rust developers are insufferable and not to be collaborated with. Scaring away good developers from your projects is a bad thing, not a good thing.


Yeah, you only need the true believers :p

Everyone else will be condemned to read and reread the latest C++ standard for all eternity!


Please don't post shallow dismissals, especially of other people's work. [...] Omit internet tropes.

https://news.ycombinator.com/newsguidelines.html


[flagged]


I would agree with you but in this case the author is catering to both types of users. Which is perfectly acceptable in my opinion. If they wrote eza to only accept UK spelling, then you'd have a stronger argument.

Personally while I use UK spelling all my tools will use color as an option flag.


I only looked at the repo home page. The license file was named LICENCE and the README used "colour." Looks like the author is Danish.




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

Search: