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

[Question] Detecting VimTeX Environment with Lua #2501

Closed
evesdropper opened this issue Sep 27, 2022 · 8 comments
Closed

[Question] Detecting VimTeX Environment with Lua #2501

evesdropper opened this issue Sep 27, 2022 · 8 comments
Labels

Comments

@evesdropper
Copy link

evesdropper commented Sep 27, 2022

Description

More of a question than an issue, but I couldn't really find a clear answer through other searches previously and I don't really know where else I can ask. I moved to LuaSnip a while earlier and I want to be able to create environment-dependent snippets. There's a way to do this on Python, but the Lua "translation" doesn't seem to work - snippets just activate regardless of environment.

Original Python:

def env(name):
    [x,y] = vim.eval("vimtex#env#is_inside('" + name + "')") 
    return x != '0' and y != '0'

Rough Lua Translation:

 local function env(name) 
     if vim.api.nvim_eval("vimtex#env#is_inside('" .. name .. "')") ~= nil then 
        return 1
     end
     return 0
end

local function tikz()
    return env("tikzpicture")
end

If someone has more information on the syntax command (if I'm using the right one - I did look at the API reference and it seemed to be outdated but still worked on UltiSnips last I checked) and figuring out what it returns so this can be manipulated for Lua, it would be helpful for things like bullet points in enumerate/itemize or TikZ specific snippets in, that would be really helpful. Thanks!

VimtexInfo

System info:
  OS: Linux 5.19.11-arch1-1
  Vim version: NVIM v0.7.2
  Has clientserver: true
  Servername: /tmp/nvimGtE41c/0

VimTeX project: test
  base: test.tex
  root: /home/revise/Documents/test
  tex: /home/revise/Documents/test/test.tex
  main parser: current file verified
  document class: article
  compiler: latexmk
    engine: -pdf
    options:
      -verbose
      -file-line-error
      -synctex=1
      -interaction=nonstopmode
    build_dir: out
    callback: 1
    continuous: 1
    executable: latexmk
  viewer: General
  qf method: LaTeX logfile
@lervag
Copy link
Owner

lervag commented Sep 27, 2022

I'm not sure, as I still don't have much Lua experience. But something like this?

local function env(name)
     local is_inside = vim.fn["vimtex#env#is_inside"](name)
     -- for debugging, check the output:
     print(vim.inspect(is_inside))
     return is_inside ~= nil
end

local function tikz()
    return env("tikzpicture")
end

@evesdropper
Copy link
Author

Hmm, doesn't quite seem to work (snippet works in non tikz and tikz environments), but I also am not too sure about how to view the is_inside output. At least what I know is that the command is correct - wasn't quite sure when I couldn't find on the API reference.

@lervag
Copy link
Owner

lervag commented Sep 27, 2022

Ah, I believe this might work:

local function env(name)
     local lnum_start = vim.fn["vimtex#env#is_inside"](name)[1]
     return lnum_start ~= 0
end

@ejmastnak
Copy link
Contributor

ejmastnak commented Sep 27, 2022

@evesdropper to make sure we're on the same page, are using LuaSnip's condition parameter to control expansion?

Hmm, doesn't quite seem to work (snippet works in non tikz and tikz environments)

I had the same behavior (expansion in tikz and non-tikz) when using the above-suggested env functions as the LuaSnip expansion condition. Here is something I got to work:

-- File: nvim/LuaSnip/tex.lua
-- Loaded using the LuaSnip Lua loader (`:help luasnip-lua`)

local tex = {}
tex.in_tikz = function()
  local is_inside = vim.fn['vimtex#env#is_inside']("tikzpicture")
  -- perhaps using both tests is redundant and only the is_inside[1] is needed?
  return (is_inside[1] > 0 and is_inside[2] > 0)
end
-- Not needed in the context of this question but perhaps useful
tex.in_mathzone = function() return vim.fn['vimtex#syntax#in_mathzone']() == 1 end
tex.in_text = function() return not tex.in_mathzone() end

-- Return snippets
return
{
  s({trig="tikztest"},
    {
      t("Works!"),
    },
    {condition = tex.in_tikz}
  ),
}

So yeah, I've hard-coded the tikz environment check (which is kind of yucky) instead of using a more flexible env(name) style function, but I think this is necessary because as far as I can tell the LuaSnip condition function cannot accept user-supplied parameters. Here is the relevant portion of help luasnip.txt:

The third argument (`opts`) is a table with the following valid keys:

- `condition`: the condition-function `fn(line_to_cursor, matched_trigger,
    captures) -> bool`. The snippet will be expanded only if it returns true
    (default is a function that just returns `true`). The function is called before
    the text is modified in any way. Some parameters are passed to the function:
    The line up to the cursor, the matched trigger, and the captures (table).

Edit: so as far as I can make out the parameters passed to the condition function will always be line_to_cursor, matched_trigger, captures, and so I assume the user cannot pass their own parameters.

I'm new to Lua myself though so I may well be missing something.

@evesdropper
Copy link
Author

@\evesdropper to make sure we're on the same page, are using LuaSnip's condition parameter to control expansion?
Yeah, the snippet I had was the following:

    s('tikztest', {t('this works only in tikz')},
    { condition=tikz }) -- defined my func slightly different

Haha, I guess we are all in the same boat - I have only used Lua for mostly new init.lua I made last month and snippets.

I think hardcoding is a bit inconvenient, but then again there aren't too many environments where specific snippets are needed, at least for me just tikz and maybe itemize/enumerate. But wouldn't it be possible to use a general function, then in_tikz would be something like env("tikzpicture") or something?

Also looked at the snippet; for me it still displays on non tikz envs as well as tikz envs:

image
image

@ejmastnak
Copy link
Contributor

But wouldn't it be possible to use a general function, then in_tikz would be something like env("tikzpicture") or something?

Good idea, I certainly think that would work (although I haven't tested it myself)

Also looked at the snippet; for me it still displays on non tikz envs as well as tikz envs:

Huh, that's interesting. Here's the result on my end using the same snippet I posted earlier:

out

(I used autotrigger to make the effect more obvious, but the behavior is the same with manually triggered snippets)

I'm not using a snippet previewer (is that nvim-cmp or something similar?) though, so I can't test your behavior. Is there a chance the snippet simply appears in the display but doesn't expand? I'm probably out of ideas otherwise, though am curious why the tikz conditional expansion would work for me and not for you.

@evesdropper
Copy link
Author

Yeah, it's nvim-cmp. So when I tried with autosnippets it seems to be fine, just it's still appearing even when it doesn't satisfy the condition. It's a bit strange that it still displays something though - I tried with a math snippet a little later and it also had the same effects. Maybe this is more of an issue I should bring up to those over at LuaSnip. I have been misled the whole time 😆

@lervag
Copy link
Owner

lervag commented Sep 27, 2022

It seems to me this particular issue is resolved, and what remains is more related to LuaSnip. I'll update the docs with a short description of the vimtex#env#is_inside function. Let me know if you otherwise disagree with my decision to close the issue.

@lervag lervag closed this as completed Sep 27, 2022
lervag added a commit that referenced this issue Sep 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants