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

add function to create augroup autocmd #6339

Open
prabirshrestha opened this issue Jun 25, 2020 · 6 comments
Open

add function to create augroup autocmd #6339

prabirshrestha opened this issue Jun 25, 2020 · 6 comments

Comments

@prabirshrestha
Copy link

prabirshrestha commented Jun 25, 2020

Given that now we have a proper lua support one feature I'm currently missing is the capability to add to define/undefined augroup and register for autocmd events without using eval and string concatenation.

Would it be possible to create a vim script function that exposes this so we can easily use vim.fn.* apis from lua?

There is a PR for this in neovim but is lua only api. neovim/neovim#12378. It could be better to make it a vimscript api so lua gets it automatically.

From PR docs it looks like this in lua.

vim.define_autocmd({"DirChanged"}, "*", {
        on_event = function()
            print("New cwd: ", vim.v.event.cwd)
        end
    }, {})

 vim.define_augroup("ExampleGroup", true)
    vim.define_autocmd(
        {"FileType"},
        "*",
        {on_event = function() print(vim.bo.filetype) end},
        {group = "ExampleGroup"} -- NOTE: <- Here's the group assignment
    )

One change could be to make the on_event to also take a parameter so we don't have to use v:event. I have always found v:event sort of hack but that is most likely since autocmd events can't capture the event data.

lua <<EOF
    vim.fn.define_augroup("asyncomplete", true) -- false to unregister
    vim.fn.define_autocmd({
        events = "InsertEnter,InsertLeave", -- could be vim.list too
        pattern = "*",
        once = false,
        nested = false,
        group = "asyncomplete",
        on_event = function (e)
            print(e) -- where e is v:event
                     -- i would also like to have e.type so I know if it is InsertEnter or InsertLeave
        end
    })
EOF
@prabirshrestha
Copy link
Author

Might want to use augroup_define() and augroup_undefine() since we already have sign_define() and sign_undefined()

@tjdevries
Copy link

I don't know if I like the entire thing being a dictionary. Do you have a strong preference that the entire function argument be one dictoinary?

@prabirshrestha
Copy link
Author

Now that I think about it not sure if e is better than v:event as this forces everyone to convert all vim types to lua types even if not needed. Another option is to use metatble with __index so it gets lazily translated only when used. This might be better.

@tjdevries
Copy link

Yes, I have been thinking of writing a few metatable helpers to properly support expected behavior on neovim side when modifying variables, reading them, etc. Maybe a lazy-loaded, read-only metatable would be good for v:event, for example.

@brammool
Copy link
Contributor

I do not think that making every Ex command available as a function is such a great idea. Especially for commands that don't have complicated arguments. :augroup has an optional exclamation point and a name argument. That's simple enough. Doing this for the Lua interface is a bit far fetched.

@prabirshrestha
Copy link
Author

For now I'm manually created helper functions to make it easy to support. Adds addListener and removeListener api.

Adding the source code here in case any wants to use it. Should work for both vim and neovim.

local vimcmd
if vim.api ~= nil then
    vimcmd = vim.api.nvim_command
else
    vimcmd = vim.command
end

local globalListenerName = 'mygloballistenername' -- change this to be unique across multiple plugin name
local autocmdhandlers = {}

_G[globalListenerName] = function (name)
  autocmdhandlers[name]()
end

local addListener = function (name, events, cb)
    autocmdhandlers[name] = cb
    vimcmd('augroup ' .. name)
    vimcmd('autocmd!')
    for _, v in ipairs(events) do
        local cmd = 'lua ' .. globalListenerName .. '("' .. name ..'")'
        vimcmd('au ' .. v .. ' ' .. cmd)
    end
    vimcmd('augroup end')
end

local removeListener = function (name)
    vimcmd('augroup ' .. name)
    vimcmd('autocmd!')
    vimcmd('augroup end')
    autocmdhandlers[name] = nil
end

-- usage:
addListener('test', { 'InsertEnter <buffer>' }, function ()
   print('insert enter')
   removeListener('test')
end)

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

No branches or pull requests

3 participants