vifm / vifm.vim

Vim plugin that allows use of vifm as a file picker
335 stars 19 forks source link

Is it possible to use vim's :terminal when opening a shell from vifm.vim? #35

Closed Melandel closed 4 years ago

Melandel commented 4 years ago

Hello,

Currently I am able to press s from within vifm.vim and have access to a shell.

Is there a way to open vim's :terminal instead?

xaizek commented 4 years ago

Hi,

This is quite horrible, but it works :) (If you have +remote in your Vim, otherwise something with a pipe can probably be done.)

let g:vifm_exec_args = "+\"let \\$SHELL = \\\"gvim --servername \\\\\\\"".v:servername."\\\\\\\" --remote-expr 'execute(\\\\\\\"call OpenTerminal(\\\\\\\\\\\\\\\"\\\\\'\\\\\\\$PWD'\\\\\\\\\\\\\\\")\\\\\\\")'\\\"\""

function! OpenTerminal(pwd)
    call term_start($SHELL, { "cwd": a:pwd, "term_finish": 'close' })
endfunction

It can probably be rewritten to have less explicit escapes, but I'm tired of messing with it for now.

Melandel commented 4 years ago

Thank you!

How do I use the shell setting I have in my vimrc?

xaizek commented 4 years ago

Good point, just replace $SHELL with &shell:

function! OpenTerminal(pwd)
    call term_start(&shell, { "cwd": a:pwd, "term_finish": 'close' })
endfunction
Melandel commented 4 years ago

I think I tried that but it wouldn't work, the vifm dual pane would slightly blink once and not change. Will confirm asap when I have access to my computer.

xaizek commented 4 years ago

It looks like v:servername is empty in vimrc. This seems to work after fresh start of Vim:

augroup set_vifm_exec_args
    autocmd! VimEnter * let g:vifm_exec_args = "+\"let \\$SHELL = \\\"gvim --servername \\\\\\\"".v:servername."\\\\\\\" --remote-expr 'execute(\\\\\\\"call OpenTerminal(\\\\\\\\\\\\\\\"\\\\\'\\\\\\\$PWD'\\\\\\\\\\\\\\\")\\\\\\\")'\\\"\""
augroup END
function! OpenTerminal(pwd)
    call term_start(&shell, { "cwd": a:pwd, "term_finish": 'close' })
endfunction
Melandel commented 4 years ago

It appears that OpenTerminal is not called :(

xaizek commented 4 years ago

Try if this works in Vim:

let $this = v:servername
:!gvim --servername "$this" --remote-expr 'OpenTerminal("/")'

And see the output of echo $SHELL in Vifm.

Melandel commented 4 years ago

I'm using gvim on Windows10.

I get

gvim --servername ^"$this^" --remote-expr 'OpenTerminal^(^"/^"^)'
') was unexpected

$SHELL still doesn't have a value in vifm

xaizek commented 4 years ago

Try this version for Windows:

augroup set_vifm_exec_args
    autocmd! VimEnter * let g:vifm_exec_args = '+"let $SHELL=\"gvim --servername \\\"'.v:servername.'\\\" --remote-expr \\\"execute(\\\\\\\"call OpenTerminal(''^%pwd^%'')\\\\\\\")\\\"\""'
augroup END
function! OpenTerminal(pwd)
    call term_start(&shell, { "cwd": a:pwd, "term_finish": 'close' })
endfunction
Melandel commented 4 years ago

It works better ; however, it opens the :terminal in a new split, and in the split that was containing vifm,there is a read-only buffer entitled vifm: edit that looks empty ; if I focus it, the status bar shows me it is a terminal buffer, and if I enter insert mode, the window shows the file selected when I entered the shell from vifm

I added the option "curwin": 'true' to the term_start call but it only masks that vifm: edit window.

Current script:

augroup set_vifm_exec_args
    autocmd! VimEnter * let g:vifm_exec_args = '+"let $SHELL=\"gvim --servername \\\"'.v:servername.'\\\" --remote-expr \\\"execute(\\\\\\\"call OpenTerminal(''^%pwd^%'')\\\\\\\")\\\"\""'
augroup END
function! OpenTerminal(pwd)
    call term_start(&shell, { "cwd": a:pwd, "term_finish": 'close', "curwin": v:true })
endfunction

Is there a way to have the vifm buffer show up in the same window when the terminal is exited (default behaviour) ?

It might be a suitable candidate for an option in the plugin (i.e. let g:vifm_use_vim_terminal_buffer_for_shell or something like that)

xaizek commented 4 years ago

vifm: edit that looks empty

That looks like an issue with :terminal on Windows or maybe how pdcurses library works. I saw it too.

it only masks that vifm: edit window.

Well, it reuses window, not the buffer.

Is there a way to have the vifm buffer show up in the same window when the terminal is exited (default behaviour) ?

It's not something that's builtin, that's for sure. But buffer can probably be remembered and switched back to.

It might be a suitable candidate for an option in the plugin

Actually I don't really get what's the point of this. If terminal was opened in another window, it made sense, but in the same window you essentially get the same result without all this. So what's the goal?

Melandel commented 4 years ago

From my experience, without configuration, vifm.vim has the following workflow:

I would:

This is the only workflow I know from using :Vifm %:h. The only thing is, I didn't know how to change the shell to vim's shell, while using vim's :terminal buffer.

Today, thanks to you, I managed to get there, but unfortunately the workflow changed: it involves the creation of another window for the shell. I was just wondering if it was possible to change the shell but keep the original workflow (the one that involves one window from beginning to end)

So what's the goal?

The goal would be to keep the original workflow of vifm.vim but just add the possibility to use vim's shell instead of the default one

xaizek commented 4 years ago

You still have two scenarios:

  1. You use Vifm to open the shell and don't need Vifm any more
  2. You use Vifm to open a shell and you need to return back to Vifm to possibly open shell again

#2 is how it works out of the box, so opening :terminal and then shuffling buffers/windows around seems quite useless.

#1 is essentially using Vifm to obtain path to open in a shell. And a function to pick a directory and then invoke some user's callback seems to be more appropriate than faking shell inside Vifm.

Melandel commented 4 years ago

I will consider this option.

Thank you for your help and your time!