Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Enhance the --opener option to pass a function #259

Closed
gbcreation opened this issue Feb 17, 2021 · 10 comments
Closed

[Feature request] Enhance the --opener option to pass a function #259

gbcreation opened this issue Feb 17, 2021 · 10 comments
Labels

Comments

@gbcreation
Copy link

Describe your feature request

Could you please enhance the --opener option so that we can set a Vim function?

It would be a generic way to do any operation on the selected files. On my end, my goal is to use the ranger plugin to insert the path of the selected file to the edited buffer at the current cursor position.

@voldikss
Copy link
Owner

voldikss commented Feb 18, 2021

Passing a function would be not a sensible choice. It was denied by myself at the begining of implementation of FloatermNew command with arguements. Actually you can define a command which accepts a filename just like built in edit command.

command! MyEdit -nargs=1 ....

@voldikss voldikss added the faq label Feb 18, 2021
@gbcreation
Copy link
Author

gbcreation commented Feb 19, 2021

Thank you for your suggestion. Defining a command is a very good solution. Here is the one I created to insert the relative path of the file selected in Ranger:

function! InsertRelativePath(path)
    let filedir = expand('%:p:h')
    let tailingPart = substitute(a:path, filedir, '', '')
    if tailingPart != a:path
        exec 'normal i.' . tailingPart
    else
        let pathItems = split(a:path, '/')
        let filedirItems = split(filedir, '/')
        while len(pathItems) && pathItems[0] == filedirItems[0]
            call remove(pathItems, 0)
            call remove(filedirItems, 0)
        endwhile
        exec 'normal i' . join(map(copy(filedirItems), string('..')) + pathItems, '/')
    endif
endfunction

command! -nargs=1 InsertRelativePath call InsertRelativePath(<q-args>)

Then, I can use

:FloatermNew --opener=InsertRelativePath ranger

The path of the selected file is correctly inserted at the position of the cursor, but the selected file is also opened. It seems to be related to those lines in the floaterm#util#open() function. Could you please fix that behavior?

@voldikss
Copy link
Owner

The problem lies in this line, but I don't have any good solutions for this.

execute 'edit ' loc.filename

Do you have some ideas?

@gbcreation
Copy link
Author

gbcreation commented Feb 19, 2021

A possible solution could be to process lnum, text and zz only if the current buffer matches loc.filename. Here is an untested suggestion:

function! floaterm#util#open(locations, ...) abort
  let opener = get(a:000, 0, g:floaterm_opener)
  for loc in a:locations
    execute opener loc.filename
    " check if the 'opener' opened filename.
    " If so, proceed to lnum, text, ss
    if expand('%') == loc.filename
        if has_key(loc, 'lnum')
          execute loc.lnum
        elseif has_key(loc, 'text')
          execute '/' . loc.text
        endif
        normal! zz
    endif
  endfor
endfunction

voldikss added a commit that referenced this issue Feb 19, 2021
@voldikss
Copy link
Owner

Thanks. I've fixed it.

@noib3
Copy link

noib3 commented Jun 19, 2021

@voldikss What if one wants to use the custom opener passed as argument to the --opener flag for more than one file? Right now only the first one is opened in that way, all the other selected files are still opened with execute 'edit ' loc.filename .

@voldikss
Copy link
Owner

@voldikss What if one wants to use the custom opener passed as argument to the --opener flag for more than one file? Right now only the first one is opened in that way, all the other selected files are still opened with execute 'edit ' loc.filename .

It's expected. We must use 'edit' after 'vsplit'(for example). Otherwise there will be a lot of splitting windows

@noib3
Copy link

noib3 commented Jun 20, 2021

But the files being selected could be anything, not just text files. In my personal use case I'm trying to write a command that checks what kind of file I'm trying to open, and then opens it accordingly. For example I could have selected 3 files: a text file, a pdf and an image. Even if I implemented a custom opener that does what I need, only the first file I select will be opened with that custom opener. The other two will always be opened in neovim. Could it be possible to pass all the selected files to that --opener function at once (say within a list)? Or maybe call the --opener for all the files, not just the first one?

@voldikss
Copy link
Owner

voldikss commented Jun 20, 2021

Sense reasonable. However if the opener is split, vsplit etc., only one split window should be opened, which means we shouldn't pass all files into split or vsplit. But in your case described above, we should pass all files into the opener, that custom opener.

I could not come up with an idea how to do that elegantly...

Sorry for... PR is welcomed and I don't have much time for now.

@voldikss
Copy link
Owner

Even if I implemented a custom opener that does what I need, only the first file I select will be opened with that custom opener. The other two will always be opened in neovim.

Use autocmd BufEnter *.png,*.jpg,*.gif,*.pdf execute 'ExternalOpen'|bw, you can define ExternalOpen by yourself.

Refer: https://github.com/voldikss/dotfiles/blob/79803efb0af19e56508abf241d27babc01eeb214/home/.config/nvim/init.vim#L248

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants