[0] https://github.com/romkatv/powerlevel10k [1] https://fishshell.com/
Fish on the other hand has stuck, and I'm still discovering nifty new built in features, like the fact that if you type `kill`, you can tab-complete on process names, so like if I want to kill emacs, I can type `kill ema<tab>` and select from the following:
> kill ema
3296 (.blueman-applet) 3595 (.blueman-tray-w) 9324 (emacsclient) 9327 (emacs) 9557 (emacsql-sqlite)
If there's only one match it completes the PID for you, and of course if you start typing a PID and press tab it shows the process names along with the potential completions.I use starship for prompt customization, which is nice because my config transfers just fine from bash over to fish.
You can even disable verbose mode via zstyle, should you be the type of person that likes a simple pid list like bash's completion project provides. To me this level of customization is the main feature zsh provides, but not everyone incessantly turns every knob they see.
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
source /Users/wyclif/.config/broot/launcher/bash/br
This gives me the best of both worlds.For all the rest, perhaps give https://github.com/edc/bass a try.
Don't even change your default shell with chsh ,rather just point your terminal emulator to launch fish
Nearly everything I want, fancy autocompletion, syntax highlighting, git-aware prompt just worked out of the box.
For those that don't work right away, just type `bash` to enter bash shell, run the command return back to Fish.
If a significant part of your day is spent copying CLI command from the internet, then yes, perhaps Bash is a better choice for you.
I've been using zsh/omz with a customized powerlevel10k for years now and I see fish mentioned all the time but I didn't really find a compelling reason to try it out for myself.
I could probably get Zsh to do all the same stuff I would want fish to do out of the box, but it would make reading through and reasoning about the shell scripts more difficult for third parties to audit, who may not be familiar with either tool before they try it.
When I set up a new computer I can just install fish and starship prompt and I'm mostly done. My fish configuration file is just aliasing and sourcing configs from other software, it's been a while since I had to touch it.
fish functions are super easy to create on the fly from a command updating $path is fish_add_path {path here} setting global variable is easy set -Ux FOO bar adding -g makes it global
most of these require me to update my .zshrc and source ~/.zshrc as far as i am aware
And the website is amazing. “Finally, a command line shell for the 90s”
The fish scripting language is nicer (more logical) than the zsh one. That's because zsh needs to be Bourne-ish for historical reasons, and fish has decided to deviate from it. Existing sh, bash, zsh scripts will continue to work just fine. You can write new scripts in fish, or keep writing scripts in zsh or whatever.
When I first tried it over a decade back, IIRC on an 11" Air, each new session was probably closer to a couple seconds. I recall there were a couple plugins in particular that were major bottlenecks. Replaced those and got the init speed to about half that but it annoyed me enough to do a clean zsh setup.
It turned slow for a whole after I installed anaconda. If you use conda and your shell is slow, try commenting out the code that loads conda, because it's probably that.
nvm likes to slow things down too. Not as bad as conda, but I did add some code to delay load it.
Do you know how fish would prevent getting slowed down by external scripts in its configuration file? Or does it just not support those scripts perhaps?
Yes, I've had to get clear where they differ, but the Fish experience is that much better that it seems worth it.
I've considered replacing more my bash scripts with Fish scripts, but it seems Fish has a slower start start-up time for scripting (not that it matters most of the time) and is more designed for interactive use.
Now it’s even rewritten in Rust!
Then you get trapped by the utility and struggle when you land on some remote server's bash shell.
Performance? If you are talking about the startup performance, no it doesn't bother me. Again, nothing is slowly enough to cause noticeable delays in basic typing/editing and the bottleneck is almost never on them. (I regularly work on codebase of hundreds to thousands of files or more.) So I don't spend time worrying about saving a few seconds in total per day when I can use my brain elsewhere.
I had slow starts when I added nvm completion to .zshrc and .. maybe conda environment but that was unrelated to oh-my-zsh
All without using any “plugins” or ohmyzsh. All just within my .zshrc, and a few extra files that get “sourced” depending which computer I’m on. Only occasional copy-pasting a few things I liked from StackOverflow.
Basically instantaneous speed. Don’t even notice any performance penalties from all of the customization and styling.
I did have a performance issue early on, but I profiled my zsh startup time and saw 97.5% of my shell startup was consumed by NVM (node version manager), and another 2.4% was RVM (ruby). Switched to FNM and Chruby instead, and it was zippy.
And it’s all mine, so there are no “updates” to break anything. Throw it all in source control and you can keep improving it without risk of losing your previous working config.
But lately I've become really happy with just installing spaceship.
Sure, it doesn't look exactly like I want it to. But it shows git status.
Various features just "pop up" if I install the right things on the system.
My prompt is a 1 liner that shows your git branch as well as coloring up $ to be red or not based on if the last command failed. Coincidentally I just released a blog post today on coloring up your prompt based on if the last command failed at https://nickjanetakis.com/blog/color-your-shell-prompt-red-i... , there's solutions for both zsh and bash.
* Exporting shell variables such as HISTFILE isn't necessary, and can be unsafe. For example, if you decide to pop open unconfigured bash from within a zsh session it would intermingle its history on write.
* There is a smart keyboard subsystem that neatly manages terminal differences¹, making it much nicer compared to inserting {system,term}-specific escapes in to your config.
Hoping this comes across in the helpful spirit it was intended, not as nitpicky unwanted code review.
¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...
* For shell history I don't think I've encountered that issue yet. For example if I have zsh loaded and run `bash` and then within that bash session run `whoami` and exit bash, my `history` within zsh doesn't include the whoami command, only `bash`. Is there another workflow that would produce intermingled history?
* Ah, this is likely in reference to the home / end / insert / etc. key binds I added? I think I came up with those from following a 2007 blog post[0] which I found here[1]. Do you know what the nicer versions would be for those specific keys? The docs are coming up empty with specific examples and most Google results return the escaped references.
[0]: https://blog.andrewbeacock.com/2007/08/how-to-get-home-end-k...
[1]: https://stackoverflow.com/questions/8638012/fix-key-settings...
Of course, their config is the best according to the benchmark (and ohmyzsh is the slowest option), but DIY configs are also covered, particularly possible performance optimizations.
Would recommend using a PS1 generator, e.g. [1].
- CLI encourages automation (shell commands are easier to repeat/parametrize then GUI steps) - shell instructions are more git friendly than screenshots (even if a process can't/shouldn't be automated. Commands are easier to document in a reusable/updatable way) - CLI can be used to run tests in a way similar how CI does it (more reproducible)
Command line tools are easier to extend/combine with existing pipelines (rg,jq,xargs): read input from stdin/write output to stdout, report on stderr, return non-zero code on error. It enables you to create adhoc tools that you wouldn't bother otherwise (unrelated: LLMs also have this property by making your skill set much broader (though very shallow with current LLMs)). Shell also has Forth-like property (compose with: retry, timeout, setuid, exec, xargs, env, ssh, etc) https://www.oilshell.org/blog/2017/01/13.html
For #1 this blog post has some good examples of quickly chaining together commands (though personally I rarely use xargs) https://drewdevault.com/2020/12/12/Shell-literacy.html
For #2 once you’ve got a command you like, maybe one that generates a metric, you can now re-run it with ease from your history, saved text file, or an alias. You could also share it with teammates.
Please correct me if there are other ways to achieve the above, shell is the only way I know
I mean, surely you already know?
Anything where feeding input between different tasks, or where you want to use regex, or similar things the cl will be superior.
The idea is to be able to use any computer/system/devices easily instead of one perfectly.
Same with computers and servers. I interact with a lot of them, but my primary computer that I use >80% of the time is worthwhile to optimize with some tooling that's not available on all the others.
rename s/_small// *_small.jpg
When you have the string ABCD_XYZ in 50 files but you need to change it to DEFG_UVW, how do you do that? perl -pi -e 's{ABCD_XYZ}{DEFG_UVW}' **/*(.)
When you need to move all the files ending '.png' into the directory 'PNG', and all the ones ending '.jpg' into 'JPG', how do you do that? mkdir JPG PNG;
for i in *.png *.jpg; mv $i $i:e:uStill wanting to try out fish and hopefully soon!
Ripgrep accept most basic flags that grep uses and is way faster (when searching for code under VC), and that makes using it very convenient, even before considering the features on top.
I would prefer that you also write your HN comments in Rust, if that's possible, for better performance and safety. In the future, there will only be Rust. You have to accept Rust into your life.
Soon a Rust userland will be table stakes.
The awesome level tab-completion and auto-completion are the firs things to notice about Fish. Also, overall cleaner syntax and a several nice built-in commands that don't ship with Bash.
I'm not sure what the use case for zsh and fish are, but I'm guessing it's different than mine.
(edit/update: apparently, judging by a quicky netbsd 10 vm install, you don't even need to explicitly "set -o emacs". /bin/sh does it by default)
alias ll='ls -lvX --almost-all --group-directories-first --human-readable'
I can sit at any machine and feel right at home.Zsh already has a module system (autoload), a prompt framework (promptinit), and Git integration (vcs_info) builtin.
I have a pretty extensive Zsh setup in vanilla Zsh: https://github.com/cbarrick/dotfiles
It consists of: - collection of plugins/themes - auto update - way to customize them
Everything could be done directly in .zshrc, it's just a bit more convinient
I have to admit that I don't find it more convenient.
It takes an ecosystem where things have a way of working, and establishes new conventions on top of those using a new set of environment variables. So if you know zsh, you don't know oh-my-zsh.
A vanilla zsh will feel very bare.
A vanilla oh-my-zsh will feel very feature rich.
If you end up configuring zsh anyways, I don't see the point at all.
¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...
setopt PROMPT_SUBST
HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000
PROMPT='%B%(?..%F{red}%?%f )%F{blue}%~ %F{green}%#%f%b '
RPROMPT='%B%F{red}$(git branch --show-current 2> /dev/null)%f%b'
And if you want autosuggestions: brew install zsh-autosuggestions
Then add the following to your ~/.zshrc: source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh PROMPT='%{%F{red}%}%~ %{%F{yellow}%}% › %{%F{reset_color}%}%'
Anything after (besides the path and the GPG setup) that is an add-on that I can remove and still function well. I've learned to live without Git info. But this is very personal and I have not been into active development for quite a while.Main culprits were language switchers (nvm, jabba, pyenv). Which I moved to lazy loading.
If I drop the ohmyzsh plugins startup time is 11ms. But, I want some quality of life.
There's a nice benchmarking command in the article if you want to test yours:
for i in $(seq 1 10); do /usr/bin/time $SHELL -i -c exit; done
A lot of people will tell you this is slow and you've got to use X,Y,Z instead. If you're new, I'd strongly recommend just sticking with this, it's much easier to configure.
Paired with zoxide and fzf for the zsh keyboard shortcuts are all I need to be very productive.
Starship.rs is very useful as well as a theme but pure and pl10k are also great.
{
programs.starship = {
enable = true;
};
programs.zsh = {
enable = true;
enableCompletion = true;
enableBashCompletion = true;
enableGlobalCompInit = true;
syntaxHighlighting.enable = true;
syntaxHighlighting.highlighters = [ "main" "brackets" ];
histSize = 100000;
# See `man zshoptions` for more details.
setOptions = [
# Remove duplicates continuously from command history (preserve newest entry).
"HIST_IGNORE_DUPS"
# Instantly share command history between all active shells.
"SHARE_HISTORY" # Alternative to: "APPEND_HISTORY", "INC_APPEND_HISTORY",
# Disable ^S and ^Z for less accidental freezing.
"FLOW_CONTROL"
# Save timestamp and duration of each command in command history.
"EXTENDED_HISTORY"
];
shellAliases = {
rm = "rm -iv";
ls = "ls -F --color=auto";
gs = "git status";
gd = "git diff";
gdc = "git diff --cached";
gap = "git add -p";
gl = "git log";
gpr = "git pull --rebase";
};
interactiveShellInit = ''
bindkey '^[[7~' beginning-of-line
bindkey '^[[8~' end-of-line
bindkey '^R' history-incremental-search-backward
eval "$(starship init zsh)"
'';
};
}
My .zshrc used to be bigger, but I've slimmed it down to see what I actually use from it.I think starting from Oh My Zsh or zprezto can be a good choice. Once you get a feel of what zsh can accomplish, eventually probably you’ll one day find it too slow and/or too complicated and then would switch to something like zim to only load the things you know is useful from then.
Does fish support something similar? If so then I could be encouraged to give it a whirl.
oh-my-fish is pretty much similar in capabilities and has a good assortment of themes.
All I used that came with zsh were git shortcuts like gc -m "comment", gst for git status which i just recreated in my fish config.
Removing omz, adding antidote and starship. feels (and measureably is) faster and snappier.