Vim: open a file based on a git command - neovim

Goal: map <localleader>n to open "$(git rev-parse --show-toplevel)/notes.md"
I know how to do mappings, and the above git command works fine on the command line. Marrying the two together in vim has been surprisingly hard.
I tried running vim commands like this: :e system("$(git rev-parse --show-toplevel)/notes.md"), but that just opens a file called "system(".
I'll take a vimscript solution, though a lua solution is slightly more preferable.

This line in my lua init file works. Backticks are the secret sauce:
vim.api.nvim_set_keymap(
'n',
'<localleader>n',
':e `git rev-parse --show-toplevel`/notes.md<CR>',
{ noremap = true, silent = true }
)

Related

Show current branch on terminal

Is there any way to show in Terminal of VS Code to show in brackets current branch? I saw it somewhere but not sure how it can be done. By some extension or whatever..
C:/myUser/project> git status
I would like to see it something like:
C:/myUser/project>(master) git status
Open zshrc file
open ~/.zshrc
Add this text in the end of zshrc file
autoload -Uz vcs_info
precmd() { vcs_info }
zstyle ':vcs_info:git:*' formats 'on branch %b'
setopt PROMPT_SUBST
PROMPT='%n in ${PWD/#$HOME/~} ${vcs_info_msg_0_} > '
Source zshrc file
source ~/.zshrc
For Linux Terminal
You can modify the PS1 variable. PS1 is a Bash Environment Variable that represents the primary prompt string which is displayed when the shell is ready.
You can achieve your result by modifying this variable with a script.
First, get the output of your current value of the variable by running
$ echo $PS1
Sample output:[\u#\h \W]$
Now you save the following code in a bash file(Remember to replace the initial string of export PS1 with the output of the above command).
#!/bin/bash
source ~/.bashrc
get_cur_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="[\u#\h \W]\$(get_cur_branch)\$ "
Let's say path of the file is "/home/samar/Documents/my_vs_script.sh"
Now change your VS code settings by adding the following lines in 'settings.json'
"terminal.integrated.shellArgs.linux": [
"--init-file",
"/home/samar/Documents/my_vs_script.sh"
]
Now each time you open a new terminal in VS code, script file "my_vs_script.sh" will execute and you get the desired output.
For Windows-Powershell
The solution above works well for the Linux terminal. But if you want to do it for another command-line shell-like Powershell, you can change the 'setting.json' to
{
"terminal.integrated.shellArgs.windows": [
"-NoExit",
"-Command", "c:/scripts/myscript.ps1"
]
}
where 'myscript.ps1' must have a function 'prompt' definition to add git branch to your prompt.
You can refer this question for your 'myscript.ps1' code.
You don't need to change 'Microsoft.PowerShell_profile.ps1'. Defining it in another file works too.
I hope it helps.

How can I make a function run every time cd successfully changes to another directory within sh on FreeBSD?

I'm using sh as my shell on FreeBSD but I want to be able to have a pretty prompt like the one bash gives me on Ubuntu. There are two things that the FreeBSD implementation of sh seems to lack as far as PS1 escape characters go:
The \w works but does not expand $HOME to ~, so this is something I have already hacked up myself
I can use PS1 to update the prompt on the terminal, but as far as I can tell it is not possible to use the PS1 variable to update the title bar as well. ESC and BEL fail to set the title as one would expect if they were using bash or ksh
Here is my .shrc file
update_prompt() {
case "$PWD" in
"$HOME"*)
pretty_pwd="~${PWD#*"${HOME}"}"
;;
"/usr$HOME"*)
pretty_pwd="~${PWD#*"/usr${HOME}"}"
;;
*)
pretty_pwd="$PWD"
;;
esac
case "$TERM" in
xterm*|rxvt*)
PS1="[$USER#\\h $pretty_pwd]\\$ "
;;
*)
;;
esac
printf "\\033]0;[%s#$(hostname -s): %s]\\007" "$USER" "$pretty_pwd"
}
update_prompt
So when I fire up a terminal or log in via ssh, it gives the pretty prompt that I like. But now I need this function to run every time that cd is executed and returns an exit status of 0.
I was going to use an alias that was something like:
alias cd="cd $1 && update_prompt"
but that was before I realized that aliases do not except arguments. How might I go about doing something like this?
You can use a function instead of an alias:
cd() {
command cd "$#" && update_prompt
}
Just put it into ~/.shrc. You have to use command here to let sh know that you are referring to the actual cd builtin command instead of the function you've just defined.
Refer to the sh(1) manual page for the details on how to make sh(1) source the ~/.shrc file when it starts:
Therefore, a user should place commands that are to be executed only at login
time in the .profile file, and commands that are executed for every shell
inside the ENV file. The user can set the ENV variable to some file by placing
the following line in the file .profile in the home directory, substituting for
.shrc the filename desired:
ENV=$HOME/.shrc; export ENV
I use this trick in my cd alias manager. Here's a link to the source code of the function: https://github.com/0mp/goat/blob/v2.5.0/libgoat.sh#L31-L57
You can do it with alias+arguments if you swap the commands:
$ alias cd="echo change; cd"
$ pwd
/nas
$ cd /
change
$ pwd
/
$ cd /etc
change
$ pwd
/etc
$

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

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.

Merging files in Sublime with Sublimerge via command line

I'm trying to find a better merge file option and wanted to try out Sublime as of my work is done using it. so I installed Sublimerge and now am stuck. I know I can compare two already open files or compare via the Sidebar but what I want to do is fire it off via the command line so I can kick it off from our source control program like I can with every other merge tool I've seen. Does anyone know the command line format to do this?
N.B. - I've long since given up trying to use sublime to handle merges and instead switched to other tools to handle this. Therefore I've never felt I can accept any answer as I'm not checking them to see if they work in the way I'd want, or indeed whether they work at all.
subl -n --wait "<LEFT>" "<RIGHT>" --command "sublimerge_diff_views {\"left_read_only\": true, \"right_read_only\": true}"
See "VCS Integration" for details.
As Nickolay already suggested, this is the whole directive you have to put in your ~/.gitconfig:
[merge]
tool = sublimerge
[mergetool "sublimerge"]
cmd = subl -n --wait \"$REMOTE\" \"$BASE\" \"$LOCAL\" \"$MERGED\" --command \"sublimerge_diff_views\"
trustExitCode = false
[diff]
tool = sublimerge
[difftool "sublimerge"]
cmd = subl -n --wait \"$REMOTE\" \"$LOCAL\" --command \"sublimerge_diff_views {\\\"left_read_only\\\": true, \\\"right_read_only\\\": true}\"
Taking jnns' answer, but making appropriate changes for windows.
%USERPROFILE%\.gitconfig:
[merge]
tool = sublimerge
[mergetool "sublimerge"]
cmd = sublime_text -n --wait \"$REMOTE\" \"$BASE\" \"$LOCAL\" \"$MERGED\" --command \"sublimerge_diff_views\"
trustExitCode = false
[diff]
tool = sublimerge
[difftool "sublimerge"]
cmd = sublime_text -n --wait \"$REMOTE\" \"$LOCAL\" --command \"sublimerge_diff_views {\\\"left_read_only\\\": true, \\\"right_read_only\\\": true}\"
note location of .gitconfig
in windows, the executable is sublime_text.exe, NOT subl
don't forget to add sublime text executable to the path
I'm not sure exactly how to do it, but I'm getting closer.
First, you need a handy path to the Sublime binary:
mkdir ~/bin
ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl
Then, in your git GUI or git command line, configure ~/bin/subl as your merge tool.
I use Source Tree, and I haven't figured exactly how to best use Sublimerge, but I managed to open both versions, merge them, and then I have to do a bit of manual work.
Still not smooth, but better than nothing!

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.