How to solve CTRL-t key binding issue for fzf? - command-line

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.

Related

How do I make zsh autocompletion remove trailing slash it returns?

I have a custom script that I pass an argument into that will create a directory in a specific folder and then cd to it, unless it already exists, then it just cd to it.
I added a zsh autocompletion that way if I want to use the command to just jump to a directory in that folder I can autocomplete the target folder and get there in less keystrokes. The only issue with my zsh autocomplete is that it leaves the tailing directory slash after the autocomplete. Is there any way to tell zsh to only return the name of the directory and leave the / off? The docs are long winded and my searching has not turned up anything useful.
Here is my zsh autocomplete
compdef '_path_files -W /home/me/dir1/dir2/folder -/ && return 0 || return 1' mycommand

Terminal errors - "zsh: command not found" when trying any command

I was adding a path to my zshrc file earlier on and after saving the file and re-opening up my Terminal, I've found that I am unable to use any command what so ever.
The error I get back on any command I type in is this:
No matter what I try typing in I get this error, I have not been able to reopen my zsh file either to remove the paths I added as there is obviously an issue with them.
Can anyone advise the best thing to do to fix this without having to reboot my entire OS?
Many thanks in advance
Use the macOS Finder to rename the .zshrc file to .Xzshrc or something.
.zshrc is in your home directory. One way to navigate to that directory is to enter Shift+Command+H.
Since the filename starts with ., it's a hidden file. To get Finder to display hidden files, enter Shift+Command+..
Now you can restart Terminal, and rebuild your .zshrc file, copying pieces from .Xzshrc as needed. The error is probably in a path assignment.
In NVM repository shows how to add source lines to correct profile file:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Source: nvm

launch sublime text 3 in terminal with zsh

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

Git Bash shell fails to create symbolic links

When I try to create a symbolic link from the Git Bash shell, it fails every time all the time:
ln -s /c/Users/bzisad0/Work testlink
Output:
ln: creating symbolic link `testlink' to `/c/Users/bzisad0/Work': Permission denied
The only thing it does, besides giving the error message, is create an empty directory named (in this case) testlink.
I don't see any problem with the ln executable. For instance, it is owned by me and marked as executable:
which ln
ls -hal /bin/ln
Output:
/bin/ln
-rwxr-xr-x 1 BZISAD0 Administ 71k Sep 5 11:55 /bin/ln
I also own the current directory (~, which is /c/Users/bzisad0):
ls -dhal .
Output:
drwxr-xr-x 115 BZISAD0 Administ 40k Sep 5 12:23 .
I have administrative rights, and I've tried opening the Git Bash shell with "Run as Administrator", but that makes no difference.
I've tried opening the Windows properties for ln.exe and setting the Privilege Level to "Run this program as an administrator" but that doesn't help.
I've gone into the Security → Advanced properties in Windows and made myself (rather than the Administrators group) the owner, but that doesn't fix anything either.
I'm at a loss. I don't know whether this error message is ultimately coming from ln, from Bash, or from Windows, or how I could possibly lack the permission. How can I get to the bottom of this?
It is possible, albeit extremely awkward, to create a symbolic link in MSysGit.
First, we need to make sure we are on Windows. Here's an example function to check that:
windows() { [[ -n "$WINDIR" ]]; }
Now, we can't do cmd /C, because MSysGit will fornicate with this argument and turn it into C:. Also, don't be tempted to use /K; it only works if you don't have a K: drive.
So while it will replace this value on program arguments, it won't on heredocs. We can use this to our advantage:
if windows; then
cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
ln -s "$target" "$link"
fi
Also: note that I included /D because I'm interested in directory symlinks only; Windows has that distinction. With plenty of effort, you could write a ln() { ... } function that wraps the Windows API and serves as a complete drop-in solution, but that's... left as an exercise for the reader.
As a thank-you for the accepted answer, here's a more comprehensive function.
# We still need this.
windows() { [[ -n "$WINDIR" ]]; }
# Cross-platform symlink function. With one parameter, it will check
# whether the parameter is a symlink. With two parameters, it will create
# a symlink to a file or directory, with syntax: link $linkname $target
link() {
if [[ -z "$2" ]]; then
# Link-checking mode.
if windows; then
fsutil reparsepoint query "$1" > /dev/null
else
[[ -h "$1" ]]
fi
else
# Link-creation mode.
if windows; then
# Windows needs to be told if it's a directory or not. Infer that.
# Also: note that we convert `/` to `\`. In this case it's necessary.
if [[ -d "$2" ]]; then
cmd <<< "mklink /D \"$1\" \"${2//\//\\}\"" > /dev/null
else
cmd <<< "mklink \"$1\" \"${2//\//\\}\"" > /dev/null
fi
else
# You know what? I think ln's parameters are backwards.
ln -s "$2" "$1"
fi
fi
}
Also note a few things:
I just wrote this and briefly tested it on Windows 7 and Ubuntu, give it a try first if you're from 2015 and using Windows 9.
NTFS has reparse points and junction points. I chose reparse points, because it's more of an actual symbolic link and works for files or directories, but junction points would have the benefit of being an usable solution in Windows XP, except it's just for directories.
Some filesystems, the FAT ones in particular, do not support symbolic links. Modern Windows versions do not support booting from them anymore, but Windows and Linux can mount them.
Bonus function: remove a link.
# Remove a link, cross-platform.
rmlink() {
if windows; then
# Again, Windows needs to be told if it's a file or directory.
if [[ -d "$1" ]]; then
rmdir "$1";
else
rm "$1"
fi
else
rm "$1"
fi
}
For my setup, that is Git for Windows 2.11.0 installed on Windows 8.1, export MSYS=winsymlinks:nativestrict does the trick as
The Git Bash shell may need to be run as an administrator, as by default on Windows only administrators can create the symbolic links.
So, in order to make tar -xf work and create the required symbolic links:
Run Git Bash shell as an administrator
Run export MSYS=winsymlinks:nativestrict
Run tar
A workaround is to run mklink from Bash. This also allows you to create either a symbolic link or a junction point.
Take care to send the mklink command as a single argument to cmd...
cmd /c "mklink link target"
Here are the options for mklink...
cmd /c mklink
Output:
Creates a symbolic link.
MKLINK [[/D] | [/H] | [/J]] Link Target
/D Creates a directory symbolic link. Default is a file
symbolic link.
/H Creates a hard link instead of a symbolic link.
/J Creates a Directory Junction.
Link specifies the new symbolic link name.
Target specifies the path (relative or absolute) that the new link
refers to.
If you want to create links via a GUI instead ... I recommend Link Shell Extension that is a Windows Explorer plugin for creating symbolic links, hard links, junction points, and volume mount points. I've been using it for years!
Link Shell Extension
Symbolic links can be a life saver if you have a smaller SSD drive on your system C: drive and need to symbolic link some bloated folders that don't need to be on SSD, but off onto other drives. I use the free WinDirStat to find the disk space hogs.
I believe that the ln that shipped with MSysGit simply tries to copy its arguments, rather than fiddle with links. This is because links only work (sort of) on NTFS filesystems, and the MSYS team didn't want to reimplement ln.
See, for example, http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html
Do
Grant yourself privileges to create symbolic links.
Search for local security policies
Local Policies/User Rights Assignment/Create symbolic links
Take a moment to scold Windows. "Bad OS! Bad!"
Profit
This grants you the privilege to create symbolic links. Note, this takes effect on the next login.
The next step is to figure out how ln is configured:
env | grep MSYS
We are looking for MSYS=winsymlink: which controls how ln creates symbolic links.
If the variable doesn't exist, create it. Note, this will overwrite the existing MSYS environment variable.
setx MSYS winsymlinks:nativestrict
Do not
Run your shell as an administrator just to create symbolic links.
Explanation
The error is somewhat self-explanatory, yet elusive.
You lack the appropriate privileges to run the command.
Why?
Be default, Windows only grants symlink creation rights to Administrators.
Cygwin has to do a song and dance to get around Windows subpar treatment of symbolic links.
Why?
Something, something "security"
¯\_(ツ)_/¯
Edit:
I just realized OP had admin rights. I leave this answer up, hoping it's useful to others.
Extending Camilo Martin's answer as you need to use the /j parameter switch for Windows 10; otherwise the call will just return "You do not have sufficient privilege to perform this operation."
This works for Git Bash 2.20.1.windows.1/MINGW64 (Windows 10) without administrator rights (if you can read/write both /old/path and /link/path:
original_folder=$(cygpath -w "/old/path")
create_link_new_folder=$(cygpath -w "/link/path")
cmd <<< "mklink /j \"${create_link_new_folder}\" \"${original_folder}\"" > /dev/null
For anyone who's interested in how to accomplish this in Windows 10 Git Bash 2.28.0.0.1:
You have to prefix the ln -s command with the MSYS=.. instead of executing export MSYS=.. first, namely it's just one command:
MSYS=winsymlinks:nativestrict ln -s <TARGET> <NEW_LINK_NAME>
Since this is one of the top links that come up when searching for creating symbolic links in MSYS or Git Bash, I found the answer was to add
set MSYS=winsymlinks:native when calling git-cmd.exe (I run ConEmu) or uncomment the same line in the msys2_shell.bat file.
I prefer PowerShell to CMD, and thought I'd share the PowerShell version of this.
In my case it consists of making symbolic links linking ~/.$file to ~/dotfiles/$file, for dotfile configurations. I put this inside a .sh script and ran it with Git Bash:
powershell New-Item -ItemType SymbolicLink\
-Path \$Home/.$file\
-Target \$Home/dotfiles/$file
Instead of symbolic links on Windows, I found it easier to write a small Bash script that I place in my ~/bin directory.
To start Notepad++ with the npp command, I have this file:
~/bin/npp
#!/usr/bin/bash
'/c/Program Files (x86)/Notepad++/notepad++.exe' $#
And I get the path syntax right by dragging and dropping the file from Windows Explorer into Vim.
The Windows command mklink /J Link Target doesn't seem to work any more.
git bash honors the symbolic links created by cygwin. The caveat is that the symbolic link not use, e.g., '/cygdrive/c/directory' and instead use '/c/directory'.

Oh-my-zsh hash (pound) symbol bad pattern or match not found

I'm quite sure is something dealing with my Oh-my-zsh configuration, but I can't figure out what it is.
When I use a "#" symbol in my git command (but on everything else too, like 'ls #2' for instance) I get 'bad pattern' error or 'no match found'
I guess is about counting something, but I can't find where to configure it.
I.E.
➜ demo git:(adlist) git push origin adlist#3
zsh: no matches found: adlist#3
or
➜ demo git:(adlist) git push origin #3-adlist
zsh: bad pattern: #3-adlist
Use single quotes:
git push origin 'adlist#3'
git push origin #3-adlist
In zsh # is used for pattern removal. See: http://zsh.sourceforge.net/Guide/zshguide05.html under the heading Standard forms: pattern removal
You can unsetopt EXTENDED_GLOB, and this should stop # being interpreted as a part of a pattern.
If you really want to keep most of the features of EXTENDED_GLOB, but want to disable # being used for patterns, then you can disable -p '#' (you have to single quote the # argument, so that it doesn't get expanded like a pattern). This certainly works in my zsh installation, version 5.7.1, even though it is not documented in zshbuiltins(1).
Open your zshrc file:
vi ~/.zshrc
Add into end of file:
unsetopt INTERACTIVE_COMMENTS
unsetopt BAD_PATTERN
Effect your file:
source ~/.zshrc
Restart your terminal and enjoy it.