Last command in same terminal - zsh

When, in Bash, I have two terminals open, each maintain its own history, so hitting arrow-up always presents the previous command entered in that terminal.
In zsh the history is shared, so arrow-up presents the last command entered in either terminal. I rather like that ctrl-R gives me the full, shared history, but is there a way to make arrow-up give me the last command from the active terminal?

What says setopt ?
Maybe you have the option SHARE_HISTORY set.
You can unset it with setopt no_share_history or unsetopt share_history.
For more options look in man zshoptions.

I can't help you directly, but in my terminals, the command history is one for one terminal, so it's behavior you will expect. Below I print out my .zshrc file. Please play with it. I run my terminals with Yakuake.
# The following lines were added by compinstall
bindkey -v
bindkey -M viins '^r' history-incremental-search-backward
bindkey -M vicmd '^r' history-incremental-search-backward
#http://grml.org/zsh/zsh-lovers.html
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
zstyle ':completion:*' completer _complete _match _approximate
zstyle ':completion:*:match:*' original only
zstyle ':completion:*:approximate:*' max-errors 1 numeric
zstyle ':completion:*' expand prefix suffix
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-suffixes true
zstyle ':completion:*' original true
zstyle ':completion:*:functions' ignored-patterns '_*'
zstyle ':completion:*:cd:*' ignore-parents parent pwd
zstyle :compinstall filename '/home/borys/.zshrc'
zstyle ':completion:*:(rm|kill|diff):*' ignore-line yes
autoload colors; colors
setopt autocd
setopt extendedglob
autoload -Uz compinit
compinit
# End of lines added by compinstall
# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=1000
SAVEHIST=1000
# End of lines configured by zsh-newuser-install
# opens txt files in vi
alias -s txt=vi
#shortcuts for going up in directories hierarchy
alias -g ...='../..'
alias -g ....='../../..'
alias -g .....='../../../..'
alias d="dirs -v"
setopt PUSHD_IGNORE_DUPS
setopt AUTO_PUSHD
DIRSTACKSIZE=14
alias findfn="find -type f -name "
alias duall="du -s ./* | sort -n| cut -f 2-|xargs -i du -sh {}"
#prompt theme
COLOR_RESET="%{$reset_color%}"
PS1="$fg_bold[black][%n#%m:$fg[blue]%~]
$COLOR_RESET%%"
PS2=$PS1
# PS1=[%n#%m:%2~]
# color stderr
exec 2>>(while read line; do
print '\e[91m'${(q)line}'\e[0m' > /dev/tty; print -n $'\0'; done &)
#show vi mode in prompt
function zle-line-init zle-keymap-select {
#fg_light_red=$'%{\e[5;25m%}'
# RPS1="$fg_light_red ${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
# RPS2=$RPS1
# PS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}
#[%n#%m:%2~]"
PS1="${${KEYMAP/vicmd/$COLOR_RESET}/(main|viins)/$fg_bold[black]}[%n#%m:$fg[blue]%~]
$COLOR_RESET%%"
PS2=$PS1
zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select
export SVN_EDITOR=vi

Related

How to make zsh keybind between emacs mode and vi mode?

I want to bind a key to toggle emacs mode and vi mode,which I use oh-my-zsh plugins(vi-mode).
I tried Is there a way to switch Bash or zsh from Emacs mode to vi mode with a keystroke?
I also try to bindkey like
bindkey '^[e' 'set -o emacs'
bindkey '^[v' 'set -o vi'
But it's not work for me.
Does any way to toggle vi/emacs or keybind to set keymap?
Thanks a lot !
bindkey is used for binding keys to ZLE widgets not any random command. So what you have guessed at is not going to work. You could write a custom ZLE widget to switch keymaps:
select-emacs() { set -o emacs }
zle -N select-emacs
bindkey '^[e' select-emacs
In practical terms, I wouldn't recommend this. If you want a hybrid approach, it is better to select emacs mode but bind a key to vi-cmd-mode. In fact Ctrl-X,Ctrl-V is bound to this by default. You might even bind the escape key to vi-cmd-mode - where emacs key sequences involve an initial escape press, that can mostly be replaced by Alt. If you're used to typing it with the actual escape key, you may be able to replace it by a custom widget in vi command mode.
I finally "found out" how to toggle vi and emacs mode with a singel key, e.g. [alt]+[i] in zsh
# in the .zshrc
# toggle vi and emacs mode
vi-mode() { set -o vi; }
emacs-mode() { set -o emacs; }
zle -N vi-mode
zle -N emacs-mode
bindkey '\ei' vi-mode # switch to vi "insert" mode
bindkey -M viins 'jk' vi-cmd-mode # (optionally) switch to vi "cmd" mode
bindkey -M viins '\ei' emacs-mode # switch to emacs mode
now you can toggle from emacs-mode to vi-mode and from vi-mode (both insert or normal mode) to emacs-mode

ZSH keeps putting backslashes in my pasted URLS

I have already tried the solution at How to disable zsh substitution/autocomplete with URL and backslashes, but this is no longer working.
If I paste a URL, it keeps putting backslashes. Very annoying.
For example:
https://www.google.com?test=sample1&test2=sample3
will become:
curl -X POST "https://www.google.com\?test\=sample1\&test2\=sample3"
Here's the top of my ~/.zshrc file:
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
DISABLE_MAGIC_FUNCTIONS=true
export ZSH=/Users/myuser/.oh-my-zsh
I have already tried to re-call the source, no luck. The only way I've been able to get around this is to open up a bash shell instead, which can be extremely inconvenient.
After search this worked for me
open the file ~/.oh-my-zsh/lib/misc.zsh
comment these lines below
if [[ $ZSH_VERSION != 5.1.1 ]]; then
for d in $fpath; do
if [[ -e "$d/url-quote-magic" ]]; then
if is-at-least 5.1; then
autoload -Uz bracketed-paste-magic
zle -N bracketed-paste bracketed-paste-magic
fi
autoload -Uz url-quote-magic
zle -N self-insert url-quote-magic
break
fi
done
fi
🌟🌟 the final result is 🌟🌟
autoload -Uz is-at-least
# *-magic is known buggy in some versions; disable if so
# if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then
# for d in $fpath; do
# if [[ -e "$d/url-quote-magic" ]]; then
# if is-at-least 5.1; then
# autoload -Uz bracketed-paste-magic
# zle -N bracketed-paste bracketed-paste-magic
# fi
# autoload -Uz url-quote-magic
# zle -N self-insert url-quote-magic
# break
# fi
# done
# fi
## jobs
setopt long_list_jobs
env_default 'PAGER' 'less'
env_default 'LESS' '-R'
## super user alias
alias _='sudo '
## more intelligent acking for ubuntu users
if (( $+commands[ack-grep] )); then
alias afind='ack-grep -il'
else
alias afind='ack -il'
fi
# recognize comments
setopt interactivecomments
Relative Links
https://github.com/ohmyzsh/ohmyzsh/issues/5499
How to disable zsh substitution/autocomplete with URL and backslashes

How do I make zsh compsys fallback to local files for commands?

I think the simplest example is that if a command does not exist, then invalid-command <TAB> will present a list of files that you can tab complete on.
If the command (and completion) does exist, then on exhausting the completions, hitting <TAB> will either produce the bell sound e.g:
prompt > yarn test <TAB>
Or it will result in - no more arguments - e.g:
prompt > yarn run test <TAB>
- no more arguments -
To produce the above behaviours I currently have the following:
zstyle ':completion:*' completer _complete _correct _approximate _files
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*:manuals.(^1*)' insert-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
zstyle ':completion:*' rehash yes
zstyle -e ':completion:*:approximate:*' max-errors \
'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
I had hoped that adding _files to the end of :completion:* it would fallback to the current files if no other completion was available, but it appears I was naive in this assumption? :)
I think I'd be able to go into the _command completion definitions and add this to each one individually, but as a general fallback this seems quite appropriate (and matches prior experiences).

How to add all tab completitions to my current command?

So I've typed a command (pacman -S perl-) and I hit tab and see that there are a whole bunch of completions (about 40), and I realize that I want to run every single completion (so I don't accidentally install from CPAN what is already a builtin).
How do I run all completions of a command?
BONUS: How do I run more than one and less than all of the commands (without typing them in individually)?
Example situation (the actual situation):
XXXXXXXXXXXXXXXXX ❯❯❯ pacman -S perl-<Tab> ⏎
-- packages --
perl perl-IPC-Run3
perl-ack perl-libwww
perl-Archive-Zip perl-Locale-Gettext
perl-Authen-SASL perl-LWP-MediaTypes
perl-Benchmark-Timer perl-LWP-Protocol-https
perl-Capture-Tiny perl-MailTools
perl-common-sense perl-MIME-tools
perl-Compress-Bzip2 perl-Mozilla-CA
perl-Convert-BinHex perl-Net-DNS
perl-Crypt-SSLeay perl-Net-HTTP
perl-DBI perl-Net-IP
perl-Digest-HMAC perl-Net-SMTP-SSL
perl-Encode-Locale perl-Net-SSLeay
perl-Error perl-Path-Class
perl-Exporter-Lite perl-Probe-Perl
perl-ExtUtils-Depends perl-Regexp-Common
perl-ExtUtils-PkgConfig perl-Socket6
perl-File-Copy-Recursive perl-Sys-CPU
perl-File-Listing perl-TermReadKey
perl-File-Next perl-Test-Pod
perl-File-Which perl-Test-Script
perl-Getopt-Tabular perl-TimeDate
perl-HTML-Parser perl-Try-Tiny
perl-HTML-Tagset perl-URI
perl-HTTP-Cookies perl-WWW-RobotRules
perl-HTTP-Daemon perl-XML-LibXML
perl-HTTP-Date perl-XML-NamespaceSupport
perl-HTTP-Message perl-XML-Parser
perl-HTTP-Negotiate perl-XML-SAX
perl-IO-HTML perl-XML-SAX-Base
perl-IO-Socket-INET6 perl-XML-Simple
perl-IO-Socket-SSL perl-YAML
perl-IO-stringy perl-YAML-Syck
Here is my own solution to deal with,
To apply matching for completion results.
To insert all the completion matches into the command line.
To activate menu selection and select the completion more than one.
To apply matching for completion results, it could be done with the _match.
Here is an example ~/.zshrc:
# below is same as the zsh default effect
# zstyle ':completion:*::::' completer _complete _ignored
zstyle ':completion:*::::' completer _complete _match _ignored
# I don't like expand-or-complete to <Tab>, so I moved it to <C-x><Tab>
bindkey '^I' complete-word
bindkey '^X^I' expand-or-complete
Now, it could be ok to use *s to get the effects like this:
% ls m*e* ;# I have some local files that matches the glob.
main.epro mem.c mem.pro modentry.c module.o modules.stamp
makepro.awk mem.epro mem.syms module.c module.pro
math.epro mem.o mkmakemod.sh module.epro module.syms
% git m*e*<Tab>
;# This prompts completions rather than expands the local files
;# like this:
% git merge
merge -- join two or more development histories together
merge-base -- find as good a common ancestor as possible for a merge
merge-file -- run a three-way file merge
merge-index -- run merge for files needing merging
merge-one-file -- standard helper-program to use with git merge-index
merge-tree -- show three-way merge without touching index
mergetool -- run merge conflict resolution tools to resolve merge conflicts
mktree -- build tree-object from git ls-tree formatted text
m*e*
To insert all the compliteon matches into the command line, it cloud be done with the all-matches. If you have the below snippets in your ~/.zshrc:
zle -C all-matches complete-word _my_generic
zstyle ':completion:all-matches::::' completer _all_matches
zstyle ':completion:all-matches:*' old-matches only
_my_generic () {
local ZSH_TRACE_GENERIC_WIDGET= # works with "setopt nounset"
_generic "$#"
}
bindkey '^X^a' all-matches
typing Tab then Control-x,Control-a inserts the completion matches to the command line.
For example:
% vim string.<Tab>
string.c string.epro string.syms
;# then hit <C-x><C-a>
% vim string.c string.epro string.syms
To activate menu selection and select the completion more than one, it could be done by customizing menuselect keymap.
(From zhmodules(1) 22.7.3 Menu selection)
zstyle ':completion:*' menu select=0
zmodload zsh/complist
bindkey -M menuselect "^[a" accept-and-hold
bindkey -M menuselect '^[^[' vi-insert
This activete menu selection for the completion results. During the menu selection is active, typing M-a (or Esc-a) inserts the selected entry and advances the "menu cursor" to next entry.
For example session:
% ls sig*
sigcount.h signals.h signals.syms signames.o signames1.awk
signals.c signals.o signames.c signames.pro signames2.awk
signals.epro signals.pro signames.epro signames.syms
% vim sig<Tab> ;# this lists the matches
sigcount.h signals.epro signals.syms signames.epro signames1.awk
signals.c signals.h signames.c signames.syms signames2.awk
;# hitting <Tab> second time, the "menu cursor" appears and
;# the first entry will be activated
;# Note: "[[]]" denotes the "menu cursor" here
% vim sigcount.h
[[sigcount.h]] signals.epro signals.syms signames.epro signames1.awk
signals.c signals.h signames.c signames.syms signames2.awk
;# then hit <M-a>(Esc a)
;# "sigcount.h" is now in the command line and
;# the "menu cursor" points "signals.c" now.
% vim sigcout.h signals.c
sigcount.h signals.epro signals.syms signames.epro signames1.awk
[[signals.c]] signals.h signames.c signames.syms signames2.awk
;# then <Tab><Tab>
% vim sigcount.h signals.h
sigcount.h signals.epro signals.syms signames.epro signames1.awk
signals.c [[signals.h]] signames.c signames.syms signames2.awk
So, you could select multiple entries in the completion results to hit M-a(or Esc-a) as you like.
Below paragraph is not bad to know.
In this expample configration, hitting EscEsc (we did bindkey -M menuselect '^[^[' vi-insert in the above snippets) while the menu selection is active, it allows us to interactively limit the completion result based on input patterns.
;# activate "menu selection" and hit <Esc><Esc>,
;# the "interacitve:" mode will be shown at this point.
% vim sig*
interactive: sig[]
[[sigcount.h]] signals.epro signals.syms signames.epro signames1.awk
signals.c signals.h signames.c signames.syms signames2.awk
;# hitting "*awk" while interactive is activetad,
;# it colud limit the completion to "sig*awk"
% vim sig*awk
interactive: sig[]
[[signames1.awk]]signames2.awk
sig*awk
I'm not sure I describe correctly, so here is the portion of the zsh doc for the menu selection's "interactive mode".
vi-insert
this toggles between normal and interactive mode; in interactive mode the keys bound to self-insert and self-insert-unmeta insert into the command line as in normal editing mode but without leaving menu selection; after each character completion is tried again and the list changes to contain only the new matches; the completion widgets make the longest unambiguous string be inserted in the command line and undo and backward-delete-char go back to the previous set of matches
-- zhmodules(1) 22.7.3 Menu selection
It could be fine to see also edit-command-line for dealing with quite big command line buffers.
Now on my debian system, I can get the below effect:
# apt-get install perl-*<Tab><C-x><C-a><C-w>
;# ⇓
# apt-get install perl-base perl-byacc perl-cross-debian perl-debug perl-depends perl-doc perl-doc-html perl-modules perl-stacktrace perl-tk
I've found a solution to my problem, and it gets the job done, but it's not the kind of solution that I want.
I selected the completion text on my screen (I'm using mintty) and copied it into my editor. I then reformatted it like so:
perl perl-IPC-Run3 \
perl-ack perl-libwww \
perl-Archive-Zip perl-Locale-Gettext \
perl-Authen-SASL perl-LWP-MediaTypes \
perl-Benchmark-Timer perl-LWP-Protocol-https \
perl-Capture-Tiny perl-MailTools \
perl-common-sense perl-MIME-tools \
perl-Compress-Bzip2 perl-Mozilla-CA \
perl-Convert-BinHex perl-Net-DNS \
perl-Crypt-SSLeay perl-Net-HTTP \
perl-DBI perl-Net-IP \
perl-Digest-HMAC perl-Net-SMTP-SSL \
perl-Encode-Locale perl-Net-SSLeay \
perl-Error perl-Path-Class \
perl-Exporter-Lite perl-Probe-Perl \
perl-ExtUtils-Depends perl-Regexp-Common \
perl-ExtUtils-PkgConfig perl-Socket6 \
perl-File-Copy-Recursive perl-Sys-CPU \
perl-File-Listing perl-TermReadKey \
perl-File-Next perl-Test-Pod \
perl-File-Which perl-Test-Script \
perl-Getopt-Tabular perl-TimeDate \
perl-HTML-Parser perl-Try-Tiny \
perl-HTML-Tagset perl-URI \
perl-HTTP-Cookies perl-WWW-RobotRules \
perl-HTTP-Daemon perl-XML-LibXML \
perl-HTTP-Date perl-XML-NamespaceSupport \
perl-HTTP-Message perl-XML-Parser \
perl-HTTP-Negotiate perl-XML-SAX \
perl-IO-HTML perl-XML-SAX-Base \
perl-IO-Socket-INET6 perl-XML-Simple \
perl-IO-Socket-SSL perl-YAML \
perl-IO-stringy perl-YAML-Syck
And pasted it back into my terminal after pacman -S.
I've said that this isn't the kind of solution that I want, and so I should mention the sort of solution I'm looking for.
I'm looking for something like pacman -S perl-* which looks like it might glob up all of the completions or something (It doesn't).

ZSH tab completion - don't fill in first file

If I have files "something1" and "something2" in a folder, how do I make ZSH's tab completion fill in only the common characters? For example, I would type:
som<Tab>
and I want it to fill in with "something", not "something1".
Current zstyles:
zstyle ':completion:*' special-dirs true
zstyle ':completion::complete:*' use-cache on
zstyle ':completion::complete:*' cache-path ~/.zsh/cache/$HOST
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion:*' list-prompt '%SAt %p: Hit TAB for more, or the character to insert%s'
zstyle ':completion:*' menu select=1 _complete _ignored _approximate
zstyle -e ':completion:*:approximate:*' max-errors \
zstyle ':completion:*' select-prompt '%SScrolling active: current selection at %p%s'
zstyle ':completion:*::::' completer _expand _complete _ignored _approximate
zstyle -e ':completion:*:approximate:*' max-errors \
zstyle ':completion:*:expand:*' tag-order all-expansions
zstyle ':completion:*' verbose yes
zstyle ':completion:*:descriptions' format '%B%d%b'
zstyle ':completion:*:messages' format '%d'
zstyle ':completion:*:warnings' format 'No matches for: %d'
zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
# zstyle ':completion:*:processes' command 'ps -au$USER'
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
#zstyle ':completion:*:processes' command 'ps ax -o pid,s,nice,stime,args | sed "/ps/d"'
zstyle ':completion:*:*:kill:*:processes' command 'ps --forest -A -o pid,user,cmd'
zstyle ':completion:*:processes-names' command 'ps axho command'
#zstyle ':completion:*:urls' local 'www' '/var/www/htdocs' 'public_html'
zstyle ':completion:*' hosts $(awk '/^[^#]/ {print $2 $3" "$4" "$5}' /etc/hosts | grep -v ip6- && grep "^#%" /etc/hosts | awk -F% '{print $2}')
zstyle ':completion:*:*:(^rm):*:*files' ignored-patterns '*?.o' '*?.c~' \
zstyle ':completion:*:functions' ignored-patterns '_*'
zstyle ':completion:*:*:*:users' ignored-patterns \
zstyle ':completion:*:scp:*' tag-order \
zstyle ':completion:*:scp:*' group-order \
zstyle ':completion:*:ssh:*' tag-order \
zstyle ':completion:*:ssh:*' group-order \
zstyle '*' single-ignored show
Adding this to ~/.zshrc works for me:
setopt noautomenu
setopt nomenucomplete
https://serverfault.com/a/447549
remove line:
setopt menu_completion
from your .zshrc
and it should work fine with filling unambiguous part first.
It works like that out of the box if you use Zsh's new completion system. Add this to your ~/.zshrc file (or to try it out, just paste it into the command line):
autoload -Uz compinit && compinit
bindkey '^I' complete-word
After this, if you have two files something1 and something2 in your present working dir, and you type
% file s
and then press Tab, it will complete to
% file something
Press Tab again and it will display
something1 something2
under the command line.
You can then keep pressing Tab to cycle through these two.
In your zshrc file (at ~/.zshrc) paste this line
zstyle ':autocomplete:*' insert-unambiguous yes
if previously it was set to no it changing to the above line will work.
Check out man zshoptions. It's pretty well organized so that all of the completion options are in a "Completion" section. I think that the option you're looking for is list_ambiguous. if so, you just need to add in the line
setopt list_ambiguous
to your .zshrc
Good news: this is totally doable, and you won't need to worry about zstyles. (I believe.) Bad news: it's a bit tricky to answer.
A great explanation of specific zsh completion options related to the problem you're trying to solve can be found in this specific section of the User's Guide to zsh.
Also, you can do a 'man zshoptions' and look for completion-specific options. The answer above mentioning list_ambiguous is part of the answer, but I don't believe it addresses the whole picture. A key question you'll need to ask yourself is "What do I want to happen after I hit TAB the first time and zsh inserts only the common characters?" You can have zsh do a lot of different things on the second TAB press or even the third. Using various combinations of the ZSH completion options can yield a wide variety of useful results. It all depends on what you want.
Good luck!

Resources