Eza: A modern, maintained replacement for ls
github.com
github.com
I've never understood taking that information away. I wonder if it's a consequence of infinite scroll or something.
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" .
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); }); })();
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;})
document.querySelectorAll("relative-time").forEach((el)=>el.replaceWith(document.createElement("span").innerHTML = el.title))
it hinders fast viewing of the data, when it is more than a small amount.
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.
For you. For some, you should not need to hover over exact dates to get humanized relative deltas.
/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.
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”
https://addons.mozilla.org/en-US/firefox/addon/yyyy-mm-dd-gi...
It feels like the categories are:
"Today, Yesterday, This Week, This Month, Last Year, Big Bang"
I always try to use it when writing HTML.
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ti...)
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".
- What it says: 1 year ago
- What it is: 1 year and 10 months ago
I agree, they should provide the detailed time, then provide the days ago thing too, if they want to.
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- 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
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
I tried magefiles[0] for a while, but Task just works so much better and isn't Go-specific as heavily.
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 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.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 .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:
- ... viddy, a replacement for watch that includes history > 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`
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.
The GNU Coreutils mailing list is fairly busy also.
This project seems to be using the word maintained for the meaning of actively developed.
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
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.
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.
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.
Do you know where it's documented by any chance?
- 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.
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-...
function ls_on_cd --on-variable PWD
ls
endSadly, it also serves as constant reminder that ~ is a bloody mess because people still can't get used to .local/.share/.config.
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.)
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.
Having a file manager set to see all dotfiles by default, is like ripping all the doors off your closets.
~/.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.
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.
- ~/.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)
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
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?!
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.
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.
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.
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).
In fish shell you can also just type the directory path and press enter and it will change the working directory.
For others (like me) who use zsh:
function chpwd() {
ls
} _chpwd_hook() {
if [[ "$PWD" != "$PREVPWD" ]]; then
ls
PREVPWD="$PWD"
fi
}
PROMPT_COMMAND=(_chpwd_hook)
Goes well with shopt -s autocd
alias r='cd -' $ cd() { builtin cd $* && ls; }
$ cd /
bin boot cdrom dev etc home lib lib64 [...] cd() { builtin cd "$@" && ls; }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.)
So, `latest *.log`, etc.
Other than that, simple autocomplete does a lot of my ls work for me.
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 unixyUpdate: the ls command is stored at __fish_ls_command, so this is a `set -g __fish_ls_command lsd` in `config.fish`.
# 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
endhttps://ethanschoonover.com/solarized/
The list on the site lacks some entries. Konsole has it built in and i bet Gnome Terminal too.
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).
It's fine as an editor colorscheme, but nearly unusable as a terminal scheme.
- 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
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.
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.
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.
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".
It at least mentions it's existence (though no link or context)
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)I also have sl installed to encourage accuracy when running it…
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
Just kidding. But on a more serious note, why does he claim ls is not maintained anymore?
Since when you give up shared libraries, you give up on security upgrades without needing to rebuild the world.
> By deliberately making some decisions differently, eza attempts to be a more featureful, more user-friendly version of ls.
> A modern, maintained replacement for ls.
“Maintained” is referring to exa I think.
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.
> 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`:
The tag line certainly reads that way
(first line in the readme)
But `eza` is a variation of `exa`, and the latter is no longer maintained, AFAICT.
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...
So much more convenient than xargs.
It’s a good point, as the shell glob syntax is too limited.
Looks a bit obscure at a glance due to lack of spaces, but it's not that different from -exclude or "| grep -v".
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 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.
ls -lrt
eza -lrt (broken)
I wish it's 100% compatible to lsI 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"
} alias l="eza --all"
alias ll="eza --long --all --time-style=long-iso --group"ls works, is not mission critical (you know what I mean), and will always be around.
To avoid having to type that option every time, I have a bash alias for ls:
alias ls='eza -F --color=always'Btw good work, i always like modern gnu compatible tools
Happy so far.
Difftastic was another gem for me.
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?
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.
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 know though lsd has one annoying bug when using it for grepping: https://github.com/lsd-rs/lsd/issues/1052
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.
Problem solved.
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.
I would guess that ls has at least 50 different behaviors based on the switches.
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.
Challenge accepted!
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.
Probably the first time ever I hear about a community built on a freaking directory listing tool.
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.