6
votes

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 :)

4
I don't think this is possible with :term, although might be possible manually starting the terminal with term_start() and a handler for a proper option (see help for job-options). I must say, though, that the whole picture is not particularly straightforward. You want features from a constantly opened terminal (history, scroll to see previous commands) without opening a terminal. I'm failing to understand how keeping a new one open after each time you run a command would be more practical.sidyll
thanks for the reply. basically i want the terminal in a vim split so i can keep context. lets say that instead of running ls on my currently edited file using %, i want to actually run % because it's a python script file. after the script is run for the first time (vanilla run with no args) from vim :term, sometimes i like to RErun the script BUT then feed it different args from the command line. sometimes those args are files and i can add them to the scripts command line using bash tab completion or i can run find or other bash commands to find which files to specify as args.robus
cont'd.. if the term exits after it runs my % scriptfile, then i can't keep working with it from the command line using different args, etc. it's just nice to keep the file editing context open b/c eventually i'm going to come back to the file and edit / change it. of course i can just open :term directly and i have a full shell which gets me 90% what i want. but if vim is NOT in the directory of my edited file, i have to find the file i'm currently editing. no context. just easier if % could be passed to shell and shell doesn't exit on it. make sense?robus

4 Answers

0
votes

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.

0
votes

You can use command 'put' to put the variable after cursor. For example:

let filename=expand(%)
term
put='ls '.filename
0
votes

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.

0
votes

Try this:

:terminal ls % && bash