0

I have next init.lua in ~/.config/nvim

vim.cmd [[packadd packer.nvim]]

require('packer').startup(function(use)
    -- Packer can manage itself
    use 'wbthomason/packer.nvim'
    
    use 'vim-airline/vim-airline'
    use 'vim-airline/vim-airline-themes'

    vim.g.airline_symbols.colnr = ' col '
end)

vim.cmd.set("background=dark")
vim.cmd.colorscheme("PaperColor")

If I open the nvim with this I get

Error detected while processing /Users/vladyslav/dotfiles/nvim/init.lua:
E5113: Error while calling lua chunk: ...e/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:1023: /Users/vladyslav/dotfiles/nvim/init.lua:68: attempt to index field 'airline_symbols' (a nil value)
stack traceback:
        [C]: in function 'error'
        ...e/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:1023: in function 'startup'
        /Users/vladyslav/dotfiles/nvim/init.lua:55: in main chunk
Press ENTER or type command to continue

Okay, I change my init.lua to

vim.cmd [[packadd packer.nvim]]

require('packer').startup(function(use)
    -- Packer can manage itself
    use 'wbthomason/packer.nvim'
    
    use 'vim-airline/vim-airline'
    use 'vim-airline/vim-airline-themes'

     if vim.g.airline_symbols == nil then
        vim.g.airline_symbols = {}
     end

    vim.g.airline_symbols.colnr = ' col '
end)

vim.cmd.set("background=dark")
vim.cmd.colorscheme("PaperColor")

And if I run it I get

enter image description here

And finally, if I do

vim.cmd [[packadd packer.nvim]]

require('packer').startup(function(use)
    -- Packer can manage itself
    use 'wbthomason/packer.nvim'
    
    use 'vim-airline/vim-airline'
    use 'vim-airline/vim-airline-themes'

     if vim.g.airline_symbols == nil then
        vim.g.airline_symbols = {colnr = ' col '}
     end
end)

vim.cmd.set("background=dark")
vim.cmd.colorscheme("PaperColor")

, then everything is ok.

What is happening? How to set vim.g.airline_symbols from init.lua not inside if as a table?

2 Answers 2

2

There is a kind of misunderstanding here.

  1. vim.g.foo.a = 0 will fail as foo does not exist (yet). This is quite common point for many languages, no matter if Lua or VimScript.

  2. vim.g.foo = {}; vim.g.foo.a = 0 will fail, because empty Lua table is converted to empty VimScript List that cannot be indexed by string.

  3. vim.g.foo = {a=1}; vim.g.foo.b = 2 kinda works but... not really. This is because vim.g is a special one that has metatable with __index and __newindex metamethods. While vim.g.foo is an ordinary variable that does not have any of them. And so one can do vim.cmd("let foo={a:1}"); t = vim.g.foo; t.b = 2 but changing t will never affect value of foo in VimScript. This is one of those old and well-known pitfalls that every newbie inevitably falls into.

1

See the reddit post for origin.

:h lua-vim-variables Note that setting dictionary fields directly will not write them back into Nvim. This is because the index into the namespace simply returns a copy. Instead the whole dictionary must be written as one. This can be achieved by creating a short-lived temporary.
Example:

vim.g.my_dict.field1 = 'value'  -- Does not work

local my_dict = vim.g.my_dict   --
my_dict.field1 = 'value'        -- Instead do
vim.g.my_dict = my_dict         --

this is why your final method works. you can just remove the if.

1
  • 1
    Seems like a weird design choice for NeoVim to make. Thanks for giving us this answer, though!
    – D. Ben Knoble
    Aug 4, 2023 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.