Giter Club home page Giter Club logo

nvim-lua-guide's People

Contributors

alexaandru avatar craigmac avatar crispgm avatar daniil-tokarchuk avatar devonmorris avatar echasnovski avatar ellisonleao avatar famiclone avatar glepnir avatar jaywonchung avatar kartiku avatar krapjost avatar kuator avatar matu3ba avatar mizhozan avatar nanotee avatar svermeulen avatar willelz avatar williamboman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nvim-lua-guide's Issues

Lua 'require' loading modules

Hello,

I am having troubles loading modules from init.lua.

For all my plugins I use vim-plug. I recently decided to use completion-nvim. Unfortunately, when loading the module:

local completion = require'completion'

I get:

E5113: Error while calling lua chunk: ~/.config/nvim/init.lua:6: module 'completion' not found:
        no field package.preload['completion']
        no file './completion.lua'
        no file '/usr/share/luajit-2.0.5/completion.lua'
        no file '/usr/local/share/lua/5.1/completion.lua'
        no file '/usr/local/share/lua/5.1/completion/init.lua'
        no file '/usr/share/lua/5.1/completion.lua'
        no file '/usr/share/lua/5.1/completion/init.lua'
        no file './completion.so'
        no file '/usr/local/lib/lua/5.1/completion.so'
        no file '/usr/lib/lua/5.1/completion.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'

I know the files modules are loaded via the paths contained in package.path but since it is impossible (if I'm not mistaken) to have recursive patterns in lua, I don't wish to add every package/neovim extensions paths in package.path.

Is there a more simple way ?

Thank you very much in advance for any help.

how to read the command arguments `:command arg1 arg2` with lua

related question.

Shells provide aliases to abbreviate typing for functionality. For this access to the command arguments (not the one neovim was started with) from lua would be necessary.

An alternative would be linking or providing a description 1. how to pipe shell output to telescope/another lua program and 2. how to sync pwd of the shell and lwd or gwd (:lcd and :cd folder) of neovim.

Does this description make sense to you?

Question: lua replacement for `executable()`?

Hello,

I hope opening an issue for this type of question is okay!

Is there a recommended lua replacement for vimscript's executable()?

My use-case is that I share a config between several machines, not all of which have the same language servers.

Instead of e.g. if executable("bash-language-server"), currently I'm using:

if os.execute("command -v bash-language-server") == 0 then
    nvim_lsp.bashls.setup({
    on_attach = default_lsp_on_attach,
    })
end

Is there a recommended alternative?

Difference between luafile and lua require

First of all, wonderful write-up! It really fills a hole in the current documentation (and pretty much closes my neovim issue about the lack of such a high-level overview: neovim/neovim#12369)

One question I still have is about the practical difference between :lua require'foo' and :luafile PATH_TO_FOO.LUA. Is it just about the explicit path for the latter and the machinery that prevents loading twice for the former? (Assuming that foo.lua is a single lua script, nothing fancy involving modules.)

Known problem: accessing variables via meta accessors

:help lua-vim-options shows

                                                             *lua-vim-options*
                                                                 *lua-vim-opt*
                                                                 *lua-vim-set*
                                                            *lua-vim-optlocal*
                                                            *lua-vim-setlocal*

and they are undocumented (dead links).

At least for me I have this issue that the filetype is set after everything is loaded, which makes vim.bo.filetype unusable to conditionally set options. see this issue.

Using the metaaccessor filetype does not work, but it works with vimscript:

  if ( vim.bo.filetype == "cpp" ) --first branch never gets executed
    vim.bo.shiftwidth       = 4; --visual mode >,<-key: number of spaces for indendation
  else
    vim.bo.shiftwidth       = 2;
  end
  if ( vim.bo.filetype == "cpp" ) then --first branch never gets executed
    vim.bo.tabstop          = 4; --Tab key: number of spaces for indendation
  else
    vim.bo.tabstop          = 2;
  end

But

if expand('%:e') == 'tex'
  "command! Buildauto :call Latexmklualatex()
  command! Buildauto :call Latexmkpdflatex()
  command! Pdf :call jobstart(["okular", "build/" . expand("%:t:r") . ".pdf"])
endif

just works. I did not find yet lua methods to replace expand.

Could you unlink [Using LibUV in Neovim]?

image

stdio = {stdout,stderr} is wrong, it should be stdio = {nil, stdout,stderr}.

This tutorial about libuv wastes my time when I develop a plugin that needs libuv.

Hope another gets rid of this wrong tutorial.

Mention abbrev

I couldn't find any information on neovim lua abbrev or noreabbrev in your guide.

Document shiftwidth/softtabstop/tabstop caveat

I ran into an issue where the following settings weren't getting applied:

vim.bo.shiftwidth = 4
vim.bo.softtabstop = 0
vim.bo.tabstop = 4

They're in the neovim help as buffer options so I couldn't figure out why it wasn't working.

I happened to see a video on converting VimScript config to lua and he mentioned that you had to also set those options globally. After setting them on vim.o, they work.

I tried removing them from vim.bo and just leaving the vim.o settings but this didn't work either. It seems that they have to be set in both places to work.

I don't know why this is (would love to know) but it might be good to at least document it here in case anyone else has this problem.

Improper handling of relative paths with spaces

I'm using a 'filename', path=1, symbols = { unnamed = '' } section in the following scenario

❯ tree ~/With\ Space/
/Users/simon.mandlik/With\ Space/
└── test.txt

0 directories, 1 file

If I cd into the "With Space" dir and open test.txt, the following is shown in lualine:

image

:pwd in neovim returns /Users/simon.mandlik/With Space

Lua Functions

This is just a drive by comment since we were chatting in gitter.

You can do something like this (which you can't do with v:lua)

lua X = function(k, v) return string.format("%s:%s", k, v) end
echo map([1, 2, 3], luaeval("X"))

Do with this information as you wish ;)

Mention scope of :lua

Here's another GoodToKnow(tm): every :lua statement has its own scope, which means that local variables in one statement will not be available in subsequent statements -- tripping people up that want to debug a script by pasting it in line-by-line. (A similar but more subtle effect is setting a local variable in a init.vim heredoc syntax and trying to access it later from a different heredoc snippet or from the command line via :lua.)

So

:lua local foo = 1
:lua print(foo)

will print nil, not 1.

A sentence pointing this out could go after the multiline heredoc example.

Gotchas re: VimL <-> Lua conversion

The side from which one does the conversion matters when converting functions:

local function hello()
    print('hello')
end

local Myfunc = vim.fn['function'](hello)
print(Myfunc)
-- vim.NIL

vim.g.Hello = hello
-- Error: Cannot convert given lua type
lua << EOF
function _G.hello()
    print('hello')
end
EOF

let s:Myfunc = function(luaeval('_G.hello'))
echo s:Myfunc
" <lambda>1

let g:Hello = luaeval('_G.hello')
echo g:Hello
" <lambda>2

Bumped into this when I tried to pass a Lua callback to vim.fn['fzf#wrap'] from the Lua side

Cleaning up and improving guide

checklist:

  1. Start or link the why (showing very fast lua plugins/faster startup time)
  2. vim.call and vim.fn expose quite the same functionality, so remove the non-luaish and link to the according neovim :help, pending core dev reply...
  3. The linked guides are outdated or dont use best practice. Better define it here and remove all nonconforming guides. TBD(separate issue, once #13823 is upstreamed)
    4. [ ] Best practice for less clutter is using vim.o.backup = false for set options (it also checks types etc), remove the other
  4. Show wrapper around vim.api.nvim_set_keymap('i', '<Tab>', 'v:lua.smart_tab()', {expr = true, noremap = true}) such that one can use something like localfunction_setting_mmode(dictionary) (dictionary) with variables definable as tab.somekey = "some value" to minimize clutter => better than vimscript :) use neovim core PR for keymap after it landed => once #13823 is upstreamed
  5. make a plan how to proceed on "General tips and recommendations" and "Miscellaneous" TBD(clarify content, once motivation is upstreamed)
  6. make init.lua best practice or minimal example for the pitifalls? TBD (separate issue, once 5. is upstreamed)
  7. shortening TOC TBD

Do you prefer individual PRs for each issue?

EDIT: according to information in discussion, TBD:=to be discussed

(issue opened by mistake)

Hi, I'm trying to setup my installer which installs my entire neovim setup on completely bare systems.

With vimplug, I had installed all my packages from this state with

nvim -c PlugInstall -c qa --headless

(of course there was a bootstrap for fetching vimplug in my init.vim).

I've tried the same approach with packer, but while the boostrap script does successfully fetch packer itself, for some reason I do not seem to be able to get it to actually execute PackerInstall, PackerSync or anything else before it exits.

After a bit more investigation, I found that this seems to be happening because nvim does not know to wait for PackerSync before executing qa and killing itself. A temporary (but not at all ideal) workaround is to do

nvim -c PackerSync -c 'sleep 5' -c qa --headless

Is there some way of forcing nvim to wait for packer to finish its sync before exiting?

vim.api.nvim_exec() example gives error

In neovim 0.5.1, when I execute the example in the vim.api.nvim_exec() section (by pasting that text into a lua script, which I then source), I get the error
"E5113: Error while calling lua chunk: tmp.lua:1: Vim(let):E461: Illegal variable name: s:mytext"

It seems that script-local variables (and also script-local functions) are not allowed from nvim_exec, so the "s:" prefixes should be omitted.

Neovim now sources Lua files from config directories

Now that neovim/neovim#14686 is merged, neovim sources Lua files from the usual config directories directly during startup (after all vim files are sourced in the corresponding directory).

Also :source foo.lua is now a valid alternative to :luafile foo.lua.

As a bonus, :<range>source works on Lua code.

Mention vim.api.nvim_call_function

especially the difference to vim.fn/vim.call:

vim.fn.{func}({...})                                    vim.fn
        Invokes vim-function or user-function {func} with arguments {...}.
        To call autoload functions, use the syntax:
            vim.fn['some#function']({...})

        Unlike vim.api.nvim_call_function this converts directly between Vim
        objects and Lua objects. If the Vim function returns a float, it will
        be represented directly as a Lua number. Empty lists and dictionaries
        both are represented by an empty table.

        Note: v:null values as part of the return value is represented as
        vim.NIL special value

        Note: vim.fn keys are generated lazily, thus pairs(vim.fn) only
        enumerates functions that were called at least once.

so I think you'd always want to use vim.call?

advanced guide: content

The one and only luajit wiki and luajit not yet implemented.

  1. Performance tips: wiki + wait for status information, computing performance guide recommended by scilua author

  2. Debugging: one step for vimkind

  3. luarocks => [wbthomason/packer.nvim] has now support luarocks packages => add firejail profile for luarocks done, but I want to test it further before upstreaming. Currently I have weird folder quirks.

  4. :checkhealth integration => check core and treesitter implementation

  5. Explaining what is most performant and why (vim.api) and what happens under the hood ie for vim.call,vim.fn etc. (blocked by missing documentation upstream) see #6
    https://www.reddit.com/r/neovim/comments/oeevcy/what_is_the_difference_between_vimapi_and_vimfn/h45ujiz?utm_source=share&utm_medium=web2x&context=3
    "What is the difference between vim.api and vim.fn functions?"
    "you can no longer use api functions from vim.fn which used to be the case
    vim.api is nvim specific functions and it goes from lua -> C while vim.fn is viml functions which goes from lua -> viml -> C
    there's more overhead for using vim.fn than vim.api"

  6. Some internal functions (categories?) and how to find more etc

Plugin guidelines:

  1. dont autostart lua stuff from vimscript: let the user handle it (for example using plugin folder makes profiling annoying/kinda breaks it): nvim-lua/wishlist#15 (comment)
  2. "Note that underscore-prefixed functions (e.g. "_os_proc_children") are internal/private and must not be used by plugins"
    => dont use underscopre-prefixed functions
  3. Guidelines how to name functions. local function a = bla() vs local a = function(). Related function M.bla() for a table.

I copied some content to the plugin template project and will delete this issue, once the stuff is documented there properly.

Reference doc for the global vim object

Is there a document for the "standard library" exposed via the global vim object? I see some functions documented when I run :h lua-vim, but quite a few of them are not. I'm trying to figure out what some functions (e.g. vim.api.nvim_list_wins) do and what their call signatures are.

If it helps, I'm on version NVIM v0.6.0-dev+106-g545e05d2f.

explain that `vim.api.nvim_set_keymap(mode, ..)` is first char of `:lua print(vim.api.nvim_get_mode().mode)` and hint that there is a minor mode

Assume the following snippet be in the init.lua

local opts = { noremap = true, silent = true }
local map = vim.api.nvim_set_keymap
map('nt', '<C-x>j', [[<cmd> lua print("not broken!")<CR>]], opts)
-- prints either nt or n
local add_cmd = vim.api.nvim_create_user_command
add_cmd('Printmode', function() print(vim.api.nvim_get_mode().mode) end, {})

This fails with E5113: Error while calling lua chunk: $USER/.config/nvim/lua/my_keymaps.lua:534: Shortname is too long: nt,
even though nvim_get_mode() provides us with a mode nt.
I would expect that there is somewhere a lua function for the "visual mode in the terminal" such that one can do keybindings there, if there is an api function that tells us we are in a different mode.

see below: "mapping mode is just the first char of nvim_get_mode().mode" info is missing

More explicit warning about boolean conversion

Converting your init.vim to init.lua is the new sport, it seems. One thing that I've seen people being bitten by repeatedly is converting something like

let g:foo = 1

to

vim.g.foo = true

which of course won't work since Lua true gets converted to v:true, which is not the same as 1. (Same for false and v:false vs. 0.)

I think it would be good to add a big, fat, caveat somewhere -- but where? The conversion itself is mentioned under "Accessing Lua from Vimscript", but it should probably be repeated on the converse side as well.

How to get &ft from lua

Hi, I checked the doc but it seems like there is no option to get specific vim variable from lua. Is it possible?

Mention setting environment variables

Hello,

First of all, thank you for this amazing guide!!! I am finally VimL free :-) and much of it is thanks to this guide :-)

One of the last issues I tackled was setting environment variables in init.lua. It would be nice if the guide would mention that as well: in init.vim it was as easy as (for example) let $GOFLAGS='-tags=development' however I could not find any immediate/obvious way to achieve that in init.lua short of using vim.cmd(...).

After some more digging, I finally found setenv() so settled for vim.fn.setenv("GOFLAGS", "-tags=development") which seems somewhat nicer.

Cheers!

Discussion of lua plugins and packages

With packer.nvim, many people might be tempted to switch from vim-plug to the native package system. There are some gotchas with that, since packages are not available during the time init.vim is read.

Things to mention, maybe (I'm sure there are others):

  • a link to a good description (does anyone know of any) of the way native packages work
  • using vim.cmd [[packadd! plugin]] in the lua code
  • adding a vimscript shim to .nvim/config/plugin that packadds and requires the lua code from .nvim/config/lua using the plugin
  • ...

Various todo items

  • Explain how to reload modules with package.loaded['modname'] = nil
    • maybe mention plenary's reload function?
  • Automated testing for plugins. A link to plenary's test harness is probably sufficient
  • LuaRocks packages. packer has support for them, so I want to at least mention that in the guide

Update section on vimscript options for vim.opt

neovim/neovim#13479 just got merged 🎉 with the following changes:

  • vim.o (set global option) was renamed to vim.go
  • a new vim.o was added that behaves (essentially) like set (is expected to -- meaning there may be weird corner cases)
  • vim.opt was added to allow a more "luanatic" way of setting and getting (in particular, appending) options.

The docs are quite good and explicit, so maybe it's not necessary to repeat much (or just copy the examples from the docs), but the change in vim.o meaning should be reflected.

Question

How to disable word/tag/buffer based completions?

Translations

Hey @nanotee thanks for this awesome repository. It is certainly helping me on moving all my plugins and dotfiles to lua right now in neovim. I was wondering if you have any plans to make it available on other languages. I recently started streaming and i am planning to make that guide available in portuguese (my main language). Is this something you are interested for making it available here as well?

Thanks in advance!

Add example config for sumneko for Lua

This is a very frequently asked question on Gitter, especially "how can I get lsp to recognize vim global"?

Until https://github.com/tjdevries/nlua.nvim is ready, it might be good to have an example config here to link to. Mine is the following (which is not uncontroversial, especially the disable on the diagnostics):

require'lspconfig'.sumneko_lua.setup{
  settings = {
    Lua = {
      runtime = {
        version = "LuaJIT",
        path = vim.split(package.path, ';'),
      },
      workspace = {
        library = {
          [vim.fn.expand("$VIMRUNTIME/lua")] = true,
          [vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true,
        },
      },
      diagnostics = {
        globals = {"vim"},
        disable = {"lowercase-global", "unused-function"},
      },
      completion = {
        keywordSnippet = "Disable",
      },
    },
  },
}

Check if feature exists

Is there a way to check if a vim feature exists? In vimscript, I can use:

if exists('+termguicolors')
  set termguicolors
end

Is there an equivalent in lua?

suggestions on how to reload keymaps and options

Reloading cached modules does not adjust the keymappings, ie

add_cmd('CRel', function()
  local lua_dirs = vim.fn.glob("./lua/*", 0, 1)
  for _, dir in ipairs(lua_dirs) do
    dir = string.gsub(dir, "./lua/", "")
    require("plenary.reload").reload_module(dir)
  end
  -- TODO keybindings are not reloaded
end, {})

does not work as expected. It would be nice to mention this and ideally explain what to use as workaround (for now).

Show how to call :echom / do print debugging

As someone trying to write my absolute first line of nvim Lua, I scanned the README hoping it'd tell me what to put in my init.lua to just make something show up in :messages and prove things were running.

(I assume the right way to do so is to perhaps execute echom on vim but yeah may be nice to explicitly call out.)

Perhaps related to #5

Create keymap to open new file adjacent to current file

Hi,

I'm struggeling a while now with this and tried serveral solutions. My goal is to use the edit command with the path of the currently edited file filled in:

nnoremap <leader>e :e <C-R>=expand("%:p:h") . "/" <CR>
vim.api.nvim_set_keymap('n', '<leader>e', '<cmd>e ???<cr>', {silent = true, noremap = true})

Using it directly just works as expected.

I tried to wrap <C-R> in the termcodes function and several other ways, but none of them worked. Maybe there is even a better way to solve this with lua. Any help is appreciated 🙏🏻

DEPRECATED replaced by mode option

Hey I get the following error. I tried a lot already but I can't fix it maybe someone has an idea?

used_by is deprecated, please use 'filetype_to_parsername'
Fehler beim Ausführen von "/Users/user/.config/nvim/after/plugin/lspkind.rc.lua":
E5113: Error while calling lua chunk: ...cal/share/nvim/plugged/lspkind-nvim/lua/lspkind/init.lua:123: Vim(echoerr):DEPRECATED replaced by mode option.
stack traceback:
        [C]: in function 'nvim_command'
        ...cal/share/nvim/plugged/lspkind-nvim/lua/lspkind/init.lua:123: in function 'init'
        /Users/user/.config/nvim/after/plugin/lspkind.rc.lua:4: in main chunk

Thanks in advanced

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.