folke / neodev.nvim

💻 Neovim setup for init.lua and plugin development with full signature help, docs and completion for the nvim lua API.
Apache License 2.0
2.01k stars 57 forks source link

"Undefined global `vim`" #98

Closed heygarrett closed 1 year ago

heygarrett commented 1 year ago

I'm getting a warning for every use of vim in my config:

CleanShot 2022-12-22 at 17 00 58@2x

I have neodev installed via lazy.nvim. I haven't made any other changes to the runtime path. Relevant parts of my config:

CleanShot 2022-12-22 at 17 02 22@2x

Neovim version:

NVIM v0.8.1
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by brew@Ventura-arm64.local

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/opt/homebrew/Cellar/neovim/0.8.1/share/nvim"

Run :checkhealth for more info
folke commented 1 year ago

neodev should run before setting up lsp config, so best to remove that neodev setup call

heygarrett commented 1 year ago

I tried adding neodev as a dependency to lspconfig and then called setup first in the config function, but I'm still seeing the same issue.

CleanShot 2022-12-22 at 17 30 22@2x

folke commented 1 year ago

Try this instead.

require("neodev").setup({
  override = function(root_dir, library)
     library.enabled = true
      library.plugins = true
   end,
})
folke commented 1 year ago

also, make sure that the first lua file you open is one in your config. Otherwise lua-langauge-server will not be crrectly initialized. That;s not a neodev issue.

heygarrett commented 1 year ago

No luck. Here's the whole config:

return {
    "neovim/nvim-lspconfig",
    dependencies = "folke/neodev.nvim",
    config = function()
        require("neodev").setup({
            override = function(root_dir, library)
                library.enabled = true
                library.plugins = true
            end,
        })

        local loaded, lspconfig = pcall(require, "lspconfig")
        if not loaded then return end

        local servers = {
            "bashls",
            "dockerls",
            "jsonls",
            "marksman",
            "pyright",
            "rust_analyzer",
            "solargraph",
            "sourcekit",
            "tsserver",
            "vimls",
            "yamlls",
        }

        local on_attach = require("lsp.on_attach")
        for _, s in ipairs(servers) do
            lspconfig[s].setup({
                on_attach = on_attach,
            })
        end

        lspconfig.sumneko_lua.setup({
            on_attach = on_attach,
            settings = {
                Lua = {
                    completion = {
                        callSnippet = "Replace",
                    },
                    workspace = {
                        checkThirdParty = false,
                    },
                    telemetry = {
                        enable = false,
                    },
                },
            },
        })
    end,
}
heygarrett commented 1 year ago

I think I figured out the problem. When tinkering with my config I usually run nvim from the ~/.config directory. But I occasionally run it from ~/.config/nvim if I'm troubleshooting a plugin or something. I think doing that created a second .luarc.json file in ~/.config/nvim, and deleting that resolved the issue.

Edit: I may have spoken too soon. When I initially run nvim and open a file from telescope all seems well, but if I then open a second file in a split, every instance of vim in both buffers gets the "undefined global" warning again.

I tried deleting both .luarc.json files to see if only the one would get recreated, but it hasn't.

ranjithshegde commented 1 year ago

I have the exact same issue, specifically after migrating from packer to lazy. No erroneous diagnostics if only single file is open, but cries over all vim and even table.insert or require calls the moment another file is open.

@heygarrett I am not sure I follow, shouldnt .luarc.json be in ~/.config/nvim/? What is the benefit of keeping it in ~/.config?

heygarrett commented 1 year ago

shouldnt .luarc.json be in ~/.config/nvim/? What is the benefit of keeping it in ~/.config?

@ranjithshegde If I'm honest, I'm not entirely familiar with the file's purpose; I didn't create it, so I assumed neodev did.

onemoresuza commented 1 year ago

Same problem here: every change of buffer causes the sumneko_lua language server to throw WARNINGS (didn't find any ERRORS) on both the old and the new buffer about vim and required being undefined variables.

Tinkering around with the plugin I found these (very odd) workarounds, besides restarting the server:

In other words, changing the contents of the buffer --- without the need of saving the change --- seems to trigger something that gets rid of the mistaken WARNINGS.

What is also strange is that, after a file has been assigned to a buffer, going back to it doesn't seem to trigger the bug again.

ranjithshegde commented 1 year ago

Well yes, redrawing the buffer does eliminate the vim.* specific warnings, but there are still warnings on lua stdlib, even on things like require

folke commented 1 year ago

I started having this too in the meantime. Will further look into this. Super weird

folke commented 1 year ago

Are you all on nightly?

ranjithshegde commented 1 year ago

I am on nightly, today's latest commit

folke commented 1 year ago

I can see there's a lot of commits related to workspace folders on lspconfig. The problem I'm having defintely is related to workspace folders, since it triggers when after opening a file in my pfoject, I open one outside of the project.

https://github.com/neovim/nvim-lspconfig/commits/master

folke commented 1 year ago

shouldnt .luarc.json be in ~/.config/nvim/? What is the benefit of keeping it in ~/.config?

@ranjithshegde If I'm honest, I'm not entirely familiar with the file's purpose; I didn't create it, so I assumed neodev did.

no, neodev does not create that file and if you want to use it. you should indeed keep it in the neovim config directory

folke commented 1 year ago

This commit is the problem https://github.com/neovim/nvim-lspconfig/commit/b0bd4297763024bfeb0c3065609361fb599c3594

folke commented 1 year ago

lsp-config before that commit works

onemoresuza commented 1 year ago

Are you all on nightly?

v0.8.1

folke commented 1 year ago

It's an lspconfig issue. Will be broken on all neovim versions. I'm looking into it and will create a PR

folke commented 1 year ago

This should now be fixed upstream, so update lspconfig.

cprn commented 1 year ago

If anyone still has that issue on Linux - make sure your init.lua isn't a symbolic link. You can make it a hard link instead. (sorry for pinging everyone)

folke commented 1 year ago

There's definitely still an issue with this in the upstream changes. Whenever I open a new file, not part of the current workspace, errors might pop up. Releoading the file, or adding a space and saving it, fixes it. I think it's an issue in sumneko somewhere...

cprn commented 1 year ago

Yeah, sumneko doesn't deal with directories outside of workspace but I think a lot of confusion comes from it also having trouble with soft/symbolic links so if your ~/.config/nvim/init.lua is a symlink to something like ~/dotfiles/init.lua then sumneko assumes the project's root is ~/dotfiles/. If it was to follow symlinks transparently then it wouldn't jump out of workspace and that 1st issue wouldn't trigger.

folke commented 1 year ago

ah didn't know that!

dstanberry commented 1 year ago

I've noticed this happening recently after updating using Lazy.nvim. Is anyone else experiencing this? Edit: I followed the notice that sumneko_lua is now renamed to lua_ls.

aldevv commented 1 year ago

same as @dstanberry

folke commented 1 year ago

Still the same. This is due to a change in lspconfig from a couple of weeks ago. Whenever you open a file that is outside your current workspace, it can happen that you get a lot of diagnostics. Making an edit to that file typically fixes this.

mdmjmsa commented 1 year ago

Anybody suffering this issue again?

mamapitufo commented 1 year ago

I am having this issue. It doesn't go away when opening another buffer or editing the Lua file.

cprn commented 1 year ago

It came back for me as well. IDK what exactly lsp-zero does differently but it doesn't happen when I use it. I've cut out a somewhat minimal working example from my config and pasted it at the end. It'll open with folds, well, folded so if you're unfamiliar with that either remove modeline section or press zR to open all folds. Add theme, etc.

  1. run nvim once
  2. let it install plugins and LSPs
  3. quit
  4. run again
  5. let it install Treesitter definitions
  6. done

You can now open ~/.config/nvim/init.lua (even when it's a symlink or you're in a different folder and call :e $MYVIMRC) - after workspace loads there's no error about vim being an undefined global, typing vim. triggers proper auto-completion, setting cursor on vim variable in normal mode and pressing shift + k triggers documentation pop-up.

-- { modeline
-- vim: ts=4 sts=4 sw=4 fdm=marker fmr={,} fdl=0 et nowrap
-- }

-- { optional: disabling some native features
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.g.loaded_ruby_provider = 0
vim.g.loaded_node_provider = 0
vim.g.loaded_perl_provider = 0
-- } optional: disabling some native features

-- { lazy.nvim plugins manager autoinstall
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system {
        'git',
        'clone',
        '--filter=blob:none',
        'https://github.com/folke/lazy.nvim.git',
        '--branch=stable',
        lazypath,
    }
end
vim.opt.rtp:prepend(lazypath)
-- } lazy.nvim plugins manager autoinstall

-- { installing plugins
require('lazy').setup({
    {
        'VonHeikemen/lsp-zero.nvim',
        branch = 'v2.x',
        dependencies = {
            {'neovim/nvim-lspconfig'},

            {
                'williamboman/mason.nvim', -- optional: easy install of LSPs, DAPs and linters with :Mason command
                build = function()
                    pcall(vim.cmd, 'MasonUpdate') -- ignore warning about vim.cmd not matching expected type
                end,
            },

            {'williamboman/mason-lspconfig.nvim'},

            {'hrsh7th/nvim-cmp'},
            {'hrsh7th/cmp-buffer'}, -- optional: completion with current buffer words
            {'hrsh7th/cmp-path'}, -- optional: completion with system paths
            {'hrsh7th/cmp-nvim-lsp'},
            {'saadparwaiz1/cmp_luasnip'}, -- optional: completion for snippets

            {'L3MON4D3/LuaSnip'}, -- optional: the actual snippets engine
            {'rafamadriz/friendly-snippets'},

            {'onsails/lspkind.nvim'}, -- optional: pictograms for file types

            {'j-hui/fidget.nvim', opts = {}}, -- optional: shows LSP working in lower right corner
            {'folke/neodev.nvim'},
        },
    },

    {
        'nvim-treesitter/nvim-treesitter',
        config = function()
            pcall(require('nvim-treesitter.install').update { with_sync = true })
        end,
    },

    {'lewis6991/gitsigns.nvim', opts = {}}, -- optional

    {
        'nvim-telescope/telescope.nvim', -- optional: however I use it in LSP keymaps, without there will be issues
        version = '*',
        dependencies = {
            {'nvim-lua/plenary.nvim'},

            {
                'nvim-telescope/telescope-fzf-native.nvim', -- Fuzzy Finder Algorithm which requires local dependencies to be built. Only load if `make` is available
                build = 'make',
                cond = function()
                    return vim.fn.executable 'make' == 1
                end,
            },
        },
    },

}, {})
-- } installing plugins

-- { NeoVim settings
vim.g.mapleader = ','      -- NOTE: leaders must be set before plugins are passed to `require()` (otherwise wrong keys will be used)
vim.g.maplocalleader = ',' -- NOTE: leaders must be set before plugins are passed to `require()` (otherwise wrong keys will be used)
vim.opt.termguicolors = true
vim.opt.foldmethod = 'expr'
vim.opt.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
vim.opt.foldlevel = 5
vim.opt.wrap = false
vim.opt.shiftwidth = 4
vim.opt.tabstop = 4
vim.opt.softtabstop = 4
vim.opt.expandtab = true
vim.opt.nrformats = 'octal' -- don't increment 007 to 010
vim.opt.fileencodings = 'ucs-bom,utf-8,latin2'
vim.opt.signcolumn = 'yes'
vim.opt.breakindent = true
vim.opt.updatetime = 250
vim.opt.timeoutlen = 300
vim.opt.completeopt = 'menuone,noselect'
-- } NeoVim settings

-- { keymaps for plugins and plugin settings
require('gitsigns').setup()

require('nvim-treesitter.configs').setup {
    ensure_installed = { 'c', 'cpp', 'c_sharp', 'javascript', 'lua', 'php', 'python', 'rust', 'typescript', 'vim', 'vimdoc' },
    auto_install = true,
    highlight = { enable = true },
    indent = { enable = true, disable = { 'python' } }, -- TODO: forgot why I don't want indent for python
    additional_vim_regex_highlighting = false,
}

-- { LSP config
require('neodev').setup() -- must be called before require('lsp-zero')

local servers = { -- list of servers goes here, will be installed and configured by lsp-zero
    'clangd',
    'intelephense',
    'pyright',
    'tsserver',
    'lua_ls',
}

-- { keymaps set when LSP attaches to buffer
local on_attach = function(client, bufnr)
    -- { nmap helper function
    local nmap = function(keys, func, desc)
        if desc then
            desc = 'LSP: ' .. desc
        end
        vim.keymap.set('n', keys, func, { buffer = bufnr, remap = false, desc = desc })
    end
    -- } nmap helper function

    -- { keymaps for language servers
    nmap('[d', vim.diagnostic.goto_prev)
    nmap(']d', vim.diagnostic.goto_next)
    nmap('<leader>d', vim.diagnostic.open_float, 'Open [d]iagnostic message')
    nmap('<leader>q', vim.diagnostic.setloclist, 'Open diagnostic [q]uicklist')
    nmap('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
    nmap('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
    nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition')
    nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
    nmap('gI', vim.lsp.buf.implementation, '[G]oto [I]mplementation')
    nmap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition')
    nmap('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols')
    nmap('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols')
    nmap('K', vim.lsp.buf.hover, 'Hover Documentation')
    vim.keymap.set('i', '<c-y>', vim.lsp.buf.signature_help, { buffer = bufnr, remap = false, desc = 'LSP: Signature Help' })
    nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
    nmap('<leader>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder')
    nmap('<leader>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder')
    nmap('<leader>wl', function()
        print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
    end, '[W]orkspace [L]ist Folders')
    -- } keymaps for language servers
end
-- } keymaps set when LSP attaches to buffer

local lsp = require('lsp-zero')
local lspconfig = require('lspconfig')

lsp.preset({})
lsp.ensure_installed(servers)
lsp.on_attach(on_attach)
lspconfig.lua_ls.setup(lsp.nvim_lua_ls()) -- here you set LSP specific configs, lsp-zero.nvim_lua_ls() generates {} you need
lsp.setup()

require('luasnip').setup()

local cmp = require('cmp')
local cmp_action = lsp.cmp_action() -- generates functions for nvim-cmp keymaps for LuaSnip

cmp.setup {
    sources = {
        { name = 'nvim_lsp' },
        { name = 'path' },
        { name = 'luasnip' },
        { name = 'buffer' },
    },
    mapping = {
        ['<c-j>'] = cmp_action.luasnip_jump_forward(),
        ['<c-k>'] = cmp_action.luasnip_jump_backward(),
        ['<c-space>'] = cmp.mapping.complete(), -- ignore warning about cmp.mapping.complete() not matching expected type
    },
}
-- } LSP config
-- } keymaps for plugins and plugin settings
Congee commented 1 year ago

My problem was a .luarc.json generated from a different machine which prevents the lua-language-server from using nvim lua runtime directories on this machine. After deleting the .luarc.json and regenerate one by the lua-language-server, the correct vim type definitions are loaded.

9999years commented 1 year ago

I ran into this and spent about an hour debugging before I tried deleting the .luarc.json file. We should consider adding a note about this in the documentation. I'd have expected neodev.nvim to append the libraries to the .luarc.json libraries.

erogers88 commented 1 year ago

I had this issue and fixed it by changing how Lazy set up the plugin.

-- Bad
{ "folke/neodev.nvim", opts = {} }
-- Good
require('lazy').setup(
  {
    'folke/neodev.nvim'
  }
)
require('neodev').setup()

I guess that when you call Lazy with the default blank opts it doesn't enter the right function for some reason.

marlun commented 8 months ago

I'm having similar problems. I only have a single config file: ~/.config/nvim/init.lua and if I open it, make a change and leave INSERT mode, I get the error. My config looks like this:

    "folke/neodev.nvim",
    {
        'neovim/nvim-lspconfig',
        config = function()
          require('neodev').setup()

          local lspconfig = require('lspconfig')

          lspconfig['lua_ls'].setup({})
          lspconfig['tsserver'].setup({})
          lspconfig['eslint'].setup({})
          lspconfig['gopls'].setup({})
        end
    },

Also if I hover over vim and hit K I get the following:

image

If however create an empty lua folder ~/.config/nvim/lua/ everything seems to work. I get no error and if I hit K again I get:

image

If I'm a little fast hitting K I get:

image

Found the solution while writing and thought I could write about it here.

edmondburnett commented 8 months ago

Same issue for me. Something really strange is that if I don't call require('neodev').setup() at all, and just install the plugin as a dependency to lspconfig, then I suddenly get completions for some things like vim.keymap but not others, like vim.fn.

I don't have any symlinks under my ~/.config/nvim folders.

edmondburnett commented 8 months ago

Ultimately fixed it (mostly, see below) by deleting ~/.config/nvim/.luarc.json, and using the following config:

~/.config/nvim/lua/plugins/neodev.lua:

return {
  'folke/neodev.nvim',
  lazy = false,
}

~/.config/nvim/lua/plugins/lspconfig.lua:

require("neodev").setup({
    override = function(_, library)
        library.enabled = true
        library.plugins = true
    end,
})

local lspconfig = require("lspconfig")

if utils.executable("lua-language-server") then
    lspconfig.lua_ls.setup({
        on_attach = on_attach,
        capabilities = capabilities,
        settings = {
            Lua = {
                telemetry = {
                    enable = false
                },
                completion = {
                    callSnippet = "Replace"
                }
            }
        }
    })
end

Though I'll say I did a lot of other experimentation and cleanup during my attempts to solve this, so it's possible there were other contributing factors in my config.

This works for nvim builtins at least. But as per #158, #151, #133 etc, any plugins that get imported via require() cannot be autocompleted.

JamesHoi commented 7 months ago

I have same issue and I fixed it by simply add lazy = true

return {
  "folke/neodev.nvim",
  opts = {},
  lazy = true,
}