Reading this and warp.dev's site [0], here's some stuff about Bash (and maybe other shells like ksh) people might find useful:
It has a "vi command mode" you can activate with `set -o vi`. It works exactly like you'd dream.
You can search your history with Ctrl-r. It's not "fuzzy" search, but it is "anywhere in the command" search
Vim's (and Neovim's) terminal let you manage the it like any other readonly buffer. You leave insert mode and you can jump around, copy, etc. as much as you like.
I bounced around for literally years between terminals, multiplexers, window managers, etc. Now I have `set -o vi` in my .bashrc and MacVim is my terminal (a close second is Vim in Kitty if you're on a Mac). I've had zero bugs with this setup, and make all my money this way. I'm also super productive, which is fortunate as I (clearly) spend way too much time on HN haha.
I also use `history | vim -` to search through the history in the context of other things I was attempting to do. Say, if I try some command and it does not work, chances are it's not the first time and I have the correct version on the line bellow :)
This one I use daily without thinking about it - it shares my bash history between screens and sessions on a given machine and extends it (grabbed from some corner of the internet):
# shares history between tabs with prompt_command
HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1 appends command to histfile
HISTFILESIZE=$HISTSIZE #2 sets max size
builtin history -c #3 clears current session history
builtin history -r #4 reads the updated histfile and makes that the current history
}
history() { #5 overrides build in history to sync it before display
_bash_history_sync
builtin history "$@"
}
PROMPT_COMMAND=_bash_history_sync
Sometimes I forget the name of git branches I've worked on lately. This displays them with dates, most recent at the bottom:
# for rails migrations and keeping test updated
alias migrate="rake db:migrate && RAILS_ENV=test rake db:migrate"
Something I should use more to track things I've done lately - this opens up vim at the end of a file in your home dir called did.txt, appends the date and puts cursor at the last line:
# didfile setup
alias did="vim +'normal Go' +'r!date' ~/did.txt"
Because sometimes you want to sudo an alias:
# trailing space in value expands aliases that come after, see: http://www.linuxcommand.org/lc3_man_pages/aliash.html
alias sudo='sudo '
And displaying the git branch in the prompt:
# this gets the git branch to display when I cd into a git repo
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\[\033[32m\]\$(parse_git_branch)\[\033[00m\]\$ "
Tip: Bash reverse search, because manually scrolling through your history is a nuisance.
How (OS X): CTRL+R, start typing a word from your command history. Press CTRL+R to cycle through matches, ENTER to execute, TAB to edit. If you want to add forward search to bash, you can re-map your key bindings in your bash profile with the following (maps to CTRL+T): bind "\C-t":forward-search-history
In Linux with bash (and probably other shells that are bash-compatible), you can use vi to edit any of the commands in your command history, and then execute the edited version.
Do this at the command prompt, or once in your ~/.bash_profile to make it permanent:
set -o vi
After that, you can search for any of the commands in your history, edit it, and then execute the edited command, by doing this:
At the prompt, type Esc once to get into vi command mode. Then you can press the k key repeatedly to scroll up through the command history, or (often easier) use the ? (search backward) vi command to search for a pattern to find a specific command. Once found, press v to edit it in a temp file. Then when you save and quit, the edited command gets executed.
The same technique works with emacs as the editor instead of vi, if you don't give the 'set -o vi' command, because the default editor for command line history is emacs. Also, if you have run 'set -o vi', you can switch the editor for commands back to emacs with 'set -o emacs'.
I was today years old when I learned about CTRL+R. I've always just done history | grep
Also, I use zsh which filters history when using up/down arrows to whatever you typed. So you can do "git" [up] [up] [up] to cycle through all recent git commands which is super useful.
I do that often myself. If you've written the command before, there's also vi mode for bash history, OR, even bash-completion package for some OSes that can give arguments for simpler commands. However, I see a couple minor limitations.
1. You're limited to binaries and executable scripts in your $PATH
2. Many commands do not have bash-completion support.
vi mode for bash, bash-completion are both innovations trying to tackle this optimization of workflow. I see tools like dmenu and slmenu as better ways to give richer UI and create/reuse workflows. GP's request for `allows fuzzy search of program names, tags and a short description` is highly doable in dmenu/slmenu if not already done [0]. Not so much with bash, vi mode for bash, bash-completion.
Those are great, here are a couple more i find very useful:
# Search for partial matches in bash history
# so $ <C-p> goes to the previous command but
# $ s<C-p> searches through history entries that start with s
"\C-p":history-search-backward
"\C-n":history-search-forward
# add a trailing '/' when tab completing a symlink
set mark-symlinked-directories on
Currently, I'll append a comment to a frequently used command for easy searching from my history. For a simple example, I can access `git diff ; git diff --cached # gitdiff` by pressing Ctrl+R and typing `# gitd`.
For commands I use frequently or that are clunky to maintain as one-liners, I'll convert them into functions in my bashrc.
This seems like the best of both worlds in many ways, or at least is a great third option to have.
* git + sql scripts
* simplenote (notes across devices) Semi-automation of pieces of my job captured in these notes.
* zapier if I'm trying to connect two web apis.
reply