nvim-lua / completion-nvim

A async completion framework aims to provide completion to neovim's built in LSP written in Lua
Apache License 2.0
973 stars 78 forks source link

[Feature request] Relative path completion #23

Open kristijanhusak opened 4 years ago

kristijanhusak commented 4 years ago

Hi,

would you consider adding a relative file path completion as an optional source? Something like this.

I tried adding it myself, but since i don't know lua, everything turned out to be calls to vimscript.

haorenW1025 commented 4 years ago

I'd loved to implement new sources! May I ask a small question though, how is this different from the filename completion of ins-complete?

kristijanhusak commented 4 years ago

ins-complete file autocompletes only absolute paths and paths relative to the CWD. Path completion allow autocompleting paths relative to the current file.

haorenW1025 commented 4 years ago

Understand. That's actually pretty helpful. I'm pretty busy recently though... Hopefully I'll be able to make some progress in the weekends.

haorenW1025 commented 4 years ago

Sorry for pending this so long...The first step of path completion should be done in the latest commit. It should still have lots of issues and it doesn't support definite path for now. You can enable it by specified path in complete_items, the given example allow path completion only in string. Feel free to report any issue after trying it!

let g:completion_chain_complete_list = {
            \ 'default' : {
            \   'default': [
            \       {'complete_items': ['lsp', 'snippet']},
            \       {'mode': '<c-p>'},
            \       {'mode': '<c-n>'}],
            \   'comment': [],
            \   'string' : [
            \       {'complete_items': ['path']}]
            \   }
kristijanhusak commented 4 years ago

Sorry for late response. I tested it, looks good to me for now.

kristijanhusak commented 4 years ago

Few minor issues that I found:

haorenW1025 commented 4 years ago

Okay, the first and the third issue should be fixed. The second one is a little tricky and I might need some time...

kristijanhusak commented 4 years ago

Yeah it's fixed, thanks!

kristijanhusak commented 4 years ago

I think i found some new issues unfortunately.

looks like relative completion is now broken.

path automatically completes without anything: So if I do this:

let g:test_path = '

It automatically starts autocompleting this file directory items, which is I guess fine. The problem is that doing ./ is broken.

So doing this:

let g:test_path = './

should basically do the same thing, but it starts listing files and folders from cwd.

If i try to go one parent up, it goes up from cwd instead of current directory of the file

let g:test_path = '../
haorenW1025 commented 4 years ago

Should be fixed now, please check if it works.

kristijanhusak commented 4 years ago

Works great! Even hidden folders are shown.

I just ran into one minor issue when testing. When I tried to autocomplete from root with /, i properly got the root folders (etc, home, usr), but when I type any of them, it doesn't continue autocompleting.

For example typing /ho properly shows /home. Then when I add slash, i should get kristijan as a single option, but I don't get anything. Once I type out kristijan it properly shows all the files from home folder.

Another one that doesn't go deeper is for example /etc I assume this has something to do with user permissions.

I'm not sure how the implementation is done, but maybe you could just use the native file autocompletion source if autocompletion starts with /. Native one properly returns any level.

haorenW1025 commented 4 years ago

That's actually some implementation flaw on my side. It should work fine now, however it's still buggy when completing hidden files.

kristijanhusak commented 4 years ago

Looks good, thanks!

kristijanhusak commented 4 years ago

@haorenW1025 I'm having one issue in javascript with path completion. Here's min vimrc:

set rtp+=~/path/to/completion-nvim

autocmd BufEnter * lua require'completion'.on_attach()

let g:completion_chain_complete_list = {
      \ 'default': [
      \    {'complete_items': ['path']},
      \  ]}

Steps to reproduce:

  1. Open any js file, for example, create new file test.js
  2. start typing this:
    const test = { f

Once you type f, it will start throwing this error:

Error executing vim.schedule lua callback: Vim:E220: Missing }.
haorenW1025 commented 4 years ago

Should be fixed in the latest commit. Please update and check.

kristijanhusak commented 4 years ago

It works, thanks!

kristijanhusak commented 4 years ago

@haorenW1025 would you consider autocompleting files only if there's a valid prefix (./, ../, /) ?

It's a bit annoying that I get all the files from current directory while typing out a string that's not a path.

weilbith commented 4 years ago

If so, please consider to make if configurable (the trigger chars). There are definitely cases when this fits. And if the priority setting are this, I think there must not be an issue for everyone.

haorenW1025 commented 4 years ago

I have some feature that haven't reveal yet(cause I'm still thinking about how it should be), so you can specify triggered_only for completion source. Use this in completion_chain_complete_list to have it only trigger in some character. For example,

let g:completion_chain_complete_list = {
            \ 'default' : {
            \   'default': [
            \       {'complete_items': ['lsp', 'snippet']},
            \       {'mode': '<c-p>'},
            \       {'mode': '<c-n>'}],
            \   'comment': [],
            \   'string' : [
            \       {'complete_items': ['path'], 'triggered_only': ['/']}]
            \   }}

This might change in the future, but it can fit your use case for now.

kristijanhusak commented 4 years ago

Ok, i'll give it a try, thanks!

kristijanhusak commented 4 years ago

It works, thanks!

kristijanhusak commented 4 years ago

I found one issue with it though. I'm using this config:

let g:completion_auto_change_source = 1
let g:completion_chain_complete_list = {
      \ 'default': [
      \    {'complete_items': ['lsp']},
      \    {'complete_items': ['path'], 'triggered_only': ['/']},
      \    {'mode': 'tags'},
      \    {'mode': 'keyn'},
      \    {'mode': '<c-p>'},
      \  ]}

And auto change source never comes to the tags and everything else after. Like that triggered_only continues to be used for all sources after it and it's not able to find anything.

haorenW1025 commented 4 years ago

Yeah that's definitely a problem now... the triggered_only key kind of destroy the chain completion. Would you expect to skip the path completion (in your example) to use other completion instead if not on the triggered_only characters?

kristijanhusak commented 4 years ago

Yeah, i would expect it just to continue as if path complete item wasn't even there.

kristijanhusak commented 4 years ago

I think we can close this issue. I believe it is resolved. If anything new arise, we can reopen it. I'll leave this decision to you.

Thanks for adding the feature!

haorenW1025 commented 4 years ago

I think there is the hidden files issue still exist, right now the file will show but will disappear upon typing .. I'll leave this issue open but the priority of solving this will be lower.

kristijanhusak commented 4 years ago

I'm not sure how's your logic around it, but you could check how mucomplete does path completion, I didn't had any issues with it. https://github.com/lifepillar/vim-mucomplete/blob/master/autoload/mucomplete/path.vim#L78

mjlbach commented 3 years ago

Error executing vim.schedule lua callback: Vim:E220: Missing }.

I'm still having this issue with strings in lua completion

else
  local sumneko_root_path = vim.fn.getenv("HOME").."/.local/bin/sumneko_lua"
  sumneko_cmd = {sumneko_root_path.."/bin/macOS(enter here)/lua-language-server", "-E", sumneko_root_path.."/main.lua" }
end
seblj commented 3 years ago

I am also having problems with completion of path. It does work when typing '/':

def test():
    "/|"

Inside the quotes, :echo synIDattr(synID(line("."),col("."),1),"name") returns pythonString

It does not work inside a string for a method call in python for example. When specifying the file in the method "open" in python, it does not autocomplete the path. Even though it is recognised as a pythonString with :echo synIDattr(synID(line("."),col("."),1),"name")

def test():
    f = open("/|")

This is the completion chain I am using:

vim.g.completion_chain_complete_list = {
    default = {
        default = {
            {complete_items = {'lsp'}},
            {complete_items = {'buffers'}}
        },
        tex = {
            {complete_items = {'vimtex', 'lsp'}}
        },
        comment = {
            {complete_items = {'buffers'}}
        },
        string = {
            {complete_items = {'path'}}
        },
    }
}
ranjithshegde commented 3 years ago

@seblj i was just going over your post, shouldn't "tex" list come outside the second default table? like this

vim.g.completion_chain_complete_list = {
    default = {
        default = {
            {complete_items = {'lsp'}},
            {complete_items = {'buffers'}}
        },
        comment = {
            {complete_items = {'buffers'}}
        },
        string = {
            {complete_items = {'path'}}
        },
    },
    tex = {
         {complete_items = {'vimtex', 'lsp'}}
    },
}
seblj commented 3 years ago

@seblj i was just going over your post, shouldn't "tex" list come outside the second default table? like this


vim.g.completion_chain_complete_list = {

    default = {

        default = {

            {complete_items = {'lsp'}},

            {complete_items = {'buffers'}}

        },

        comment = {

            {complete_items = {'buffers'}}

        },

        string = {

            {complete_items = {'path'}}

        },

    },

    tex = {

         {complete_items = {'vimtex', 'lsp'}}

    },

}

Maybe, but I have switched over to compe, so it's not a problem anymore