Skip to content

Conversation

@kiryph
Copy link
Contributor

@kiryph kiryph commented May 31, 2025

I have several questions:

  1. The completions should only be visible within tikz environments. Is this possible?

  2. tkz-euclide offers a package option [mini]. In this case only a subset of the completion candidates should be loaded. Here the user wants to use the package tkz-elements and write the coordinate calculations and definitions in lua code.
    Is it possible to have variants of completion files for the same package dependent on a package option?

  3. When using the tool robust-externalize, it is possible to NOT load tikz and the tkz-* packages in the main document. However, the code is still in the main document. Can a VimTeX user specify manually to load certain packages for completion regardless of .fls and preamble parsing? I have seen the option g:vimtex_syntax_packages with the load value of 2. But it is not clear if this option is also considered for omni-completion.

Note
The list of commands is generated from the texmf tree of TeXLive 2024 and tkz-euclide version: v5.10c (April 2024)
with following ripgrep command applied on the path /usr/local/texlive/2024/texmf-dist/doc/latex/tkz-euclide:

rg -I -N -o "\\\\tkz[a-zA-Z]*" | sort | uniq > $HOME/tkz-euclide

Other possible source is the .cwl file for tkz-euclide in TeXStudio:

https://github.com/texstudio-org/texstudio/blob/master/completion/tkz-euclide.cwl

@lervag
Copy link
Owner

lervag commented May 31, 2025

  1. The completions should only be visible within tikz environments. Is this possible?

Sort of. The way these completion packages work is that they are loaded if the package with a corresponding name is recognized.

Do you have a small compilable sample .tex file that uses one or more of the commands in tkz-euclide? That would be nice to include in the PR, as it helps for testing purposes.

  1. tkz-euclide offers a package option [mini]. In this case only a subset of the completion candidates should be loaded. Here the user wants to use the package tkz-elements and write the coordinate calculations and definitions in lua code.
    Is it possible to have variants of completion files for the same package dependent on a package option?

I don't think that's possible, and I don't see an immediate simple solution for it, sorry. But again, it would be easier to consider it if I saw an example of how this looks.

  1. When using the tool robust-externalize, it is possible to NOT load tikz and the tkz-* packages in the main document. However, the code is still in the main document. Can a VimTeX user specify manually to load certain packages for completion regardless of .fls and preamble parsing? I have seen the option g:vimtex_syntax_packages with the load value of 2. But it is not clear if this option is also considered for omni-completion.

Good question! It is not possible through any features, but you can force it. E.g., if you open some minimal latex file - doing \li will show you the recognized packages. Now you can easily add another package by doing :let b:vimtex.packages["tkz-euclide"] = {}.

I don't think I want to add a specific feature for it, but it should be very easy to make a simple custom feature here, e.g. a custom mapping or custom command that simply loads a package for you. Something like this, for instance:

command -nargs=1 AddPackage :let b:vimtex.packages[<q-args>] = {}

Version: v5.10c (April 2024)

with a sample document
@kiryph kiryph force-pushed the complete-tkz-euclide branch from ce3265a to 03711b4 Compare June 2, 2025 06:25
@kiryph
Copy link
Contributor Author

kiryph commented Jun 2, 2025

Sort of. The way these completion packages work is that they are loaded if the package with a corresponding name is recognized.

If I get this correctly, the answer is closer to no. They are not shown if the package is not loaded, but it does not depend on the current surrounding environment.

I have looked at the default omni-completions as described under :h compl-omni-filetypes.
ft-html-omni says that the omnifunc evaluates contexts and offers different completions, e.g. after "<" complete tag name and inside of a tag complete proper attributes. This is what I had in mind.

Another possibility is to look into completion plugins like nvm-cmp and their filtering capabilities:

https://github.com/hrsh7th/nvim-cmp/blob/main/doc/cmp.txt#L678-L700

However, I am not sure how to create different sources for the LaTeX preamble, default LaTeX context, math environments, TikZ environments, and others.

or LuaSnip:

https://github.com/L3MON4D3/LuaSnip/wiki/Cool-Snippets#context-aware-snippets

Do you have a small compilable sample .tex file that uses one or more of the commands in tkz-euclide? That would be nice to include in the PR, as it helps for testing purposes.

I have added one.

Is it possible to have variants of completion files for the same package dependent on a package option?

I don't think that's possible, and I don't see an immediate simple solution for it, sorry.

That's ok. I just wanted to ask.

Can a VimTeX user specify manually to load certain packages for completion regardless of .fls and preamble parsing?

It is not possible through any features, but you can force it.

Thanks for pointing a custom solution out.

I actually would do it the following way using one of vimtex-events

local au_group = vim.api.nvim_create_augroup("vimtex_events", {})
vim.api.nvim_create_autocmd('User', {
    pattern = 'VimtexEventInitPost',
    group = au_group,
    command = "let b:vimtex.packages['tkz-euclide'] = {}"
  })

I have placed this in my ~/.config/nvim/init.lua for Neovim.

When I open a minimal.tex document

\documentclass{article}

\begin{document}

\end{document}

and then press \li, tkz-euclide is listed. Since this itself loads tikz as well, I guess I have to adjust it little bit further.
Ideally, I specify this in a project specific file, since not all documents I edit use them. But I can live with the current way.

System info:
  OS: macOS 12.6.1 (21G217)
  Vim version: NVIM v0.11.1
  Has clientserver: true
  Servername: /var/folders/2z/bljkcy1j2cbf7l9zf3dk0nqc0000gn/T/nvim.kiryph/IzSTOs/nvim.69250.0

VimTeX project: minimal
  base: minimal.tex
  root: /Users/kiryph
  tex: /Users/kiryph/minimal.tex
  main parser: current file verified
  document class: article
  packages: tkz-euclide
  compiler: latexmk
    engine: -pdf
    options:
      -shell-escape
      -verbose
      -file-line-error
      -synctex=1
      -interaction=nonstopmode
    callback: 1
    continuous: 1
    executable: latexmk
  viewer: sioyek
  qf method: LaTeX logfile

First I was surprised, the buffer-local variable b:vimtex.packages is apparently removed afterwards: I cannot :echo b:vimtex.packages.

@lervag
Copy link
Owner

lervag commented Jun 5, 2025

Sort of. The way these completion packages work is that they are loaded if the package with a corresponding name is recognized.

If I get this correctly, the answer is closer to no. They are not shown if the package is not loaded, but it does not depend on the current surrounding environment. …

However, I am not sure how to create different sources for the LaTeX preamble, default LaTeX context, math environments, TikZ environments, and others.

I'm sorry, but I didn't quite understand your thoughts here.

VimTeX relies on omni completion and uses the line context to determine which type of completion will be performed. The tkz-euclide completion is a command-completion and is triggered by the slash. The relevant code is here, but I'll admit it is probably not trivial to understand at a glance:

https://github.com/lervag/vimtex/blob/main/autoload/vimtex/complete.vim#L292

Do you have a small compilable sample .tex file that uses one or more of the commands in tkz-euclide? That would be nice to include in the PR, as it helps for testing purposes.

I have added one.

Thanks! I'll adjust it so that the tests work and merge this, then.

I actually would do it the following way using one of vimtex-events

Or even more Lua:

local au_group = vim.api.nvim_create_augroup("vimtex_events", {})
vim.api.nvim_create_autocmd('User', {
    pattern = 'VimtexEventInitPost',
    group = au_group,
    callback = function()
      vim.b.vimtex.packages['tkz-euclide'] = {}
    end
  })

First I was surprised, the buffer-local variable b:vimtex.packages is apparently removed afterwards: I cannot :echo b:vimtex.packages.

That's strange - this does not happen on my end. The variable is present as expected whenever I test it.

lervag added a commit that referenced this pull request Jun 5, 2025
@lervag lervag closed this Jun 5, 2025
@kiryph
Copy link
Contributor Author

kiryph commented Jun 9, 2025

I'm sorry, but I didn't quite understand your thoughts here.

VimTeX relies on omni completion and uses the line context to determine which type of completion will be performed. The tkz-euclide completion is a command-completion and is triggered by the slash.

Consider the lines 299 and 302 in autoload/vimtex/complete.vim:

function! s:completer_cmd.complete(regex) dict abort " {{{2
let l:candidates = self.gather_candidates()
let l:mode = vimtex#syntax#in_mathzone() ? 'm' : 'n'
call s:filter(l:candidates, a:regex)
call filter(l:candidates, 'l:mode =~# v:val.mode')
return l:candidates
endfunction

They apparently check if a user tries to complete a command in a math zone and filter candidates accordingly.

I had to search for a while in the repo to find the completion candidates which offer the value mode.

They are in https://github.com/lervag/vimtex/blob/master/autoload/vimtex/complete/tools/symbols.json

If I overlooked something, let me know.

So I miss something which filters based on tikz environment (and others). The code could look like:

let l:mode = vimtex#syntax#in_mathzone() ? 'm' : vimtex#env#in_tikz() ? 't' : vimtex#env#in_document() ? 'n' : 'p'

Relevant existing vimtex functions

vimtex#env#get_inner
vimtex#env#get_outer
vimtex#env#get_all
vimtex#env#is_inside
vimtex#syntax#in_mathzone
vimtex#syntax#in

And of course the command completion candidates have to be added to the symbols.json file with the appropriate context information (math, tikz, preamble, text) instead of the simple line-based files. If I read the directory autoload/vimtex/complete/tools correctly, they have been generated from .cwl files, probably from TeXstudio.

So I checked the repo of TeXstudio. Apparently, TeXstudio has many handwritten .cwl files (3337). There is also a .cwl file for tkz-euclide even with the specifications for the arguments of the commands:

https://github.com/texstudio-org/texstudio/blob/master/completion/tkz-euclide.cwl

The .cwl file format is described here:

https://texstudio-org.github.io/background.html#description-of-the-cwl-format

and supports many features. For example a long list of classifications:

https://texstudio-org.github.io/background.html#classification-format

I actually miss a dedicated tikz classification, since tikz environments can be named differently when using packages like tikz-cd etc.

The .cwl format has actually a feature to answer one of my previous questions about package options:

#ifOption: (at start of line): the following block is only loaded if was used in the usepackage command, e.g. \usepackage[svgnames]{color} -> option=svgnames

Update: Also environments can be marked as an alias for other, so that tikzcd can be set as an alias for tikzpicture.

Is it clearer now what I am talking about?

Since so much work has been done for the .cwl files in TeXstudio, I am wondering whether vimtex omnicompletion could be extended to support cwl files.

I'll adjust it so that the tests work and merge this, then.

Thanks. But as indicated I get tkz-euclide omni-completion candidates also outside of a tikz environment:

Bildschirmfoto 2025-06-09 um 10 11 49

And apparently, TeXstudio has the same behavior:

Bildschirmfoto 2025-06-09 um 10 27 31

@kiryph
Copy link
Contributor Author

kiryph commented Jun 9, 2025

Update

I checked old issues and apparently we had already a command completion discussion in 2017:

I guess I was asking what you have mentioned back then that this was left to implement:

What is lacking now is mode specific completion, but I think this should be fine for now.

If someone would be willing to learn the format of the cwl files from texstudio and explain how to parse the mode specifiers, then I could try to parse that as well and add mode specific command completion. #770 (comment)

2nd Update

Someone else has asked more or less the same for LuaSnip:

#2501

I guess I will go down this road as well.

@lervag
Copy link
Owner

lervag commented Jun 9, 2025

Consider the lines 299 and 302 in autoload/vimtex/complete.vim:

function! s:completer_cmd.complete(regex) dict abort " {{{2
let l:candidates = self.gather_candidates()
let l:mode = vimtex#syntax#in_mathzone() ? 'm' : 'n'
call s:filter(l:candidates, a:regex)
call filter(l:candidates, 'l:mode =~# v:val.mode')
return l:candidates
endfunction

They apparently check if a user tries to complete a command in a math zone and filter candidates accordingly.

Ah, yes. I've comletely forgotten about that!

So I miss something which filters based on tikz environment (and others). The code could look like: …

Yes, I guess this was something I was thinking about back then.

Is it clearer now what I am talking about?

Yes, definitely.

Since so much work has been done for the .cwl files in TeXstudio, I am wondering whether vimtex omnicompletion could be extended to support cwl files.

Well, to be honest, this feels like a big task, and one where I'm not immediately sure where to start. And I'm sorry to say I don't think I have the time to work on this.

As you noticed, the completion works, but it is not context dependent. So, clearly, it could be improved, but it is also better than nothing.

I would not mind considering PR's, of course, but I don't think I'll pursue this personally.

@kiryph
Copy link
Contributor Author

kiryph commented Jun 9, 2025

Well, to be honest, this feels like a big task, and one where I'm not immediately sure where to start. And I'm sorry to say I don't think I have the time to work on this.

I agree that this is probably a big task.

Right now I think delegating this to a snippet plugin like LuaSnip is probably the best option without putting too much burden on VimTeX.

LuaSnip has already a wiki entry how to define snippets using conditions based on information from vimtex: in_mathzone, tikz, in_beamer, in_siunitx:

"Context-aware" Snippets

So defining the completion candidates can be left to the user.

However, I am not sure how to check if a package was loaded. I will raise a separate issue/discussion for this.

Nevertheless in the long run I see value in collections of snippets or support existing cwl files since most people do the same thing.

A few references, if someone wants to take on the cwl path, e.g. a converter from cwl format to LuaSnip format:

  1. CWL Specification
  2. CWL Files in TeXstudio
  3. The LaTeX Workshop Plugin for VS Code repurposes .cwl files for its own completion:

If you write your own package along with the corresponding .cwl file, you can use the Typescript script parse-cwl.ts. For details on how to run this script, please read https://github.com/James-Yu/LaTeX-Workshop/tree/master/dev#parse-cwlts . Place the generated .json file in a folder defined in latex-workshop.intellisense.package.dirs. Note it only works when latex-workshop.intellisense.package.enabled is set to true and you have imported this package in LaTeX, i.e., \usepackage{mypackage}.
https://github.com/James-Yu/LaTeX-Workshop/wiki/Intellisense#commands-starting-with-

  1. The LaTeXTools Plugin for Sublime Text also uses cwl files: https://github.com/SublimeText/LaTeXTools/tree/master/cwl

Alternatively, I think a luasnip-tikz-snippets collection as a sensible project similar to the ones for math by iurimateus or by evesdropper.

@lervag
Copy link
Owner

lervag commented Jun 12, 2025

Right now I think delegating this to a snippet plugin like LuaSnip is probably the best option without putting too much burden on VimTeX.

LuaSnip has already a wiki entry how to define snippets using conditions based on information from vimtex: in_mathzone, tikz, in_beamer, in_siunitx:

"Context-aware" Snippets

So defining the completion candidates can be left to the user.

Yes, agreed, this sounds like a good option.

Nevertheless in the long run I see value in collections of snippets or support existing cwl files since most people do the same thing.

A few references, if someone wants to take on the cwl path, e.g. a converter from cwl format to LuaSnip format: …

Thanks for sharing!

@kiryph kiryph deleted the complete-tkz-euclide branch June 12, 2025 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants