ZSH keeps putting backslashes in my pasted URLS - zsh

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

Related

Changing a default Zsh completion function

I noticed that tab completion for the source command in Zsh tries to complete a LOT of files. Maybe everything in $PATH? I tried using a blank .zshrc file to make sure it wasn't anything in there.
ubuntu% source d
zsh: do you wish to see all 109 possibilities (16 lines)?
I did find this file that seems to control that: /usr/share/zsh/functions/Completion/Zsh/_source
#compdef source .
if [[ CURRENT -ge 3 ]]; then
compset -n 2
_normal
else
if [[ -prefix */ && ! -o pathdirs ]]; then
_files
elif [[ $service = . ]]; then
_files -W path
else
_files -W "(. $path)"
fi
fi
If I change the line in that last "else" statement from _files -W "(. $path)" to _files, it works the way I want it to. The tab completion only looks at files & directories in the current dir.
It doesn't seem like altering this file is the best way to go. I'd rather change something in my .zshrc file. But my knowledge of Zsh completions is a bit lacking and the searching I've done thus far hasn't led me to an answer for this.
Maybe everything in $PATH?
Yes, that is correct. It offers those, because source will search your the current dir and your $PATH for any file name you pass it.
To apply your change without modifying the original file, add this to your .zshrc file after calling compinit:
compdef '
if [[ CURRENT -ge 3 ]]; then
compset -n 2
_normal
else
_files
fi
' source
This tells the completion system to use the inline function you specified for the command source (instead of the default function).
Alternatively, to see file completions for the current dir only, you can type
$ source ./<TAB>

ZSH: Behavior on Enter

I realize, when I'm in my terminal, I would expect to press Enter on empty input to make a ls or a git status when I'm on a git repos.
How can I achieve that? I mean, have a custom behavior on Empty input -> Enter in zsh?
EDIT: Thanks for the help. Here's my take with preexec...
precmd() {
echo $0;
if ["${0}" -eq ""]; then
if [ -d .git ]; then
git status
else
ls
fi;
else
$1
fi;
}
On Enter zsh calls the accept-line widget, which causes the buffer to be executed as command.
You can write your own widget in order to implement the behaviour you want and rebind Enter:
my-accept-line () {
# check if the buffer does not contain any words
if [ ${#${(z)BUFFER}} -eq 0 ]; then
# put newline so that the output does not start next
# to the prompt
echo
# check if inside git repository
if git rev-parse --git-dir > /dev/null 2>&1 ; then
# if so, execute `git status'
git status
else
# else run `ls'
ls
fi
fi
# in any case run the `accept-line' widget
zle accept-line
}
# create a widget from `my-accept-line' with the same name
zle -N my-accept-line
# rebind Enter, usually this is `^M'
bindkey '^M' my-accept-line
While it would be sufficient to run zle accept-line only in cases where there actually was a command, zsh would not put a new prompt after the output. And while it is possible to redraw the prompt with zle redisplay, this will probably overwrite the last line(s) of the output if you are using multi-line prompts. (Of course there are workarounds for that, too, but nothing as simple as just using zle accept-line.
Warning: This redfines an (the most?) essential part of your shell. While there is nothing wrong with that per se (else I would not have posted it here), it has the very real chance to make your shell unusable if my-accept-line does not run flawlessly. For example, if zle accept-line were to be missing, you could not use Enter to confirm any command (e.g. to redefine my-accept-line or to start an editor). So please, test it before putting it into your ~/.zshrc.
Also, by default accept-line is bound to Ctrl+J, too. I would recommend to leave it that way, to have an easy way to run the default accept-line.
In my .zshrc I use a combination of precmd and preexec found here:
http://zsh.sourceforge.net/Doc/Release/Functions.html#Hook-Functions
I also find that the git-prompt is super useful:
https://github.com/olivierverdier/zsh-git-prompt

zsh - first tab completion with autocd

I am currently switching from csh to zsh I am writing a .zshrc trying to get all the options I am used to in this new shell.
I use autocd (to go into a directory just typing its name (without the cd command), and I wonder if it is possible that my first propose all the files existing in the current directory (like it's working in csh).
I am quite used to this way of having an overview of the files I can open or directory I can "autocd" into, before typing my command just pressing without anything written in my commandline yet.
Right now when I first press it does not trigger any completion mechanism but it just write an actual tabulation.
I did not find any solution yet, and if anyone has any magic options to get this results, feel free to enlighten me!
Thanks
I found a way!
No need for autocd, though this option exists in zsh
To put in your ~/.zshrc:
first-tab() {
if [[ $#BUFFER == 0 ]]; then
BUFFER="cd "
CURSOR=3
zle list-choices
else
zle expand-or-complete
fi
}
zle -N first-tab
bindkey '^I' first-tab
Thanks to this question: zsh tab completion on empty line
So press tab once and you will get "cd " and the existing directories.
Checkout man zshoptions for other existing options which could be useful
(setopt menucomplete could be useful to save a tab, but change behaviour for other completion as well.)
Here is another more complex variation.
It will list files on on an empty command line, and in the middle of any command.
It will list directories on on an empty command line.
It will list executables on on an empty command line.
It can be configured to prepend "cd " or "./" in those cases with a global variable.
export TAB_LIST_FILES_PREFIX
# List files in zsh with <TAB>
#
# Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
# GPL licensed (see end of file) * Use at your own risk!
#
# Usage:
# In the middle of the command line:
# (command being typed)<TAB>(resume typing)
#
# At the beginning of the command line:
# <SPACE><TAB>
# <SPACE><SPACE><TAB>
#
# Notes:
# This does not affect other completions
# If you want 'cd ' or './' to be prepended, write in your .zshrc 'export TAB_LIST_FILES_PREFIX'
# I recommend to complement this with push-line-or edit (bindkey '^q' push-line-or-edit)
function tab_list_files
{
if [[ $#BUFFER == 0 ]]; then
BUFFER="ls "
CURSOR=3
zle list-choices
zle backward-kill-word
elif [[ $BUFFER =~ ^[[:space:]][[:space:]].*$ ]]; then
BUFFER="./"
CURSOR=2
zle list-choices
[ -z ${TAB_LIST_FILES_PREFIX+x} ] && BUFFER=" " CURSOR=2
elif [[ $BUFFER =~ ^[[:space:]]*$ ]]; then
BUFFER="cd "
CURSOR=3
zle list-choices
[ -z ${TAB_LIST_FILES_PREFIX+x} ] && BUFFER=" " CURSOR=1
else
BUFFER_=$BUFFER
CURSOR_=$CURSOR
zle expand-or-complete || zle expand-or-complete || {
BUFFER="ls "
CURSOR=3
zle list-choices
BUFFER=$BUFFER_
CURSOR=$CURSOR_
}
fi
}
zle -N tab_list_files
bindkey '^I' tab_list_files
# uncomment the following line to prefix 'cd ' and './'
# when listing dirs and executables respectively
#export TAB_LIST_FILES_PREFIX
# these two lines are usually included by oh-my-zsh, but just in case
autoload -Uz compinit
compinit
# uncomment the following line to complement tab_list_files with ^q
#bindkey '^q' push-line-or-edit
# License
#
# This script is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this script; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA
More details in this post

Last command in same terminal

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

How do I require a minimum version of zsh?

I want to use a feature only present in newer versions of zsh:
[[ "$foo" =~ "regexp" ]] where regexp is a regular expression.
Is it possible to do this check?
Something like:
if [[ $ZSH_VERSION > 4.3.9 ]]; then
....
fi
Except that > won't work.
Ciao!
I just found is-at-least but I'm not sure if it is available in all/many versions of zsh.
Usage:
autoload -U is-at-least
if is-at-least 4.3.9; then
....
fi
It's described in zshcontrib.
Ciao!

Resources