reddit / emacs
Help wanted: Zsh completion like Vertico+Orderless
varsderk · 2022-12-14 18:15
The great goodness of Emacs has tainted how I feel about my shell. I use Vertico+Marginalia+Consult+Orderless, and life feels awesome inside of Emacs. I go back to my pretty vanilla zsh shell and feel that it's a little… lacking.
I understand zsh's completion system is quite configurable. I'd love it if I could make completion inside of zsh feel more like how it behaves in Emacs. In particular:
- When I hit `tab` to complete something, I want to be able to hit the `down` key to start cycling through the candidates.
- When I find the candidate I want, `tab` should fill it in instead of moving to the next candidate.
- If I'm completing a path, after hitting `tab` whilst completing a directory, I should immediately see the contents of that directory, which I can then pick the file I want and hit `tab` again.
- Fuzzy completion ala [Orderless](https://github.com/oantolin/orderless) would be awesome: hitting `space` during completion acts as a pattern separator.
Does anyone have enough zsh-fu to know how to get something like what I described in the shell? I would prefer to do everything with configuration (i.e. no packages) but that's secondary to getting the behavior that I want.
Thanks in advance. :)
PhantomSeahorse · 2022-12-14 18:35
Probably better to ask in a zsh sub or Linux sub
varsderk · 2022-12-14 18:37
I figured other Emacs users would probably be pedantic like me about completion interfaces. :) You're probably right though.
I crossposted in the [zsh](https://www.reddit.com/r/zsh/comments/zly477/help_wanted_zsh_completion_like_verticoorderless/) sub. Any other subs you'd recommend I try?
trararawe · 2022-12-14 18:39
Have a look at https://github.com/Aloxaf/fzf-tab
paretoOptimalDev · 2022-12-14 19:44
Interestingly the same problem led me to conclude I should replace my shell usage with eshell or emacs solutions.
I think I've mostly succeeded, but that might be more difficult, not desired, or not worth it in your case.
varsderk · 2022-12-14 20:53
I recently discovered eshell and it is awesome. Some things don’t play nice with eshell though. (REPLs for various languages, etc) and I often use the terminal to get some work done.
paretoOptimalDev · 2022-12-14 23:03
> Some things don’t play nice with eshell though. (REPLs for various languages, etc)
I agree, I have a few fixes for those in order of ease:
- coterm.el just makes a lot of ANSI stuff work
- eshell-visual-commands and eshell-visual-sub-commands let me open others in vterm seamlessly
- better integration for repls with comint
> I often use the terminal to get some work done.
If you mean like for cp / rm / find type stuff I find eshell fully replaces and improves on those for my use cases.
Some of those links:
https://github.com/iostapyshyn/eshell-vterm
https://www.masteringemacs.org/article/comint-writing-command-interpreter
tangonov · 2022-12-14 23:11
I'd be curious to know how that's going. All of the Emacs shells/terms fail me in some way. Even vterm. I just move to another workspace and open up a couple of kitties instead. vterm is the closest to happy I have gotten but there are still update rendering problems with long lines and there's no emacs magic to be had. vterm also seems slow/laggy compared to a proper emulator.
tosstossytossy · 2022-12-14 23:14
I've found oh-my-zsh[1] and fzf-tab very helpful. In the past I've used PowerLevel10k[2] to cut down on the time needed to spawn a new shell. Though I've switched to starship[3] lately in anticipation of me changing to another shell in the future, which I've yet to do--however ,having the command prompt formatting in a shell-independent tool makes me happy, I'm willing to pay the start-up time.
On top of all that I wrap my shell sessions in tmux[4], occasionally making use of ob-tmux[5] to wrap sessions and record them as I might need to do. When I use a terminal session inside of emacs, I use vterm[6], which tends to be snappier and also allows me to connect my other shell sessions and use that should I need to copy or track things from there.
Within tmux, I use tpm[7] to install themes and plugins and to allow live-reloading my tmux config.
Here is the content of that file:
# This configuration file binds many vi- and vim-like bindings to the
# appropriate tmux key bindings. Note that for many key bindings there is no
# tmux analogue.
set-window-option -g automatic-rename on
set -g mouse on
set -g history-limit 1000000
## FZF for panes
TMUX_FZF_POPUP=1
TMUX_FZF_PREVIEW=1
TMUX_FZF_OPTIONS="-p -w 62% -h 38%"
TMUX_FZF_ORDER="session|window|pane|command|keybinding"
TMUX_FZF_PANE_FORMAT="[#{window_name}] #{pane_current_command} [#{pane_width}x#{pane_height}] [history #{history_size}/{history_limit}, #{history_bytes} bytes] #{?pane_active,[active],[inactive]}"
TMUX_FZF_LAUNCH_KEY="C-a"
# set prefix key to ctrl+a until I have time to adapt
unbind C-b
set -g prefix C-a
set -g escape-time 0
# split windows like vim
# vim's definition of a horizontal/vertical split is reversed from tmux's
bind - split-window -v
bind | split-window -h
bind S setw synchronize-panes
# move around panes with hjkl, as one would in vim after pressing ctrl-w
bind C-h select-pane -L
bind C-j select-pane -D
bind C-k select-pane -U
bind C-l select-pane -R
# resize panes like vim
# feel free to change the "1" to however many lines you want to resize by, only
# one at a time can be slow
bind H resize-pane -L 20
bind J resize-pane -D 20
bind K resize-pane -U 20
bind L resize-pane -R 20
# bind : to command-prompt like vim
# this is the default in tmux already
bind : command-prompt
# vi-style controls for copy mode
setw -g mode-keys vi
set -g default-terminal screen-256color
# Copy-paste integration
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel pbcopy
bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel pbcopy
bind-key -T copy-mode-vi MouseDragEnd3Pane send -X copy-pipe-and-cancel pbcopy
# Use vim keybindings in copy mode
setw -g mode-keys vi
# Start copy mode when scrolling up and exit when scrolling down to bottom.
# The "#{mouse_any_flag}" check just sends scrolls to any program running that
# has mouse support (like vim).
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"
## LINK TO CLONE tpm
# git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
#
# List of plugins
# Supports `github_username/repo` or full git repo URLs
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'tmux-plugins/tmux-copycat'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'tmux-plugins/tmux-open'
set -g @plugin 'tmux-plugins/tmux-urlview'
set -g @plugin 'tmux-plugins/tmux-online-status'
set -g @plugin 'tmux-plugins/tmux-logging'
set -g @plugin 'christoomey/vim-tmux-navigator'
set -g @plugin 'jimeh/tmux-themepack'
set -g @plugin 'yardnsm/tmux-1password'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-open'
set -g @plugin 'Morantron/tmux-fingers'
set -g @plugin 'sainnhe/tmux-fzf'
set -g @plugin 'laktak/extrakto'
set -g @plugin 'tmux-plugins/tmux-sessionist'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'rafi/tmux-pass'
set -g @plugin 'Morantron/tmux-fingers'
set -g @plugin 'dracula/tmux'
#set -g @plugin 'charlietag/tmux-themes'
#set -g @theme-loading-cpu-mem 'on' # [ on | off] , default: on
#set -g @theme-network-bandwith 'on' # [ on | off] , default: on
#set -g @theme-dark-mode 'on' # [ on | off] , default off
#set -g @theme-dark-mode-bindkey 'T' # [ -r T | M-s | -n F11 ] , this is for toggle theme dark mode, define yourself just like bind-key
set -g @pass-key 'P'
set -g @pass-copy-to-clipboard 'on'
set -g @pass-hide-pw-from-preview 'on'
set -g @continuum-save-interval '15'
set -g @continuum-boot-options 'iterm'
set -g @continuum-boot 'on'
#set -g @themepack 'basic'
run-shell ~/.tmux/plugins/themes/theme.tmux
# Initializes TMUX plugin manager.
# Keep this line at the very bottom of tmux.conf.
run-shell '~/.tmux/plugins/tpm/tpm'
Footnotes:
[1]https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/fzf
[2]https://github.com/romkatv/powerlevel10k
[3]https://starship.rs/
[4]https://github.com/tmux/tmux
[5]https://github.com/ahendriksen/ob-tmux
[6]https://github.com/akermu/emacs-libvterm
[7]https://github.com/tmux-plugins/tpm
bagtowneast · 2022-12-15 04:14
Don't use eshell to run a repl. Use a comint buffer with an inferior process. Many language modes come with a way to send code to a repl, and let you switch over to the buffer to interact with the repl directly.
[deleted] · 2022-12-15 04:21
[deleted]
deaddyfreddy · 2022-12-15 09:03
> REPLs for various languages
you may find `comint` interesting for this.
As for the cursed stuff, sometimes there are Emacs-native counterparts (like `proced` for `top`, `magit` for `tig` etc).
Also, I'm a big fan of [Detached](https://git.sr.ht/~niklaseklund/detached.el), it uses an underlying binary to interact with external commands, but does it better than native solutions.
cradlemann · 2022-12-15 13:28
I copy pasted this setup somewhere and it works almost like you describe it, except fuzzy completion
zstyle ':completion:*' completer _expand _complete _ignored _approximate
zstyle ':completion:*' matcher-list '' '' 'm:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._-]=** r:|=** l:|=*'
zstyle ':completion:*:*:*:*:descriptions' format '%F{green}-- %d --%f'
zstyle ':completion:*:*:*:*:corrections' format '%F{yellow}!- %d (errors: %e) -!%f'
zstyle ':completion:*:descriptions' format '%U%K{yellow} %F{green}-- %F{red} %BNICE!1! %b%f %d --%f%k%u'
zstyle ':completion:*:default' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' group-name ''
zstyle ':completion:*' menu select=2
zstyle ':completion:*' rehash true
zstyle :compinstall filename '$ZDOTDIR/.zshrc'
setopt AUTO_CD # Go to folder path without using cd.
setopt AUTO_NAME_DIRS # Any parameter that is set to the absolute name of a directory immediately becomes a name for that directory
setopt AUTO_PUSHD # Push the old directory onto the stack on cd.
setopt CDABLE_VARS # Change directory to a path stored in a variable.
setopt CORRECT # Spelling correction
setopt CORRECTALL
setopt EXTENDED_GLOB # Use extended globbing syntax.
setopt GLOB_DOTS # Do not require a leading ‘.’ in a filename to be matched explicitly.
setopt INTERACTIVE_COMMENTS # Allow comments even in interactive shells
setopt MAGIC_EQUAL_SUBST # All unquoted arguments of the form ‘anything=expression’ appearing after the command name have filename expansion
setopt NOTIFY # Report the status of background jobs immediately, rather than waiting until just before printing a prompt.
setopt PROMPT_SUBST # If set, parameter expansion, command substitution and arithmetic expansion are performed in prompts.
setopt PUSHD_IGNORE_DUPS # Do not store duplicates in the stack.
setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd.