'Run a command but stay in the shell vs exit
I know that in vim I can type
:terminal <command> %
to run a command on the file in the current edit buffer. For example and to simplify what I want to do let's take a simple ls command:
:terminal ls %
which will split the window, run the command and exit the shell while leaving the output on the screen. that's not what I want. I want it to run the command but leave me in the shell so I can run more bash commands potentially related to the current file/operation, then exit manually when I'm done.
If I simply type
:terminal
it brings me to a bash shell which allows me to type as many commands as I want which is great. BUT I then lose the ability to use the expansion facility of %, and the ease of spawning the terminal from the file I'm editing. ie. I lose the automation of the context provided by spawning from the original file/buffer which means I have to manually type in the current file name including potentially long path and or scroll previous bash history to rerun the original command. this is a waste of keystrokes.
Basically, I'm trying to find a way to create a vim map that lets me use % filename expansion in a bash command via :term
withOUT ending the job after the command is run (i prefer to be left in at a prompt in a shell to continue the session!)
I actually don't care if a solution just starts the :term
shell and echos my command with % filename expansion at the bash prompt without entering it.. that would allow me to still stay in bash after the command is executed by me with a manual carriage return.
I'm not sure if what I want to do is possible? note, I'm not looking to suspend my current edit session and fg back as it ties up the current editing session. I'm not sure if tmux - vim integration might provide a way to do what I want though I'd prefer to find a solution using straight-up :term
since it's a built-in feature and works well except for what I'm trying to achieve :)
Solution 1:[1]
As people have commented, there isn't really a way of doing this directly, but you could use a helper script to get most of what you want.
Using bash as the shell (why not), make a script like this:
#!/bin/bash
# could add echo $1 or ls $1 or whatever you want here.
V="$1" exec bash
Call it, say, vim-bash
, make it executable and put it somewhere on your path. Then from within vim, :terminal vim-bash %
would give you a shell with the current filename available as $V
.
You extend this idea by creating a vim command to wrap it:
command! Vterminal :execute 'terminal vim-bash %'
and then all you need to run from vim is :Vterminal
. You'll get a shell where you can access the filename easily:
$ echo $V
my/really/long/pathname
You can see that you can add your ls
command directly to the script, but if you want to be adventurous you could adapt the vim command to pass through a single line to execute at that point instead.
Solution 2:[2]
You can use command 'put' to put the variable after cursor. For example:
let filename=expand(%)
term
put='ls '.filename
Solution 3:[3]
You can do this with a mapping.
This mapping works for expanding '%' and leaving the new terminal active:
:nmap <F12> :let $MYFILE=expand('%')<CR>:terminal<CR>echo $MYFILE<CR>
You might need to map to a different key but otherwise this should work.
Solution 4:[4]
Try this:
:terminal ls % && bash
Solution 5:[5]
This is a little complicated, but it would work:
- Type :terminal echo % > ~/.path
- Then, type :terminal (or just exit vim) and type:
"export file=
cat ~/.path
"
without the quotes.
- Then, the
file
variable has the same value as % would have had. Just type$file
where you would type %.
I hope this helps you ?.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | DedSecer |
Solution 3 | |
Solution 4 | hankchiutw |
Solution 5 | Nicholas Stands with Ukraine |