Convert from vimscript to lua, how to lookup built in functions in lua

Hello everyone

I am super new to nvim’s lua, want to convert my old vim config to lua. Some use-cases that I have is whenever I have custom functions like this

" find and edit a ".env" file in a git project dir
function! s:edit_env_file()
  let dir = finddir('.git/..', expand('%:p:h').';')
  let file = findfile('.env', dir)
  execute "e ".fnameescape(file)
endfunction

I want to rewrite this function in lua. My goal is to know how to find equivalent built in functions in lua for functions like finddir, findfile and execute "e ".fnameescape(file)

I would love if you guys help me with steps on your process for trying to rewrite this function if you don’t know any of the built in functions in nvim

Really appreciate it

That’s the reason I don’t wanna transition to Lua yet. But since your functions are all related with file tree manipulation, I think you can read Lua’s reference and look into the IO section. I’m no expert on Lua, but that’s what I would do.

Lua is a barebones language, that doesn’t come with many built-in functions therefore nvim is leveraged to provide a ton of functionality, as a standard library for lua.

All the functions you showed there you can use in Lua, read :help vim.fn so I’ll rewrite the function without changing any logic.

function edit_env_file()
  local dir = vim.fn.finddir('.git/..', vim.fn.expand('%:p:h') .. ';')
  local file = vim.fn.findfile('.env', dir)
  vim.cmd("e " .. vim.fn.fnameescape(file))
end

The advantage of Lua are so much speed and better primitives language design, something that matters a lot when writing mantainable, and extendable code.

VimL is a domain specific language, while Lua is a general purpose (geared towards embedding) so things might always be more ergonomic in VimL (writing less line for some operations, etc) but Lua is a net win (at leas for me).

I’d recommend reading GitHub - nanotee/nvim-lua-guide: A guide to using Lua in Neovim

7 Likes

do you have some advice to simplify this common pattern: having a .vim file to define functions, that calls a lua function, that calls to a string vim command that calls a lua cmd. I.e. vim->lua->vim->lua

" in init.vim
lua vim.api.nvim_command [[autocmd CursorHold   * lua require'utils'.blameVirtText()]]

this seems terrible, but is there some reason to write plugins this way, or should this vim file just call

" in init.vim
autocmd CursorHold   * lua require'utils'.blameVirtText()

A related question, is there any discussion about moving toward native bindings?
like for example:

require('nvim')
pos = nvim.cursor_pos()

vim’s api is pretty unhelpful in my opinion, and it might be nice to start from scratch and have better ergonomics without needing to learn or use vimscript at all.

Yes we now have in 0.7 vim.api.nvim_create_autocmd and you can pass Lua functions to it as a callback.

1 Like