itchyny/lightline.vim

Calling lua function from `g:lightline` config

dccboss opened this issue · 9 comments

My current vim.g.lightline in init.lua:

  { "itchyny/lightline.vim",
    config = function()
      vim.g.lightline = {
        -- powerlineish, rosepine, nord, ayu_light, seoul256, Tomorrow, materia, ayu_dark, Tomorrow_Night_Bright, PaperColor_light,
        -- default, powerline, 16color, Tomorrow_Night, selenized_white, molokai, Tomorrow_Night_Blue, selenized_light, Tomorrow_Night_Eighties,
        -- PaperColor, selenized_black, wombat, one, PaperColor_dark, apprentice, deus, ayu_mirage, darcula, landscape, OldHope, jellybeans,
        -- material, solarized, srcery_drk, selenized_dark, simpleblack, dragoon
        colorscheme = "dragoon",
        active = {
          left = {
            { "mode", "paste" },
            { "readonly", "filename", "modified" },
            { "gitbranch", "gitstatus", "cocstatus" },
          },
          right = {
            { "lineinfo" },
            { "percent" },
            { "filetype" },
          },
        },
        component_function = {
          gitbranch = 'gitBranch',
          gitstatus = 'GitStatus',
          cocstatus = 'coc#status',
        },
        component_expand = {
          filetype = "lightline#filetype",
        },
      }
    end,
  },

and the lua function gitBranch:

--[[ function to add  to branch display --]]
function _G.gitBranch()
  return "" .. vim.fn["gitbranch#name"]()
end

I've tried:

gitbranch = 'lua gitBranch'

I have defined function AS a vim function, as a temporary solution:

--[[ Current kludge for gitBranch() --]] ]
vim.api.nvim_exec(
[[
function! g:VimGitBranch()
  return " " .. gitbranch#name()
endfunction
]],
true)

Using it as:

gitbranch = 'VimGitBranch',

This works for now, but it'd be nice to be able to call the native lua function directly.

I created lightline plugin before NeoVim was forked from Vim, and Lua API became so common. So the design does not look well with the Lua API (I don't use NeoVim and not tested the plugin with the Lua API). Having said that, gitbranch = 'v:lua.gitBranch' should work, but it needs some patch fixing code not working with v:lua. I can't include as it is, the question here is how can we check the function existence of v:lua.F?

diff --git a/autoload/lightline.vim b/autoload/lightline.vim
index e1f09ca..5ca6c20 100644
--- a/autoload/lightline.vim
+++ b/autoload/lightline.vim
@@ -296,7 +296,7 @@ endfunction
 function! s:subseparator(components, subseparator, expanded) abort
   let [a, c, f, v, u] = [a:components, s:lightline.component, s:lightline.component_function, s:lightline.component_visible_condition, s:lightline.component_function_visible_condition]
   let xs = map(range(len(a:components)), 'a:expanded[v:val] ? "1" :
-        \ has_key(f, a[v:val]) ? (has_key(u, a[v:val]) ? "(".u[a[v:val]].")" : (exists("*".f[a[v:val]]) ? "" : "exists(\"*".f[a[v:val]]."\")&&").f[a[v:val]]."()!=#\"\"") :
+        \ has_key(f, a[v:val]) ? (has_key(u, a[v:val]) ? "(".u[a[v:val]].")" : f[a[v:val]]."()!=#\"\"") :
         \ has_key(v, a[v:val]) ? "(".v[a[v:val]].")" : has_key(c, a[v:val]) ? "1" : "0"')
   return '%{' . (xs[0] ==# '1' || xs[0] ==# '(1)' ? '' : xs[0] . '&&(') . join(xs[1:], '||') . (xs[0] ==# '1' || xs[0] ==# '(1)' ? '' : ')') . '?"' . a:subseparator . '":""}'
 endfunction
@@ -380,7 +380,7 @@ function! s:expand(components) abort
 endfunction
 
 function! s:func(name) abort
-  return exists('*' . a:name) ? '%{' . a:name . '()}' : '%{exists("*' . a:name . '")?' . a:name . '():""}'
+  return '%{' . a:name . '()}'
 endfunction
 
 function! s:line(tabline, inactive) abort

Thank you, worked like a charm. Not sustainable, but at least it was nice to see it work directly.

Any chance of using this, to check for the Lua function:

function! IsLuaFunction(name) abort
    return luaeval(a:name)->type() == v:t_func
endfunction

I don't like to use luaeval here. I believe we could check function existence in a consistent way, hope anyone asks NeoVim devs if they have thoughts on making exists("*v:lua.F") works.

Although this issue isn't resolved, I can do nothing to fix in this plugin so closing the issue. I still think the request for NeoVim neovim/neovim#24587 (comment) is reasonable. Please help them by writing a NeoVim patch to make Vim script plugins work well on NeoVim.

@itchyny neovim/neovim#26485 has landed and makes exists able to check for v:lua functions 🎉 I'm hoping that means there's a path to getting v:lua.F to work? Currently it yields:

E15: Invalid expression: v:lua

@jonhoo @pauldesmondparker @glepnir NeoVim v0.9.5 does not work with exists("*v:lua.F"). Existence check for user-defined functions should be prefixed by *.

hmm i dont know why it through invaid expression. i don't check lightline code :P should return 0 when it start with *v:lua ..for viml user custom function it start with * for lua i just use v:lua directly...let me think about it.

This check should check "*v:lua." right? The patch implements in the different way than proposed by the original issue.

Yes. Opportunistic but breaks compatibility T.T working on it