Getting this error _setup:37: compstate: assignment to invalid subscript range when trying to navigate to a previously visited directory using zsh-z that has worked before.
What is zsh-z?
Zsh-z is a command line tool that allows you to jump quickly to directories that you have visited frequently in the past
The problem is fixed when I type this into my terminal source ~/.zshrc does anyone know a workaround where it all works without me typing anything into the terminal when I have restarted my computer? Anyone had this issue and knows how to solve it?
did you use an alias for "z" maybe?
if so, change it to:
unalias z 2> /dev/null
z() {
[ $# -gt 0 ] && zshz "$*" && return
cd "$(zshz -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')"
}
Related
I'm having trouble getting the 'complete' function in the fish shell to behave as I would like and I've been searching for an answer for days now.
Summary
Essentially I need to provide tab directory auto-completion as if I was in a different directory to the one I am currently in. It should behave exactly as 'cd' and 'ls' do, but with the starting point in another directory. It seems like such a trivial thing to be able to do but I can't find a way to make it work.
Explanation
Example folder structure below
- root
- foo
- a
- dir1
- subdir1
- dir2
- subdir2
- b
- dir3
- subdir3
- dir4
- subdir4
I am running these scripts whilst in the 'root' directory, but I need tab auto-complete to behave as if I was in the 'foo' directory.
testfunc -d a/dir2/subdir2
Instead of
testfunc -d foo/a/dir2/subdir2
There are a lot of directories inside 'foo' and a lot of sub-directories within them, and this auto-complete behaviour is necessary to speed our process (this script is used extensively throughout the day).
Attempted Solution
I've tried using the 'complete' builtin to get this working by specifying the directory to use, but all this managed to do was auto-complete the first level of directories with a space after the argument instead of continuing to auto-complete like 'cd' would.
complete -x -c testfunc -a "(__fish_complete_directories ./foo/)"
Working bash version
I have already got this working in Bash and I am trying to port it over to fish. See below for the Bash version.
_testfunc()
{
local cur prev words cword
_init_completion || return
compopt +o default
case $prev in
testfunc)
COMPREPLY=( $( compgen -W '-d' -- "$cur" ) )
compopt +o nospace
return
;;
-d)
curdir=$(pwd)
cd foo/ 2>/dev/null && _filedir -d
COMPREPLY=( $( compgen -d -S / -- "$cur" ) )
cd $curdir
return
;;
esac
} &&
complete -o nospace -F _testfunc testfunc
This is essentially stepping into the folder that I want, doing the autocompletion, then stepping back into the original folder that the script was run in. I was hoping this would be easier in Fish after getting it working in Bash (I need to support these two shells), but I'm just pulling my hair out.
Any help would be really appreciated!
I am not a bash completions expert, but it looks like the bash completions are implemented by changing directories, running completions, and then changing back. You can do the same in fish:
function complete_testfunc
set prevdir $PWD
cd foo
__fish_complete_directories
cd $prevdir
end
complete -x -c testfunc -a "(complete_testfunc)"
does that work for you?
I recently found this command line tool called fzf. I installed it according to the instructions and it does work, except for the CTRL-T key binding. Even though, I installed the special stuff with the key bindings as per their instructions, and I also tried installing fzf downloaded from the git repo as opposed to via homebrew, all the CTRL-T key binding does, still, is swap the last two characters.
I found this discussion about this, but none of the answers offered worked for me.
edit: you can see it in the first video here what I want to achieve.
edit 2: I'm using the Terminal of MacOs.
I use zsh with Oh My Zsh on Mac.
If I put fzf before vi-mode in the plugin setting in .zshrc like
plugins=(... fzf ... vi-mode ...)
Ctrl-t does not work showing ^T. Ctrl-r does not work, either.
But, if fzf comes AFTER vi-mode like
plugins=(... vi-mode ... fzf ...)
no problem arises.
If you clone fzf from the repository it contains a file called fzf/shell/key-bindings.zsh which refers to
fzf-file-widget() {
LBUFFER="${LBUFFER}${__fsel}"
local ret=$?
zle redisplay
typeset -f zle-line-init >/dev/null && zle-line-init
return $ret
}
zle -N fzf-file-widget
bindkey "^T" fzf-file-widget
the Control-T keybinding. This is normally sourced by your .zshrc
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
which should contain its reference in .fzf.zsh:
source "$HOME/.fzf/shell/key-bindings.zsh"
If your keybinding does not work then your keybinding may be overwritten by your zshrc or may not be invoked by your zshrc.
If you are using zsh-vi-mode, then replace this line
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
with this
zvm_after_init_commands+=('[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh')
From zsh-vi-mode GitHub page
Psst! if you use fzf-tab, you might want to enable that also
zvm_after_init_commands+=('[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh && enable-fzf-tab')
I put the below script in my .zshrc and sourced it using source ~/.zshrc
if [ -x "$(command -v fzf)" ]
then
source /usr/share/fzf/key-bindings.zsh
fi
and now key bindings (CTRL-T, CTRL-R, and ALT-C) work for me.
got the above script from how to enable hotkeys for fzf
explanation
you have key-bindings.zsh inside /usr/share/fzf or a few directories deeper.
Above script only sources key-bindings.zsh if fzf is installed.
rest of the working is part of the key-bindings.zsh, which frankly I did not bother to
understand.
OS: Manjaro GNU-Linux
I have noticed CTRL-T does not work (in bash) when I have the "vi mode" enabled by set -o vi.
I managed to make the CTRL-t key combo work as desired. There was one step I had missed.
After installing useful keybindings and fuzzy completion with /usr/local/opt/fzf/install, I updated fzf.bash manually with [ -f ~/.fzf.bash ] && source ~/.fzf.bash. After restarting the Terminal, it now works.
Edit: Also, this line needs to be added to your .bash_profile or .bashrc: source ~/.fzf.bash.
I am basically looking for a way to do this
list=$(command)
while read -r arg
do
...
done <<< "$list"
Using sh intead of bash. The code as it is doesn't run because of the last line:
syntax error: unexpected redirection
Any fixes?
Edit: I need to edit variables and access them outside the loop, so using | is not acceptable (as it creates a sub-shell with independent scope)
Edit 2: This question is NOT similar to Why does my Bash counter reset after while loop as I am not using | (as I just noticed in the last edit). I am asking for another way of achiving it. (The answers to the linked question only explain why the problem happens but do not provide any solutions that work with sh (no bash).
There's no purely syntactic way to do this in POSIX sh. You'll need to use either a temporary file for the output of the command, or a named pipe.
mkfifo output
command > output &
while read -r arg; do
...
done < output
rm output
Any reason you can't do this? Should work .. unless you are assigning any variables inside the loop that you want visible when it's done.
command |
while read -r arg
do
...
done
I am trying to remove a certain element from a list in korn shell. It's working on my linux machine but the exact same code gives me an error on a solaris11 machine. I need a code that will work for both. It's probably because of different ksh versions but I would like to find a solution that works for both.
The code is:
#!/bin/ksh
MY_LIST="HELLO HOW ARE YOU"
toDel="HOW"
MY_LIST=( "${MY_LIST[#]/$toDel}" )
echo "MY LIST AFTER REMOVING HOW IS $MY_LIST"
On Solaris I get the following error:
syntax error at line 4 : '(' unexpected
Any suggestions?
Melodie wrote: Finally, I used 'Walter A' solution
Nice I could help.
Enabling you to vote for me and close the question, I post my comment as an answer.
MY_LIST=`echo $MY_LIST | sed "s/$toDel//"`
You'll probably need to spend some time with the ksh88 man page.
Without futher explanation:
set -A my_list HELLO HOW ARE YOU # note, separate words
toDel=HOW
set -- # using positional parameters as "temp array"
for word in "${my_list[#]}"; do
[[ $word != $toDel ]] && set -- "$#" "$word"
done
set -A my_list "$#"
printf "%s\n" "${my_list[#]}"
HELLO
ARE
YOU
Finally, I used 'Walter A' solution:
MY_LIST=`echo $MY_LIST | sed "s/$toDel//"`
I recently purchased a new MacBook and I am trying to re-configure my system.
The app is inside the Applications folder as 'Sublime Text.app'
I have edited the sublime.plugin.zsh file via other advice I found online to 'Sublime Text 3.app' as well as 'Sublime Text.app' with no luck on either:
elif [[ $('uname') == 'Darwin' ]]; then
local _sublime_darwin_paths > /dev/null 2>&1
_sublime_darwin_paths=(
"/usr/local/bin/subl"
"/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
"/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
"/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
"$HOME/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
"$HOME/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
"$HOME/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
)
for _sublime_path in $_sublime_darwin_paths; do
if [[ -a $_sublime_path ]]; then
alias subl="'$_sublime_path'"
alias st=subl
break
fi
done
fi
alias stt='st .'
I still get
zsh: command not found: st
I am simply at a loss on where to go next
I had the same problem with zsh and this did the job:
ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
Then you launch a open a file my_file.txt with Sublime:
subl ./my_file.txt
Don't specify any file if you just want to open Sublime. I hope this helps ;)
First, try to first launch the sublime binary manually (interactively) via zsh.
To do that, you'll have to discover where this binary is. There are two practical options here, choose what you are most comfortable with:
Check manually those listed binaries, see which of them exist.
Slightly modify your script to echo something inside your if:
if [[ -a $_sublime_path ]]; then
echo "Sublime found: $_sublime_path"
alias subl="'$_sublime_path'"
alias st=subl
break
fi
After finding the correct one, create the st alias in your .zshrc file:
alias st="/correct/path/to/subl"
If you don't find anything in the first step, then your original script is really not supposed to work.
Just moved to App in mac
Check your current path
echo $PATH
Add a sym link from Sublime App to one of your path. Choose /usr/local/bin for example
ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/sublime
Then back to terminal and run sublime. You should be open the sublime through terminal
To setup alias for mac users;
open ~/.zshrc using the below command
vi ~/.zshrc
Add the following alias
alias subl="'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl'"
run subl . command should work properly.
Official documentation: https://www.sublimetext.com/docs/command_line.html#mac
ZSH
If using Zsh, the default starting with macOS 10.15, the following command will add the bin folder to the PATH environment variable:
echo 'export PATH="/Applications/Sublime Text.app/Contents/SharedSupport/bin:$PATH"' >> ~/.zprofile