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

Vim9: cannot refer to exported autoload function via dot notation without sourcing its script too early #9578

Closed
lacygoill opened this issue Jan 20, 2022 · 3 comments

Comments

@lacygoill
Copy link

Steps to reproduce

Run this shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    var dir = '/tmp/.vim'
    &runtimepath = dir
    dir ..= '/autoload'
    dir->mkdir('p')
    var lines =<< trim END
        vim9script
        export def ThesaurusFunc(findbase: bool, _): any
            if findbase
                return 1
            endif
            return [
                'check',
                'experiment',
                'test',
                'verification'
            ]
        enddef
        sleep 5
    END
    lines->writefile(dir .. '/completion.vim')
    import autoload 'completion.vim'
    &thesaurusfunc = completion.ThesaurusFunc
    feedkeys("i\<C-X>\<C-T>")
EOF
)

It takes 5 seconds for Vim to start, then the completion menu is opened.

Run this other shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    var dir = '/tmp/.vim'
    &runtimepath = dir
    dir ..= '/autoload'
    dir->mkdir('p')
    var lines =<< trim END
        vim9script
        export def ThesaurusFunc(findbase: bool, _): any
            if findbase
                return 1
            endif
            return [
                'check',
                'experiment',
                'test',
                'verification'
            ]
        enddef
        sleep 5
    END
    lines->writefile(dir .. '/completion.vim')
    import autoload 'completion.vim'
    &thesaurusfunc = 'completion.ThesaurusFunc'
    feedkeys("i\<C-X>\<C-T>")
EOF
)

Vim starts immediately, but E117 is given:

E117: Unknown function: completion.ThesaurusFunc

Run this last shell command:

vim -Nu NONE -S <(tee <<'EOF'
    vim9script
    var dir = '/tmp/.vim'
    &runtimepath = dir
    dir ..= '/autoload'
    dir->mkdir('p')
    var lines =<< trim END
        vim9script
        export def ThesaurusFunc(findbase: bool, _): any
            if findbase
                return 1
            endif
            return [
                'check',
                'experiment',
                'test',
                'verification'
            ]
        enddef
        sleep 5
    END
    lines->writefile(dir .. '/completion.vim')
    import autoload 'completion.vim'
    &thesaurusfunc = function('completion.ThesaurusFunc')
    feedkeys("i\<C-X>\<C-T>")
EOF
)

Vim starts after 5 seconds, and E117 is given:

E117: Unknown function: completion.ThesaurusFunc

Expected behavior

In at least one of these shell commands, Vim starts immediately, then sleeps for 5 seconds, then opens the completion menu. Otherwise, it means we have no way to refer to an exported autoload function via the Vim9 dot notation without sourcing its script too early, which defeats the whole purpose of writing it inside an autoload script in the first place.

Version of Vim

8.2 Included patches: 1-4162

Environment

Operating system: Ubuntu 20.04.3 LTS
Terminal: xterm
Value of $TERM: xterm-256color
Shell: zsh 5.8

Additional context

If we refer to the autoload function via the legacy name completion#ThesaurusFunc(), then we can get the desired result simply by quoting the name:

&thesaurusfunc = 'completion#ThesaurusFunc'
                 ^                        ^

Test:

vim9script
var dir = '/tmp/.vim'
&runtimepath = dir
dir ..= '/autoload'
dir->mkdir('p')
var lines =<< trim END
    vim9script
    export def ThesaurusFunc(findbase: bool, _): any
        if findbase
            return 1
        endif
        return [
            'check',
            'experiment',
            'test',
            'verification'
        ]
    enddef
    sleep 5
END
lines->writefile(dir .. '/completion.vim')
import autoload 'completion.vim'
&thesaurusfunc = 'completion#ThesaurusFunc'
feedkeys("i\<C-X>\<C-T>")
Vim starts immediately
Vim sleeps for 5 seconds
Vim opens the pum
@lacygoill lacygoill changed the title Vim9: cannot refer to exported autoload function via Vim9 dot notation without sourcing its script too early Vim9: cannot refer to exported autoload function via dot notation without sourcing its script too early Jan 20, 2022
@lacygoill
Copy link
Author

Sorry, it might not be easy to understand the purpose of the 3 shell commands.

They test these assignments:

&thesaurusfunc = completion.ThesaurusFunc
&thesaurusfunc = 'completion.ThesaurusFunc'
&thesaurusfunc = function('completion.ThesaurusFunc')

Summary of the results:

┌──────────────────────────────────────┬───────────────────────────────────┐
│ completion.ThesaurusFunc             │ autoload script sourced too early │
│                                      │ completion working                │
├──────────────────────────────────────┼───────────────────────────────────┤
│ 'completion.ThesaurusFunc'           │ completion not working            │
├──────────────────────────────────────┼───────────────────────────────────┤
│ function('completion.ThesaurusFunc') │ autoload script sourced too early │
│                                      │ completion not working            │
└──────────────────────────────────────┴───────────────────────────────────┘

┌──────────────────────────────────────┬───────────────────────────────────┐
│ completion#ThesaurusFunc             │ autoload script sourced too early │
│                                      │ completion working                │
├──────────────────────────────────────┼───────────────────────────────────┤
│ 'completion#ThesaurusFunc'           │ autoload script lazy-loaded       │
│                                      │ completion working                │
├──────────────────────────────────────┼───────────────────────────────────┤
│ function('completion#ThesaurusFunc') │ autoload script lazy-loaded       │
│                                      │ completion working                │
└──────────────────────────────────────┴───────────────────────────────────┘

Notice that the 2 tables are inconsistent. The right cell gives identical results on the first line, but not on the 2nd and 3rd lines.

@brammool
Copy link
Contributor

If you use the completion it is normal the autoload script is actually loaded. But when setting 'thesaurusfunc' to an autoloaded function it should not be loaded yet. it appears that it does happen with just this:

import autoload 'completion.vim'
&thesaurusfunc = completion.ThesaurusFunc

It should be possible to avoid that.

@brammool
Copy link
Contributor

Actually, using the assignment style won't work, because the expression will be evaluated, causing the autoload script to be loaded. Using a string should work though.

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

No branches or pull requests

2 participants