1

Update generated nvim config

This commit is contained in:
2024-06-05 22:05:42 +02:00
parent 859ee3a2ba
commit 075fe5f587
1292 changed files with 152601 additions and 0 deletions

View File

@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest a new feature or enhancement
labels: enhancement
---
NB! Before posting an issue:
* Make sure to search for a solution in old issues before posting a new one.
* Learn at least a minimum of Markdown formatting (https://guides.github.com/features/mastering-markdown).
Finally, please remove any boilerplate template content that is not relevant!
**Is your feature request related to a problem? Please describe it.**
A clear and short description of what the problem is.
**Describe the solution you'd like**
A clear and short description of what you want to happen.
**Describe alternatives you've considered**
A clear and short description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,55 @@
---
name: General issue
about: Report a bug, a problem or any kind of issue
---
NB! Before posting an issue:
* Make sure to search for a solution in old issues before posting a new one.
* Learn at least a minimum of Markdown formatting (https://guides.github.com/features/mastering-markdown).
Note, the following can be useful tips to try before posting the issue:
* Run `:checkhealth` (if available, e.g. on neovim).
* Inspect output of `:VimtexCompileOutput`.
Finally, please remove any boilerplate template content that is not relevant!
**Issue**
Provide a clear and short description of the issue. Use simple english.
Provide relevant files and commands in detail, so everybody can reproduce the issue! The following are _examples_ of minimal input files. To use the minimal vimrc files:
* Regular Vim: `vim --servername VIM -u minimal.vim minimal.tex`
* neovim: `nvim -u minimal.vim minimal.tex`
**minimal.vim**
```vim
set nocompatible
let &runtimepath = '~/.vim/bundle/vimtex,' . &runtimepath
let &runtimepath .= ',~/.vim/bundle/vimtex/after'
filetype plugin indent on
syntax enable
```
**minimal.tex**
```tex
\documentclass{minimal}
\begin{document}
Hello world!
\end{document}
```
NB: If relevant, include the content of your `.latexmkrc` file!
**Commands/Input**
Provide set of keys or command to reproduce the issue.
**Observed Behaviour**
Describe the observed behaviour.
**Expected Behaviour**
Describe both the expected and the observed behaviour.
**Output from VimtexInfo**
Run `:VimtexInfo` and paste the content here.

View File

@ -0,0 +1,85 @@
name: General issue
description: Report a bug, a problem, or any kind of issue
labels: [bug]
body:
- type: markdown
attributes:
value: |
Before reporting, please [search existing issues](https://github.com/lervag/vimtex/issues?q=is%3Aissue+is%3Aopen).
- type: textarea
attributes:
label: "Description"
description: |
Provide a clear and short description of the issue. Use simple english.
validations:
required: true
- type: textarea
attributes:
label: "Steps to reproduce"
description: |
Steps to reproduce. Please include minimal test files (`minimal.vim` and `minimal.tex`) and include an initial step like:
* Vim: `vim -u minimal.vim minimal.tex`.
* neovim: `nvim -u minimal.vim minimal.tex`
See below for examples of minimal test files.
placeholder: |
1. `vim -u minimal.vim minimal.tex`
2. Do something
3. Do something more
- type: textarea
attributes:
label: "Expected behavior"
description: "A description of the behavior you expected."
placeholder: "When following the above steps, I expect ..."
- type: textarea
attributes:
label: "Actual behavior"
placeholder: "When following the above steps, I observe ..."
- type: input
attributes:
label: "Do you use a latexmkrc file?"
description: |
This can either be a global `~/.latexmkrc` file or a project specific `/my/project/latexmkrc` file. Or something similar.
If _yes_, then consider if it is relevant to describe it in the above descriptions!
placeholder: "Yes / No"
validations:
required: true
- type: textarea
attributes:
label: "VimtexInfo"
description: |
Run `:VimtexInfo` in a relevant LaTeX file and copy the content here.
render: yaml
validations:
required: true
- type: markdown
attributes:
value: |
## Example of minimal test files
**minimal.vim**
```vim
set nocompatible
let &runtimepath = '~/.vim/bundle/vimtex,' . &runtimepath
let &runtimepath .= ',~/.vim/bundle/vimtex/after'
filetype plugin indent on
syntax enable
" Add relevant options and VimTeX configuration below.
```
**minimal.tex**
```tex
\documentclass{minimal}
\begin{document}
Hello world!
\end{document}
```

View File

@ -0,0 +1,57 @@
name: CI tests
on:
pull_request:
paths-ignore:
- 'doc/*'
- 'docker/*'
- 'media/*'
- '*.md'
push:
paths-ignore:
- 'doc/*'
- 'docker/*'
- 'media/*'
- '*.md'
env:
SHELL: bash
jobs:
run-tests:
name: Test on ubuntu-latest
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: Install packages
run: |
sudo apt update
sudo apt install \
moreutils \
texlive texlive-latex-extra texlive-extra-utils \
texlive-bibtex-extra libtext-bibtex-perl \
texlive-publishers \
latexmk \
libmodule-build-perl \
libconfig-autoconf-perl \
libextutils-libbuilder-perl
- uses: jdx/mise-action@v2
with:
tool_versions: |
neovim 0.9.5
vim 9.1.0
- uses: actions/checkout@master
with:
fetch-depth: 1
- name: Test with neovim
working-directory: ./test
run: |
mise use neovim
make -j1
- name: Test with vim
env:
MYVIM: vim -T dumb --not-a-term -n
working-directory: ./test
run: |
mise use vim
make -j1

View File

@ -0,0 +1,6 @@
doc/tags
test/test-compiler/latexrun
test/test-syntax/syntax/
test/test-textobj-targets/targets.vim/
test/issues

View File

@ -0,0 +1,13 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
"runtime": {
"version": "LuaJIT"
},
"workspace": {
"library": [
"$VIMRUNTIME",
"${3rd}/luv/library"
],
"checkThirdParty": false
}
}

View File

@ -0,0 +1,5 @@
column_width = 80
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"
call_parentheses = "None"

View File

@ -0,0 +1,3 @@
policies:
ProhibitAbbreviationOption:
enabled: false

View File

@ -0,0 +1,81 @@
# Guide for code contributions
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Branch model](#branch-model)
- [Documentation style](#documentation-style)
- [Code style](#code-style)
- [Running tests](#running-tests)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Branch model
VimTeX is developed mainly through the master branch, and pull requests should
be [fork based](https://help.github.com/articles/using-pull-requests/).
## Documentation style
Vim help files have their own specific syntax. There is a Vim help section on
how to write them, see [`:h help-writing`](http://vimdoc.sourceforge.net/htmldoc/helphelp.html#help-writing).
The VimTeX documentation style should be relatively clear, and it should be
easy to see from the existing documentation how to write it. Still, here are
some pointers:
- Max 80 columns per line
- Use the help tag system for pointers to other parts of the Vim documentation
- Use line of `=`s to separate sections
- Use line of `-`s to separate subsections
- The section tags should be right aligned at the 79th column
- Sections should be included and linked to from the table of contents
VimTeX also has a high level code [documentation](./DOCUMENTATION.md) mainly
for developers. It should provide an overview of the VimTeX code and APIs and
may help developers (and users) to understand the functionalities of the
plugin a little bit faster.
## Code style
When submitting code for VimTeX, please adhere to the following standards:
- Use `shiftwidth=2` - no tabs!
- Write readable code
- Break lines for readability
- Line should not be longer than 80 columns
- Use comments:
- For complex code that is difficult to understand
- Simple code does not need comments
- Use (single) empty lines to separate logical blocks of code
- Use good variable names
- The name should indicate what the variable is/does
- Variable names should be lower case
- Local function variables should be preceded with `l:`
- Prefer single quoted strings
- See also the [Google vimscript style
guide](https://google.github.io/styleguide/vimscriptguide.xml)
- Use markers for folding
- I generally only fold functions, and I tend to group similar functions so
that when folded, I get a nice structural overview of a file
- See some of the files for examples of how I do this
## Running tests
New functionality should be accompanied by tests. Tests can be run from the
`test` folder with `make`. The tests currently only run on Linux, and the
following utilities are required to run all the tests:
- `wget`
- `chronic` (from [moreutils](https://joeyh.name/code/moreutils/))
These utilities may not come with all Linux distributions and may need to be
installed with your favorite package manager (e.g. `yum`, `apt-get`, or `brew`
on Mac).
By default, the tests are run with the Neovim executable `nvim`. You can change
the executable by setting the environment variable `MYVIM` before running. To
run with vanilla vim, use `MYVIM="vim -T dumb --not-a-term --noplugin -n"`.
Either export this in your shell, or prepend to `make`, that is, run
`MYVIM="vim -T dumb --not-a-term --noplugin -n" make`.

View File

@ -0,0 +1,381 @@
# Documentation
Welcome to the "high-level documentation" of VimTeX. The goal of this document
is to help developers (and curious users) to understand the structure of the
plugin and how it works. That is, it should essentially provide a useful and
quick overview of the most important files and directories. See also `:help
vimtex-code` for some related information.
The table of contents has the same structure as the essential file structure of
VimTeX. E.g., if you want to know something about
`vimtex/autoload/vimtex/somefile.vim`, then you can lookup the path in the
table of contents and click on it.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [ftplugin](#ftplugin)
- [syntax](#syntax)
- [indent](#indent)
- [after/ftplugin](#afterftplugin)
- [autoload](#autoload)
- [vimtex.vim](#vimtexvim)
- [vimtex](#vimtex)
- [state.vim](#statevim)
- [delim.vim](#delimvim)
- [cmd.vim](#cmdvim)
- [cache.vim](#cachevim)
- [compiler.vim](#compilervim)
- [compiler](#compiler)
- [debug.vim](#debugvim)
- [complete.vim](#completevim)
- [tools](#tools)
- [context.vim](#contextvim)
- [fold.vim](#foldvim)
- [parser.vim](#parservim)
- [qf.vim](#qfvim)
- [syntax](#syntax-1)
- [text\_obj.vim](#text_objvim)
- [view.vim](#viewvim)
- [health/vimtex.vim](#healthvimtexvim)
- [unite/sources/vimtex.vim](#unitesourcesvimtexvim)
- [rplugin/python3/denite/source/vimtex.py](#rpluginpython3denitesourcevimtexpy)
- [test](#test)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# ftplugin
The main features of VimTeX are implemented as a filetype plugin for Vim and
neovim. This is a specific concept that you can read about with `:help
filetype-plugins`.
VimTeX provides a filetype plugin for the `tex` and `bib` filetypes. These
scripts are the main entry points for the bulk functionalities of VimTeX. They
are both very simple: they ensure that the user wants to load VimTeX, then they
execute the function `vimtex#init()` from [`autoload/vimtex.vim`](#vimtexvim).
# syntax
VimTeX is also a syntax plugin and provides a `tex` syntax plugin script. The
relevant Vim and neovim docs for this is `:help :syn-files`. Essentially, this
is the entry point for loading the syntax highlighting.
# indent
VimTeX also has an indentation script; this feature is also a special concept
with an entry point under the `indent/` directory, see `:help
indent-expression`. The main purpose of `indent/tex.vim` and `indent/bib.vim`
is to provide functions like `VimtexIndent()` that are used with the
`:help 'indentexpr'` option.
# after/ftplugin
The `after/` directory is a simple Vim and neovim concept that allows to ensure
that some scripts are loaded _after_ the main scripts. For details of the
concept, see `:help after-directory`.
Currently, there's only one script `after/ftplugin/tex.vim`. This is used to
make sure that VimTeX loaded successfully and that there're no conflicts with
other plugins such as LaTeX-Box.
# autoload
The `autoload` directory is an important concept in Vimscript. It allows to
avoid loading code until it is strictly necessary. This allows to substantially
speed up the initialization phase, since the bulk VimTeX code is not sourced
unless necessary. See `:help autoload` for more details. It may also be
instructive to read [this
chapter](https://learnvimscriptthehardway.stevelosh.com/chapters/42.html) of
the well known [Learn Vimscript the Hard
Way](https://learnvimscriptthehardway.stevelosh.com/chapters/42.html) by Steve
Losh.
## vimtex.vim
This file defines the main entry point `vimtex#init()`, which is responsible
for loading all of the VimTeX functionalities, except:
* syntax highlighting is loaded from `syntax/tex.vim`
* indentation is loaded from `indent/tex.vim`
The main initialization function calls `vimtex#mymodule#init_buffer()` for each
submodule, if it exists. This function should take care of defining buffer
local mappings, commands, and autocommands for the respective submodule.
The initialization function also ensures that the current buffer is coupled with
a corresponding state dictionary, see [autoload/vimtex/state.vim](#statevim).
## vimtex
This directory holds the bulk of the VimTeX source code. Each `.vim` file
represents a separate submodule that may provide one or more of the following:
* a functional API that is used in other parts of VimTeX
* buffer functionalities (mappings, commands, and/or autocommands)
* state data
### state.vim
The VimTeX state variable is a dictionary that contains data specific to
a single LaTeX project. A project may consist of several buffers for different
files, e.g. if the project is a multi-file project (see `:help
vimtex-multi-file`). A submodule may add to the state during initialization
with `vimtex#mymodule#init_state(state)`, which takes the state object as
a single argument.
### delim.vim
This file defines an API and some buffer mappings for detecting and
manipulating the surrounding delimiters.
The API is mostly based on the function `vimtex#delim#get_surrounding(type)`.
The following is a simple example to detect the surrounding environment. Let
`|` denote the cursor position:
```tex
\begin{Environment}
Some awesome | text
\end{Environment}
```
Example code for working with the environment delimiter:
```vim
" The return values are dictionaries
let [l:open, l:close] = vimtex#delim#get_surrounding('env_tex')
" Empty dicts mean we did not find a surrounding environment
if empty(l:open) | return | endif
" The dicts have several attributes, the most important are probably these:
echo l:open.name
echo l:open.lnum
echo l:open.cnum
```
### cmd.vim
This file defines an API and some buffer mappings for detecting and
manipulating LaTeX commands.
The main API relies on the functions `vimtex#cmd#get_*(...)`, e.g.
`vimtex#cmd#get_current()`. A simple example usage:
```vim
let l:cmd = vimtex#cmd#get_current()
if empty(l:cmd) | return | endif
echo l:cmd.name
echo l:cmd.pos_start
echo l:cmd.pos_end
echo l:cmd.args
echo l:cmd.opts
```
### cache.vim
This file implements an API for creating and accessing caches that can be both
volatile and persistent, as well as project and buffer local.
Here's an example of how to use a cache.
```vim
function VimTeXCacheExample()
" create a new cache (if the name doesn't exist yet)
" with an attribute 'number'. So the cache would be like that:
"
" let l:test = {
" 'number' = 10,
" }
let l:my_cache = vimtex#cache#open('cache_name', {'number' : 10})
" change the value in you cache
let l:my_cache['number'] = 9001
" will print '9001'
echo l:my_cache['number']
" save your changes
" In general it'll be saved in your `$XDG_CACHE_HOME/vimtex/` directory
" (normally '~/.cache/vimtex') in the appropriate tex-file where you accessed
" cache file.
call vimtex#cache#close('cache_name')
endfunction
```
### compiler.vim
This submodule defines an API for interacting with LaTeX compiler backends. It
also defines the main compiler mappings and commands (e.g. `:VimtexCompile`).
Each supported backend is defined in separated scripts under
`vimtex/autoload/vimtex/compiler/*.vim`. These scripts provide
`vimtex#compiler#mycompiler#init()`, which is used to initialize a particular
backend - it should return a dictionary object that will be part of the VimTeX
state.
The main compiler API essentially connects to the specified backend. E.g., if
one uses the default `latexmk` backend, then the top level
`vimtex#compiler#start()` function will essentially call the
`s:compiler_nvim.start_single()` function from
`vimtex/autolaod/vimtex/compiler/latexmk.vim`.
### debug.vim
This standalone script defines a convenience function for internal debugging:
`vimtex#debug#stacktrace()` parses the stacktrace from the `v:throwpoint`
variable (see `:h v:throwpoint` for more information). If this does not exist,
then we forcibly create it and remove the top element. You can try this code as
an example:
```vim
" Save as test.py
function! Test() abort
try
throw "Nasty error message is here :D"
catch
call vimtex#debug#stacktrace(1)
endtry
endfunction
```
Now type `:call Test()`, and the quickfix window should pop up with the
specified error message and the location of the error.
### complete.vim
This script defines the main completion API: `vimtex#complete#omnifunc(...)`.
See `:help complete-functions` for details on how omnifunctions work.
The function is relatively advanced and allows different completion mechanisms
for different contexts.
The `complete/` subdirectory contains simple files that lists keywords defined
for specific packages or classes. These files are used by the command and
environment completers.
The `complete/tools` directory includes a large map between LaTeX commands and
unicode glyphs, like `\alpha -> α` and `\beta -> β`. This is used to enrich the
keywords lists under `complete/` to add more fancy completion menus.
### context.vim
This script provides a context menu feature (`:help :VimtexContextMenu`). Each
script under `autoload/vimtex/context/*.vim` defines a specific context and
its related actions. See
[here](https://github.com/lervag/vimtex/pull/1961#issuecomment-795476750) for
a more detailed description of how this is implemented.
For instance, the context `context/cite.vim` defines a citation context (see
`:help vimtex-context-citation`).
### fold.vim
This defines the fold functions for VimTeX. Folding is explained in `:help
folds`. An example of how a folded document may look like:
![folding example](https://github.com/lervag/vimtex-media/blob/main/img/folding.png)
VimTeX defines a custom fold expression, see `:help fold-expr`. The
`vimtex#fold#init_state` function will apply folding as per the related
configuration (see `:help vimtex-folding`).
The fold expression is modularized to allow a relatively high degree of
customizability. Each type is defined in its separate file, e.g.
`autoload/vimtex/fold/envs.vim` for folding of environments.
### parser.vim
A lot of VimTeX functionalities relies on some type of parsing. This module
defines an API for various parsers, both for TeX files and other filetypes
(e.g. `aux` and `bib`), as well as some specific types of parser (e.g. `toc`
for parsing TeX files for a table of contents).
The code for each parser is defined in sub modules, e.g. `parser/bib.vim`.
The `vimcomplete.bst` file is used by `parser/bib.vim` in the
`s:parse_with_bibtex()` function. It is used to convert a `.bib` file to
a `.bbl` file with `bibtex` - this is useful because the `.bbl` file generated
with this `.bst` file is very easy to parse.
### toc.vim
Specifies a simple API and buffer mappings/commands for creating a convenient
table of contents (TOC) to navigate and inspect a file (`:h :VimtexTocToggle`
for more information).
![toc example](https://github.com/lervag/vimtex-media/blob/main/img/toc.png)
### qf.vim
This submodule defines functions and buffer mappings to parse log files and
similar and put errors and warnings into the quickfix window (see `:help
quickfix`). The functions are used e.g. by callbacks from the compilers, if
supported and enabled, to automatically parse log files and display potential
errors after compilation.
The files `vimtex/autoload/vimtex/qf/*.vim` define different types of log
parsers. E.g., `qf/bibtex.vim` is used to parse `.blg` files for BibTeX related
warnings and errors, and `qf/latexlog.vim` parses `.log` files for LaTeX
warnings and errors. `qf/pulp.vim` defines an alternative log parser that can
be used instead of `latexlog.vim`. See also `:help g:vimtex_quickfix_method`.
Here's an example of the quickfix list generated by the `qf/latexlog.vim`
script:
![quickfix example](https://github.com/lervag/vimtex-media/blob/main/img/quickfix.png)
### syntax.vim
This script implements some convenience functions for the bulk VimTeX code.
This may be counter intuitive, so be warned.
The idea is that other parts of VimTeX may rely on the syntax state, e.g. to
determine if a position is within math mode (`vimtex#syntax#in_mathzone(...)`).
The actual syntax rules are defined in the scripts under `syntax/*.vim`.
### syntax
This subdirectory contains the main syntax highlighting scripts. The entry
point for the syntax scripts are, as mentioned previously, the top level
[`syntax/tex.vim`](#syntax). However, as most of the code, the bulk source is
defined in the autoloaded functions.
In short: `syntax/core.vim` implements the core syntax rules, whereas the
scripts under `syntax/p/` define package specific syntax rules.
### text\_obj.vim
This submodule defines text objects, see `:help text-objects`. Buffer local
mappings are created during initialization.
The module allows to use different backends, including the popular
[`targets.vim`](https://github.com/wellle/targets.vim).
### view.vim
This submodule defines the main view API and buffer mappings/commands. That is,
mappings and commands to open a PDF viewer for the compiled LaTeX document.
The desired PDF viewer is specified with `g:vimtex_view_method` variable, and
the specified viewer is initialized from `view/VIEWER.vim` (e.g.
`view/zathura.vim`). This does essentially just the following for a given VimTeX
state:
```vim
let a:state.viewer = vimtex#view#{g:vimtex_view_method}#new()
```
That is, if `g:vimtex_view_method` is `zathura`, then this calls
`vimtex#view#zathura#new()`. The `new()` method should return a dictionary
object with e.g. a `.view()` method that is used to open a file with the
specified viewer.
## health/vimtex.vim
VimTeX hooks into the `health.vim` framework provided by `neovim` (see `:help
health`). This is a utility framework for performing health checks that may
help users discover problems with e.g. configuration. VimTeX has a few checks
for e.g. Vim versions and configuration validation.
Note: This is not relevant for regular Vim.
## unite/sources/vimtex.vim
This script defines a VimTeX table-of-content source for the
[unite](https://github.com/Shougo/unite.vim) plugin. See `:help vimtex-unite`
for more info.
# rplugin/python3/denite/source/vimtex.py
This script defines a VimTeX table-of-content source for the
[denite.vim](https://github.com/Shougo/denite.nvim) plugin. See also `:help
vimtex-denite`.
# test
This directory is used to, you guessed it, define tests for the VimTeX code.
The tests are built on top of a Makefile based workflow. The `test/Makefile`
runs all tests defined in sub directories named `test-...`. It is a fundamental
requirement that all tests run with `make` from the top level `test` directory
should pass for VimTeX to be deemed stable and fully functional.
The `test/` directory also contains some simple LaTeX and VimTeX configuration
examples under `test/example-...`, as well as some issue specific test files
under `issues/ISSUE-NUMBER`.

View File

@ -0,0 +1,21 @@
MIT license
Copyright (c) 2021 Karl Yngve Lervåg
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,352 @@
# VimTeX
VimTeX is a modern [Vim](http://www.vim.org/) and [Neovim](https://neovim.io/)
filetype and syntax plugin for LaTeX files.
[![Gitter](https://badges.gitter.im/vimtex-chat/community.svg)](https://gitter.im/vimtex-chat/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
![CI tests](https://github.com/lervag/vimtex/workflows/CI%20tests/badge.svg)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5N4MFVXN7U8NW)
## Table of contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Tutorial](#tutorial)
- [Documentation](#documentation)
- [Screenshots](#screenshots)
- [GIFs](#gifs)
- [Features](#features)
- [Other relevant plugins](#other-relevant-plugins)
- [Linting and syntax checking](#linting-and-syntax-checking)
- [Snippets and templates](#snippets-and-templates)
- [Tag navigation](#tag-navigation)
- [Alternatives](#alternatives)
- [VimTeX on the Web](#vimtex-on-the-web)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Requirements
VimTeX requires Vim version 8.2.3995 or Neovim version 0.9.5. The requirements
were updated in April 2024 after the release of VimTeX 2.15. If you are stuck
on older versions of Vim or Neovim, then you should not use the most recent
version of VimTeX, but instead remain at the v2.15 tag.
Some features require external tools. For example, the default compiler backend
relies on [latexmk](https://www.cantab.net/users/johncollins/latexmk/index.html).
Users are encouraged to read the requirements section in the
[documentation](doc/vimtex.txt) (`:h vimtex-requirements`).
## Installation
There are a lot of methods for installing plugins.
The following explains the most common and popular approaches.
**Note**: Many plugin managers provide mechanisms to lazy load plugins. Please
don't use this for VimTeX! VimTeX is already lazy loaded by virtue of being
a filetype plugin and by using the autoload mechanisms. There is therefore
nothing to gain by forcing VimTeX to lazily load through the plugin
manager. In fact, doing it will _break_ the inverse-search mechanism, which
relies on a _global_ command (`:VimtexInverseSearch`).
### lazy.nvim
In Neovim, [lazy.nvim](https://github.com/folke/lazy.nvim) is probably the most popular plugin manger.
To install VimTeX, add a plugin spec similar to this:
```lua
{
"lervag/vimtex",
lazy = false, -- we don't want to lazy load VimTeX
-- tag = "v2.15", -- uncomment to pin to a specific release
init = function()
-- VimTeX configuration goes here
end
}
```
### vim-plug
If you use [vim-plug](https://github.com/junegunn/vim-plug), then add *one* of the following lines to your configuration.
The first will use the latest versions from the `master` branch, whereas the second will pin to a release tag.
```vim
Plug 'lervag/vimtex'
Plug 'lervag/vimtex', { 'tag': 'v2.15' }
```
### Other
There are many other plugin managers out there.
They are typically well documented, and it should be straightforward to extrapolate the above snippets.
**Note**: If you use the built-in package feature, then:
* Make sure to read and understand the package feature: `:help package`!
* Use the `/pack/foo/start` subdirectory to make sure the filetype plugin is
automatically loaded for the `tex` filetypes.
* Helptags are not generated automatically. Run `:helptags` to generate them.
* Please note that by default Vim puts custom `/start/` plugin directories at
the end of the `&runtimepath`. This means the built in filetype plugin is
loaded, which prevents VimTeX from loading. See
[#1413](https://github.com/lervag/vimtex/issues/1413) for two suggested
solutions to this. To see which scripts are loaded and in which order, use
`:scriptnames`.
* For more information on how to use the Vim native package solution, see
[here](https://vi.stackexchange.com/questions/9522/what-is-the-vim8-package-feature-and-how-should-i-use-it)
and [here](https://shapeshed.com/vim-packages/).
## Configuration
After installing VimTeX, you should edit your `.vimrc` file or `init.vim` file
to configure VimTeX to your liking. Users should read the documentation to
learn the various configuration possibilities, but the below is a simple
overview of some of the main aspects.
**PLEASE don't just copy this without reading the comments!**
```vim
" This is necessary for VimTeX to load properly. The "indent" is optional.
" Note that most plugin managers will do this automatically.
filetype plugin indent on
" This enables Vim's and neovim's syntax-related features. Without this, some
" VimTeX features will not work (see ":help vimtex-requirements" for more
" info).
syntax enable
" Viewer options: One may configure the viewer either by specifying a built-in
" viewer method:
let g:vimtex_view_method = 'zathura'
" Or with a generic interface:
let g:vimtex_view_general_viewer = 'okular'
let g:vimtex_view_general_options = '--unique file:@pdf\#src:@line@tex'
" VimTeX uses latexmk as the default compiler backend. If you use it, which is
" strongly recommended, you probably don't need to configure anything. If you
" want another compiler backend, you can change it as follows. The list of
" supported backends and further explanation is provided in the documentation,
" see ":help vimtex-compiler".
let g:vimtex_compiler_method = 'latexrun'
" Most VimTeX mappings rely on localleader and this can be changed with the
" following line. The default is usually fine and is the symbol "\".
let maplocalleader = ","
```
**Note**: If the compiler or the viewer doesn't start properly, one may
type `<localleader>li` to view the system commands that were executed to
start them. To inspect the compiler output, use `<localleader>lo`.
## Quick Start
The following video shows how to use VimTeX's main features (credits:
[@DustyTopology](https://github.com/DustyTopology) from
[#1946](https://github.com/lervag/vimtex/issues/1946#issuecomment-846345095)).
The example LaTeX file used in the video is available under
[`test/example-quick-start/main.tex`](test/example-quick-start/main.tex) and it
may be instructive to copy the file and play with it to learn some of these
basic functions.
https://user-images.githubusercontent.com/66584581/119213849-1b7d4080-ba77-11eb-8a31-7ff7b9a4a020.mp4
### Tutorial
Both new and experienced users are encouraged to read the excellent guide by
@ejmastnak: [Getting started with the VimTeX plugin](https://ejmastnak.com/tutorials/vim-latex/vimtex/).
The guide covers all the fundamentals of setting up a VimTeX-based LaTeX
workflow, including usage of the VimTeX plugin, compilation, setting up forward
and inverse search with a PDF reader, and Vimscript tools for user-specific
customization.
### Documentation
Users are of course _strongly_ encouraged to read the documentation, at least
the introduction, to learn about the different features and possibilities
provided by VimTeX (see [`:h vimtex`](doc/vimtex.txt)). Advanced users and
potential developers may also be interested in reading the supplementary
documents:
* [CONTRIBUTING.md](CONTRIBUTING.md)
* [DOCUMENTATION.md](DOCUMENTATION.md)
## Screenshots
Here is an example of the syntax highlighting provided by VimTeX. The conceal
feature is active on the right-hand side split. The example is made by
@DustyTopology with the
[vim-colors-xcode](https://github.com/arzg/vim-colors-xcode) colorscheme with
some minor adjustments [described
here](https://github.com/lervag/vimtex/issues/1946#issuecomment-843674951).
![Syntax example](https://github.com/lervag/vimtex-media/blob/main/img/syntax.png)
### GIFs
See the file [VISUALS.md](VISUALS.md) for screencast-style GIFs demonstrating
VimTeX's core motions, text-editing commands, and text objects.
## Features
Below is a list of features offered by VimTeX. The features are accessible as
both commands and mappings. The mappings generally start with `<localleader>l`,
but if desired one can disable default mappings to define custom mappings.
Nearly all features are enabled by default, but each feature may be disabled if
desired. The two exceptions are code folding and formating, which are disabled
by default and must be manually enabled.
- Document compilation with
[latexmk](https://www.cantab.net/users/johncollins/latexmk/index.html),
[latexrun](https://github.com/aclements/latexrun),
[tectonic](https://tectonic-typesetting.github.io), or
[arara](https://github.com/cereda/arara)
- LaTeX log parsing for quickfix entries using
- internal method
- [pplatex](https://github.com/stefanhepp/pplatex)
- Compilation of selected part of document
- Support for several PDF viewers with forward search
- [MuPDF](http://www.mupdf.com/)
- [Okular](https://okular.kde.org/)
- [qpdfview](https://launchpad.net/qpdfview)
- [Skim](http://skim-app.sourceforge.net/)
- [SumatraPDF](http://www.sumatrapdfreader.org/free-pdf-reader.html)
- [TeXShop](https://pages.uoregon.edu/koch/texshop/)
- [Zathura](https://pwmt.org/projects/zathura/)
- Other viewers are supported through a general interface
- Completion of
- citations
- labels
- commands
- file names for figures, input/include, includepdf, includestandalone
- glossary entries
- package and documentclass names based on available `.sty` and `.cls` files
- Document navigation through
- table of contents
- table of labels
- proper settings for `'include'`, `'includexpr'`, `'suffixesadd'` and
`'define'`, which among other things
- allow `:h include-search` and `:h definition-search`
- give enhanced `gf` command
- Easy access to (online) documentation of packages
- Word count (through `texcount`)
- Motions ([link to GIF demonstrations](VISUALS.md#motion-commands))
- Move between section boundaries with `[[`, `[]`, `][`, and `]]`
- Move between environment boundaries with `[m`, `[M`, `]m`, and `]M`
- Move between math environment boundaries with `[n`, `[N`, `]n`, and `]N`
- Move between frame environment boundaries with `[r`, `[R`, `]r`, and `]R`
- Move between comment boundaries with `[*` and `]*`
- Move between matching delimiters with `%`
- Text objects ([link to GIF demonstrations](VISUALS.md#text-objects))
- `ic ac` Commands
- `id ad` Delimiters
- `ie ae` LaTeX environments
- `i$ a$` Math environments
- `iP aP` Sections
- `im am` Items
- Other mappings ([link to GIF demonstrations](VISUALS.md#deleting-surrounding-latex-content))
- Delete the surrounding command, environment or delimiter with
`dsc`/`dse`/`ds$`/`dsd`
- Change the surrounding command, environment or delimiter with
`csc`/`cse`/`cs$`/`csd`
- Toggle starred command or environment with `tsc`/`tse`
- Toggle inline and displaymath with `ts$`
- Toggle between e.g. `()` and `\left(\right)` with `tsd`
- Toggle (inline) fractions with `tsf`
- Toggle line-break macro `\\` with `tsb`
- Close the current environment/delimiter in insert mode with `]]`
- Add `\left ... \right)` modifiers to surrounding delimiters with `<F8>`
- Insert new command with `<F7>`
- Convenient insert mode mappings for faster typing of e.g. maths
- Context menu on citations (e.g. `\cite{...}`) mapped to `<cr>`
- Improved folding (`:h 'foldexpr'`)
- Improved indentation (`:h 'indentexpr'`)
- Syntax highlighting
- A consistent core syntax specification
- General syntax highlighting for several popular LaTeX packages
- Nested syntax highlighting for several popular LaTeX packages
- Highlight matching delimiters
- Support for multi-file project packages
- [import](http://ctan.uib.no/macros/latex/contrib/import/import.pdf)
- [subfiles](http://ctan.uib.no/macros/latex/contrib/subfiles/subfiles.pdf)
See the documentation for a thorough introduction to VimTeX (e.g. `:h vimtex`).
## Other relevant plugins
Even though VimTeX provides a lot of nice features for working with LaTeX
documents, there are several features that are better served by other,
dedicated plugins. For a more detailed listing of these, please see [`:help
vimtex-and-friends`](doc/vimtex.txt#L540).
### Linting and syntax checking
* [ale](https://github.com/w0rp/ale)
* [neomake](https://github.com/neomake/neomake)
* [syntastic](https://github.com/vim-syntastic/syntastic)
### Snippets and templates
* [UltiSnips](https://github.com/SirVer/ultisnips)
* [neosnippet](https://github.com/Shougo/neosnippet.vim)
### Tag navigation
* [vim-gutentags](https://github.com/ludovicchabant/vim-gutentags)
## Alternatives
The following are some alternative LaTeX plugins for Vim:
* [LaTeX-Suite](http://vim-latex.sourceforge.net)
The main difference between VimTeX and LaTeX-Suite (aka vim-latex) is
probably that VimTeX does not try to implement a full fledged IDE for LaTeX
inside Vim. E.g.:
* VimTeX does not provide a full snippet feature, because this is better
handled by [UltiSnips](https://github.com/SirVer/ultisnips) or
[neosnippet](https://github.com/Shougo/neosnippet.vim) or similar snippet
engines.
* VimTeX builds upon Vim principles: It provides text objects for
environments, inline math, it provides motions for sections and
paragraphs
* VimTeX uses `latexmk`, `latexrun`, `tectonic` or `arara` for compilation
with a callback feature to get instant feedback on compilation errors
* VimTeX is very modular: if you don't like a feature, you can turn it off.
* [TexMagic.nvim](https://github.com/jakewvincent/texmagic.nvim)
"A simple, lightweight Neovim plugin that facilitates LaTeX build engine
selection via magic comments. It is designed with the TexLab LSP server's
build functionality in mind, which at the time of this plugin's inception
had to be specified in init.lua/init.vim and could not be set on
a by-project basis."
This plugin should be combined with the TexLab LSP server, and it only
works on neovim.
* [LaTeX-Box](https://github.com/LaTeX-Box-Team/LaTeX-Box)
VimTeX currently has most of the features of LaTeX-Box, as well as
some additional ones. See [here](#features) for a relatively complete list
of features.
One particular feature that LaTeX-Box has but VimTeX misses, is the ability
to do single-shot compilation _with callback_. This functionality was
removed because it adds a lot of complexity for relatively little gain
(IMHO).
* [AutomaticTexPlugin](http://atp-vim.sourceforge.net)
* [vim-latex-live-preview](https://github.com/xuhdev/vim-latex-live-preview)
For more alternatives and more information and discussions regarding LaTeX
plugins for Vim, see:
* [What are the differences between LaTeX plugins](http://vi.stackexchange.com/questions/2047/what-are-the-differences-between-latex-plugins)
* [List of LaTeX editors (not only Vim)](https://tex.stackexchange.com/questions/339/latex-editors-ides)

View File

@ -0,0 +1,257 @@
# VimTeX Visualized
This page contains animated GIFs that demonstrate many of the core VimTeX
editing features listed in `:help vimtex-features`. The related mappings are
documented in detail at `:help vimtex-mappings`. The GIFs and accompanying
descriptions are used with permission from
[@ejmastnak](https://github.com/ejmastnak)'s guide to [Getting started with the
VimTeX plugin](https://www.ejmastnak.com/tutorials/vim-latex/vimtex.html).
Hopefully, the animations can give you a clearer mental image of what VimTeX's
mappings do and how you might use them. You may want to scroll through this page
while simultaneously looking through `:help vimtex-features`—the animations
should nicely complement the plain-text documentation.
You can find a description of how the GIFs were made [at the bottom of this
page](#how-these-gifs-were-made).
#### This page is community-maintained
* This page is made possible only with help from the community.
[@ejmastnak](https://github.com/ejmastnak), not
[@lervag](https://github.com/lervag), takes primary responsibility for
maintaining it, but contributions from all VimTeX users are welcome.
* If you notice mistakes or outdated content (following a VimTeX update, say),
feel free to open a PR to fix it yourself. Alternatively, contact
[@ejmastnak](https://github.com/ejmastnak) at
[ejmastnak@gmail.com](mailto:ejmastnak@gmail.com), who will be happy to help
fix it.
## Table of contents
<!-- vim-markdown-toc GFM -->
* [Motion commands](#motion-commands)
* [Navigating sections](#navigating-sections)
* [Navigating environments](#navigating-environments)
* [Navigating math zones](#navigating-math-zones)
* [Navigating frames](#navigating-frames)
* [Navigating matching delimiters](#navigating-matching-delimiters)
* [Text objects](#text-objects)
* [The math text object](#the-math-text-object)
* [The section, delimiter, and command text objects](#the-section-delimiter-and-command-text-objects)
* [The environment and item text objects](#the-environment-and-item-text-objects)
* [Deleting surrounding LaTeX content](#deleting-surrounding-latex-content)
* [Delete surrounding commands](#delete-surrounding-commands)
* [Delete surrounding environments](#delete-surrounding-environments)
* [Delete surrounding math zones](#delete-surrounding-math-zones)
* [Delete surrounding delimiters](#delete-surrounding-delimiters)
* [Changing surrounding LaTeX content](#changing-surrounding-latex-content)
* [Change surrounding commands](#change-surrounding-commands)
* [Change surrounding environments](#change-surrounding-environments)
* [Change surrounding math zones](#change-surrounding-math-zones)
* [Change surrounding delimiters](#change-surrounding-delimiters)
* [Toggling commands](#toggling-commands)
* [Toggling starred commands and environments](#toggling-starred-commands-and-environments)
* [Toggling between inline and display math](#toggling-between-inline-and-display-math)
* [Toggling delimiter modifiers](#toggling-delimiter-modifiers)
* [Toggling fractions](#toggling-fractions)
* [How these GIFs were made](#how-these-gifs-were-made)
<!-- vim-markdown-toc -->
## Motion commands
### Navigating sections
Use `]]` to jump to the beginning of the next `\section`, `\subsection` or
`\subsubsection`, whichever comes first. Use `[[` to jump backward through
sections, and see the similar shortcuts `][` and `[]` in the VimTeX
documentation at `:help <Plug>(vimtex-][)` and `:help <Plug>(vimtex-[])`.
![Navigating sections](https://github.com/lervag/vimtex-media/blob/main/gif/move/move-section.gif)
### Navigating environments
Use `]m` and `[m` to jump to the next or previous environment `\begin{}`
command. See the VimTeX documentation for the similar shortcuts `]M` and `[M`,
described in `:help <Plug>(vimtex-]M)` and `:help <Plug>(vimtex-[M)`.
![Navigating environments](https://github.com/lervag/vimtex-media/blob/main/gif/move/move-environment.gif)
### Navigating math zones
Use `]n` and `[n` to jump to the beginning of the next or previous math zone.
See the VimTeX documentation for the similar shortcuts `]N` and `[N`,
described in `:help <Plug>(vimtex-]N)` and `:help <Plug>(vimtex-[N)`.
![Navigating math zones](https://github.com/lervag/vimtex-media/blob/main/gif/move/move-math.gif)
### Navigating frames
Use `]r` and `[r` to jump to the beginning of the next or previous Beamer
`frame` environment. See the VimTeX documentation for the similar shortcuts
`]R` and `[R`, described in `:help <Plug>(vimtex-]R)` and `:help
<Plug>(vimtex-[R)`.
![Navigating frames](https://github.com/lervag/vimtex-media/blob/main/gif/move/move-frame.gif)
### Navigating matching delimiters
Use `%` to move between matching delimiters, inline-math `$` delimiters, and LaTeX environments.
![Navigating matching delimiters](https://github.com/lervag/vimtex-media/blob/main/gif/move/move-matching.gif)
## Text objects
VimTeX provides text objects for commands, delimiters, environments,
math zones, sections, and items. The following GIFs use Vim's visual
mode to show the scope of the text objects.
### The math text object
The `i$` and `a$` text objects select inline math, display math, and
common math environments.
![The math text object](https://github.com/lervag/vimtex-media/blob/main/gif/text-objects/obj-math.gif)
### The section, delimiter, and command text objects
The `iP` and `aP` text objects select LaTeX sections (their
subsection variations); the `id` and `ad` objects select delimiters
(parentheses, brackets, braces...); the `ic` and `ac` objects select
LaTeX commands.
![The section, delimiter, and command text objects](https://github.com/lervag/vimtex-media/blob/main/gif/text-objects/obj-sec-delim-cmd.gif)
### The environment and item text objects
The `ie` and `ae` text objects select LaTeX environments and the `im`
and `am` objects select items in enumerated environments.
![The environment and item text objects](https://github.com/lervag/vimtex-media/blob/main/gif/text-objects/obj-env-item.gif)
## Deleting surrounding LaTeX content
### Delete surrounding commands
Use `dsc` to delete a LaTeX command while preserving the command's argument(s);
the `dsc` mapping also recognizes and correctly deletes parameters inside square
brackets.
![`dsc`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/dsc.gif)
### Delete surrounding environments
Use `dse` to delete the `\begin{}` and `\end{}` declaration surrounding a LaTeX
environment without changing the environment contents.
![`dse`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/dse.gif)
### Delete surrounding math zones
Use `ds$` to delete surrounding math zones (display math, standard environments,
and inline math) without changing the math contents.
![`ds$`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/dsm.gif)
### Delete surrounding delimiters
Use `dsd` to delete delimiters (e.g. `()`, `[]`, `{}`, *and* any of their `\left
\right`, `\big \big` variants) without changing the enclosed content.
![`dsd`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/dsd.gif)
## Changing surrounding LaTeX content
### Change surrounding commands
Use `csc` to change a LaTeX command while preserving the command's argument(s).
![`csc`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/csc.gif)
### Change surrounding environments
Use `cse` to change the type of a LaTeX environment without changing the
environment contents.
![`cse`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/cse.gif)
### Change surrounding math zones
Use `cs$` to change the type of surrounding math zone without changing the math
contents. You can switch between display math, standard environments, and inline
math.
![`cs$`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/csm.gif)
### Change surrounding delimiters
Use `csd` to change delimiters (e.g. `()`, `[]`, `{}`, and any of their `\left
\right`, `\big \big` variants) without changing the enclosed content; the `csd`
command is "smart" and correctly recognizes and preserves `\left \right`-style
modifiers.
![`csd`](https://github.com/lervag/vimtex-media/blob/main/gif/change-delete/csd.gif)
## Toggling commands
### Toggling starred commands and environments
Use `tsc` and `tse` to toggle between starred and un-starred versions of
commands and environments, respectively.
![`tsc` and `tse`](https://github.com/lervag/vimtex-media/blob/main/gif/toggle/tsc-tse.gif)
### Toggling between inline and display math
Use `ts$` to toggle between inline math, display math, and standard math environments.
![`ts$`](https://github.com/lervag/vimtex-media/blob/main/gif/toggle/tsm.gif)
### Toggling delimiter modifiers
Use `tsd` to change between plain and `\left`/`\right` versions of delimiters.
Use the `g:vimtex_delim_toggle_mod_list` variable to add more modifiers to the
delimiter toggle list. (e.g. `\big` as in the GIF below)
![`tsd`](https://github.com/lervag/vimtex-media/blob/main/gif/toggle/tsd.gif)
### Toggling fractions
Use `tsf` to toggle between inline and `\frac{}{}` versions of fractions.
![`tsf`](https://github.com/lervag/vimtex-media/blob/main/gif/toggle/tsf.gif)
## How these GIFs were made
(Based on interest and discussion in issue
[#2685](https://github.com/lervag/vimtex/issues/2685).)
The basic toolkit is [Menyoki](https://github.com/orhun/menyoki) for
recording the GIFs and [screenkey](https://gitlab.com/screenkey/screenkey) to
display the keys being typed, all running on a Linux system using the X11
window system.
On top of this are some aesthetic details to make the GIFs look nicer,
including:
- [Goyo](https://github.com/junegunn/goyo.vim) to remove Vim peripherals
(status bar, line numbers, etc.) for a cleaner look
- [Limelight](https://github.com/junegunn/limelight.vim) to draw focus to the
currently selected paragraph (and gray out the rest of the document)
- Screen recording region (crop, basically) set via Menyoki to exactly capture
the terminal window (and not e.g. the rest of my desktop)
- Enlarged terminal font for the duration of the GIF recording for better
readability
- Vim and screenkey color schemes and fonts aligned for visual consistency.
The aesthetic details and cropping are wrapped in shell scripts for
repeatability across multiple GIF recordings—the original scripts and auxiliary
files can be found in the GitHub repo
[ejmastnak/ejmastnak.github.io](https://github.com/ejmastnak/ejmastnak.github.io/tree/main/tutorials/vim-latex/gifs),
although they might be difficult to parse without additional context.
Feel free to contact [@ejmastnak](https://github.com/ejmastnak) if you're
interested in the details or recording similar GIFs.

View File

@ -0,0 +1,27 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
if !get(g:, 'vimtex_enabled', 1)
finish
endif
if exists('b:did_ftplugin_vimtex')
finish
endif
let b:did_ftplugin_vimtex = 1
" Check for plugin clashes.
" Note: This duplicates the code in health/vimtex.vim:s:check_plugin_clash()
let s:scriptnames = vimtex#util#command('scriptnames')
let s:latexbox = !empty(filter(copy(s:scriptnames), "v:val =~# 'latex-box'"))
if s:latexbox
call vimtex#log#warning([
\ 'Conflicting plugin detected: LaTeX-Box',
\ 'VimTeX does not work as expected when LaTeX-Box is installed!',
\ 'Please disable or remove it to use VimTeX!',
\])
endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,184 @@
function! health#vimtex#check() abort
call vimtex#options#init()
call v:lua.vim.health.start('VimTeX')
call s:check_general()
call s:check_plugin_clash()
call s:check_view()
call s:check_compiler()
endfunction
function! s:check_general() abort " {{{1
if !has('nvim') || v:version < 800
call v:lua.vim.health.warn('VimTeX works best with Vim 8 or neovim')
else
call v:lua.vim.health.ok('Vim version should have full support!')
endif
if !executable('bibtex')
call v:lua.vim.health.warn('bibtex is not executable!',
\ 'bibtex is required for cite completions.')
endif
if !executable('biber')
call v:lua.vim.health.warn(
\ 'biber is not executable!',
\ 'Biber is often required so this may give unexpected problems.')
endif
endfunction
" }}}1
function! s:check_compiler() abort " {{{1
if !g:vimtex_compiler_enabled | return | endif
if !executable(g:vimtex_compiler_method)
let l:ind = ' '
call v:lua.vim.health.error(printf(
\ '|g:vimtex_compiler_method| (`%s`) is not executable!',
\ g:vimtex_compiler_method))
return
endif
call v:lua.vim.health.ok('Compiler should work!')
endfunction
" }}}1
function! s:check_plugin_clash() abort " {{{1
" Note: This duplicates the code in after/ftplugin/tex.vim
let l:scriptnames = vimtex#util#command('scriptnames')
let l:latexbox = !empty(filter(copy(l:scriptnames), "v:val =~# 'latex-box'"))
if l:latexbox
call v:lua.vim.health.warn('Conflicting plugin detected: LaTeX-Box')
call v:lua.vim.health.info('VimTeX does not work as expected when LaTeX-Box is installed!')
call v:lua.vim.health.info('Please disable or remove it to use VimTeX!')
endif
endfunction
" }}}1
function! s:check_view() abort " {{{1
call s:check_view_{g:vimtex_view_method}()
if executable('xdotool') && !executable('pstree')
call v:lua.vim.health.warn('pstree is not available',
\ 'vimtex#view#inverse_search is better if pstree is available.')
endif
endfunction
" }}}1
function! s:check_view_general() abort " {{{1
if executable(g:vimtex_view_general_viewer)
call v:lua.vim.health.ok('General viewer should work properly!')
else
call v:lua.vim.health.error(
\ 'Selected viewer is not executable!',
\ '- Selection: ' . g:vimtex_view_general_viewer,
\ '- Please see :h g:vimtex_view_general_viewer')
endif
endfunction
" }}}1
function! s:check_view_zathura() abort " {{{1
let l:ok = 1
if !executable('zathura')
call v:lua.vim.health.error('Zathura is not executable!')
let l:ok = 0
endif
if !executable('xdotool')
call v:lua.vim.health.warn('Zathura requires xdotool for forward search!')
let l:ok = 0
endif
if l:ok
call v:lua.vim.health.ok('Zathura should work properly!')
endif
endfunction
" }}}1
function! s:check_view_zathura_simple() abort " {{{1
let l:ok = 1
if !executable('zathura')
call v:lua.vim.health.error('Zathura is not executable!')
let l:ok = 0
endif
if l:ok
call v:lua.vim.health.ok('Zathura should work properly!')
endif
endfunction
" }}}1
function! s:check_view_mupdf() abort " {{{1
let l:ok = 1
if !executable('mupdf')
call v:lua.vim.health.error('MuPDF is not executable!')
let l:ok = 0
endif
if !executable('xdotool')
call v:lua.vim.health.warn('MuPDF requires xdotool for forward search!')
let l:ok = 0
endif
if !executable('synctex')
call v:lua.vim.health.warn('MuPDF requires synctex for forward search!')
let l:ok = 0
endif
if l:ok
call v:lua.vim.health.ok('MuPDF should work properly!')
endif
endfunction
" }}}1
function! s:check_view_sioyek() abort " {{{1
let l:ok = 1
if !executable(g:vimtex_view_sioyek_exe)
call v:lua.vim.health.error('Sioyek is not executable!')
let l:ok = 0
endif
if l:ok
call v:lua.vim.health.ok('Sioyek should work properly!')
endif
endfunction
" }}}1
function! s:check_view_skim() abort " {{{1
call vimtex#jobs#run(join([
\ 'osascript -e ',
\ '''tell application "Finder" to POSIX path of ',
\ '(get application file id (id of application "Skim") as alias)''',
\]))
if v:shell_error == 0
call v:lua.vim.health.ok('Skim viewer should work!')
else
call v:lua.vim.health.error('Skim is not installed!')
endif
endfunction
" }}}1
function! s:check_view_texshop() abort " {{{1
let l:cmd = join([
\ 'osascript -e ',
\ '''tell application "Finder" to POSIX path of ',
\ '(get application file id (id of application "TeXShop") as alias)''',
\])
if system(l:cmd)
call v:lua.vim.health.error('TeXShop is not installed!')
else
call v:lua.vim.health.ok('TeXShop viewer should work!')
endif
endfunction
" }}}1

View File

@ -0,0 +1,83 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
let s:save_cpo = &cpo
set cpo&vim
let s:source = {
\ 'name' : 'vimtex',
\ 'sorters' : 'sorter_nothing',
\ 'default_kind' : 'jump_list',
\ 'syntax' : 'uniteSource__vimtex',
\ 'entries' : [],
\ 'maxlevel' : 1,
\ 'hooks' : {},
\}
function! s:source.gather_candidates(args, context) abort " {{{1
if exists('b:vimtex')
let s:source.entries = vimtex#parser#toc()
let s:source.maxlevel = max(map(copy(s:source.entries), 'v:val.level'))
endif
return map(copy(s:source.entries),
\ 's:create_candidate(v:val, s:source.maxlevel)')
endfunction
" }}}1
function! s:source.hooks.on_syntax(args, context) abort " {{{1
syntax match VimtexTocSecs /.* @\d$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocSec0 /.* @0$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocSec1 /.* @1$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocSec2 /.* @2$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocSec3 /.* @3$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocSec4 /.* @4$/
\ contains=VimtexTocNum,VimtexTocTag,@Tex
\ contained containedin=uniteSource__vimtex
syntax match VimtexTocNum
\ /\%69v\%(\%([A-Z]\+\>\|\d\+\)\%(\.\d\+\)*\)\?\s*@\d$/
\ contains=VimtexTocLevel
\ contained containedin=VimtexTocSec[0-9*]
syntax match VimtexTocTag
\ /\[.\]\s*@\d$/
\ contains=VimtexTocLevel
\ contained containedin=VimtexTocSec[0-9*]
syntax match VimtexTocLevel
\ /@\d$/ conceal
\ contained containedin=VimtexTocNum,VimtexTocTag
endfunction
" }}}1
function! s:create_candidate(entry, maxlevel) abort " {{{1
let level = a:maxlevel - a:entry.level
let title = printf('%-65S%-10s',
\ strpart(repeat(' ', 2*level) . a:entry.title, 0, 60),
\ b:vimtex.toc.print_number(a:entry.number))
return {
\ 'word' : title,
\ 'abbr' : title . ' @' . level,
\ 'action__path' : a:entry.file,
\ 'action__line' : get(a:entry, 'line', 0),
\ }
endfunction
" }}}1
function! unite#sources#vimtex#define() abort
return s:source
endfunction
let &cpo = s:save_cpo

View File

@ -0,0 +1,434 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#init() abort " {{{1
if exists('#User#VimtexEventInitPre')
doautocmd <nomodeline> User VimtexEventInitPre
endif
call vimtex#options#init()
call s:init_state()
call s:init_buffer()
call s:init_default_mappings()
if exists('#User#VimtexEventInitPost')
doautocmd <nomodeline> User VimtexEventInitPost
endif
augroup vimtex_main
autocmd!
autocmd VimLeave * call s:quit()
augroup END
endfunction
" }}}1
function! s:init_state() abort " {{{1
call vimtex#state#init()
call vimtex#state#init_local()
endfunction
" }}}1
function! s:init_buffer() abort " {{{1
try
let l:disabled_modules = s:init_buffer_{&filetype}()
catch /E117/
let l:disabled_modules = []
endtry
" Define autocommands
augroup vimtex_buffers
autocmd! * <buffer>
autocmd BufFilePre <buffer> call s:filename_changed_pre()
autocmd BufFilePost <buffer> call s:filename_changed_post()
autocmd BufUnload <buffer> call s:buffer_deleted('unload')
autocmd BufWipeout <buffer> call s:buffer_deleted('wipe')
augroup END
" Initialize buffer settings for sub modules
call extend(l:disabled_modules, get(b:vimtex, 'disabled_modules', []))
for l:mod in filter(copy(s:modules),
\ 'index(l:disabled_modules, v:val) < 0')
try
call vimtex#{l:mod}#init_buffer()
catch /E117.*#init_/
catch /E127.*vimtex#profile#/
endtry
endfor
endfunction
" }}}1
function! s:init_buffer_tex() abort " {{{1
setlocal comments=sO:%\ -,mO:%\ \ ,eO:%%,:%
setlocal commentstring=\%\ %s
for l:suf in [
\ '.sty',
\ '.cls',
\ '.log',
\ '.aux',
\ '.bbl',
\ '.out',
\ '.blg',
\ '.brf',
\ '.cb',
\ '.dvi',
\ '.fdb_latexmk',
\ '.fls',
\ '.idx',
\ '.ilg',
\ '.ind',
\ '.inx',
\ '.pdf',
\ '.synctex.gz',
\ '.toc',
\ ]
execute 'set suffixes+=' . l:suf
endfor
setlocal suffixesadd=.tex,.sty,.cls
setlocal iskeyword+=:
setlocal includeexpr=vimtex#include#expr()
let &l:include = g:vimtex#re#tex_include
let &l:define = '\v\\%('
\ . '([egx]|mathchar|count|dimen|muskip|skip|toks)?def'
\ . '|font'
\ . '|(future)?let'
\ . '|new(count|dimen|skip|muskip|box|toks|read|write|fam|insert)'
\ . '|(re)?new(boolean|command|counter|environment'
\ . '|font|if|length|savebox|theorem(style)?)'
\ . '|DeclareMathOperator'
\ . '|bibitem%(\[[^]]*\])?'
\ . ')'
" Specify list of modules to disable
return []
endfunction
" }}}1
function! s:init_buffer_bib() abort " {{{1
setlocal comments=sO:%\ -,mO:%\ \ ,eO:%%,:%
setlocal commentstring=\%\ %s
for l:suf in [
\ '.sty',
\ '.cls',
\ '.log',
\ '.aux',
\ '.bbl',
\ '.out',
\ '.blg',
\ '.brf',
\ '.cb',
\ '.dvi',
\ '.fdb_latexmk',
\ '.fls',
\ '.idx',
\ '.ilg',
\ '.ind',
\ '.inx',
\ '.pdf',
\ '.synctex.gz',
\ '.toc',
\ ]
execute 'set suffixes+=' . l:suf
endfor
setlocal suffixesadd=.tex,.bib
if g:vimtex_fold_bib_enabled
call vimtex#fold#bib#init()
endif
" Specify list of modules to disable
return [
\ 'fold', 'matchparen', 'format', 'doc', 'imaps', 'delim',
\ 'env', 'motion', 'complete',
\]
endfunction
" }}}1
function! s:init_default_mappings() abort " {{{1
if !g:vimtex_mappings_enabled | return | endif
call s:map_prefixed(0, 'n', 'i', '<plug>(vimtex-info)')
call s:map_prefixed(0, 'n', 'I', '<plug>(vimtex-info-full)')
call s:map_prefixed(0, 'n', 'x', '<plug>(vimtex-reload)')
call s:map_prefixed(0, 'n', 'X', '<plug>(vimtex-reload-state)')
call s:map_prefixed(1, 'n', 's', '<plug>(vimtex-toggle-main)')
call s:map_prefixed(0, 'n', 'q', '<plug>(vimtex-log)')
call s:map_prefixed(1, 'n', 'a', '<plug>(vimtex-context-menu)')
call s:map(0, 'n', 'ds$', '<plug>(vimtex-env-delete-math)')
call s:map(0, 'n', 'cs$', '<plug>(vimtex-env-change-math)')
call s:map(0, 'n', 'dse', '<plug>(vimtex-env-delete)')
call s:map(0, 'n', 'cse', '<plug>(vimtex-env-change)')
call s:map(0, 'n', 'tse', '<plug>(vimtex-env-toggle-star)')
call s:map(0, 'n', 'ts$', '<plug>(vimtex-env-toggle-math)')
call s:map(0, 'n', '<F6>', '<plug>(vimtex-env-surround-line)')
call s:map(0, 'x', '<F6>', '<plug>(vimtex-env-surround-visual)')
call s:map(0, 'n', 'dsc', '<plug>(vimtex-cmd-delete)')
call s:map(0, 'n', 'csc', '<plug>(vimtex-cmd-change)')
call s:map(0, 'n', 'tsc', '<plug>(vimtex-cmd-toggle-star)')
call s:map(0, 'n', 'tsf', '<plug>(vimtex-cmd-toggle-frac)')
call s:map(0, 'x', 'tsf', '<plug>(vimtex-cmd-toggle-frac)')
call s:map(0, 'n', 'tsb', '<plug>(vimtex-cmd-toggle-break)')
call s:map(0, 'i', '<F7>', '<plug>(vimtex-cmd-create)')
call s:map(0, 'n', '<F7>', '<plug>(vimtex-cmd-create)')
call s:map(0, 'x', '<F7>', '<plug>(vimtex-cmd-create)')
call s:map(0, 'n', 'dsd', '<plug>(vimtex-delim-delete)')
call s:map(0, 'n', 'csd', '<plug>(vimtex-delim-change-math)')
call s:map(0, 'n', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
call s:map(0, 'x', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
call s:map(0, 'n', 'tsD', '<plug>(vimtex-delim-toggle-modifier-reverse)')
call s:map(0, 'x', 'tsD', '<plug>(vimtex-delim-toggle-modifier-reverse)')
call s:map(0, 'i', ']]', '<plug>(vimtex-delim-close)')
call s:map(0, 'n', '<F8>', '<plug>(vimtex-delim-add-modifiers)')
if g:vimtex_compiler_enabled
call s:map_prefixed(0, 'n', 'l', '<plug>(vimtex-compile)')
call s:map_prefixed(0, 'n', 'o', '<plug>(vimtex-compile-output)')
call s:map_prefixed(1, 'n', 'L', '<plug>(vimtex-compile-selected)')
call s:map_prefixed(1, 'x', 'L', '<plug>(vimtex-compile-selected)')
call s:map_prefixed(0, 'n', 'k', '<plug>(vimtex-stop)')
call s:map_prefixed(0, 'n', 'K', '<plug>(vimtex-stop-all)')
call s:map_prefixed(0, 'n', 'e', '<plug>(vimtex-errors)')
call s:map_prefixed(0, 'n', 'c', '<plug>(vimtex-clean)')
call s:map_prefixed(0, 'n', 'C', '<plug>(vimtex-clean-full)')
call s:map_prefixed(0, 'n', 'g', '<plug>(vimtex-status)')
call s:map_prefixed(0, 'n', 'G', '<plug>(vimtex-status-all)')
endif
if g:vimtex_motion_enabled
" These are forced in order to overwrite matchit mappings
call s:map(1, 'n', '%', '<plug>(vimtex-%)', 1)
call s:map(1, 'x', '%', '<plug>(vimtex-%)', 1)
call s:map(1, 'o', '%', '<plug>(vimtex-%)', 1)
call s:map(1, 'n', ']]', '<plug>(vimtex-]])')
call s:map(1, 'n', '][', '<plug>(vimtex-][)')
call s:map(1, 'n', '[]', '<plug>(vimtex-[])')
call s:map(1, 'n', '[[', '<plug>(vimtex-[[)')
call s:map(1, 'x', ']]', '<plug>(vimtex-]])')
call s:map(1, 'x', '][', '<plug>(vimtex-][)')
call s:map(1, 'x', '[]', '<plug>(vimtex-[])')
call s:map(1, 'x', '[[', '<plug>(vimtex-[[)')
call s:map(1, 'o', ']]', '<plug>(vimtex-]])')
call s:map(1, 'o', '][', '<plug>(vimtex-][)')
call s:map(1, 'o', '[]', '<plug>(vimtex-[])')
call s:map(1, 'o', '[[', '<plug>(vimtex-[[)')
call s:map(1, 'n', ']M', '<plug>(vimtex-]M)')
call s:map(1, 'n', ']m', '<plug>(vimtex-]m)')
call s:map(1, 'n', '[M', '<plug>(vimtex-[M)')
call s:map(1, 'n', '[m', '<plug>(vimtex-[m)')
call s:map(1, 'x', ']M', '<plug>(vimtex-]M)')
call s:map(1, 'x', ']m', '<plug>(vimtex-]m)')
call s:map(1, 'x', '[M', '<plug>(vimtex-[M)')
call s:map(1, 'x', '[m', '<plug>(vimtex-[m)')
call s:map(1, 'o', ']M', '<plug>(vimtex-]M)')
call s:map(1, 'o', ']m', '<plug>(vimtex-]m)')
call s:map(1, 'o', '[M', '<plug>(vimtex-[M)')
call s:map(1, 'o', '[m', '<plug>(vimtex-[m)')
call s:map(1, 'n', ']N', '<plug>(vimtex-]N)')
call s:map(1, 'n', ']n', '<plug>(vimtex-]n)')
call s:map(1, 'n', '[N', '<plug>(vimtex-[N)')
call s:map(1, 'n', '[n', '<plug>(vimtex-[n)')
call s:map(1, 'x', ']N', '<plug>(vimtex-]N)')
call s:map(1, 'x', ']n', '<plug>(vimtex-]n)')
call s:map(1, 'x', '[N', '<plug>(vimtex-[N)')
call s:map(1, 'x', '[n', '<plug>(vimtex-[n)')
call s:map(1, 'o', ']N', '<plug>(vimtex-]N)')
call s:map(1, 'o', ']n', '<plug>(vimtex-]n)')
call s:map(1, 'o', '[N', '<plug>(vimtex-[N)')
call s:map(1, 'o', '[n', '<plug>(vimtex-[n)')
call s:map(1, 'n', ']R', '<plug>(vimtex-]R)')
call s:map(1, 'n', ']r', '<plug>(vimtex-]r)')
call s:map(1, 'n', '[R', '<plug>(vimtex-[R)')
call s:map(1, 'n', '[r', '<plug>(vimtex-[r)')
call s:map(1, 'x', ']R', '<plug>(vimtex-]R)')
call s:map(1, 'x', ']r', '<plug>(vimtex-]r)')
call s:map(1, 'x', '[R', '<plug>(vimtex-[R)')
call s:map(1, 'x', '[r', '<plug>(vimtex-[r)')
call s:map(1, 'o', ']R', '<plug>(vimtex-]R)')
call s:map(1, 'o', ']r', '<plug>(vimtex-]r)')
call s:map(1, 'o', '[R', '<plug>(vimtex-[R)')
call s:map(1, 'o', '[r', '<plug>(vimtex-[r)')
call s:map(1, 'n', ']/', '<plug>(vimtex-]/)')
call s:map(1, 'n', ']*', '<plug>(vimtex-]*)')
call s:map(1, 'n', '[/', '<plug>(vimtex-[/)')
call s:map(1, 'n', '[*', '<plug>(vimtex-[*)')
call s:map(1, 'x', ']/', '<plug>(vimtex-]/)')
call s:map(1, 'x', ']*', '<plug>(vimtex-]*)')
call s:map(1, 'x', '[/', '<plug>(vimtex-[/)')
call s:map(1, 'x', '[*', '<plug>(vimtex-[*)')
call s:map(1, 'o', ']/', '<plug>(vimtex-]/)')
call s:map(1, 'o', ']*', '<plug>(vimtex-]*)')
call s:map(1, 'o', '[/', '<plug>(vimtex-[/)')
call s:map(1, 'o', '[*', '<plug>(vimtex-[*)')
endif
if g:vimtex_text_obj_enabled
call s:map(0, 'x', 'id', '<plug>(vimtex-id)')
call s:map(0, 'x', 'ad', '<plug>(vimtex-ad)')
call s:map(0, 'o', 'id', '<plug>(vimtex-id)')
call s:map(0, 'o', 'ad', '<plug>(vimtex-ad)')
call s:map(0, 'x', 'i$', '<plug>(vimtex-i$)')
call s:map(0, 'x', 'a$', '<plug>(vimtex-a$)')
call s:map(0, 'o', 'i$', '<plug>(vimtex-i$)')
call s:map(0, 'o', 'a$', '<plug>(vimtex-a$)')
call s:map(1, 'x', 'iP', '<plug>(vimtex-iP)')
call s:map(1, 'x', 'aP', '<plug>(vimtex-aP)')
call s:map(1, 'o', 'iP', '<plug>(vimtex-iP)')
call s:map(1, 'o', 'aP', '<plug>(vimtex-aP)')
call s:map(1, 'x', 'im', '<plug>(vimtex-im)')
call s:map(1, 'x', 'am', '<plug>(vimtex-am)')
call s:map(1, 'o', 'im', '<plug>(vimtex-im)')
call s:map(1, 'o', 'am', '<plug>(vimtex-am)')
if vimtex#text_obj#targets#enabled()
call vimtex#text_obj#targets#init()
" These are handled explicitly to avoid conflict with gitgutter
call s:map(0, 'x', 'ic', '<plug>(vimtex-targets-i)c')
call s:map(0, 'x', 'ac', '<plug>(vimtex-targets-a)c')
call s:map(0, 'o', 'ic', '<plug>(vimtex-targets-i)c')
call s:map(0, 'o', 'ac', '<plug>(vimtex-targets-a)c')
else
if g:vimtex_text_obj_variant ==# 'targets'
call vimtex#log#warning(
\ "Ignoring g:vimtex_text_obj_variant = 'targets'"
\ . " because 'g:loaded_targets' does not exist or is 0.")
endif
let g:vimtex_text_obj_variant = 'vimtex'
call s:map(0, 'x', 'ie', '<plug>(vimtex-ie)')
call s:map(0, 'x', 'ae', '<plug>(vimtex-ae)')
call s:map(0, 'o', 'ie', '<plug>(vimtex-ie)')
call s:map(0, 'o', 'ae', '<plug>(vimtex-ae)')
call s:map(0, 'x', 'ic', '<plug>(vimtex-ic)')
call s:map(0, 'x', 'ac', '<plug>(vimtex-ac)')
call s:map(0, 'o', 'ic', '<plug>(vimtex-ic)')
call s:map(0, 'o', 'ac', '<plug>(vimtex-ac)')
endif
endif
if g:vimtex_toc_enabled
call s:map_prefixed(0, 'n', 't', '<plug>(vimtex-toc-open)')
call s:map_prefixed(0, 'n', 'T', '<plug>(vimtex-toc-toggle)')
endif
if has_key(b:vimtex, 'viewer')
call s:map_prefixed(0, 'n', 'v', '<plug>(vimtex-view)')
if !empty(maparg('<plug>(vimtex-reverse-search)', 'n'))
call s:map_prefixed(1, 'n', 'r', '<plug>(vimtex-reverse-search)')
endif
endif
if g:vimtex_imaps_enabled
call s:map_prefixed(0, 'n', 'm', '<plug>(vimtex-imaps-list)')
endif
if g:vimtex_doc_enabled
call s:map(1, 'n', 'K', '<plug>(vimtex-doc-package)')
endif
endfunction
" }}}1
function! s:filename_changed_pre() abort " {{{1
let s:filename_changed = expand('%:p') ==# b:vimtex.tex
endfunction
" }}}1
function! s:filename_changed_post() abort " {{{1
if s:filename_changed
let l:old = b:vimtex.tex
let b:vimtex.tex = expand('%:p')
let b:vimtex.root = fnamemodify(b:vimtex.tex, ':h')
let b:vimtex.base = fnamemodify(b:vimtex.tex, ':t')
let b:vimtex.name = fnamemodify(b:vimtex.tex, ':t:r')
call vimtex#log#warning('Filename change detected')
call vimtex#log#info('Old: ' . l:old)
call vimtex#log#info('New: ' . b:vimtex.tex)
if has_key(b:vimtex, 'compiler')
if b:vimtex.compiler.is_running()
call vimtex#log#warning('Compilation stopped!')
call vimtex#compiler#stop()
endif
endif
endif
endfunction
" }}}1
function! s:buffer_deleted(reason) abort " {{{1
"
" We need a simple cache of buffer ids because a buffer unload might clear
" buffer variables, so that a subsequent buffer wipe will not trigger a full
" cleanup. By caching the buffer id, we should avoid this issue.
"
let s:buffer_cache = get(s:, 'buffer_cache', {})
let l:file = expand('<afile>')
if !has_key(s:buffer_cache, l:file)
let s:buffer_cache[l:file] = getbufvar(l:file, 'vimtex_id', -1)
endif
if a:reason ==# 'wipe'
call vimtex#state#cleanup(s:buffer_cache[l:file])
call remove(s:buffer_cache, l:file)
endif
endfunction
" }}}1
function! s:quit() abort " {{{1
for l:state in vimtex#state#list_all()
call l:state.cleanup()
endfor
call vimtex#cache#write_all()
endfunction
" }}}1
function! s:map_prefixed(ftype, mode, lhs, rhs) abort " {{{1
let l:lhs = g:vimtex_mappings_prefix . a:lhs
call s:map(a:ftype, a:mode, l:lhs, a:rhs)
endfunction
" }}}1
function! s:map(ftype, mode, lhs, rhs, ...) abort " {{{1
if (a:ftype == 0
\ || a:ftype == 1 && &filetype ==# 'tex'
\ || a:ftype == 2 && &filetype ==# 'bib')
\ && !hasmapto(a:rhs, a:mode)
\ && index(get(g:vimtex_mappings_disable, a:mode, []), a:lhs) < 0
\ && (a:0 > 0
\ || g:vimtex_mappings_override_existing
\ || empty(maparg(a:lhs, a:mode)))
silent execute a:mode . 'map <silent><buffer><nowait>' a:lhs a:rhs
endif
endfunction
" }}}1
" {{{1 Initialize module
let s:modules = map(
\ glob(expand('<sfile>:r') . '/*.vim', 0, 1),
\ { _, x -> fnamemodify(x, ':t:r') })
call remove(s:modules, index(s:modules, 'test'))
" }}}1

View File

@ -0,0 +1,125 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#bib#files() abort " {{{1
if !exists('b:vimtex') | return [] | endif
if has_key(b:vimtex, 'compiler')
if has_key(b:vimtex.packages, 'biblatex')
let l:file = b:vimtex.compiler.get_file('bcf')
if filereadable(l:file)
let l:bibs = map(
\ filter(readfile(l:file), "v:val =~# 'bcf:datasource'"),
\ {_, x -> matchstr(x, '<[^>]*>\zs[^<]*')})
for l:f in filter(copy(l:bibs), {_, x -> x =~# '[*?{[]' })
let l:bibs += glob(l:f, 0, 1)
endfor
if !empty(l:bibs) | return s:validate(l:bibs) | endif
endif
endif
let l:file = b:vimtex.compiler.get_file('blg')
if filereadable(l:file)
let l:bibs = map(
\ filter(readfile(l:file), 'v:val =~# ''^Database file #\d'''),
\ {_, x -> matchstr(x, '#\d\+: \zs.*\ze\.bib$')})
" Ignore '{name}-blx.bib' file (created by biblatex)
if has_key(b:vimtex.packages, 'biblatex')
call filter(l:bibs, 'v:val !~# ''-blx$''')
endif
" Ignore '{name}Notes.bib' file (created by revtex4)
if b:vimtex.documentclass =~# '^revtex4'
call filter(l:bibs, 'v:val !~# ''.Notes$''')
endif
if !empty(l:bibs) | return s:validate(l:bibs) | endif
endif
endif
return s:validate(s:files_manual())
endfunction
" }}}1
function! s:validate(files) abort " {{{1
call filter(a:files, {_, x -> !empty(x)})
call map(a:files, {_, x -> substitute(x, '\%(\.bib\)\?$', '.bib', '')})
call map(a:files, {_, x -> filereadable(x) ? x : vimtex#kpsewhich#find(x)})
call filter(a:files, {_, x -> filereadable(x)})
return a:files
endfunction
" }}}1
function! s:files_manual() abort " {{{1
"
" Search for bibliography files by parsing the source code
" * Parse commands such as \bibliography{file1,file2.bib,...}
"
let l:cache = vimtex#cache#open('bibfiles', {
\ 'local': 1,
\ 'default': {'files': [], 'ftime': -1}
\})
" Handle local file editing (e.g. subfiles package)
let l:id = get(get(b:, 'vimtex_local', {'main_id' : b:vimtex_id}), 'main_id')
let l:vimtex = vimtex#state#get(l:id)
let l:bibfiles = []
for l:file in map(l:vimtex.get_sources(), 'l:vimtex.root . ''/'' . v:val')
let l:current = l:cache.get(l:file)
let l:ftime = getftime(l:file)
if l:ftime > l:current.ftime
let l:cache.modified = 1
let l:current.ftime = l:ftime
let l:current.files = []
for l:entry in map(
\ filter(readfile(l:file), {_, x -> x =~# s:bib_re}),
\ {_, x -> matchstr(x, s:bib_re)})
" Interpolate the \jobname command
let l:entry = substitute(l:entry, '\\jobname', b:vimtex.name, 'g')
" Assume comma separated list of files
let l:files = split(l:entry, ',')
" But also add the unmodified entry for consideration, as the comma may
" be part of the filename or part of a globbing expression.
if len(l:files) > 1
let l:files += [l:entry]
endif
" Now attempt to apply globbing where applicable
for l:exp in filter(copy(l:files), {_, x -> x =~# '[*?{[]'})
try
let l:globbed = glob(l:exp, 0, 1)
let l:files += l:globbed
catch /E220/
endtry
endfor
let l:current.files += l:files
endfor
endif
let l:bibfiles += l:current.files
endfor
" Write cache to file
call l:cache.write()
return uniq(l:bibfiles)
endfunction
" }}}1
let s:bib_re = g:vimtex#re#not_comment . '\\('
\ . join(g:vimtex_bibliography_commands, '|')
\ . ')\s*\{\zs.+\ze}'

View File

@ -0,0 +1,329 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#cache#init_buffer() abort " {{{1
command! -buffer -nargs=1 VimtexClearCache call vimtex#cache#clear(<q-args>)
endfunction
" }}}1
function! vimtex#cache#path(name) abort " {{{1
let l:root = s:root()
if !isdirectory(l:root)
call mkdir(l:root, 'p')
endif
return vimtex#paths#join(l:root, a:name)
endfunction
" }}}1
function! vimtex#cache#wrap(Func, name, ...) abort " {{{1
if !has('lambda')
throw 'error: vimtex#cache#wrap requires +lambda'
endif
let l:opts = a:0 > 0 ? a:1 : {}
let l:cache = vimtex#cache#open(a:name, l:opts)
function! CachedFunc(key) closure
if l:cache.has(a:key)
return l:cache.get(a:key)
else
return l:cache.set(a:key, a:Func(a:key))
endif
endfunction
return function('CachedFunc')
endfunction
" }}}1
function! vimtex#cache#open(name, ...) abort " {{{1
let l:opts = extend({
\ 'local': v:false,
\ 'default': 0,
\ 'persistent': get(g:, 'vimtex_cache_persistent', v:true),
\ 'validate': s:_version,
\}, a:0 > 0 ? a:1 : {})
let l:project_local = remove(l:opts, 'local')
return s:cache_open(a:name, l:project_local, l:opts)
endfunction
" }}}1
function! vimtex#cache#close(name) abort " {{{1
" Note: This will close BOTH local and global cache!
for [l:name, l:cache] in s:cache_get_both(a:name)
if !empty(l:cache) && has_key(s:caches, l:name)
call l:cache.write()
unlet s:caches[l:name]
endif
endfor
endfunction
" }}}1
function! vimtex#cache#clear(name) abort " {{{1
if empty(a:name) | return | endif
if a:name ==# 'ALL'
return s:cache_clear_all()
endif
let l:persistent = get(g:, 'vimtex_cache_persistent', 1)
for [l:name, l:cache] in s:cache_get_both(a:name)
if !empty(l:cache)
call l:cache.clear()
unlet s:caches[l:name]
elseif l:persistent
let l:path = vimtex#cache#path(l:name . '.json')
call delete(l:path)
endif
endfor
endfunction
" }}}1
function! vimtex#cache#write_all() abort " {{{1
for l:cache in values(get(s:, 'caches', {}))
call l:cache.write()
endfor
endfunction
" }}}1
function! s:cache_open(name, project_local, opts) abort " {{{1
let l:name = a:project_local ? s:local_name(a:name) : a:name
let s:caches = get(s:, 'caches', {})
if !has_key(s:caches, l:name)
let l:path = vimtex#cache#path(l:name . '.json')
let s:caches[l:name] = s:cache.init(l:path, a:opts)
endif
return s:caches[l:name]
endfunction
" }}}1
function! s:cache_get(name, ...) abort " {{{1
let l:project_local = a:0 > 0 ? a:1 : v:false
let l:name = l:project_local ? s:local_name(a:name) : a:name
let s:caches = get(s:, 'caches', {})
return [l:name, get(s:caches, l:name, {})]
endfunction
" }}}1
function! s:cache_get_both(name) abort " {{{1
return map(
\ [v:false, v:true],
\ { _, x -> s:cache_get(a:name, x) }
\)
endfunction
" }}}1
function! s:cache_clear_all() abort " {{{1
" Delete cache state map
unlet! s:caches
if !get(g:, 'vimtex_cache_persistent', 1) | return | endif
" Delete cache files
for l:file in globpath(s:root(), '*.json', 0, 1)
call delete(l:file)
endfor
endfunction
" }}}1
let s:cache = {}
function! s:cache.init(path, opts) dict abort " {{{1
let new = deepcopy(self)
unlet new.init
let new.data = {}
let new.path = a:path
let new.ftime = -1
let new.default = a:opts.default
let new.__validated = 0
let new.__validation_value = deepcopy(a:opts.validate)
if type(new.__validation_value) == v:t_dict
let new.__validation_value._version = s:_version
endif
let new.data.__validate = deepcopy(new.__validation_value)
if a:opts.persistent
return extend(new, s:cache_persistent)
endif
return extend(new, s:cache_volatile)
endfunction
" }}}1
let s:cache_persistent = {
\ 'type': 'persistent',
\ 'modified': 0,
\}
function! s:cache_persistent.validate() dict abort " {{{1
let self.__validated = 1
if type(self.data.__validate) != type(self.__validation_value)
\ || self.data.__validate != self.__validation_value
call self.clear()
let self.data.__validate = deepcopy(self.__validation_value)
call self.write()
endif
endfunction
" }}}1
function! s:cache_persistent.get(key) dict abort " {{{1
call self.read()
if !has_key(self.data, a:key)
let self.data[a:key] = deepcopy(self.default)
endif
return get(self.data, a:key)
endfunction
" }}}1
function! s:cache_persistent.has(key) dict abort " {{{1
call self.read()
return has_key(self.data, a:key)
endfunction
" }}}1
function! s:cache_persistent.set(key, value) dict abort " {{{1
call self.read()
let self.data[a:key] = a:value
call self.write(1)
return a:value
endfunction
" }}}1
function! s:cache_persistent.write(...) dict abort " {{{1
call self.read()
let l:modified = self.modified || a:0 > 0
if !l:modified || empty(self.data) | return | endif
try
let l:encoded = json_encode(self.data)
call writefile([l:encoded], self.path)
let self.ftime = getftime(self.path)
let self.modified = 0
catch /E474:/
call vimtex#log#warning(
\ 'Could not encode cache "'
\ . fnamemodify(self.path, ':t:r') . '"',
\ string(self.data)
\)
endtry
endfunction
" }}}1
function! s:cache_persistent.read() dict abort " {{{1
if getftime(self.path) <= self.ftime | return | endif
let self.ftime = getftime(self.path)
let l:contents = join(readfile(self.path))
if empty(l:contents) | return | endif
let l:data = json_decode(l:contents)
if type(l:data) != v:t_dict
call vimtex#log#warning(
\ 'Inconsistent cache data while reading:',
\ self.path,
\ 'Decoded data type: ' . type(l:data)
\)
return
endif
call extend(self.data, l:data)
if !self.__validated
call self.validate()
endif
endfunction
" }}}1
function! s:cache_persistent.clear() dict abort " {{{1
let self.data = { '__validate': deepcopy(self.__validation_value) }
let self.ftime = -1
let self.modified = 0
call delete(self.path)
endfunction
" }}}1
let s:cache_volatile = {
\ 'type': 'volatile',
\}
function! s:cache_volatile.get(key) dict abort " {{{1
if !has_key(self.data, a:key)
let self.data[a:key] = deepcopy(self.default)
endif
return get(self.data, a:key)
endfunction
" }}}1
function! s:cache_volatile.has(key) dict abort " {{{1
return has_key(self.data, a:key)
endfunction
" }}}1
function! s:cache_volatile.set(key, value) dict abort " {{{1
let self.data[a:key] = a:value
let self.ftime = localtime()
return a:value
endfunction
" }}}1
function! s:cache_volatile.write(...) dict abort " {{{1
endfunction
" }}}1
function! s:cache_volatile.read() dict abort " {{{1
endfunction
" }}}1
function! s:cache_volatile.clear() dict abort " {{{1
let self.data = {}
let self.ftime = -1
endfunction
" }}}1
" Utility functions
function! s:root() abort " {{{1
return get(g:, 'vimtex_cache_root',
\ (empty($XDG_CACHE_HOME) ? $HOME . '/.cache' : $XDG_CACHE_HOME)
\ . '/vimtex')
endfunction
" }}}1
function! s:local_name(name) abort " {{{1
let l:filename = exists('b:vimtex.tex')
\ ? fnamemodify(b:vimtex.tex, ':r')
\ : expand('%:p:r')
let l:filename = substitute(l:filename, '\s\+', '_', 'g')
let l:filename = substitute(l:filename, '\/', '%', 'g')
let l:filename = substitute(l:filename, '\\', '%', 'g')
let l:filename = substitute(l:filename, ':', '%', 'g')
return a:name . l:filename
endfunction
" }}}1
let s:_version = 'cache_v2'

View File

@ -0,0 +1,55 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#cite#get_entry(...) abort " {{{1
let l:key = a:0 > 0 ? a:1 : vimtex#cite#get_key()
if empty(l:key) | return {} | endif
" Ensure we're at the root directory when locating bib files
call vimtex#paths#pushd(b:vimtex.root)
let l:entries = []
for l:file in vimtex#bib#files()
let l:entries += vimtex#parser#bib(
\ l:file,
\ {'backend': has('nvim') ? 'lua' : 'vim'}
\)
endfor
call vimtex#paths#popd()
" Return entry with the given key
return l:entries->filter({_, x -> x.key ==# l:key})->get(0, {})
endfunction
" }}}1
function! vimtex#cite#get_key(...) abort " {{{1
let l:cmd = a:0 > 0 ? a:1 : vimtex#cmd#get_current()
if empty(l:cmd)
\ || l:cmd.name[1:] !~# g:vimtex#re#cite_cmd
\ || len(l:cmd.args) < 1
\ || len(l:cmd.args) > 2
return ''
endif
let l:current_word = a:0 > 1 ? a:2 : expand('<cword>')
let l:cites = l:cmd.args->map({_, x -> x.text})->join(',')->split(',\s*')
return index(l:cites, l:current_word) >= 0
\ ? l:current_word
\ : l:cites[0]
endfunction
" }}}1
function! vimtex#cite#get_key_at(line, col) abort " {{{1
let l:pos_saved = vimtex#pos#get_cursor()
call vimtex#pos#set_cursor(a:line, a:col)
let l:key = vimtex#cite#get_key()
call vimtex#pos#set_cursor(l:pos_saved)
return l:key
endfunction
" }}}1

View File

@ -0,0 +1,763 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#cmd#init_buffer() abort " {{{1
nnoremap <silent><buffer> <plug>(vimtex-cmd-delete)
\ :<c-u>call <sid>operator_setup('delete')<bar>normal! g@l<cr>
nnoremap <silent><buffer> <plug>(vimtex-cmd-change)
\ :<c-u>call <sid>operator_setup('change')<bar>normal! g@l<cr>
inoremap <silent><buffer> <plug>(vimtex-cmd-create)
\ <c-r>=vimtex#cmd#create_insert()<cr>
nnoremap <silent><buffer> <plug>(vimtex-cmd-create)
\ :<c-u>call <sid>operator_setup('create')<bar>normal! g@l<cr>
xnoremap <silent><buffer> <plug>(vimtex-cmd-create)
\ :<c-u>call vimtex#cmd#create_visual()<cr>
nnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-star)
\ :<c-u>call <sid>operator_setup('toggle_star')<bar>normal! g@l<cr>
nnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-frac)
\ :<c-u>call <sid>operator_setup('toggle_frac')<bar>normal! g@l<cr>
xnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-frac)
\ :<c-u>call vimtex#cmd#toggle_frac_visual()<cr>
nnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-break)
\ :<c-u>call <sid>operator_setup('toggle_break')<bar>normal! g@l<cr>
endfunction
" }}}1
function! vimtex#cmd#change(new_name) abort " {{{1
let l:cmd = vimtex#cmd#get_current()
if empty(l:cmd) | return | endif
let l:old_name = l:cmd.name
let l:lnum = l:cmd.pos_start.lnum
let l:cnum = l:cmd.pos_start.cnum
" Get new command name
let l:new_name = substitute(a:new_name, '^\\', '', '')
if empty(l:new_name) | return | endif
" Update current position
let l:save_pos = vimtex#pos#get_cursor()
if strlen(l:new_name) < strlen(l:old_name)
let l:col = searchpos('\\\k', 'bcnW')[1] + strlen(l:new_name)
if l:col < l:save_pos[2]
let l:save_pos[2] = l:col
endif
endif
" Perform the change
let l:line = getline(l:lnum)
call setline(l:lnum,
\ strpart(l:line, 0, l:cnum)
\ . l:new_name
\ . strpart(l:line, l:cnum + strlen(l:old_name) - 1))
" Restore cursor position
cal vimtex#pos#set_cursor(l:save_pos)
endfunction
function! vimtex#cmd#delete(...) abort " {{{1
if a:0 > 0
let l:cmd = call('vimtex#cmd#get_at', a:000)
else
let l:cmd = vimtex#cmd#get_current()
endif
if empty(l:cmd) | return | endif
" Save current position
let l:save_pos = vimtex#pos#get_cursor()
let l:lnum_cur = l:save_pos[1]
let l:cnum_cur = l:save_pos[2]
" Remove closing bracket (if exactly one argument)
if len(l:cmd.args) == 1
let l:lnum = l:cmd.args[0].close.lnum
let l:cnum = l:cmd.args[0].close.cnum
let l:line = getline(l:lnum)
call setline(l:lnum,
\ strpart(l:line, 0, l:cnum - 1)
\ . strpart(l:line, l:cnum))
let l:cnum2 = l:cmd.args[0].open.cnum
endif
" Remove command (and possibly the opening bracket)
let l:lnum = l:cmd.pos_start.lnum
let l:cnum = l:cmd.pos_start.cnum
let l:cnum2 = get(l:, 'cnum2', l:cnum + strlen(l:cmd.name) - 1)
let l:line = getline(l:lnum)
call setline(l:lnum,
\ strpart(l:line, 0, l:cnum - 1)
\ . strpart(l:line, l:cnum2))
" Restore appropriate cursor position
if l:lnum_cur == l:lnum
if l:cnum_cur > l:cnum2
let l:save_pos[2] -= l:cnum2 - l:cnum + 1
else
let l:save_pos[2] -= l:cnum_cur - l:cnum
endif
endif
cal vimtex#pos#set_cursor(l:save_pos)
endfunction
function! vimtex#cmd#delete_all(...) abort " {{{1
if a:0 > 0
let l:cmd = call('vimtex#cmd#get_at', a:000)
else
let l:cmd = vimtex#cmd#get_current()
endif
if empty(l:cmd) | return | endif
call vimtex#pos#set_cursor(l:cmd.pos_start)
normal! v
call vimtex#pos#set_cursor(l:cmd.pos_end)
normal! d
endfunction
function! vimtex#cmd#create_insert() abort " {{{1
if mode() !=# 'i' | return | endif
let l:re = '\v%(^|\A)\zs\a+(\*=)@>\a*\ze%(\A|$)'
let l:c0 = col('.') - 1
let [l:l1, l:c1] = searchpos(l:re, 'bcn', line('.'))
let l:c1 -= 1
let l:line = getline(l:l1)
let l:match = matchstr(l:line, l:re, l:c1)
let l:c2 = l:c1 + strlen(l:match)
if l:c0 > l:c2
call vimtex#log#warning('Could not create command')
return ''
endif
let l:strpart1 = strpart(l:line, 0, l:c1)
let l:strpart2 = '\' . strpart(l:match, 0, l:c0 - l:c1) . '{'
let l:strpart3 = strpart(l:line, l:c0)
call setline(l:l1, l:strpart1 . l:strpart2 . l:strpart3)
call vimtex#pos#set_cursor(l:l1, l:c2+3)
return ''
endfunction
" }}}1
function! vimtex#cmd#create(cmd, visualmode) abort " {{{1
if empty(a:cmd) | return | endif
" Avoid autoindent (disable indentkeys)
let l:save_indentkeys = &l:indentkeys
setlocal indentkeys=
if a:visualmode
let l:pos_start = getpos("'<")
let l:pos_end = getpos("'>")
if visualmode() ==# ''
normal! gvA}
execute 'normal! gvI\' . a:cmd . '{'
let l:pos_end[2] += strlen(a:cmd) + 3
else
normal! `>a}
normal! `<
execute 'normal! i\' . a:cmd . '{'
let l:pos_end[2] +=
\ l:pos_end[1] == l:pos_start[1] ? strlen(a:cmd) + 3 : 1
endif
call vimtex#pos#set_cursor(l:pos_end)
else
let l:pos = vimtex#pos#get_cursor()
let l:save_reg = getreg('"')
let l:pos[2] += strlen(a:cmd) + 2
execute 'normal! ciw\' . a:cmd . '{"}'
call setreg('"', l:save_reg)
call vimtex#pos#set_cursor(l:pos)
endif
" Restore indentkeys setting
let &l:indentkeys = l:save_indentkeys
endfunction
" }}}1
function! vimtex#cmd#create_visual() abort " {{{1
let l:cmd = vimtex#ui#input({
\ 'info': ['Create command: ', ['VimtexWarning', '(empty to cancel)']],
\})
let l:cmd = substitute(l:cmd, '^\\', '', '')
call vimtex#cmd#create(l:cmd, 1)
endfunction
" }}}1
function! vimtex#cmd#toggle_star() abort " {{{1
let l:cmd = vimtex#cmd#get_current()
if empty(l:cmd) | return | endif
let l:old_name = l:cmd.name
let l:lnum = l:cmd.pos_start.lnum
let l:cnum = l:cmd.pos_start.cnum
" Set new command name
if match(l:old_name, '\*$') == -1
let l:new_name = l:old_name.'*'
else
let l:new_name = strpart(l:old_name, 0, strlen(l:old_name)-1)
endif
let l:new_name = substitute(l:new_name, '^\\', '', '')
if empty(l:new_name) | return | endif
" Update current position
let l:save_pos = vimtex#pos#get_cursor()
let l:save_pos[2] += strlen(l:new_name) - strlen(l:old_name) + 1
" Perform the change
let l:line = getline(l:lnum)
call setline(l:lnum,
\ strpart(l:line, 0, l:cnum)
\ . l:new_name
\ . strpart(l:line, l:cnum + strlen(l:old_name) - 1))
" Restore cursor position
cal vimtex#pos#set_cursor(l:save_pos)
endfunction
" }}}1
function! vimtex#cmd#toggle_frac() abort " {{{1
let l:frac = s:get_frac_cmd()
if empty(l:frac)
let l:frac = s:get_frac_inline()
endif
if empty(l:frac) | return | endif
let l:lnum = line('.')
let l:line = getline(l:lnum)
call setline(l:lnum,
\ strpart(l:line, 0, l:frac.col_start)
\ . l:frac.text_toggled
\ . strpart(l:line, l:frac.col_end+1))
endfunction
" }}}1
function! vimtex#cmd#toggle_frac_visual() abort " {{{1
let l:save_reg = getreg('a')
normal! gv"ay
let l:selected = substitute(getreg('a'), '\n\s*', ' ', '')
call setreg('a', l:save_reg)
let l:frac = s:get_frac_inline_visual(l:selected)
if empty(l:frac)
let l:frac = s:get_frac_cmd_visual(l:selected)
endif
if empty(l:frac) | return | endif
let l:save_reg = getreg('a')
call setreg('a', l:frac.text_toggled)
normal! gv"ap
call setreg('a', l:save_reg)
endfunction
" }}}1
function! vimtex#cmd#toggle_break() abort " {{{1
let l:lnum = line('.')
let l:line = getline(l:lnum)
let l:replace = l:line =~# '\s*\\\\\s*$'
\ ? substitute(l:line, '\s*\\\\\s*$', '', '')
\ : substitute(l:line, '\s*$', ' \\\\', '')
call setline(l:lnum, l:replace)
endfunction
" }}}1
function! vimtex#cmd#parser_separator_check(separator_string) abort " {{{1
return a:separator_string =~# '\v^%(\n\s*)?$'
endfunction
" }}}1
function! s:get_frac_toggled(origin, numerator, denominator) abort " {{{1
let l:target = get(g:vimtex_toggle_fractions, a:origin, 'INLINE')
if l:target ==# 'INLINE'
let l:numerator = (a:numerator =~# '^\\\?\w*$')
\ ? a:numerator
\ : '(' . a:numerator . ')'
let l:denominator = (a:denominator =~# '^\\\?\w*$')
\ ? a:denominator
\ : '(' . a:denominator . ')'
return l:numerator . '/' . l:denominator
endif
return printf('\%s{%s}{%s}', l:target, a:numerator, a:denominator)
endfunction
" }}}1
function! s:get_frac_cmd() abort " {{{1
let l:frac_cmds = map(filter(
\ keys(g:vimtex_toggle_fractions), { _, x -> x !~# 'INLINE' }),
\ { _, x -> '\' .. x })
let l:save_pos = vimtex#pos#get_cursor()
while 1
let l:cmd = s:get_cmd('prev')
if empty(l:cmd) || l:cmd.pos_start.lnum < line('.')
call vimtex#pos#set_cursor(l:save_pos)
return {}
endif
" Note: \dfrac and \cfrac are defined by amsmath and are common variants
if index(l:frac_cmds, l:cmd.name) >= 0
break
endif
call vimtex#pos#set_cursor(vimtex#pos#prev(l:cmd.pos_start))
endwhile
call vimtex#pos#set_cursor(l:save_pos)
let l:frac = {
\ 'type': 'cmd',
\ 'origin': l:cmd.name[1:],
\ 'col_start': l:cmd.pos_start.cnum - 1,
\ 'col_end': l:cmd.pos_end.cnum - 1,
\}
if len(l:cmd.args) >= 2
let l:consume = []
let l:frac.numerator = l:cmd.args[0].text
let l:frac.denominator = l:cmd.args[1].text
elseif len(l:cmd.args) == 1
let l:consume = ['denominator']
let l:frac.numerator = l:cmd.args[0].text
let l:frac.denominator = ''
else
let l:consume = ['numerator', 'denominator']
let l:frac.numerator = ''
let l:frac.denominator = ''
endif
" Handle unfinished cases
let l:line = getline('.')
let l:pos = l:frac.col_end + 1
for l:key in l:consume
let l:part = strpart(l:line, l:frac.col_end + 1)
let l:blurp = matchstr(l:part, '^\s*{[^}]*}')
if !empty(l:blurp)
let l:frac[l:key] = trim(l:blurp)[1:-2]
let l:frac.col_end += len(l:blurp)
continue
endif
let l:blurp = matchstr(l:part, '^\s*\w')
if !empty(l:blurp)
let l:frac[l:key] = trim(l:blurp)
let l:frac.col_end += len(l:blurp)
endif
endfor
" Abort if \frac region does not cover cursor
if l:frac.col_end < col('.') | return {} | endif
let l:frac.text = strpart(getline('.'),
\ l:frac.col_start, l:frac.col_end - l:frac.col_start + 1)
let l:frac.text_toggled = s:get_frac_toggled(
\ l:frac.origin, l:frac.numerator, l:frac.denominator)
return l:frac
endfunction
" }}}1
function! s:get_frac_cmd_visual(selected) abort " {{{1
let l:frac_re = '\\\(' . join(filter(
\ keys(g:vimtex_toggle_fractions),
\ { _, x -> x !~# 'INLINE' }), '\|') . '\)'
let l:matches = matchlist(
\ a:selected, '^\s*' . l:frac_re . '\s*{\(.*\)}\s*{\(.*\)}\s*$')
if empty(l:matches) | return {} | endif
let l:frac = {
\ 'type': 'cmd',
\ 'origin': l:matches[1],
\ 'text': a:selected,
\ 'numerator': l:matches[2],
\ 'denominator': l:matches[3],
\}
let l:frac.text_toggled = s:get_frac_toggled(
\ l:frac.origin, l:frac.numerator, l:frac.denominator)
return l:frac
endfunction
" }}}1
function! s:get_frac_inline() abort " {{{1
let l:line = getline('.')
let l:col = col('.') - 1
let l:pos_after = -1
let l:pos_before = -1
while 1
let l:pos_before = l:pos_after
let l:pos_after = match(l:line, '\/', l:pos_after+1)
if l:pos_after < 0 || l:pos_after >= l:col | break | endif
endwhile
if l:pos_after == -1 && l:pos_before == -1
return {}
endif
let l:positions = []
if l:pos_before > 0
let l:positions += [l:pos_before]
endif
if l:pos_after > 0
let l:positions += [l:pos_after]
endif
for l:pos in l:positions
let l:frac = {'type': 'inline'}
"
" Parse numerator
"
let l:before = strpart(l:line, 0, l:pos)
if l:before =~# ')\s*$'
let l:pos_before = s:get_inline_limit(l:before, -1) - 1
let l:parens = strpart(l:before, l:pos_before)
else
let l:pos_before = match(l:before, '\s*$')
let l:parens = ''
endif
let l:before = strpart(l:line, 0, l:pos_before)
let l:atoms = matchstr(l:before, '\(\\(\)\?\zs[^-$(){} ]*$')
let l:pos_before = l:pos_before - strlen(l:atoms)
let l:frac.numerator = s:get_inline_trim(l:atoms . l:parens)
let l:frac.col_start = l:pos_before
"
" Parse denominator
"
let l:after = strpart(l:line, l:pos+1)
let l:atoms = l:after =~# '^\s*[^$()} ]*\\)'
\ ? matchstr(l:after, '^\s*[^$()} ]*\ze\\)')
\ : matchstr(l:after, '^\s*[^$()} ]*')
let l:pos_after = l:pos + strlen(l:atoms)
let l:after = strpart(l:line, l:pos_after+1)
if l:after =~# '^('
let l:index = s:get_inline_limit(l:after, 1)
let l:pos_after = l:pos_after + l:index + 1
let l:parens = strpart(l:after, 0, l:index+1)
else
let l:parens = ''
endif
let l:frac.denominator = s:get_inline_trim(l:atoms . l:parens)
let l:frac.col_end = l:pos_after
"
" Combine/Parse inline and frac expressions
"
let l:frac.origin = 'INLINE'
let l:frac.text = strpart(l:line,
\ l:frac.col_start,
\ l:frac.col_end - l:frac.col_start + 1)
let l:frac.text_toggled = s:get_frac_toggled(
\ l:frac.origin, l:frac.numerator, l:frac.denominator)
"
" Accept result if the range contains the cursor column
"
if l:col >= l:frac.col_start && l:col <= l:frac.col_end
return l:frac
endif
endfor
return {}
endfunction
" }}}1
function! s:get_frac_inline_visual(selected) abort " {{{1
let l:parts = split(a:selected, '/')
if len(l:parts) != 2 | return {} | endif
let l:frac = {
\ 'type': 'inline',
\ 'origin': 'INLINE',
\ 'text': a:selected,
\ 'numerator': s:get_inline_trim(l:parts[0]),
\ 'denominator': s:get_inline_trim(l:parts[1]),
\}
let l:frac.text_toggled = s:get_frac_toggled(
\ l:frac.origin, l:frac.numerator, l:frac.denominator)
return l:frac
endfunction
" }}}1
function! s:get_inline_limit(str, dir) abort " {{{1
if a:dir > 0
let l:open = '('
let l:string = a:str
else
let l:open = ')'
let l:string = join(reverse(split(a:str, '\zs')), '')
endif
let idx = -1
let depth = 0
while idx < len(l:string)
let idx = match(l:string, '[()]', idx + 1)
if idx < 0
let idx = len(l:string)
endif
if idx >= len(l:string) || l:string[idx] ==# l:open
let depth += 1
else
let depth -= 1
if depth == 0
return a:dir < 0 ? len(a:str) - idx : idx
endif
endif
endwhile
return -1
endfunction
" }}}1
function! s:get_inline_trim(str) abort " {{{1
let l:str = trim(a:str)
return substitute(l:str, '^(\(.*\))$', '\1', '')
endfunction
" }}}1
function! vimtex#cmd#get_next() abort " {{{1
return s:get_cmd('next')
endfunction
" }}}1
function! vimtex#cmd#get_prev() abort " {{{1
return s:get_cmd('prev')
endfunction
" }}}1
function! vimtex#cmd#get_current() abort " {{{1
let l:save_pos = vimtex#pos#get_cursor()
let l:pos_val_cursor = vimtex#pos#val(l:save_pos)
let l:depth = 3
while l:depth > 0
let l:depth -= 1
let l:cmd = s:get_cmd('prev')
if empty(l:cmd) | break | endif
let l:pos_val = vimtex#pos#val(l:cmd.pos_end)
if l:pos_val >= l:pos_val_cursor
call vimtex#pos#set_cursor(l:save_pos)
return l:cmd
else
call vimtex#pos#set_cursor(vimtex#pos#prev(l:cmd.pos_start))
endif
endwhile
call vimtex#pos#set_cursor(l:save_pos)
return {}
endfunction
" }}}1
function! vimtex#cmd#get_at(...) abort " {{{1
let l:pos_saved = vimtex#pos#get_cursor()
call call('vimtex#pos#set_cursor', a:000)
let l:cmd = vimtex#cmd#get_current()
call vimtex#pos#set_cursor(l:pos_saved)
return l:cmd
endfunction
" }}}1
function! s:operator_setup(operator) abort " {{{1
let s:operator = a:operator
let &opfunc = s:snr() . 'operator_function'
" Ask for user input if necessary/relevant
if s:operator ==# 'change'
let l:current = vimtex#cmd#get_current()
if empty(l:current) | return | endif
let s:operator_cmd_name = substitute(vimtex#ui#input({
\ 'info': ['Change command: ', ['VimtexWarning', l:current.name]],
\}), '^\\', '', '')
elseif s:operator ==# 'create'
let s:operator_cmd_name = substitute(vimtex#ui#input({
\ 'info': ['Create command: ', ['VimtexWarning', '(empty to cancel)']],
\}), '^\\', '', '')
endif
endfunction
" }}}1
function! s:operator_function(_) abort " {{{1
let l:name = get(s:, 'operator_cmd_name', '')
execute 'call vimtex#cmd#' . {
\ 'change': 'change(l:name)',
\ 'create': 'create(l:name, 0)',
\ 'delete': 'delete()',
\ 'toggle_star': 'toggle_star()',
\ 'toggle_frac': 'toggle_frac()',
\ 'toggle_break': 'toggle_break()',
\ }[s:operator]
endfunction
" }}}1
function! s:snr() abort " {{{1
return matchstr(expand('<sfile>'), '<SNR>\d\+_')
endfunction
" }}}1
function! s:get_cmd(direction) abort " {{{1
let [lnum, cnum, match] = s:get_cmd_name(a:direction ==# 'next')
if lnum == 0 | return {} | endif
let res = {
\ 'name' : match,
\ 'text' : '',
\ 'pos_start' : { 'lnum' : lnum, 'cnum' : cnum },
\ 'pos_end' : { 'lnum' : lnum, 'cnum' : cnum + strlen(match) - 1 },
\ 'args' : [],
\ 'opts' : [],
\}
" Environments always start with environment name and allows option
" afterwords
if res.name ==# '\begin'
let arg = s:get_cmd_part('{', res.pos_end)
if empty(arg) | return res | endif
call add(res.args, arg)
let res.pos_end.lnum = arg.close.lnum
let res.pos_end.cnum = arg.close.cnum
endif
" Get overlay specification
let res.overlay = s:get_cmd_overlay(res.pos_end.lnum, res.pos_end.cnum)
if !empty(res.overlay)
let res.pos_end.lnum = res.overlay.close.lnum
let res.pos_end.cnum = res.overlay.close.cnum
endif
" Get options and arguments
while v:true
let opt = s:get_cmd_part('[', res.pos_end)
if !empty(opt)
call add(res.opts, opt)
let res.pos_end.lnum = opt.close.lnum
let res.pos_end.cnum = opt.close.cnum
continue
endif
let arg = s:get_cmd_part('{', res.pos_end)
if !empty(arg)
call add(res.args, arg)
let res.pos_end.lnum = arg.close.lnum
let res.pos_end.cnum = arg.close.cnum
continue
endif
break
endwhile
" Include entire cmd text
let res.text = s:text_between(res.pos_start, res.pos_end, 1)
return res
endfunction
" }}}1
function! s:get_cmd_name(next) abort " {{{1
let [l:lnum, l:cnum] = searchpos(
\ '\v\\%(\a+\*?|[,:;!])',
\ a:next ? 'nW' : 'cbnW')
let l:match = matchstr(getline(l:lnum), '^\v\\%([,:;!]|\a*\*?)', l:cnum-1)
return [l:lnum, l:cnum, l:match]
endfunction
" }}}1
function! s:get_cmd_part(part, start_pos) abort " {{{1
let l:save_pos = vimtex#pos#get_cursor()
call vimtex#pos#set_cursor(a:start_pos)
let l:open = vimtex#delim#get_next('delim_tex', 'open')
call vimtex#pos#set_cursor(l:save_pos)
" Ensure that the next delimiter is found and is of the right type
if empty(l:open) || l:open.match !=# a:part | return {} | endif
" Ensure that the delimiter is the next non-whitespace character according to
" a configurable rule
if ! call(g:vimtex_parser_cmd_separator_check, [
\ s:text_between(a:start_pos, l:open)
\])
return {}
endif
let l:close = vimtex#delim#get_matching(l:open)
if empty(l:close)
return {}
endif
return {
\ 'open' : l:open,
\ 'close' : l:close,
\ 'text' : s:text_between(l:open, l:close),
\}
endfunction
" }}}1
function! s:get_cmd_overlay(lnum, cnum) abort " {{{1
let l:match = matchstr(getline(a:lnum), '^\s*<[^>]*>', a:cnum)
return empty(l:match)
\ ? {}
\ : {
\ 'open' : {'lnum' : a:lnum, 'cnum' : a:cnum + 1},
\ 'close' : {'lnum' : a:lnum, 'cnum' : a:cnum + strlen(l:match)},
\ 'text' : l:match
\ }
endfunction
" }}}1
function! s:text_between(p1, p2, ...) abort " {{{1
let [l1, c1] = [a:p1.lnum, a:p1.cnum - (a:0 > 0)]
let [l2, c2] = [a:p2.lnum, a:p2.cnum - (a:0 <= 0)]
let lines = getline(l1, l2)
if !empty(lines)
let lines[0] = strpart(lines[0], c1)
let lines[-1] = strpart(lines[-1], 0,
\ l1 == l2 ? c2 - c1 : c2)
endif
return join(lines, "\n")
endfunction
" }}}1

View File

@ -0,0 +1,461 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#init_buffer() abort " {{{1
if !g:vimtex_compiler_enabled | return | endif
" Define commands
command! -buffer -nargs=* VimtexCompile call vimtex#compiler#compile(<f-args>)
command! -buffer -bang -nargs=* VimtexCompileSS call vimtex#compiler#compile_ss(<f-args>)
command! -buffer -range VimtexCompileSelected <line1>,<line2>call vimtex#compiler#compile_selected('command')
command! -buffer VimtexCompileOutput call vimtex#compiler#output()
command! -buffer VimtexStop call vimtex#compiler#stop()
command! -buffer VimtexStopAll call vimtex#compiler#stop_all()
command! -buffer -bang VimtexClean call vimtex#compiler#clean(<q-bang> == "!")
command! -buffer -bang VimtexStatus call vimtex#compiler#status(<q-bang> == "!")
" Define mappings
nnoremap <buffer> <plug>(vimtex-compile) :call vimtex#compiler#compile()<cr>
nnoremap <buffer> <plug>(vimtex-compile-ss) :call vimtex#compiler#compile_ss()<cr>
nnoremap <buffer> <plug>(vimtex-compile-selected) :set opfunc=vimtex#compiler#compile_selected<cr>g@
xnoremap <buffer> <plug>(vimtex-compile-selected) :<c-u>call vimtex#compiler#compile_selected('visual')<cr>
nnoremap <buffer> <plug>(vimtex-compile-output) :call vimtex#compiler#output()<cr>
nnoremap <buffer> <plug>(vimtex-stop) :call vimtex#compiler#stop()<cr>
nnoremap <buffer> <plug>(vimtex-stop-all) :call vimtex#compiler#stop_all()<cr>
nnoremap <buffer> <plug>(vimtex-clean) :call vimtex#compiler#clean(0)<cr>
nnoremap <buffer> <plug>(vimtex-clean-full) :call vimtex#compiler#clean(1)<cr>
nnoremap <buffer> <plug>(vimtex-status) :call vimtex#compiler#status(0)<cr>
nnoremap <buffer> <plug>(vimtex-status-all) :call vimtex#compiler#status(1)<cr>
endfunction
" }}}1
function! vimtex#compiler#init_state(state) abort " {{{1
if !g:vimtex_compiler_enabled | return | endif
let a:state.compiler = s:init_compiler({
\ 'file_info': {
\ 'root': a:state.root,
\ 'target': a:state.tex,
\ 'target_name': a:state.name,
\ 'target_basename': a:state.base,
\ 'jobname': a:state.name,
\ }
\})
endfunction
" }}}1
function! vimtex#compiler#callback(status) abort " {{{1
" Status:
" 1: Compilation cycle has started
" 2: Compilation complete - Success
" 3: Compilation complete - Failed
if !exists('b:vimtex.compiler') | return | endif
silent! call s:output.pause()
let l:__silent = b:vimtex.compiler.silence_next_callback
if l:__silent
let b:vimtex.compiler.silence_next_callback = v:false
if g:vimtex_compiler_silent
let l:__silent = v:false
else
call vimtex#log#set_silent()
endif
endif
let b:vimtex.compiler.status = a:status
if a:status == 1
if exists('#User#VimtexEventCompiling')
doautocmd <nomodeline> User VimtexEventCompiling
endif
silent! call s:output.resume()
return
endif
if a:status == 2
if !g:vimtex_compiler_silent
call vimtex#log#info('Compilation completed')
endif
if exists('b:vimtex')
call b:vimtex.update_packages()
call vimtex#syntax#packages#init()
endif
call vimtex#qf#open(0)
if exists('#User#VimtexEventCompileSuccess')
doautocmd <nomodeline> User VimtexEventCompileSuccess
endif
elseif a:status == 3
if !g:vimtex_compiler_silent
call vimtex#log#warning('Compilation failed!')
endif
call vimtex#qf#open(0)
if exists('#User#VimtexEventCompileFailed')
doautocmd <nomodeline> User VimtexEventCompileFailed
endif
endif
if l:__silent
call vimtex#log#set_silent_restore()
endif
silent! call s:output.resume()
endfunction
" }}}1
function! vimtex#compiler#compile(...) abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if b:vimtex.compiler.is_running()
call vimtex#compiler#stop()
else
call call('vimtex#compiler#start', a:000)
endif
endfunction
" }}}1
function! vimtex#compiler#compile_ss(...) abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if b:vimtex.compiler.is_running()
call vimtex#log#info(
\ 'Compiler is already running, use :VimtexStop to stop it!')
return
endif
call b:vimtex.compiler.start_single(expandcmd(join(a:000)))
if g:vimtex_compiler_silent | return | endif
call vimtex#log#info('Compiler started in background!')
endfunction
" }}}1
function! vimtex#compiler#compile_selected(type) abort range " {{{1
if !b:vimtex.compiler.enabled | return | endif
" Values of a:firstline and a:lastline are not available in nested function
" calls, so we must handle them here.
let l:opts = a:type ==# 'command'
\ ? {'type': 'range', 'range': [a:firstline, a:lastline]}
\ : {'type': a:type =~# 'line\|char\|block' ? 'operator' : a:type}
let l:state = vimtex#parser#selection_to_texfile(l:opts)
if empty(l:state) | return | endif
" Create and initialize temporary compiler
let l:compiler = s:init_compiler({
\ 'file_info': {
\ 'root': l:state.root,
\ 'target': l:state.tex,
\ 'target_name': l:state.name,
\ 'target_basename': l:state.base,
\ 'jobname': l:state.name,
\ },
\ 'out_dir': '',
\ 'continuous': 0,
\ 'callback': 0,
\})
if empty(l:compiler) | return | endif
call vimtex#log#info('Compiling selected lines ...')
call vimtex#log#set_silent()
call l:compiler.start()
call l:compiler.wait()
" Check if successful
if vimtex#qf#inquire(l:state.tex)
call vimtex#log#set_silent_restore()
call vimtex#log#warning('Compiling selected lines ... failed!')
botright cwindow
return
else
call l:compiler.clean(0)
call b:vimtex.viewer.view(l:state.pdf)
call vimtex#log#set_silent_restore()
call vimtex#log#info('Compiling selected lines ... done')
endif
endfunction
" }}}1
function! vimtex#compiler#output() abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if !exists('b:vimtex.compiler.output')
\ || !filereadable(b:vimtex.compiler.output)
call vimtex#log#warning('No output exists!')
return
endif
" If relevant output is open, then reuse it
if exists('s:output')
if s:output.name ==# b:vimtex.compiler.output
if bufwinnr(b:vimtex.compiler.output) == s:output.winnr
execute s:output.winnr . 'wincmd w'
endif
return
else
call s:output.destroy()
endif
endif
call s:output_factory.create(b:vimtex.compiler.output)
endfunction
" }}}1
function! vimtex#compiler#start(...) abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if !b:vimtex.is_compileable()
call vimtex#log#error(
\ 'Compilation error due to failed mainfile detection!',
\ 'Please ensure that VimTeX can locate the proper main .tex file.',
\ 'Read ":help vimtex-multi-file" for more info.'
\)
return
endif
if b:vimtex.compiler.is_running()
call vimtex#log#warning(
\ 'Compiler is already running for `' . b:vimtex.base . "'")
return
endif
call b:vimtex.compiler.start(expandcmd(join(a:000)))
if g:vimtex_compiler_silent | return | endif
" We add a redraw here to clear messages (e.g. file written). This is useful
" to avoid the "Press ENTER" prompt in some cases, see e.g.
" https://github.com/lervag/vimtex/issues/2149
redraw
if b:vimtex.compiler.continuous
call vimtex#log#info('Compiler started in continuous mode')
else
call vimtex#log#info('Compiler started in background!')
endif
endfunction
" }}}1
function! vimtex#compiler#stop() abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if !b:vimtex.compiler.is_running()
call vimtex#log#warning(
\ 'There is no process to stop (' . b:vimtex.base . ')')
return
endif
call b:vimtex.compiler.stop()
if g:vimtex_compiler_silent | return | endif
call vimtex#log#info('Compiler stopped (' . b:vimtex.base . ')')
endfunction
" }}}1
function! vimtex#compiler#stop_all() abort " {{{1
for l:state in vimtex#state#list_all()
if exists('l:state.compiler.enabled')
\ && l:state.compiler.enabled
\ && l:state.compiler.is_running()
call l:state.compiler.stop()
call vimtex#log#info('Compiler stopped ('
\ . l:state.compiler.file_info.target_basename . ')')
endif
endfor
endfunction
" }}}1
function! vimtex#compiler#clean(full) abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
let l:restart = b:vimtex.compiler.is_running()
if l:restart
call b:vimtex.compiler.stop()
endif
call b:vimtex.compiler.clean(a:full)
sleep 100m
call b:vimtex.compiler.remove_dirs()
call vimtex#log#info('Compiler clean finished' . (a:full ? ' (full)' : ''))
if l:restart
let b:vimtex.compiler.silence_next_callback = 1
silent call b:vimtex.compiler.start()
endif
endfunction
" }}}1
function! vimtex#compiler#status(detailed) abort " {{{1
if !b:vimtex.compiler.enabled | return | endif
if a:detailed
let l:running = []
for l:data in vimtex#state#list_all()
if l:data.compiler.is_running()
let l:name = l:data.tex
if len(l:name) >= winwidth('.') - 20
let l:name = '...' . l:name[-winwidth('.')+23:]
endif
call add(l:running, printf('%-6s %s',
\ string(l:data.compiler.get_pid()) . ':', l:name))
endif
endfor
if empty(l:running)
call vimtex#log#info('Compiler is not running!')
else
call vimtex#log#info('Compiler is running', l:running)
endif
else
if exists('b:vimtex.compiler')
\ && b:vimtex.compiler.is_running()
call vimtex#log#info('Compiler is running')
else
call vimtex#log#info('Compiler is not running!')
endif
endif
endfunction
" }}}1
function! s:init_compiler(options) abort " {{{1
if type(g:vimtex_compiler_method) == v:t_func
\ || exists('*' . g:vimtex_compiler_method)
let l:method = call(g:vimtex_compiler_method, [a:options.file_info.target])
else
let l:method = g:vimtex_compiler_method
endif
if index([
\ 'arara',
\ 'generic',
\ 'latexmk',
\ 'latexrun',
\ 'tectonic',
\], l:method) < 0
call vimtex#log#error('Error! Invalid compiler method: ' . l:method)
let l:method = 'latexmk'
endif
let l:options = extend(
\ deepcopy(get(g:, 'vimtex_compiler_' . l:method, {})),
\ a:options)
return vimtex#compiler#{l:method}#init(l:options)
endfunction
" }}}1
let s:output_factory = {}
function! s:output_factory.create(file) dict abort " {{{1
let l:vimtex = b:vimtex
silent execute 'split' a:file
let b:vimtex = l:vimtex
setlocal autoread
setlocal nomodifiable
setlocal bufhidden=wipe
nnoremap <silent><buffer><nowait> q :bwipeout<cr>
if has('nvim') || has('gui_running')
nnoremap <silent><buffer><nowait> <esc> :bwipeout<cr>
endif
let s:output = deepcopy(self)
unlet s:output.create
let s:output.name = a:file
let s:output.ftime = -1
let s:output.paused = v:false
let s:output.bufnr = bufnr('%')
let s:output.winnr = bufwinnr('%')
let s:output.timer = timer_start(100,
\ {_ -> s:output.update()},
\ {'repeat': -1})
augroup vimtex_output_window
autocmd!
autocmd BufDelete <buffer> call s:output.destroy()
autocmd BufEnter * call s:output.update()
autocmd FocusGained * call s:output.update()
autocmd CursorHold * call s:output.update()
autocmd CursorHoldI * call s:output.update()
autocmd CursorMoved * call s:output.update()
autocmd CursorMovedI * call s:output.update()
augroup END
endfunction
" }}}1
function! s:output_factory.pause() dict abort " {{{1
let self.paused = v:true
endfunction
" }}}1
function! s:output_factory.resume() dict abort " {{{1
let self.paused = v:false
endfunction
" }}}1
function! s:output_factory.update() dict abort " {{{1
if self.paused | return | endif
let l:ftime = getftime(self.name)
if self.ftime >= l:ftime
\ || mode() ==? 'v' || mode() ==# "\<c-v>"
return
endif
let self.ftime = getftime(self.name)
if bufwinnr(self.name) != self.winnr
let self.winnr = bufwinnr(self.name)
endif
let l:swap = bufwinnr('%') != self.winnr
if l:swap
let l:return = bufwinnr('%')
execute 'keepalt' self.winnr . 'wincmd w'
endif
" Force reload file content
silent edit
if l:swap
" Go to last line of file if it is not the current window
normal! Gzb
execute 'keepalt' l:return . 'wincmd w'
redraw
endif
endfunction
" }}}1
function! s:output_factory.destroy() dict abort " {{{1
call timer_stop(self.timer)
autocmd! vimtex_output_window
augroup! vimtex_output_window
unlet s:output
endfunction
" }}}1
" {{{1 Initialize module
if !get(g:, 'vimtex_compiler_enabled') | finish | endif
augroup vimtex_compiler
autocmd!
autocmd VimLeave * call vimtex#compiler#stop_all()
augroup END
" }}}1

View File

@ -0,0 +1,512 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#_template#new(opts) abort " {{{1
return extend(deepcopy(s:compiler), a:opts)
endfunction
" }}}1
let s:compiler = {
\ 'name': '__template__',
\ 'enabled': v:true,
\ 'out_dir': '',
\ 'continuous': 0,
\ 'hooks': [],
\ 'output': tempname(),
\ 'silence_next_callback': 0,
\ 'file_info': {},
\ 'status': -1,
\}
function! s:compiler.new(options) abort dict " {{{1
let l:compiler = extend(deepcopy(self), a:options)
let l:backend = has('nvim') ? 'nvim' : 'jobs'
call extend(l:compiler, deepcopy(s:compiler_{l:backend}))
call l:compiler.__check_requirements()
call vimtex#util#materialize_property(
\ l:compiler, 'out_dir', l:compiler.file_info)
call l:compiler.__init()
" $VIMTEX_OUTPUT_DIRECTORY overrides configured compiler.out_dir
if !empty($VIMTEX_OUTPUT_DIRECTORY)
if !empty(l:compiler.out_dir)
\ && (l:compiler.out_dir !=# $VIMTEX_OUTPUT_DIRECTORY)
call vimtex#log#warning(
\ 'Setting VIMTEX_OUTPUT_DIRECTORY overrides out_dir!',
\ 'Changed out_dir from: ' . l:compiler.out_dir,
\ 'Changed out_dir to: ' . $VIMTEX_OUTPUT_DIRECTORY)
endif
let l:compiler.out_dir = $VIMTEX_OUTPUT_DIRECTORY
endif
" Remove init methods
unlet l:compiler.new
unlet l:compiler.__check_requirements
unlet l:compiler.__init
return l:compiler
endfunction
" }}}1
function! s:compiler.__check_requirements() abort dict " {{{1
let self.enabled = v:false
endfunction
" }}}1
function! s:compiler.__init() abort dict " {{{1
endfunction
" }}}1
function! s:compiler.__build_cmd(opts) abort dict " {{{1
throw 'VimTeX: __build_cmd method must be defined!'
endfunction
" }}}1
function! s:compiler.__pprint() abort dict " {{{1
let l:list = []
if self.file_info.target !=# b:vimtex.tex
call add(l:list, ['root', self.file_info.root])
call add(l:list, ['target', self.file_info.target_basename])
endif
if self.file_info.jobname !=# b:vimtex.name
call add(l:list, ['jobname', self.file_info.jobname])
endif
if has_key(self, 'get_engine')
call add(l:list, ['engine', self.get_engine()])
endif
if has_key(self, 'options')
call add(l:list, ['options', self.options])
endif
if !empty(self.out_dir)
call add(l:list, ['out_dir', self.out_dir])
endif
if has_key(self, '__pprint_append')
call extend(l:list, self.__pprint_append())
endif
if has_key(self, 'job')
let l:job = []
call add(l:job, ['jobid', self.job])
call add(l:job, ['output', self.output])
call add(l:job, ['cmd', self.cmd])
if self.continuous
call add(l:job, ['pid', self.get_pid()])
endif
call add(l:list, ['job', l:job])
endif
return l:list
endfunction
" }}}1
function! s:compiler._create_build_dir(path) abort dict " {{{1
" Create build dir "path" if it does not exist
" Note: This may need to create a hierarchical structure!
if empty(a:path) | return | endif
if has_key(b:vimtex, 'get_sources')
let l:dirs = b:vimtex.get_sources()
call filter(map(
\ l:dirs, "fnamemodify(v:val, ':h')"),
\ {_, x -> x !=# '.'})
call filter(l:dirs, {_, x -> stridx(x, '../') != 0})
else
let l:dirs = glob(self.file_info.root . '/**/*.tex', v:false, v:true)
call map(l:dirs, "fnamemodify(v:val, ':h')")
call map(l:dirs, 'strpart(v:val, strlen(self.file_info.root) + 1)')
endif
call uniq(sort(filter(l:dirs, '!empty(v:val)')))
call map(l:dirs, {_, x ->
\ (vimtex#paths#is_abs(a:path) ? '' : self.file_info.root . '/')
\ . a:path . '/' . x})
call filter(l:dirs, '!isdirectory(v:val)')
if empty(l:dirs) | return | endif
" Create the non-existing directories
call vimtex#log#warning(["Creating directorie(s):"]
\ + map(copy(l:dirs), {_, x -> '* ' . x}))
for l:dir in l:dirs
call mkdir(l:dir, 'p')
endfor
endfunction
" }}}1
function! s:compiler._remove_dir(path) abort dict " {{{1
if empty(a:path) | return | endif
let l:out_dir = vimtex#paths#is_abs(a:path)
\ ? a:path
\ : self.file_info.root . '/' . a:path
if !isdirectory(l:out_dir) | return | endif
let l:tree = glob(l:out_dir . '/**/*', 0, 1)
let l:files = filter(copy(l:tree), 'filereadable(v:val)')
if empty(l:files)
for l:dir in sort(l:tree) + [l:out_dir]
call delete(l:dir, 'd')
endfor
endif
endfunction
" }}}1
function! s:compiler.create_dirs() abort dict " {{{1
call self._create_build_dir(self.out_dir)
endfunction
" }}}1
function! s:compiler.remove_dirs() abort dict " {{{1
call self._remove_dir(self.out_dir)
endfunction
" }}}1
function! s:compiler.get_file(ext) abort dict " {{{1
for l:root in [
\ $VIMTEX_OUTPUT_DIRECTORY,
\ self.out_dir,
\ self.file_info.root
\]
if empty(l:root) | continue | endif
let l:cand = printf('%s/%s.%s', l:root, self.file_info.jobname, a:ext)
if !vimtex#paths#is_abs(l:root)
let l:cand = self.file_info.root . '/' . l:cand
endif
if filereadable(l:cand)
return fnamemodify(l:cand, ':p')
endif
endfor
return ''
endfunction
" }}}1
function! s:compiler.clean(full) abort dict " {{{1
let l:extensions = ['synctex.gz', 'toc', 'out', 'aux', 'log', 'xdv', 'fls']
if a:full
call extend(l:extensions, ['pdf'])
endif
call map(l:extensions, { _, x -> self.get_file(x) })
for l:file in filter(l:extensions, { _, x -> !empty(x) })
call delete(l:file)
endfor
for l:expr in g:vimtex_compiler_clean_paths
for l:path in glob(self.file_info.root . '/' . l:expr, v:false, v:true)
call delete(l:path, 'rf')
endfor
endfor
endfunction
" }}}1
function! s:compiler.start(...) abort dict " {{{1
if self.is_running() | return | endif
call self.create_dirs()
" Initialize output file
call writefile([], self.output, 'a')
" Prepare compile command
let l:passed_options = a:0 > 0 ? ' ' . a:1 : ''
let self.cmd = self.__build_cmd(l:passed_options)
let l:cmd = has('win32')
\ ? 'cmd /s /c "' . self.cmd . '"'
\ : ['sh', '-c', self.cmd]
" Handle -jobname if it is passed as an option
let l:jobname = matchstr(self.cmd, '-jobname=\zs\S*')
let self.file_info.jobname = empty(l:jobname)
\ ? self.file_info.target_name
\ : l:jobname
" Execute command and toggle status
call self.exec(l:cmd)
let self.status = 1
" Use timer to check that compiler started properly
if self.continuous
let self.check_timer
\ = timer_start(50, function('s:check_if_running'), {'repeat': 20})
let self.vimtex_id = b:vimtex_id
let s:check_timers[self.check_timer] = self
endif
if exists('#User#VimtexEventCompileStarted')
doautocmd <nomodeline> User VimtexEventCompileStarted
endif
endfunction
let s:check_timers = {}
function! s:check_if_running(timer) abort " {{{2
if s:check_timers[a:timer].is_running() | return | endif
call timer_stop(a:timer)
let l:compiler = remove(s:check_timers, a:timer)
unlet l:compiler.check_timer
if l:compiler.vimtex_id == get(b:, 'vimtex_id', -1)
call vimtex#compiler#output()
endif
call vimtex#log#error('Compiler did not start successfully!')
endfunction
" }}}2
" }}}1
function! s:compiler.start_single(...) abort dict " {{{1
let l:continuous = self.continuous
let self.continuous = 0
call call(self.start, a:000)
let self.continuous = l:continuous
endfunction
" }}}1
function! s:compiler.stop() abort dict " {{{1
if !self.is_running() | return | endif
silent! call timer_stop(self.check_timer)
let self.status = 0
call self.kill()
if exists('#User#VimtexEventCompileStopped')
doautocmd <nomodeline> User VimtexEventCompileStopped
endif
endfunction
" }}}1
let s:compiler_jobs = {}
function! s:compiler_jobs.exec(cmd) abort dict " {{{1
let l:options = {
\ 'in_io': 'null',
\ 'out_io': 'file',
\ 'err_io': 'file',
\ 'out_name': self.output,
\ 'err_name': self.output,
\ 'cwd': self.file_info.root,
\}
if self.continuous
let l:options.out_io = 'pipe'
let l:options.err_io = 'pipe'
let l:options.out_cb = function('s:callback_continuous_output')
let l:options.err_cb = function('s:callback_continuous_output')
else
let s:cb_target = self.file_info.target !=# b:vimtex.tex
\ ? self.file_info.target
\ : ''
let s:cb_output = self.output
let l:options.exit_cb = function('s:callback')
endif
let self.job = job_start(a:cmd, l:options)
endfunction
" }}}1
function! s:compiler_jobs.kill() abort dict " {{{1
call job_stop(self.job)
for l:dummy in range(25)
sleep 1m
if !self.is_running() | return | endif
endfor
endfunction
" }}}1
function! s:compiler_jobs.wait() abort dict " {{{1
for l:dummy in range(500)
sleep 10m
if !self.is_running() | return | endif
endfor
call self.stop()
endfunction
" }}}1
function! s:compiler_jobs.is_running() abort dict " {{{1
return has_key(self, 'job') && job_status(self.job) ==# 'run'
endfunction
" }}}1
function! s:compiler_jobs.get_pid() abort dict " {{{1
return has_key(self, 'job')
\ ? get(job_info(self.job), 'process') : 0
endfunction
" }}}1
function! s:callback(ch, msg) abort " {{{1
if !exists('b:vimtex.compiler') | return | endif
if b:vimtex.compiler.status == 0 | return | endif
try
call vimtex#compiler#callback(2 + vimtex#qf#inquire(s:cb_target))
catch /E565:/
" In some edge cases, the callback seems to be issued while executing code
" in a protected context where "cclose" is not allowed with the resulting
" error code from compiler#callback->qf#open. The reported error message
" is:
"
" E565: Not allowed to change text or change window: cclose
"
" See https://github.com/lervag/vimtex/issues/2225
endtry
if !exists('b:vimtex.compiler.hooks') | return | endif
try
let l:lines = readfile(s:cb_output)
for l:Hook in b:vimtex.compiler.hooks
for l:line in l:lines
call l:Hook(l:line)
endfor
endfor
catch /E716/
endtry
endfunction
" }}}1
function! s:callback_continuous_output(channel, msg) abort " {{{1
if exists('b:vimtex.compiler.output')
\ && filewritable(b:vimtex.compiler.output)
call writefile([a:msg], b:vimtex.compiler.output, 'aS')
endif
call s:check_callback(a:msg)
if !exists('b:vimtex.compiler.hooks') | return | endif
try
for l:Hook in b:vimtex.compiler.hooks
call l:Hook(a:msg)
endfor
catch /E716/
endtry
endfunction
" }}}1
let s:compiler_nvim = {}
function! s:compiler_nvim.exec(cmd) abort dict " {{{1
let l:shell = {
\ 'stdin': 'null',
\ 'on_stdout': function('s:callback_nvim_output'),
\ 'on_stderr': function('s:callback_nvim_output'),
\ 'cwd': self.file_info.root,
\ 'tex': self.file_info.target,
\ 'output': self.output,
\}
if !self.continuous
let l:shell.on_exit = function('s:callback_nvim_exit')
endif
call vimtex#jobs#neovim#shell_default()
let self.job = jobstart(a:cmd, l:shell)
call vimtex#jobs#neovim#shell_restore()
endfunction
" }}}1
function! s:compiler_nvim.kill() abort dict " {{{1
call jobstop(self.job)
endfunction
" }}}1
function! s:compiler_nvim.wait() abort dict " {{{1
let l:retvals = jobwait([self.job], 5000)
if empty(l:retvals) | return | endif
let l:status = l:retvals[0]
if l:status >= 0 | return | endif
if l:status == -1 | call self.stop() | endif
endfunction
" }}}1
function! s:compiler_nvim.is_running() abort dict " {{{1
try
let pid = jobpid(self.job)
return l:pid > 0
catch
return v:false
endtry
endfunction
" }}}1
function! s:compiler_nvim.get_pid() abort dict " {{{1
try
return jobpid(self.job)
catch
return 0
endtry
endfunction
" }}}1
function! s:callback_nvim_output(id, data, event) abort dict " {{{1
" Filter out unwanted newlines
let l:data = split(substitute(join(a:data, 'QQ'), '^QQ\|QQ$', '', ''), 'QQ')
if !empty(l:data) && filewritable(self.output)
call writefile(l:data, self.output, 'a')
endif
call s:check_callback(
\ get(filter(copy(a:data),
\ {_, x -> x =~# '^vimtex_compiler_callback'}), -1, ''))
if !exists('b:vimtex.compiler.hooks') | return | endif
try
for l:Hook in b:vimtex.compiler.hooks
call l:Hook(join(a:data, "\n"))
endfor
catch /E716/
endtry
endfunction
" }}}1
function! s:callback_nvim_exit(id, data, event) abort dict " {{{1
if !exists('b:vimtex.compiler') | return | endif
if b:vimtex.compiler.status == 0 | return | endif
let l:target = self.tex !=# b:vimtex.tex ? self.tex : ''
call vimtex#compiler#callback(2 + vimtex#qf#inquire(l:target))
endfunction
" }}}1
function! s:check_callback(line) abort " {{{1
let l:status = get(s:callbacks, substitute(a:line, '\r', '', ''))
if l:status <= 0 | return | endif
call vimtex#compiler#callback(l:status)
endfunction
let s:callbacks = {
\ 'vimtex_compiler_callback_compiling': 1,
\ 'vimtex_compiler_callback_success': 2,
\ 'vimtex_compiler_callback_failure': 3,
\}
" }}}1

View File

@ -0,0 +1,32 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#arara#init(options) abort " {{{1
return s:compiler.new(a:options)
endfunction
" }}}1
let s:compiler = vimtex#compiler#_template#new({
\ 'name': 'arara',
\ 'options': ['--log'],
\})
function! s:compiler.__check_requirements() abort dict " {{{1
if !executable('arara')
call vimtex#log#warning('arara is not executable!')
let self.enabled = v:false
endif
endfunction
" }}}1
function! s:compiler.__build_cmd(passed_options) abort dict " {{{1
return 'arara ' . join(self.options)
\ . ' ' . a:passed_options
\ . ' ' . vimtex#util#shellescape(self.file_info.target_basename)
endfunction
" }}}1

View File

@ -0,0 +1,31 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#generic#init(options) abort " {{{1
return s:compiler.new(a:options)
endfunction
" }}}1
let s:compiler = vimtex#compiler#_template#new({
\ 'name' : 'generic',
\ 'command' : '',
\})
function! s:compiler.__check_requirements() abort dict " {{{1
if empty(self.command)
call vimtex#log#warning('Please specify the command to run!')
let self.enabled = v:false
endif
endfunction
" }}}1
function! s:compiler.__build_cmd(passed_options) abort dict " {{{1
return self.command . a:passed_options
endfunction
" }}}1

View File

@ -0,0 +1,367 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#latexmk#init(options) abort " {{{1
return s:compiler.new(a:options)
endfunction
" }}}1
function! vimtex#compiler#latexmk#get_rc_opt(root, opt, type, default) abort " {{{1
"
" Parse option from .latexmkrc.
"
" Arguments:
" root Root of LaTeX project
" opt Name of options
" type 0 if string, 1 if integer, 2 if list
" default Value to return if option not found in latexmkrc file
"
" Output:
" [value, location]
"
" value Option value (integer or string)
" location An integer that indicates where option was found
" -1: not found (default value returned)
" 0: global latexmkrc file
" 1: local latexmkrc file
"
if a:type == 0
let l:pattern = '^\s*\$' . a:opt . '\s*=\s*[''"]\(.\+\)[''"]'
elseif a:type == 1
let l:pattern = '^\s*\$' . a:opt . '\s*=\s*\(\d\+\)'
elseif a:type == 2
let l:pattern = '^\s*@' . a:opt . '\s*=\s*(\(.*\))'
else
throw 'VimTeX: Argument error'
endif
" Candidate files
" - each element is a pair [path_to_file, is_local_rc_file].
let l:files = [
\ [a:root . '/latexmkrc', 1],
\ [a:root . '/.latexmkrc', 1],
\ [fnamemodify('~/.latexmkrc', ':p'), 0],
\ [fnamemodify(
\ !empty($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME : '~/.config', ':p')
\ . '/latexmk/latexmkrc', 0]
\]
let l:result = [a:default, -1]
for [l:file, l:is_local] in l:files
if filereadable(l:file)
let l:match = matchlist(readfile(l:file), l:pattern)
if len(l:match) > 1
let l:result = [l:match[1], l:is_local]
break
end
endif
endfor
" Parse the list
if a:type == 2 && l:result[1] > -1
let l:array = split(l:result[0], ',')
let l:result[0] = []
for l:x in l:array
let l:x = substitute(l:x, "^'", '', '')
let l:x = substitute(l:x, "'$", '', '')
let l:result[0] += [l:x]
endfor
endif
return l:result
endfunction
" }}}1
function! vimtex#compiler#latexmk#copy_temp_files() abort " {{{1
if exists('*b:vimtex.compiler.__copy_temp_files')
call b:vimtex.compiler.__copy_temp_files()
endif
endfunction
" }}}1
let s:compiler = vimtex#compiler#_template#new({
\ 'name' : 'latexmk',
\ 'aux_dir': '',
\ 'callback' : 1,
\ 'continuous': 1,
\ 'executable' : 'latexmk',
\ 'options' : [
\ '-verbose',
\ '-file-line-error',
\ '-synctex=1',
\ '-interaction=nonstopmode',
\ ],
\})
function! s:compiler.__check_requirements() abort dict " {{{1
if !executable(self.executable)
call vimtex#log#warning(self.executable . ' is not executable')
let self.enabled = v:false
endif
endfunction
" }}}1
function! s:compiler.__init() abort dict " {{{1
call vimtex#util#materialize_property(self, 'aux_dir', self.file_info)
call s:compare_with_latexmkrc(self, 'out_dir')
call s:compare_with_latexmkrc(self, 'aux_dir')
" $VIMTEX_OUTPUT_DIRECTORY overrides configured compiler.aux_dir
if !empty($VIMTEX_OUTPUT_DIRECTORY)
if !empty(self.aux_dir)
\ && (self.aux_dir !=# $VIMTEX_OUTPUT_DIRECTORY)
call vimtex#log#warning(
\ 'Setting VIMTEX_OUTPUT_DIRECTORY overrides aux_dir!',
\ 'Changed aux_dir from: ' . self.aux_dir,
\ 'Changed aux_dir to: ' . $VIMTEX_OUTPUT_DIRECTORY)
endif
let self.aux_dir = $VIMTEX_OUTPUT_DIRECTORY
endif
call self.__init_temp_files()
endfunction
" }}}1
function! s:compiler.__build_cmd(passed_options) abort dict " {{{1
let l:cmd = (has('win32')
\ ? 'set max_print_line=2000 & '
\ : 'max_print_line=2000 ') . self.executable
let l:cmd .= ' ' . join(self.options) . a:passed_options
let l:cmd .= ' ' . self.get_engine()
if !empty(self.out_dir)
let l:cmd .= ' -outdir=' . fnameescape(self.out_dir)
endif
if !empty(self.aux_dir)
let l:cmd .= ' -emulate-aux-dir'
let l:cmd .= ' -auxdir=' . fnameescape(self.aux_dir)
endif
if self.continuous
let l:cmd .= ' -pvc -pvctimeout- -view=none'
if self.callback
for [l:opt, l:val] in [
\ ['compiling_cmd', 'vimtex_compiler_callback_compiling'],
\ ['success_cmd', 'vimtex_compiler_callback_success'],
\ ['failure_cmd', 'vimtex_compiler_callback_failure'],
\]
let l:cmd .= s:wrap_option_appendcmd(l:opt, 'echo ' . l:val)
endfor
endif
endif
return l:cmd . ' ' . vimtex#util#shellescape(self.file_info.target_basename)
endfunction
" }}}1
function! s:compiler.__pprint_append() abort dict " {{{1
let l:list = []
if !empty(self.aux_dir)
call add(l:list, ['aux_dir', self.aux_dir])
endif
call add(l:list, ['callback', self.callback])
call add(l:list, ['continuous', self.continuous])
call add(l:list, ['executable', self.executable])
return l:list
endfunction
" }}}1
function! s:compiler.get_file(ext) abort dict " {{{1
if g:vimtex_view_use_temp_files
\ && index(['pdf', 'synctex.gz'], a:ext) >= 0
return self.__get_temp_file(a:ext)
endif
for l:root in [
\ $VIMTEX_OUTPUT_DIRECTORY,
\ self.aux_dir,
\ self.out_dir,
\ self.file_info.root
\]
if empty(l:root) | continue | endif
let l:cand = printf('%s/%s.%s', l:root, self.file_info.jobname, a:ext)
if !vimtex#paths#is_abs(l:root)
let l:cand = self.file_info.root . '/' . l:cand
endif
if filereadable(l:cand)
return fnamemodify(l:cand, ':p')
endif
endfor
return ''
endfunction
" }}}1
function! s:compiler.create_dirs() abort dict " {{{1
call self._create_build_dir(self.out_dir)
call self._create_build_dir(self.aux_dir)
endfunction
" }}}1
function! s:compiler.remove_dirs() abort dict " {{{1
call self._remove_dir(self.out_dir)
call self._remove_dir(self.aux_dir)
endfunction
" }}}1
function! s:compiler.clean(full) abort dict " {{{1
call self.__clean_temp_files(a:full)
let l:cmd = self.executable
let l:cmd .= a:full ? ' -C' : ' -c'
if !empty(self.out_dir)
let l:cmd .= ' -outdir=' . fnameescape(self.out_dir)
endif
if !empty(self.aux_dir)
let l:cmd .= ' -emulate-aux-dir'
let l:cmd .= ' -auxdir=' . fnameescape(self.aux_dir)
endif
let l:cmd .= ' ' . vimtex#util#shellescape(self.file_info.target_basename)
call vimtex#jobs#run(l:cmd, {'cwd': self.file_info.root})
endfunction
" }}}1
function! s:compiler.get_engine() abort dict " {{{1
" Parse tex_program from TeX directive
let l:tex_program_directive = b:vimtex.get_tex_program()
let l:tex_program = l:tex_program_directive
" Parse tex_program from pdf_mode option in .latexmkrc
let [l:pdf_mode, l:is_local] = vimtex#compiler#latexmk#get_rc_opt(
\ self.file_info.root, 'pdf_mode', 1, -1)
if l:pdf_mode >= 1 && l:pdf_mode <= 5
let l:tex_program_pdfmode = [
\ 'pdflatex',
\ 'pdfps',
\ 'pdfdvi',
\ 'lualatex',
\ 'xelatex',
\][l:pdf_mode-1]
" Use pdf_mode if there is no TeX directive
if l:tex_program_directive ==# '_'
let l:tex_program = l:tex_program_pdfmode
elseif l:is_local && l:tex_program_directive !=# l:tex_program_pdfmode
" Give warning when there may be a confusing conflict
call vimtex#log#warning(
\ 'Value of pdf_mode from latexmkrc is inconsistent with ' .
\ 'TeX program directive!',
\ 'TeX program: ' . l:tex_program_directive,
\ 'pdf_mode: ' . l:tex_program_pdfmode,
\ 'The value of pdf_mode will be ignored.')
endif
endif
return get(g:vimtex_compiler_latexmk_engines,
\ l:tex_program,
\ g:vimtex_compiler_latexmk_engines._)
endfunction
" }}}1
function! s:compiler.__init_temp_files() abort dict " {{{1
let self.__temp_files = {}
if !g:vimtex_view_use_temp_files | return | endif
let l:root = !empty(self.out_dir)
\ ? self.out_dir
\ : self.file_info.root
for l:ext in ['pdf', 'synctex.gz']
let l:source = printf('%s/%s.%s', l:root, self.file_info.jobname, l:ext)
let l:target = printf('%s/_%s.%s', l:root, self.file_info.jobname, l:ext)
let self.__temp_files[l:source] = l:target
endfor
augroup vimtex_compiler
autocmd!
autocmd User VimtexEventCompileSuccess
\ call vimtex#compiler#latexmk#copy_temp_files()
augroup END
endfunction
" }}}1
function! s:compiler.__copy_temp_files() abort dict " {{{1
for [l:source, l:target] in items(self.__temp_files)
if getftime(l:source) > getftime(l:target)
call writefile(readfile(l:source, 'b'), l:target, 'b')
endif
endfor
endfunction
" }}}1
function! s:compiler.__get_temp_file(ext) abort dict " {{{1
for l:file in values(self.__temp_files)
if filereadable(l:file) && l:file =~# a:ext . '$'
return l:file
endif
endfor
return ''
endfunction
" }}}1
function! s:compiler.__clean_temp_files(full) abort dict " {{{1
for l:file in values(self.__temp_files)
if filereadable(l:file) && (a:full || l:file[-3:] !=# 'pdf')
call delete(l:file)
endif
endfor
endfunction
" }}}1
function! s:compare_with_latexmkrc(dict, option) abort " {{{1
" Check if option is specified in .latexmkrc.
" If it is, .latexmkrc should be respected!
let l:value = vimtex#compiler#latexmk#get_rc_opt(
\ a:dict.file_info.root, a:option, 0, '')[0]
if !empty(l:value)
if !empty(a:dict[a:option]) && (a:dict[a:option] !=# l:value)
call vimtex#log#warning(
\ 'Option "' . a:option . '" is overridden by latexmkrc',
\ 'Changed from: ' . a:dict[a:option],
\ 'Changed to: ' . l:value)
endif
let a:dict[a:option] = l:value
endif
endfunction
" }}}1
function! s:wrap_option_appendcmd(name, value) abort " {{{1
" Note: On Linux, we use double quoted perl strings; these interpolate
" variables. One should therefore NOT pass values that contain `$`.
let l:win_cmd_sep = has('nvim') ? '^&' : '&'
let l:common = printf('$%s = ($%s ? $%s', a:name, a:name, a:name)
return has('win32')
\ ? printf(' -e "%s . '' %s '' : '''') . ''%s''"',
\ l:common, l:win_cmd_sep, a:value)
\ : printf(' -e ''%s . " ; " : "") . "%s"''',
\ l:common, a:value)
endfunction
"}}}1

View File

@ -0,0 +1,53 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#latexrun#init(options) abort " {{{1
return s:compiler.new(a:options)
endfunction
" }}}1
let s:compiler = vimtex#compiler#_template#new({
\ 'name' : 'latexrun',
\ 'options' : [
\ '--verbose-cmds',
\ '--latex-args="-synctex=1"',
\ ],
\})
function! s:compiler.__check_requirements() abort dict " {{{1
if !executable('latexrun')
call vimtex#log#warning('latexrun is not executable!')
let self.enabled = v:false
endif
endfunction
" }}}1
function! s:compiler.__build_cmd(passed_options) abort dict " {{{1
return 'latexrun ' . join(self.options)
\ . ' --latex-cmd ' . self.get_engine()
\ . ' -O '
\ . (empty(self.out_dir) ? '.' : fnameescape(self.out_dir))
\ . a:passed_options
\ . ' ' . vimtex#util#shellescape(self.file_info.target_basename)
endfunction
" }}}1
function! s:compiler.clean(...) abort dict " {{{1
let l:cmd = printf('latexrun --clean-all -O %s',
\ empty(self.out_dir) ? '.' : fnameescape(self.out_dir))
call vimtex#jobs#run(l:cmd, {'cwd': self.file_info.root})
endfunction
" }}}1
function! s:compiler.get_engine() abort dict " {{{1
return get(g:vimtex_compiler_latexrun_engines,
\ b:vimtex.get_tex_program(),
\ g:vimtex_compiler_latexrun_engines._)
endfunction
" }}}1

View File

@ -0,0 +1,49 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#compiler#tectonic#init(options) abort " {{{1
return s:compiler.new(a:options)
endfunction
" }}}1
let s:compiler = vimtex#compiler#_template#new({
\ 'name' : 'tectonic',
\ 'options' : [
\ '--keep-logs',
\ '--synctex'
\ ],
\})
function! s:compiler.__check_requirements() abort dict " {{{1
if !executable('tectonic')
call vimtex#log#warning('tectonic is not executable!')
let self.enabled = v:false
endif
for l:opt in self.options
if l:opt =~# '^-\%(o\|-outdir\)'
call vimtex#log#warning("Don't use --outdir or -o in compiler options,"
\ . ' use out_dir instead, see :help g:vimtex_compiler_tectonic'
\ . ' for more details')
break
endif
endfor
endfunction
" }}}1
function! s:compiler.__build_cmd(passed_options) abort dict " {{{1
let l:outdir = !empty(self.out_dir)
\ ? self.out_dir
\ : self.file_info.root
return 'tectonic ' . join(self.options)
\ . ' --outdir="' . l:outdir . '"'
\ . a:passed_options
\ . ' ' . vimtex#util#shellescape(self.file_info.target_basename)
endfunction
" }}}1

View File

@ -0,0 +1,956 @@
" VimTeX - LaTeX plugin for Vim
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
function! vimtex#complete#init_buffer() abort " {{{1
if !g:vimtex_complete_enabled | return | endif
if !has_key(b:vimtex, 'complete')
let b:vimtex.complete = {}
endif
for l:completer in s:completers
if has_key(l:completer, 'init')
call l:completer.init()
endif
endfor
setlocal omnifunc=vimtex#complete#omnifunc
endfunction
" }}}1
function! vimtex#complete#omnifunc(findstart, base) abort " {{{1
if a:findstart
if exists('s:completer') | unlet s:completer | endif
let l:pos = col('.') - 1
let l:line = getline('.')[:l:pos-1]
for l:completer in s:completers
if !get(l:completer, 'enabled', 1) | continue | endif
for l:pattern in l:completer.patterns
if l:line =~# l:pattern
let s:completer = l:completer
while l:pos > 0
if l:line[l:pos - 1] =~# '{\|,\|\[\|\\'
\ || l:line[l:pos-2:l:pos-1] ==# ', '
let s:completer.context = matchstr(l:line,
\ get(s:completer, 're_context', '\S*$'))
return l:pos
else
let l:pos -= 1
endif
endwhile
return -2
endif
endfor
endfor
return -3
elseif !exists('s:completer')
return []
endif
return g:vimtex_complete_close_braces && get(s:completer, 'inside_braces', 1)
\ ? s:close_braces(s:completer.complete(a:base))
\ : s:completer.complete(a:base)
endfunction
" }}}1
function! vimtex#complete#complete(type, input, context) abort " {{{1
try
let s:completer = s:completer_{a:type}
let s:completer.context = a:context
return s:completer.complete(a:input)
catch /E121/
return []
endtry
endfunction
" }}}1
"
" Completers
"
" {{{1 Bibtex
let s:completer_bib = {
\ 'patterns' : [
\ '\v\\%(\a*cite|Cite)\a*\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*$',
\ '\v\\%(\a*cites|Cites)%(\s*\([^)]*\)){0,2}'
\ . '%(%(\s*\[[^]]*\]){0,2}\s*\{[^}]*\})*'
\ . '%(\s*\[[^]]*\]){0,2}\s*\{[^}]*$',
\ '\v\\bibentry\s*\{[^}]*$',
\ '\v\\%(text|block)cquote\*?%(\s*\[[^]]*\]){0,2}\{[^}]*$',
\ '\v\\%(for|hy)\w+cquote\*?\{[^}]*\}%(\s*\[[^]]*\]){0,2}\{[^}]*$',
\ '\v\\defbibentryset\{[^}]*\}\{[^}]*$',
\ '\v\\\a?[vV]olcite%(\s*\[[^]]*\])?\s*\{[^}]*\}%(\s*\[[^]]*\])?\s*\{[^}]*$',
\ ],
\ 'initialized' : 0,
\}
function! s:completer_bib.init() dict abort " {{{2
if self.initialized | return | endif
let self.initialized = 1
let self.patterns += g:vimtex_complete_bib.custom_patterns
endfunction
function! s:completer_bib.complete(regex) dict abort " {{{2
let self.candidates = self.gather_candidates()
if g:vimtex_complete_bib.simple
call s:filter(self.candidates, a:regex)
else
call s:filter_with_options(self.candidates, a:regex, {
\ 'anchor': 0,
\ 'filter_key': 'mstr',
\})
endif
return self.candidates
endfunction
function! s:completer_bib.gather_candidates() dict abort " {{{2
let l:entries = []
let l:cache = vimtex#cache#open('bibcomplete', {
\ 'local': 1,
\ 'default': {'result': [], 'ftime': -1},
\ 'validate': {'options': deepcopy(g:vimtex_complete_bib)}
\})
"
" Find data from external bib files
"
" Note: bibtex seems to require that we are in the project root
call vimtex#paths#pushd(b:vimtex.root)
for l:file in vimtex#bib#files()
let l:current = l:cache.get(l:file)
let l:ftime = getftime(l:file)
if l:ftime > l:current.ftime
let l:current.ftime = l:ftime
let l:current.result = map(
\ vimtex#parser#bib(l:file),
\ {_, x -> s:bib_to_candidate(x)})
let l:cache.modified = 1
endif
let l:entries += l:current.result
endfor
call vimtex#paths#popd()
"
" Find data from 'thebibliography' environments
"
let l:ftime = b:vimtex.getftime()
if l:ftime > 0
let l:current = l:cache.get(sha256(b:vimtex.tex))
if l:ftime > l:current.ftime
let l:current.ftime = l:ftime
let l:current.result = []
let l:lines = vimtex#parser#tex(b:vimtex.tex, {'detailed' : 0})
if match(l:lines, '\C\\begin{thebibliography}') >= 0
call filter(l:lines, 'v:val =~# ''\C\\bibitem''')
for l:line in l:lines
let l:matches = matchlist(l:line, '\\bibitem\(\[[^]]\]\)\?{\([^}]*\)')
if len(l:matches) > 1
call add(l:current.result, s:bib_to_candidate({
\ 'key': l:matches[2],
\ 'type': 'thebibliography',
\ 'author': '',
\ 'year': '',
\ 'title': l:matches[2],
\ }))
endif
endfor
endif
endif
let l:entries += l:current.result
endif
" Write cache to file
call l:cache.write()
return l:entries
endfunction
" }}}2
function! s:bib_to_candidate(entry) abort " {{{2
let l:auth = substitute(get(a:entry, 'author', 'Unknown'), '\~', ' ', 'g')
let l:substitutes = {
\ '@author_all' : g:vimtex_complete_bib.auth_len > 0
\ ? strcharpart(l:auth, 0, g:vimtex_complete_bib.auth_len)
\ : l:auth,
\ '@author_short' : substitute(l:auth, ',.*\ze', ' et al.', ''),
\ '@key' : a:entry['key'],
\ '@title' : get(a:entry, 'title', 'No title'),
\ '@type' : empty(a:entry['type']) ? '-' : a:entry['type'],
\ '@year' : get(a:entry, 'year', get(a:entry, 'date', '?')),
\}
let l:cand = {'word': a:entry['key']}
" Create match and menu strings
let l:cand.mstr = copy(g:vimtex_complete_bib.match_str_fmt)
let l:cand.menu = copy(g:vimtex_complete_bib.menu_fmt)
let l:cand.info = copy(g:vimtex_complete_bib.info_fmt)
for [l:key, l:val] in items(l:substitutes)
let l:val = escape(l:val, '&')
let l:cand.mstr = substitute(l:cand.mstr, l:key, l:val, '')
let l:cand.menu = substitute(l:cand.menu, l:key, l:val, '')
let l:cand.info = substitute(l:cand.info, l:key, l:val, '')
endfor
if empty(l:cand.menu)
unlet l:cand.menu
endif
if empty(l:cand.info)
unlet l:cand.info
endif
" Create abbreviation string (if necessary)
if !empty(g:vimtex_complete_bib.abbr_fmt)
let l:cand.abbr = copy(g:vimtex_complete_bib.abbr_fmt)
for [l:key, l:val] in items(l:substitutes)
let l:cand.abbr = substitute(l:cand.abbr, l:key, escape(l:val, '&'), '')
endfor
endif
return l:cand
endfunction
" }}}2
" }}}1
" {{{1 Labels
let s:completer_ref = {
\ 'patterns' : [
\ '\v\\v?%(auto|eq|[cC]?%(page)?|labelc)?ref%(\s*\{[^}]*|range\s*\{[^,{}]*%(\}\{)?)$',
\ '\\hyperref\s*\[[^]]*$',
\ '\\subref\*\?{[^}]*$',
\ '\\nameref{[^}]*$',
\ ],
\ 're_context' : '\\\w*{[^}]*$',
\ 'initialized' : 0,
\}
function! s:completer_ref.init() dict abort " {{{2
if self.initialized | return | endif
let self.initialized = 1
" Add custom patterns
let self.patterns += g:vimtex_complete_ref.custom_patterns
endfunction
function! s:completer_ref.complete(regex) dict abort " {{{2
let l:candidates = self.get_matches(a:regex)
if self.context =~# '\\eqref'
\ && !empty(filter(copy(l:candidates), 'v:val.word =~# ''^eq:'''))
call filter(l:candidates, 'v:val.word =~# ''^eq:''')
endif
return l:candidates
endfunction
function! s:completer_ref.get_matches(regex) dict abort " {{{2
let l:labels = vimtex#parser#auxiliary#labels()
" Match number
let l:matches = filter(copy(l:labels), {_, x -> x.menu =~# a:regex})
if !empty(l:matches) | return l:matches | endif
" Match label
let l:matches = filter(copy(l:labels), {_, x -> x.word =~# a:regex})
if !empty(l:matches) | return l:matches | endif
" Match label and number
let l:regex_split = split(a:regex)
if len(l:regex_split) > 1
let l:base = l:regex_split[0]
let l:number = escape(join(l:regex_split[1:], ' '), '.')
let l:matches = filter(copy(l:labels),
\ {_, x -> x.word =~# l:base && x.menu =~# l:number})
endif
return l:matches
endfunction
" }}}1
" {{{1 Commands
let s:completer_cmd = {
\ 'patterns' : [g:vimtex#re#not_bslash . '\\\a*$'],
\ 'inside_braces' : 0,
\}
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
function! s:completer_cmd.gather_candidates() dict abort " {{{2
let l:candidates = s:load_from_document('cmd')
let l:candidates += self.gather_candidates_from_lets()
for l:pkg in s:get_packages()
let l:candidates += s:load_from_package(l:pkg, 'cmd')
endfor
let l:candidates += self.gather_candidates_from_glossary_keys()
return vimtex#util#uniq_unsorted(l:candidates)
endfunction
function! s:completer_cmd.gather_candidates_from_glossary_keys() dict abort " {{{2
if !has_key(b:vimtex.packages, 'glossaries') | return [] | endif
let l:preamble = vimtex#parser#preamble(b:vimtex.tex)
call map(l:preamble, {_, x -> substitute(x, '\s*%.*', '', 'g')})
let l:glskeys = split(join(l:preamble, "\n"), '\n\s*\\glsaddkey\*\?')[1:]
call map(l:glskeys, {_, x -> substitute(x, '\n\s*', '', 'g')})
call map(l:glskeys, 'vimtex#util#tex2tree(v:val)[2:6]')
let l:candidates = map(vimtex#util#flatten(l:glskeys), {_, x -> {
\ 'word' : x[1:],
\ 'mode' : '.',
\ 'kind' : '[cmd: glossaries]',
\}})
return l:candidates
endfunction
function! s:completer_cmd.gather_candidates_from_lets() dict abort " {{{2
let l:preamble = vimtex#parser#preamble(b:vimtex.tex)
let l:lets = filter(copy(l:preamble), 'v:val =~# ''\\let\>''')
let l:defs = filter(copy(l:preamble), 'v:val =~# ''\\def\>''')
let l:candidates = map(l:lets, {_, x -> {
\ 'word': matchstr(x, '\\let[^\\]*\\\zs\w*'),
\ 'mode': '.',
\ 'kind': '[cmd: \let]',
\}})
\ + map(l:defs, {_, x -> {
\ 'word': matchstr(x, '\\def[^\\]*\\\zs\w*'),
\ 'mode': '.',
\ 'kind': '[cmd: \def]',
\}})
return l:candidates
endfunction
" }}}1
" {{{1 Environments
let s:completer_env = {
\ 'patterns' : ['\v\\%(begin|end)%(\s*\[[^]]*\])?\s*\{[^}]*$'],
\}
function! s:completer_env.complete(regex) dict abort " {{{2
if self.context =~# '^\\end\>'
" When completing \end{, search for an unmatched \begin{...}
let l:matching_env = ''
let l:save_pos = vimtex#pos#get_cursor()
let l:pos_val_cursor = vimtex#pos#val(l:save_pos)
let l:lnum = l:save_pos[1] + 1
while l:lnum > 1
let l:open = vimtex#delim#get_prev('env_tex', 'open')
if empty(l:open) || get(l:open, 'name', '') ==# 'document'
break
endif
let l:close = vimtex#delim#get_matching(l:open)
if empty(l:close.match)
let l:matching_env = l:close.name . (l:close.starred ? '*' : '')
break
endif
let l:pos_val_try = vimtex#pos#val(l:close) + strlen(l:close.match)
if l:pos_val_try > l:pos_val_cursor
break
else
let l:lnum = l:open.lnum
call vimtex#pos#set_cursor(vimtex#pos#prev(l:open))
endif
endwhile
call vimtex#pos#set_cursor(l:save_pos)
if !empty(l:matching_env) && l:matching_env =~# a:regex
return [{
\ 'word': l:matching_env,
\ 'kind': '[env: matching]',
\}]
endif
endif
return s:filter(copy(self.gather_candidates()), a:regex)
endfunction
" }}}2
function! s:completer_env.gather_candidates() dict abort " {{{2
let l:candidates = s:load_from_document('env')
for l:pkg in s:get_packages()
let l:candidates += s:load_from_package(l:pkg, 'env')
endfor
return vimtex#util#uniq_unsorted(l:candidates)
endfunction
" }}}2
" }}}1
" {{{1 Filenames (\includegraphics)
let s:completer_img = {
\ 'patterns' : ['\v\\includegraphics\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*$'],
\ 'ext_re' : '\v\.%('
\ . join(['png', 'jpg', 'eps', 'pdf', 'pgf', 'tikz'], '|')
\ . ')$',
\}
function! s:completer_img.complete(regex) dict abort
let l:added_files = []
let l:generated_pdf = b:vimtex.compiler.get_file('pdf')
let l:candidates = []
for l:path in b:vimtex.graphicspath + [b:vimtex.root]
let l:files = globpath(l:path, '**/*.*', 1, 1)
\ ->filter({_, x ->
\ x =~? self.ext_re
\ && x !=# l:generated_pdf
\ && index(l:added_files, x) < 0
\})
let l:added_files += l:files
let l:candidates += map(l:files, {_, x -> {
\ 'abbr': vimtex#paths#shorten_relative(x),
\ 'word': vimtex#paths#relative(x, l:path),
\ 'kind': '[graphics]',
\}})
endfor
return s:filter(l:candidates, a:regex)
endfunction
" }}}1
" {{{1 Filenames (\input, \include, and \subfile)
let s:completer_inc = {
\ 'patterns' : [
\ g:vimtex#re#tex_input . '[^}]*$',
\ '\v\\includeonly\s*\{[^}]*$',
\ ],
\}
function! s:completer_inc.complete(regex) dict abort
let l:candidates = globpath(b:vimtex.root, '**/*.tex', 0, 1)
" Add .tikz files if appropriate
if has_key(b:vimtex.packages, 'tikz') && self.context !~# '\\subfile'
call extend(l:candidates, globpath(b:vimtex.root, '**/*.tikz', 0, 1))
endif
if self.context =~# '\\include'
let l:candidates = map(l:candidates, {_, x -> #{
\ word: vimtex#paths#relative(x, b:vimtex.root)->fnamemodify(':r'),
\ kind: '[include]',
\}})
else
let l:candidates = map(l:candidates, {_, x -> #{
\ word: vimtex#paths#relative(x, b:vimtex.root),
\ kind: '[input]',
\}})
endif
return s:filter(l:candidates, a:regex)
endfunction
" }}}1
" {{{1 Filenames (\includepdf)
let s:completer_pdf = {
\ 'patterns' : ['\v\\includepdf%(\s*\[[^]]*\])?\s*\{[^}]*$'],
\}
function! s:completer_pdf.complete(regex) dict abort
let l:candidates = globpath(b:vimtex.root, '**/*.pdf', 0, 1)
\ ->map({_, x -> #{
\ word: vimtex#paths#relative(x, b:vimtex.root),
\ kind: '[includepdf]',
\ }
\})
return s:filter(l:candidates, a:regex)
endfunction
" }}}1
" {{{1 Filenames (\includestandalone)
let s:completer_sta = {
\ 'patterns' : ['\v\\includestandalone%(\s*\[[^]]*\])?\s*\{[^}]*$'],
\}
function! s:completer_sta.complete(regex) dict abort
let l:candidates = globpath(b:vimtex.root, '**/*.tex', 0, 1)
\ ->map({_, x -> #{
\ word: vimtex#paths#relative(x, b:vimtex.root)->fnamemodify(':r'),
\ kind: '[includestandalone]',
\}})
return s:filter(l:candidates, a:regex)
endfunction
" }}}1
" {{{1 Glossary (\gls +++)
let s:completer_gls = {
\ 'patterns' : [
\ '\v\\([cpdr]?(gls|Gls|GLS)|acr|Acr|ACR)\a*\s*\{[^}]*$',
\ '\v\\(ac|Ac|AC)\s*\{[^}]*$',
\ ],
\ 'key' : {
\ 'newglossaryentry' : ' [gls]',
\ 'longnewglossaryentry' : ' [gls]',
\ 'newacronym' : ' [acr]',
\ 'newabbreviation' : ' [abbr]',
\ 'glsxtrnewsymbol' : ' [symbol]',
\ },
\}
function! s:completer_gls.init() dict abort " {{{2
if !has_key(b:vimtex.packages, 'glossaries-extra') | return | endif
" Detect stuff like this:
" \GlsXtrLoadResources[src=glossary.bib]
" \GlsXtrLoadResources[src={glossary.bib}, selection={all}]
" \GlsXtrLoadResources[selection={all},src={glossary.bib}]
" \GlsXtrLoadResources[
" src={glossary.bib},
" selection={all},
" ]
let l:do_search = 0
for l:line in vimtex#parser#preamble(b:vimtex.tex)
if line =~# '^\s*\\GlsXtrLoadResources\s*\['
let l:do_search = 1
let l:line = matchstr(l:line, '^\s*\\GlsXtrLoadResources\s*\[\zs.*')
endif
if !l:do_search | continue | endif
let l:matches = split(l:line, '[=,]')
if empty(l:matches) | continue | endif
while !empty(l:matches)
let l:key = trim(remove(l:matches, 0))
if l:key ==# 'src'
let l:value = trim(remove(l:matches, 0))
let l:value = substitute(l:value, '^{', '', '')
let l:value = substitute(l:value, '[]}]\s*', '', 'g')
let b:vimtex.complete.glsbib = l:value
break
endif
endwhile
endfor
endfunction
function! s:completer_gls.complete(regex) dict abort " {{{2
return s:filter(
\ self.parse_glsentries() + self.parse_glsbib(), a:regex)
endfunction
function! s:completer_gls.parse_glsentries() dict abort " {{{2
let l:candidates = []
let l:re_commands = '\v\\(' . join(keys(self.key), '|') . ')'
let l:re_matcher = l:re_commands . '\s*%(\[.*\])=\s*\{([^{}]*)'
for l:line in filter(
\ vimtex#parser#tex(b:vimtex.tex, {'detailed' : 0}),
\ 'v:val =~# l:re_commands')
let l:matches = matchlist(l:line, l:re_matcher)
call add(l:candidates, {
\ 'word' : l:matches[2],
\ 'menu' : self.key[l:matches[1]],
\})
endfor
return l:candidates
endfunction
function! s:completer_gls.parse_glsbib() dict abort " {{{2
let l:filename = get(b:vimtex.complete, 'glsbib', '')
if empty(l:filename) | return [] | endif
let l:candidates = []
for l:entry in vimtex#parser#bib(l:filename, {'backend': 'vim'})
call add(l:candidates, {
\ 'word': l:entry.key,
\ 'menu': get(l:entry, 'name', '--'),
\})
endfor
return l:candidates
endfunction
" }}}1
" {{{1 Packages (\usepackage)
let s:completer_pck = {
\ 'patterns' : [
\ '\v\\%(usepackage|RequirePackage)%(\s*\[[^]]*\])?\s*\{[^}]*$',
\ '\v\\PassOptionsToPackage\s*\{[^}]*\}\s*\{[^}]*$',
\ ],
\ 'candidates' : [],
\}
function! s:completer_pck.complete(regex) dict abort " {{{2
return s:filter(self.gather_candidates(), a:regex)
endfunction
function! s:completer_pck.gather_candidates() dict abort " {{{2
if empty(self.candidates)
let self.candidates = map(s:get_texmf_candidates('sty'), {_, x -> {
\ 'word': x,
\ 'kind': '[package]',
\}})
endif
return copy(self.candidates)
endfunction
" }}}1
" {{{1 Documentclasses (\documentclass)
let s:completer_doc = {
\ 'patterns' : [
\ '\v\\documentclass%(\s*\[[^]]*\])?\s*\{[^}]*$',
\ '\v\\PassOptionsToClass\s*\{[^}]*\}\s*\{[^}]*$',
\ ],
\ 'candidates' : [],
\}
function! s:completer_doc.complete(regex) dict abort " {{{2
return s:filter(self.gather_candidates(), a:regex)
endfunction
function! s:completer_doc.gather_candidates() dict abort " {{{2
if empty(self.candidates)
let self.candidates = map(s:get_texmf_candidates('cls'), {_, x -> {
\ 'word' : x,
\ 'kind' : '[documentclass]',
\}})
endif
return copy(self.candidates)
endfunction
" }}}1
" {{{1 Bibliographystyles (\bibliographystyle)
let s:completer_bst = {
\ 'patterns' : ['\v\\bibliographystyle\s*\{[^}]*$'],
\ 'candidates' : [],
\}
function! s:completer_bst.complete(regex) dict abort " {{{2
return s:filter(self.gather_candidates(), a:regex)
endfunction
function! s:completer_bst.gather_candidates() dict abort " {{{2
if empty(self.candidates)
let self.candidates = map(s:get_texmf_candidates('bst'), {_, x -> {
\ 'word' : x,
\ 'kind' : '[bst files]',
\}})
endif
return copy(self.candidates)
endfunction
" }}}1
"
" Functions to parse candidates from packages
"
function! s:get_packages() abort " {{{1
let l:packages = [
\ 'default',
\ 'class-' . get(b:vimtex, 'documentclass', ''),
\ ] + keys(b:vimtex.packages)
call vimtex#paths#pushd(s:complete_dir)
let l:missing = filter(copy(l:packages), '!filereadable(v:val)')
call filter(l:packages, 'filereadable(v:val)')
" Parse include statements in complete files
let l:queue = copy(l:packages)
while !empty(l:queue)
let l:current = remove(l:queue, 0)
let l:includes = filter(readfile(l:current), 'v:val =~# ''^\#\s*include:''')
if empty(l:includes) | continue | endif
call map(l:includes, {_, x -> matchstr(x, 'include:\s*\zs.*\ze\s*$')})
let l:missing += filter(copy(l:includes),
\ {_, x -> !filereadable(x) && index(l:missing, x) < 0})
call filter(l:includes,
\ {_, x -> filereadable(x) && index(l:packages, x) < 0})
let l:packages += l:includes
let l:queue += l:includes
endwhile
call vimtex#paths#popd()
return l:packages + l:missing
endfunction
" }}}1
function! s:load_from_package(pkg, type) abort " {{{1
let s:pkg_cache = get(s:, 'pkg_cache',
\ vimtex#cache#open('pkgcomplete', {'default': {}}))
let l:current = s:pkg_cache.get(a:pkg)
let l:pkg_file = s:complete_dir . '/' . a:pkg
if filereadable(l:pkg_file)
if !has_key(l:current, 'candidates')
let s:pkg_cache.modified = 1
let l:current.candidates
\ = s:_load_candidates_from_complete_file(a:pkg, l:pkg_file)
endif
else
if !has_key(l:current, 'candidates')
let s:pkg_cache.modified = 1
let l:current.candidates = {'cmd': [], 'env': []}
endif
let l:filename = a:pkg =~# '^class-'
\ ? vimtex#kpsewhich#find(a:pkg[6:] . '.cls')
\ : vimtex#kpsewhich#find(a:pkg . '.sty')
let l:ftime = getftime(l:filename)
if l:ftime > get(l:current, 'ftime', -1)
let s:pkg_cache.modified = 1
let l:current.ftime = l:ftime
let l:current.candidates = s:_load_candidates_from_source(
\ readfile(l:filename), a:pkg)
endif
endif
" Write cache to file
call s:pkg_cache.write()
return copy(l:current.candidates[a:type])
endfunction
" }}}1
function! s:load_from_document(type) abort " {{{1
let s:pkg_cache = get(s:, 'pkg_cache',
\ vimtex#cache#open('pkgcomplete', {'default': {}}))
let l:ftime = b:vimtex.getftime()
if l:ftime < 0 | return [] | endif
let l:current = s:pkg_cache.get(sha256(b:vimtex.tex))
if l:ftime > get(l:current, 'ftime', -1)
let l:current.ftime = l:ftime
let l:current.candidates = s:_load_candidates_from_source(
\ vimtex#parser#tex(b:vimtex.tex, {'detailed' : 0}),
\ 'local')
" Write cache to file
let s:pkg_cache.modified = 1
call s:pkg_cache.write()
endif
return copy(l:current.candidates[a:type])
endfunction
" }}}1
function! s:_load_candidates_from_complete_file(pkg, pkgfile) abort " {{{1
let l:result = {'cmd': [], 'env': []}
let l:lines = readfile(a:pkgfile)
let l:candidates = filter(copy(l:lines), 'v:val =~# ''^\a''')
call map(l:candidates, 'split(v:val)')
call map(l:candidates, {_, x -> {
\ 'word': x[0],
\ 'mode': '.',
\ 'kind': '[cmd: ' . a:pkg . '] ',
\ 'menu': get(x, 1, ''),
\}})
let l:result.cmd += l:candidates
let l:candidates = filter(l:lines, 'v:val =~# ''^\\begin{''')
call map(l:candidates, {_, x -> {
\ 'word': substitute(x, '^\\begin{\|}$', '', 'g'),
\ 'mode': '.',
\ 'kind': '[env: ' . a:pkg . '] ',
\}})
let l:result.env += l:candidates
return l:result
endfunction
" }}}1
function! s:_load_candidates_from_source(lines, pkg) abort " {{{1
return {
\ 'cmd':
\ s:gather_candidates_from_newcommands(
\ copy(a:lines), 'cmd: ' . a:pkg),
\ 'env':
\ s:gather_candidates_from_newenvironments(
\ a:lines, 'env: ' . a:pkg)
\}
endfunction
" }}}1
function! s:gather_candidates_from_newcommands(lines, label) abort " {{{1
" Arguments:
" a:lines Lines of TeX that may contain \newcommands (or some variant,
" e.g. as provided by xparse and standard declaration)
" a:label Label to use in the menu
let l:re = '\v\\%(%(provide|renew|new)command'
\ . '|%(New|Declare|Provide|Renew)%(Expandable)?DocumentCommand'
\ . '|DeclarePairedDelimiter)'
let l:re_match = l:re . '\*?%(\{\\?\zs[^}]*|\\\zs\w+)'
return map(filter(a:lines, 'v:val =~# l:re'), {_, x -> {
\ 'word': matchstr(x, l:re_match),
\ 'mode': '.',
\ 'kind': '[' . a:label . ']',
\}})
endfunction
" }}}1
function! s:gather_candidates_from_newenvironments(lines, label) abort " {{{1
" Arguments:
" a:lines Lines of TeX that may contain \newenvironments (or some
" variant, e.g. as provided by xparse and standard declaration)
" a:label Label to use in the menu
let l:re = '\v\\((renew|new)environment'
\ . '|(New|Renew|Provide|Declare)DocumentEnvironment)'
let l:re_match = l:re . '\*?\{\\?\zs[^}]*'
return map(filter(a:lines, 'v:val =~# l:re'), {_, x -> {
\ 'word': matchstr(x, l:re_match),
\ 'mode': '.',
\ 'kind': '[' . a:label . ']',
\}})
endfunction
" }}}1
"
" Utility functions
"
function! s:filter(input, regex) abort " {{{1
if empty(a:input) | return a:input | endif
let l:ignore_case = g:vimtex_complete_ignore_case
\ && (!g:vimtex_complete_smart_case || a:regex !~# '\u')
if type(a:input[0]) == v:t_dict
let l:Filter = l:ignore_case
\ ? {_, x -> x.word =~? '^' . a:regex}
\ : {_, x -> x.word =~# '^' . a:regex}
else
let l:Filter = l:ignore_case
\ ? {_, x -> x =~? '^' . a:regex}
\ : {_, x -> x =~# '^' . a:regex}
endif
return filter(a:input, l:Filter)
endfunction
" }}}1
function! s:filter_with_options(input, regex, opts) abort " {{{1
if empty(a:input) | return a:input | endif
let l:regex = (get(a:opts, 'anchor', 1) ? '^' : '') . a:regex
let l:ignore_case = g:vimtex_complete_ignore_case
\ && (!g:vimtex_complete_smart_case || a:regex !~# '\u')
if type(a:input[0]) == v:t_dict
let l:key = get(a:opts, 'filter_key', 'word')
let l:Filter = l:ignore_case
\ ? {_, x -> x[l:key] =~? l:regex}
\ : {_, x -> x[l:key] =~# l:regex}
else
let l:Filter = l:ignore_case
\ ? {_, x -> x =~? l:regex}
\ : {_, x -> x =~# l:regex}
endif
return filter(a:input, l:Filter)
endfunction
" }}}1
function! s:get_texmf_candidates(filetype) abort " {{{1
let l:candidates = []
let l:texmfhome = $TEXMFHOME
if empty(l:texmfhome)
let l:texmfhome = get(vimtex#kpsewhich#run('--var-value TEXMFHOME'), 0, '')
endif
" Add locally installed candidates first
if !empty(l:texmfhome)
let l:candidates += glob(l:texmfhome . '/**/*.' . a:filetype, 0, 1)
call map(l:candidates, "fnamemodify(v:val, ':t:r')")
endif
" Then add globally available candidates (based on ls-R files)
for l:file in vimtex#kpsewhich#run('--all ls-R')
let l:candidates += map(filter(readfile(l:file),
\ {_, x -> x =~# '\.' . a:filetype}),
\ "fnamemodify(v:val, ':r')")
endfor
return l:candidates
endfunction
" }}}1
function! s:close_braces(candidates) abort " {{{1
if strpart(getline('.'), col('.') - 1) !~# '^\s*[,}]'
for l:cand in a:candidates
if !has_key(l:cand, 'abbr')
let l:cand.abbr = l:cand.word
endif
let l:cand.word = substitute(l:cand.word, '}*$', '}', '')
endfor
endif
return a:candidates
endfunction
" }}}1
"
" Initialize module
"
let s:completers = map(
\ filter(items(s:), 'v:val[0] =~# ''^completer_'''),
\ 'v:val[1]')
let s:complete_dir = expand('<sfile>:r') . '/'

View File

@ -0,0 +1,8 @@
bibtextitlecommand
citeauthor
citeauthoronline
citeonline
citeoptions
citeyear
leftovercite
rightovercite

View File

@ -0,0 +1,33 @@
aca*
acap
acap*
acf*
Acf*
acfirstupper
acflike
acflike*
acfp
Acfp
acfp*
Acfp*
acfplike
acfplike*
acifused
acl*
Acl*
aclp
Aclp
aclp*
Aclp*
acp*
Acp*
acreset
acresetall
acs*
acsetup
acsp
acsp*
acuse
acuseall
DeclareAcronym
printacronyms

View File

@ -0,0 +1,29 @@
acf*
acffont
acfi
acfi*
acfp
acfp*
acfsfont
acl*
aclp
aclp*
aclu
aclu*
acp*
acresetall
acro
acrodef
acrodefplural
acroextra
acroplural
acs*
acsfont
acsp
acsp*
acsu
acsu*
acused
newacro
newacroplural
\begin{acronym}

View File

@ -0,0 +1 @@
afterpage

View File

@ -0,0 +1,205 @@
#include:color
#include:endfloat
#include:ifthen
#include:relsize
#include:tocbibind
#include:xspace
AlCapFnt
AlCapNameFnt
AlCapNameSty
AlCapSty
AlFnt
algocfautorefname
algocffuncautorefname
algocfprocautorefname
algoendfloat
algoheightrule
algoheightruledefault
AlgoLineautorefname
algoplace
algorithmautorefname
algorithmcflinename
algorithmcfname
algotitleheightrule
algotitleheightruledefault
AlTitleFnt
AlTitleSty
ArgSty
Begin
BlankLine
Case
CommentSty
DataSty
decmargin
DecMargin
dontprintsemicolon
DontPrintSemicolon
Else
ElseIf
ForAll
ForEach
FuncSty
functionautorefname
Hlne
incmargin
IncMargin
Indentp
Indm
Indmm
Indp
Indpp
InOutSizeDefined
KwData
KwIn
KwOut
KwResult
KwRet
KwSty
KwTo
lCase
leIf
lElse
lElseif
lElseIf
lFor
lForAll
lForEach
linesnotnumbered
LinesNotNumbered
linesnumbered
LinesNumbered
linesnumberedhidden
LinesNumberedHidden
listalgorithmcfname
listofalgocfs
lnlset
lOther
lRepeat
lWhile
next
nllabel
nlset
nlSty
NlSty
nocaptionofalgo
NoCaptionOfAlgo
Other
printsemicolon
PrintSemicolon
ProcArgFnt
ProcArgSty
procedureautorefname
ProcFnt
ProcNameFnt
ProcNameSty
ProcSty
relsize
Repeat
ResetInOut
restorecaptionofalgo
RestoreCaptionOfAlgo
restylealgo
RestyleAlgo
Return
SetAlCapFnt
setalcaphskip
SetAlCapHSkip
SetAlCapNameFnt
SetAlCapNameSty
setalcapskip
SetAlCapSkip
SetAlCapSty
SetAlFnt
SetAlgoCaptionLayout
SetAlgoCaptionSeparator
SetAlgoFuncName
SetAlgoInsideSkip
SetAlgoLined
SetAlgoLongEnd
SetAlgoNlRelativeSize
SetAlgoNoEnd
SetAlgoNoLine
SetAlgoProcName
SetAlgoRefName
SetAlgoRefRelativeSize
SetAlgorithmName
SetAlgoShortEnd
SetAlgoSkip
SetAlgoVlined
SetAlTitleFnt
SetAlTitleSty
SetArgSty
SetCommentSty
SetDataSty
SetEndCharOfAlgoLine
SetFillComment
SetFuncSty
SetInd
SetKw
SetKwArray
SetKwBlock
SetKwComment
SetKwData
SetKwFor
SetKwFunction
SetKwHangingKw
SetKwIF
SetKwInOut
SetKwInput
SetKwRepeat
SetKwSty
SetKwSwitch
setLeftLinesNumbers
SetLine
setnlskip
Setnlskip
SetNlSkip
Setnlsty
SetNlSty
SetNoFillComment
SetNoLine
SetNothing
SetProcArgFnt
SetProcArgSty
SetProcFnt
SetProcNameFnt
SetProcNameSty
SetProcSty
setRightLinesNumbers
SetSideCommentLeft
SetSideCommentRight
SetTitleSty
SetVline
SetVlineSkip
showln
ShowLn
showlnlabel
ShowLnLabel
Switch
tcc*
tcp*
test
thealgocf
thealgocfline
thealgocfproc
theAlgoLine
theHalgocf
theHalgocffunc
theHalgocfproc
theHAlgoLine
thepostalgo
Titleofalgo
TitleOfAlgo
TitleSty
uCase
uElse
uElseIf
vespace
While
\begin{algocf}
\begin{algorithm}
\begin{algorithm*}
\begin{function}
\begin{function*}
\begin{procedure}
\begin{procedure*}

View File

@ -0,0 +1,31 @@
arafamily
arcfamily
arlfamily
armfamily
arnfamily
artfamily
curvedtwigs
hflip
hightwigs
lfseries
lowtwigs
roundedtwigs
straighttwigs
textara
textarc
textarl
textarm
textarn
textart
textcu
texthi
textlf
textlo
textro
textst
textwil
textwol
turn
vflip
withlines
withoutlines

View File

@ -0,0 +1 @@
boldsymbol

View File

@ -0,0 +1,17 @@
dashleftarrow ⇠
dashrightarrow ⇢
llcorner └
lozenge ◊
lrcorner ┘
rightsquigarrow ⇝
sqsubset ⊏
sqsupset ⊐
square □
trianglelefteq ⊴
trianglerighteq ⊵
ulcorner ┌
unlhd ⊴
unrhd ⊵
urcorner ┐
vartriangleleft ⊲
vartriangleright ⊳

View File

@ -0,0 +1,93 @@
allowdisplaybreaks
AmSfont
binom
bmod
boldsymbol
boxed
cfrac
dbinom
ddddot
dddot
DeclareMathOperator
DeclareMathOperator*
displaybreak
dotsb ⋯
dotsc …
dotsi ⋯
dotsm ⋯
dotso …
eqref
hdotsfor
idotsint
iiiint ⨌
iiint ∭
iint ∬
impliedby ⟸
implies ⇒
intertext
leftroot
lvert
lVert ∥
medspace
mspace
negmedspace
negthickspace
negthinspace
nobreakdash
notag
operatorname
operatornamewithlimits
overleftrightarrow ↔
overset
pmod
raisetag
rvert
rVert ∥
sideset
substack
tag*
tbinom
text
tfrac
thickspace
thinspace
underleftarrow ←
underleftrightarrow ↔
underrightarrow →
underset
uproot
varDelta Δ
varGamma Γ
varLambda Λ
varOmega Ω
varPhi Φ
varPi Π
varPsi Ψ
varSigma Σ
varTheta Θ
varUpsilon Υ
varXi Ξ
xleftarrow ←
xrightarrow →
\begin{align}
\begin{align*}
\begin{alignat}
\begin{alignat*}
\begin{aligned}
\begin{alignedat}
\begin{cases}
\begin{equation*}
\begin{flalign}
\begin{flalign*}
\begin{gather}
\begin{gather*}
\begin{gathered}
\begin{multline}
\begin{multline*}
\begin{smallmatrix}
\begin{split}
\begin{subarray}
\begin{subequations}
\begin{xalignat}
\begin{xalignat*}
\begin{xxalignat}

View File

@ -0,0 +1,8 @@
injlim
nolimits
operatornamewithlimits
projlim
varinjlim
varliminf
varlimsup
varprojlim

View File

@ -0,0 +1,199 @@
approxeq ≊
backepsilon ∍
backprime
backsim ∽
backsimeq ⋍
barwedge ⊼
Bbbk 𝕜
because ∵
beth ℶ
between ≬
bigstar ★
blacklozenge ◆
blacksquare ■
blacktriangle ▲
blacktriangledown ▼
blacktriangleleft ◀
blacktriangleright ▶
boxdot ⊡
boxminus ⊟
boxplus ⊞
boxtimes ⊠
bumpeq ≏
Bumpeq ≎
centerdot ⋅
checkmark ✓
circeq ≗
circlearrowleft ↺
circlearrowright ↻
circledast ⊛
circledcirc ⊚
circleddash ⊝
circledS Ⓢ
complement ∁
curlyeqprec ⋞
curlyeqsucc ⋟
curlyvee ⋎
curlywedge ⋏
curvearrowleft ↶
curvearrowright ↷
daleth ℸ
diagdown ╲
diagup
digamma ϝ
divideontimes ⋇
doteqdot ≑
dotplus ∔
doublebarwedge ⩞
downdownarrows ⇊
downharpoonleft ⇃
downharpoonright ⇂
eqcirc ≖
eqsim ≂
eqslantgtr ⪖
eqslantless ⪕
fallingdotseq ≒
Finv Ⅎ
Game ⅁
geqq ≧
geqslant ⩾
gimel ℷ
gnapprox ⪊
gneq ⪈
gneqq ≩
gnsim ⋧
gtrapprox ⪆
gtrdot ⋗
gtreqless ⋛
gtreqqless ⪌
gtrless ≷
gtrsim ≳
gvertneqq 
hslash ℏ
intercal ⊺
leftarrowtail ↢
leftleftarrows ⇇
leftrightarrows ⇆
leftrightharpoons ⇋
leftrightsquigarrow ↭
leftthreetimes ⋋
leqq ≦
leqslant ⩽
lessapprox ⪅
lessdot ⋖
lesseqgtr ⋚
lesseqqgtr ⪋
lessgtr ≶
lesssim ≲
Lleftarrow ⇚
lnapprox ⪉
lneq ⪇
lneqq ≨
lnsim ⋦
looparrowleft ↫
looparrowright ↬
lozenge ◊
ltimes ⋉
lvertneqq 
maltese ✠
measuredangle ∡
multimap ⊸
ncong ≆
nexists ∄
ngeq ≱
ngeqq 
ngeqslant 
ngtr ≯
nleftarrow ↚
nLeftarrow ⇍
nleftrightarrow ↮
nLeftrightarrow ⇎
nleq ≰
nleqq 
nleqslant 
nless ≮
nmid ∤
nparallel ∦
nprec ⊀
npreceq ⋠
nrightarrow ↛
nRightarrow ⇏
nshortmid 
nshortparallel 
nsim ≁
nsubseteq ⊈
nsubseteqq 
nsucc ⊁
nsucceq ⋡
nsupseteq ⊉
nsupseteqq 
ntriangleleft ⋪
ntrianglelefteq ⋬
ntriangleright ⋫
ntrianglerighteq ⋭
nvdash ⊬
nvDash ⊭
nVdash ⊮
nVDash ⊯
pitchfork ⋔
precapprox ⪷
preccurlyeq ≼
precnapprox ⪹
precneqq ⪵
precnsim ⋨
precsim ≾
rightarrowtail ↣
rightleftarrows ⇄
rightrightarrows ⇉
rightsquigarrow ⇝
rightthreetimes ⋌
risingdotseq ≓
Rrightarrow ⇛
rtimes ⋊
shortmid
shortparallel ∥
smallfrown ⌢
smallsetminus
smallsmile ⌣
sphericalangle ∢
square □
Subset ⋐
subseteqq ⫅
subsetneq ⊊
subsetneqq ⫋
succapprox ⪸
succcurlyeq ≽
succnapprox ⪺
succneqq ⪶
succnsim ⋩
succsim ≿
Supset ⋑
supseteqq ⫆
supsetneq ⊋
supsetneqq ⫌
therefore ∴
thickapprox ≈
thicksim
triangledown ▽
trianglelefteq ⊴
triangleq ≜
trianglerighteq ⊵
twoheadleftarrow ↞
twoheadrightarrow ↠
upharpoonleft ↿
upharpoonright ↾
upuparrows ⇈
varkappa ϰ
varnothing ∅
varpropto ∝
varsubsetneq 
varsubsetneqq 
varsupsetneq 
varsupsetneqq 
vartriangle △
vartriangleleft ⊲
vartriangleright ⊳
vDash ⊨
Vdash ⊩
veebar ⊻
Vvdash ⊪

View File

@ -0,0 +1,6 @@
newtheoremstyle
qedhere
qedsymbol
swapnumbers
theoremstyle
\begin{proof}

View File

@ -0,0 +1,21 @@
addappheadtotoc
appendicestocpagenum
appendixheaderoff
appendixheaderon
appendixpage
appendixpagename
appendixpageoff
appendixpageon
appendixtitleoff
appendixtitleon
appendixtitletocoff
appendixtitletocon
appendixtocname
appendixtocoff
appendixtocon
noappendicestocpagenum
restoreapp
setthesection
setthesubsection
\begin{appendices}
\begin{subappendices}

View File

@ -0,0 +1,7 @@
arraybackslash
extrarowheight
extratabsurround
firsthline
lasthline
newcolumntype
showcols

View File

@ -0,0 +1,5 @@
attachfile
attachfilesetup
noattachfile
notextattachfile
textattachfile

View File

@ -0,0 +1,72 @@
aliasshorthand
alsoname
babelhyphenation
bibname
captionsfrench
ccname
DecimalMathComma
defineshorthand
degres
dotFFN
enclname
extrasfrenchb
Fcolonspace
foreignlanguage
frenchabstractname
frenchalsoname
frenchappendixname
frenchbibname
frenchbsetup
frenchccname
frenchchaptername
frenchcontentsname
frenchenclname
FrenchEnumerate
frenchfigurename
frenchglossaryname
frenchheadtoname
frenchindexname
frenchlistfigurename
frenchlisttablename
frenchpagename
frenchpartname
frenchprefacename
frenchproofname
frenchrefname
frenchseename
frenchspacing
frenchtablename
Fthinspace
glossaryname
headtoname
ieme
iemes
iere
ieres
iers
iflanguage
kernFFN
languageattribute
languagename
languageshorthands
NoAutoSpacing
noextrasfrenchb
nombre
nonfrenchspacing
parindentFFN
prefacename
primo
proofname
quarto
secundo
seename
selectlanguage
shorthandoff
shorthandon
StandardFootnotes
StandardMathComma
tertio
useshorthands
\begin{hypenrules}
\begin{otherlanguage}
\begin{otherlanguage*}

View File

@ -0,0 +1,9 @@
bmstyle
endfoil
foilhead
FoilTeX
LogoOff
LogoOn
MyLogo
rotatefoilhead
\begin{boldequation}

View File

@ -0,0 +1,33 @@
dualslide
email
fontText
fontTitle
fromSlide
FromSlide
fromSlide*
hiddenitem
institution
Logo
onlyInPDF
onlyInPS
onlySlide
OnlySlide
onlySlide*
overlays
PDForPS
PDFtransition
prosperpart
slideCaption
tsection
tsection*
tsectionandpart
tsectionandpart*
untilSlide
UntilSlide
untilsSlide
untilsSlide*
\begin{enumstep}
\begin{Itemize}
\begin{itemstep}
\begin{notes}
\begin{slides}

View File

@ -0,0 +1,8 @@
blue
green
ifarticle
ifportrait
ifslide
ifslidesonly
overlay
\begin{slide}

View File

@ -0,0 +1,18 @@
boxedsteps
bstep
code
codeswitch
dstep
liststepwise
nonboxedsteps
parstepwise
rebstep
redstep
restep
reswitch
revstep
step
steponce
stepwise
switch
vstep

View File

@ -0,0 +1,26 @@
#include:euler
#include:fhginstitutes
#include:graphicx
#include:pgf
#include:textcomp
boxitem
cdotitem
endtitleframe
fhgpaperwidth
fhgtextwidth
insertframepart
insertframesection
insertframesubsection
questionitem
setinstitute
splitvnext
splitvvnext
titleframe
triangledownitem
triangleleftitem
trianglerightitem
triangleupitem
vdotsitem
\begin{splitv}
\begin{splitvv}
\begin{titleframe}

View File

@ -0,0 +1,203 @@
#include:natbib
addabbrvspace
addabthinspace
addbibresource
adddotspace
addglobalbib
addhighpenspace
addhpthinspace
addlowpenspace
addlpthinspace
addnbspace
addnbthinspace
addsectionbib
addslash
addspace
addthinspace
addtocategory
andmoredelim
andothersdelim
autocap
autocite
Autocite
autocite*
Autocite*
autocites
Autocites
avolcite
Avolcite
bibbycategory
bibbysection
bibbysegment
bibcplstring
bibcpsstring
bibcpstring
bibdatelong
bibdateshort
bibellipsis
bibfont
bibhang
bibitemextrasep
bibitemsep
biblabelsep
biblclstring
biblcsstring
biblcstring
bibleftbracket
bibleftparen
biblstring
bibnamedash
bibpagespunct
bibparsep
bibrangedash
bibrightbracket
bibrightparen
bibsetup
bibsstring
bibstring
bibuclstring
bibucstring
biburldatelong
biburldateshort
bibuscstring
bibxlstring
bibxsstring
bibxstring
category
Cite
cite*
citeauthor
Citeauthor
citedate
citefield
citelist
citename
citereset
citereset*
cites
Cites
citesetup
citetitle
citetitle*
citeurl
citeyear
compcitedelim
DeclareBibliographyCategory
DeclareFieldAlias
DeclareFieldFormat
DeclareFieldFormat*
DeclareIndexFieldAlias
DeclareIndexFieldFormat
DeclareIndexFieldFormat*
DeclareIndexListAlias
DeclareIndexListFormat
DeclareIndexListFormat*
DeclareIndexNameAlias
DeclareIndexNameFormat
DeclareIndexNameFormat*
DeclareListAlias
DeclareListFormat
DeclareListFormat*
DeclareNameAlias
DeclareNameFormat
DeclareNameFormat*
defbibfilter
defbibheading
defbibnote
DefineBibliographyExtras
DefineBibliographyStrings
DefineHyphenationExceptions
ExecuteBibliographyOptions
finalandcomma
finallistdelim
finalnamedelim
finentrypunct
fnotecite
footcite
Footcite
footcites
Footcites
footfullcite
forceE
forceY
fullcite
hyphen
hyphenate
ifkomabibtotoc
ifkomabibtotocnumbered
ifmemoirbibintoc
keyword
labelalphaothers
labelnamepunct
mainlang
mancite
mkbibacro
mkbibbold
mkbibbrackets
mkbibemph
mkbibendnote
mkbibendnotetext
mkbibfemord
mkbibfootnote
mkbibfootnotetext
mkbibitalic
mkbibmascord
mkbibnameaffix
mkbibnamefirst
mkbibnamelast
mkbibnameprefix
mkbibordinal
mkbibparens
mkbibquote
mkbibsuperscript
mknumalph
multicitedelim
multilistdelim
multinamedelim
nameyeardelim
nbhyphen
NewBibliographyString
newblockpunct
newrefsection
newrefsegment
newunitpunct
noligature
nopp
notecite
Notecite
parencite
Parencite
parencite*
parencites
Parencites
pnotecite
Pnotecite
postnotedelim
ppno
prenotedelim
printbibliography
printshorthands
psqq
revsdnamedelim
segment
smartcite
Smartcite
smartcites
Smartcites
subtitlepunct
supercite
supercitedelim
supercites
svolcite
Svolcite
textcite
Textcite
textcites
Textcites
tvolcite
Tvolcite
type
UndefineBibliographyExtras
unspace
\begin{refsection}
\begin{refsegment}

View File

@ -0,0 +1,7 @@
bmdefine
bmmax
boldsymbol
DeclareBoldMathCommand
heavysymbol
hmdefine
hmmax

View File

@ -0,0 +1,7 @@
addlinespace
bottomrule
cmidrule
midrule
morecmidrules
specialrule
toprule

View File

@ -0,0 +1,2 @@
braket
Braket

View File

@ -0,0 +1,9 @@
depthof
heightof
maxof
minof
ratio
real
settototalheight
totalheightof
widthof

View File

@ -0,0 +1,5 @@
bcancel
cancel
CancelColor
cancelto
xcance

View File

@ -0,0 +1,20 @@
bothIfFirst
bothIfSecond
caption*
captionlistentry
captionof
captionof*
captionsetup
clearcaptionsetup
ContinuedFloat
ContinuedFloat*
DeclareCaptionFont
DeclareCaptionFormat
DeclareCaptionJustification
DeclareCaptionLabelFormat
DeclareCaptionLabelSeparator
DeclareCaptionListFormat
DeclareCaptionStyle
DeclareCaptionTextFormat
DeclareCaptionType
showcaptionsetup

View File

@ -0,0 +1,2 @@
\begin{numcases}
\begin{subnumcases}

View File

@ -0,0 +1,42 @@
#include:expl3
#include:xparse
#include:l3keys2e
#include:tikz
#include:amstext
#include:xfrac
#include:nicefrac
#include:scrlfile
bond
charrow
chcpd
chemformula
chlewis
chname
chstoich
DeclareChemAdditionSymbol
DeclareChemArrow
DeclareChemBond
DeclareChemBondAlias
DeclareChemCompoundProperty
DeclareChemSymbol
DeprecatedFormulaCommand
NewChemAdditionSymbol
NewChemArrow
NewChemBond
NewChemBondAlias
NewChemCompoundProperty
NewChemSymbol
ProvideChemAdditionSymbol
ProvideChemArrow
ProvideChemBond
ProvideChemCompoundProperty
ProvideChemSymbol
RemoveChemCompoundProperty
RenewChemAdditionSymbol
RenewChemArrow
RenewChemBond
RenewChemCompoundProperty
RenewChemSymbol
setchemformula
ShowChemArrow
ShowChemBond

View File

@ -0,0 +1,20 @@
#include:SIunits
#include:amstext
#include:caption
#include:chemscheme
#include:siunitx
#include:varioref
#include:xspace
cstsetup
cubiccentimeter
etal
expandafter
invacuo
latin
latinemphoff
latinemphon
mmHg
molar
Molar
standardstate
thebibnote

View File

@ -0,0 +1,92 @@
#include:siunitx
#include:tikz
#include:xstring
anchor
anchorborder
backgroundpath
beforebackgroundpath
beforeforegroundpath
behindbackgroundpath
behindforegroundpath
circuitikzbasekey
circuitikzset
ctikzset
ctikzsetvalof
ctikzvalof
deferredanchor
drawpoles
foregroundpath
inheritanchor
inheritanchorborder
inheritbackgroundpath
inheritbeforebackgroundpath
inheritbeforeforegroundpath
inheritbehindbackgroundpath
inheritbehindforegroundpath
inheritforegroundpath
inheritlogicport
inheritnodeparts
inheritsavedanchors
myfrac
nodeparts
pgfcircdeclarebipole
pgfcircdeclareeurologicport
pgfcircdeclarefet
pgfcircdeclarelogicport
pgfcircdeclaremos
pgfcircdeclarequadpole
pgfcircdeclaretransistor
pgfcircmathresult
pgfcircresetpath
pgfcircversion
pgfdeclaredecoration
pgfdeclaremetadecoration
pgfdeclaresnake
pgfdecorateaftercode
pgfdecoratebeforecode
pgfdecoratecurrentpath
pgfdecoratedpath
pgfdecorateexisitingpath
pgfdecoratepath
pgfdecorationinputsegmentclosepath
pgfdecorationinputsegmentcurveto
pgfdecorationinputsegmentlast
pgfdecorationinputsegmentlineto
pgfdecorationinputsegmentmoveto
pgfdecorationpath
pgfdecorationsegmentangle
pgfdecorationsegmentaspect
pgfifdecoration
pgfifmetadecoration
pgfmathresult
pgfmetadecorationsegmentamplitude
pgfmetadecorationsegmentlength
pgfpathsnakealongvector
pgfpathsnakesto
pgfpathsnaketo
pgfpointdecoratedinputsegmentfirst
pgfpointdecoratedinputsegmentlast
pgfpointdecoratedpathfirst
pgfpointdecoratedpathlast
pgfsetdecorationsegmenttransformation
pgfsetsnakesegmenttransformation
pgfsnakeangle
pgfsnakecompleteddistance
pgfsnakeremainingdistance
pgfsnakesegmentamplitude
pgfsnakesegmentangle
pgfsnakesegmentaspect
pgfsnakesegmentlength
pgfsnakesegmentobjectlength
savedanchor
saveddimen
savedmacro
startpgfdecoration
startpgfmetadecoration
state
stoppgfdecoration
stoppgfmetadecoration
stretto
\begin{circuitikz}
\begin{pgfdecoration}
\begin{pgfmetadecoration}

View File

@ -0,0 +1,235 @@
#include:etoolbox
#include:ifpdf
#include:keyval
#include:geometry
#include:graphicx
#include:graphics
#include:infwarerr
#include:ltxcmds
#include:pgfsys
#include:pgfrcs
#include:everyshi
#include:xcolor
#include:xxcolor
#include:atbegshi
#include:hyperref
#include:ifluatex
#include:intcalc
#include:etexcmds
#include:kvsetkeys
#include:kvdefinekeys
#include:pdftexcmds
#include:pdfescape
#include:bigintcalc
#include: bitset
#include:uniquecounter
#include:letltxmacro
#include:hopatch
#include:xcolor-patch
#include:atveryend
#include:refcount
#include:hycolor
#include:auxhook
#include:kvoptions
#include:url
#include:rerunfilecheck
#include:amssymb
#include:amsfonts
#include:sansmathaccent
#include:filehook
#include:translator
#include:amsmath
#include:amstext
#include:amsgen
#include:amsbsy
#include:amsopn
#include:amsthm
#include:epstopdf-base
#include:grfext
#include:nameref
#include:gettitlestring
action
addfootbox
addheadbox
addtobeamertemplate
againframe
alert
animate
animatevalue
AtBeginLecture
AtBeginNote
AtBeginPart
AtBeginSection
AtBeginSubsection
AtBeginSubsubsection
AtEndNote
beamerbutton
beamerdefaultoverlayspecification
beamergotobutton
beamerreturnbutton
beamerskipbutton
column
defbeamertemplate
defbeamertemplatealias
defbeamertemplateparent
expandbeamertemplate
framesubtitle
frametitle
framezoom
hyperlink
hyperlinkappendixend
hyperlinkappendixstart
hyperlinkdocumentend
hyperlinkdocumentstart
hyperlinkframeend
hyperlinkframeendprev
hyperlinkframestart
hyperlinkframestartnext
hyperlinkmute
hyperlinkpresentationend
hyperlinkpresentationstart
hyperlinkslidenext
hyperlinkslideprev
hyperlinksound
hypertarget
ifbeamercolorempty
ifbeamertemplateempty
includeonlyframes
includeonlylecture
includeslide
insertappendixendpage
insertappendixstartpage
insertbackfindforwardnavigationsymbol
insertcaption
insertcaptionname
insertcaptionnumber
insertdescriptionitem
insertdocnavigationsymbol
insertdocumentendpage
insertdocumentstartpage
insertenumlabel
insertfootnotemark
insertfootnotetext
insertframeendpage
insertframenavigationsymbol
insertframenumber
insertframestartpage
insertinstitute
insertlogo
insertnavigation
insertnote
insertpagenumber
insertpartendpage
insertpartheadnumber
insertpartstartpage
insertpresentationendpage
insertpresentationstartpage
insertsection
insertsectionendpage
insertsectionhead
insertsectionheadnumber
insertsectionnavigation
insertsectionnavigationhorizontal
insertsectionnavigationsymbol
insertsectionstartpage
insertshortauthor
insertshortdate
insertshortinstitute
insertshortpart
insertshortsubtitle
insertshorttitle
insertslideintonotes
insertslidenavigationsymbol
insertsubsection
insertsubsectionendpage
insertsubsectionhead
insertsubsectionheadnumber
insertsubsectionnavigation
insertsubsectionnavigationhorizontal
insertsubsectionnavigationsymbol
insertsubsectionstartpage
insertsubsubenumlabel
inserttheoremaddition
inserttheoremheadfont
inserttheoremname
inserttheoremnumber
inserttheorempunctuation
inserttotalframenumber
insertverticalnavigation
inst
institute
invisible
keywords
lecture
logo
mode
mode*
multiinclude
note
only
onslide
onslide*
opaqueness
partpage
pause
resetcounteronoverlays
resetcountonoverlays
setbeamercolor
setbeamercolor*
setbeamercovered
setbeamerfont
setbeamerfont*
setbeamersize
setbeamertemplate
setjobnamebeamerversion
sound
structure
subject
subtitle
temporal
titlegraphic
titlepage
transblindshorizontal
transblindsvertical
transboxin
transboxout
transdissolve
transduration
transglitter
transsplithorizontalin
transsplithorizontalout
transsplitverticalin
transsplitverticalout
transwipe
uncover
usebeamercolor
usebeamercolor*
usebeamerfont
usebeamerfont*
usebeamertemplate
usebeamertemplate*
usecolortheme
usefonttheme
useinnertheme
useoutertheme
usetheme
visible
\begin{actionenv}
\begin{alertblock}
\begin{alertenv}
\begin{altenv}
\begin{beamerboxesrounded}
\begin{beamercolorbox}
\begin{block}
\begin{column}
\begin{columns}
\begin{definition}
\begin{example}
\begin{exampleblock}
\begin{frame}
\begin{onlyenv}
\begin{overlayarea}
\begin{overprint}
\begin{proof}
\begin{semiverbatim}
\begin{structureenv}

View File

@ -0,0 +1,3 @@
backmatter
frontmatter
mainmatter

View File

@ -0,0 +1,10 @@
address
closing
encl
location
name
opening
signature
subject
telephone
\begin{letter}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
#include:xcolor
#include:url
#include:graphicx
#include:fancyhdr
#include:tweaklist
#include:calc
#include:xparse
#include:microtype
#include:hyperref
address
closing
cvcolumn
cvdoubleitem
cventry
cvitem
cvitemwithcomment
cvlistdoubleitem
cvlistitem
email
enclosure
extrainfo
familyname
firstname
homepage
makecvtitle
makeletterclosing
makelettertitle
mobile
moderncvcolor
moderncvstyle
nopagenumbers
opening
phone
photo
quote
recipient
\begin{cvcolumns}

View File

@ -0,0 +1 @@
#include:class-scrartcl,scrreprt,scrbook

View File

@ -0,0 +1,95 @@
#include:scrpage2
addchap
addchap*
addpart
addpart*
addsec
addsec*
addtokomafont
appendixmore
areaset
autodot
backmatter
capfont
caplabelfont
captionabove
captionbelow
captionformat
chapapp
chapappifchapterprefix
chapterformat
chaptermarkformat
chapterpagestyle
cleardoubleemptypage
cleardoubleevenemptypage
cleardoubleevenpage
cleardoubleevenplainpage
cleardoubleevenstandardpage
cleardoubleevenusingstyle
cleardoubleoddemptypage
cleardoubleoddpage
cleardoubleoddplainpage
cleardoubleoddstandardpage
cleardoubleoddusingstyle
cleardoublepageusingstyle
cleardoubleplainpage
cleardoublestandardpage
dedication
deffootnotemark
defpagestyle
descfont
dictum
dictumauthorformat
dictumwidth
extratitle
figureformat
frontmatter
ifpdfoutput
ifthispageodd
ifthispagewasodd
indexpagestyle
KOMAScript
linespread
lowertitleback
mainmatter
marginline
markleft
minisec
newpagestyle
othersectionlevelsformat
partformat
partpagestyle
providepagestyle
publishers
raggeddictum
raggeddictumauthor
raggeddictumtext
raggedsection
renewpagestyle
sectfont
sectionmarkformat
setbibpreamble
setcaphanging
setcapindent
setcapindent*
setcapmargin
setcapmargin*
setcapwidth
setchapterpreamble
SetDIVList
setindexpreamble
setkomafont
setpartpreamble
subject
subsectionmarkformat
subtitle
tableformat
titlehead
titlepagestyle
typearea
uppertitleback
usekomafont
\begin{addmargin}
\begin{addmargin*}
\begin{captionbeside}
\begin{labeling}

View File

@ -0,0 +1 @@
#include:class-scrartcl,scrreprt,scrbook

View File

@ -0,0 +1,78 @@
addrchar
addrentry
addtolengthplength
addtoreffields
adrchar
adrentry
AtBeginLetter
bankname
captionsamerican
captionsaustrian
captionsbritish
captionscroatian
captionsdutch
captionsenglish
captionsfinnish
captionsfrench
captionsgerman
captionsitalian
captionsngerman
captionsspanish
captionsUKenglish
captionsUSenglish
ccname
closing
customername
dateamerican
dateaustrian
datebritish
datecroatian
datedutch
dateenglish
datefinnish
datefrench
dategerman
dateitalian
datename
datengerman
datespanish
dateUKenglish
dateUSenglish
defaultreffields
emailname
encl
enclname
faxname
firstfoot
firsthead
headfromname
headtoname
ifkomavarempty
ifkomavarempty*
invoicename
KOMAoptions
LetterOptionNeedsPapersize
LoadLetterOption
myrefname
newcaptionname
newkomavar
newkomavar*
nextfoot
nexthead
opening
phonename
providecaptionname
raggedsignature
removereffields
renewcaptionname
setkomavar
setkomavar*
setlengthtoplength
subjectname
usekomavar
usekomavar*
useplength
wwwname
yourmailname
yourrefname
\begin{letter}

View File

@ -0,0 +1 @@
#include:class-scrartcl,scrreprt,scrbook

View File

@ -0,0 +1,36 @@
cpageref
Cpageref
cpagerefrange
Cpagerefrange
cref
Cref
cref*
Cref*
crefalias
crefdefaultlabelformat
crefformat
Crefformat
creflabelformat
crefmultiformat
Crefmultiformat
crefname
Crefname
crefrange
Crefrange
crefrangeformat
Crefrangeformat
crefrangelabelformat
crefrangemultiformat
Crefrangemultiformat
labelcpageref
labelcref
labelcrefformat
labelcrefmultiformat
labelcrefrangeformat
labelcrefrangemultiformat
lcnamecref
lcnamecrefs
namecref
nameCref
namecrefs
nameCrefs

View File

@ -0,0 +1,6 @@
color
colorbox
definecolor
fcolorbox
pagecolor
textcolor

View File

@ -0,0 +1,5 @@
arrayrulecolor
cellcolor
columncolor
doublerulesepcolor
rowcolor

View File

@ -0,0 +1,22 @@
#include:amsmath
#include:ifthen
appref
assref
colref
defnref
envert
enVert
eval
exref
figref
fullfunction
intcc
intco
intoc
intoo
lemref
propref
remref
secref
sVert
thmref

View File

@ -0,0 +1,7 @@
comment
endcomment
excludecoment
includecomment
processcomment
specialcomment
\begin{comment}

View File

@ -0,0 +1,22 @@
bcoordsys
bcoordsys*
coordgrid
coordgrid*
coordsys
coordsys*
fcoordsys
fcoordsys*
gridstyle
htickratio
numbline
numbline*
rescaleby
sethlabel
setvlabel
ticklength
tickstyle
vnumbline
vnumbline*
vtickratio
window
window*

View File

@ -0,0 +1,72 @@
#include:amsmath
#include:array
#include:booktabs
#include:tabularx
#include:longtable
#include:multirow
#include:diagbox
#include:graphicx
#include:hyperref
#include:xparse
#include:ntheorem
#include:metalogo
#include:xcolor
#include:mhchem
#include:siunitx
#include:upgreek
#include:subcaption
backmatter
bigcell
ccwd
colsep
cquauthpage
cqusetup
cquthesis
ctexset
ding
eqlist
fangsong
figref
frontmatter
headcell
heiti
inlinecite
kaishu
lishu
listeq
listofequations
mainmatter
makeabstract
makecover
onlinecite
resetrownum
resetxuhao
rownum
rownumseparator
rownumtype
setxuhao
songti
tabref
version
xuhao
xuhaoseparator
xuhaotype
youyuan
zihao
\begin{assumption}
\begin{axiom}
\begin{cabstract}
\begin{conjecture}
\begin{corollary}
\begin{Cplus}
\begin{definition}
\begin{denotation}
\begin{eabstract}
\begin{example}
\begin{exercise}
\begin{lemma}
\begin{problem}
\begin{proof}
\begin{proposition}
\begin{Python}
\begin{remark}

View File

@ -0,0 +1,58 @@
blockcquote
blockquote
DeleteQuotes
DisableQuotes
EnableQuotes
enquote
enquote*
foreignblockcquote
foreignblockquote
foreignblockquote*
foreignquote
foreignquote*
foreigntextcquote
foreigntextcquote*
foreigntextquote
foreigntextquote*
hybridblockcquote
hybridblockquote
hybridblockquote*
hyphenblockcquote
hyphenblockquote
hyphenblockquote*
hyphenquote
hyphenquote*
hyphentextcquote
hyphentextcquote*
hyphentextquote
hyphentextquote*
MakeAutoQuote
MakeAutoQuote*
MakeBlockQuote
MakeForeignBlockQuote
MakeForeignQuote
MakeForeignQuote*
MakeHybridBlockQuote
MakeHyphenBlockQuote
MakeHyphenQuote
MakeHyphenQuote*
MakeInnerQuote
MakeOuterQuote
SetCiteCommand
setquotestyle
setquotestyle*
textcquote
textcquote*
textelp
textelp*
textins
textins*
textquote
textquote*
VerbatimQuotes
\begin{displaycquote}
\begin{displayquote}
\begin{foreigndisplaycquote}
\begin{foreigndisplayquote}
\begin{hyphendisplaycquote}
\begin{hyphendisplayquote}

View File

@ -0,0 +1,10 @@
cvbibname
cvheadingfont
cvlabelfont
cvlabelsep
cvlabelskip
cvlabelwidth
cvlistheadingfont
cvplace
\begin{cv}
\begin{cvlist}

View File

@ -0,0 +1,157 @@
cyra
CYRA
cyrabhch
CYRABHCH
cyrabhchdsc
CYRABHCHDSC
cyrabhdze
CYRABHDZE
cyrabhha
CYRABHHA
cyrae
CYRAE
cyrb
CYRB
cyrc
CYRC
cyrch
CYRCH
cyrchldsc
CYRCHLDSC
cyrchrdsc
CYRCHRDSC
cyrchvcrs
CYRCHVCRS
cyrd
CYRD
cyrdje
CYRDJE
cyrdze
CYRDZE
cyrdzhe
CYRDZHE
cyre
CYRE
cyrerev
CYREREV
cyrery
CYRERY
cyrf
CYRF
cyrg
CYRG
cyrghcrs
CYRGHCRS
cyrghk
CYRGHK
cyrgup
CYRGUP
cyrh
CYRH
cyrhdsc
CYRHDSC
cyrhrdsn
CYRHRDSN
cyri
CYRI
cyrie
CYRIE
cyrii
CYRII
cyrishrt
CYRISHRT
cyrje
CYRJE
cyrk
CYRK
cyrkdsc
CYRKDSC
cyrkhcrs
CYRKHCRS
cyrkhk
CYRKHK
cyrkvcrs
CYRKVCRS
cyrl
CYRL
cyrldsc
CYRLDSC
cyrlje
CYRLJE
cyrm
CYRM
cyrmdsc
CYRMDSC
cyrn
CYRN
cyrndsc
CYRNDSC
cyrng
CYRNG
cyrnhk
CYRNHK
cyrnje
CYRNJE
cyro
CYRO
cyrotld
CYROTLD
cyrp
CYRP
CYRpalochka
cyrphk
CYRPHK
cyrr
CYRR
cyrrtick
CYRRTICK
cyrs
CYRS
cyrschwa
CYRSCHWA
cyrsdsc
CYRSDSC
cyrsemisftsn
CYRSEMISFTSN
cyrsftsn
CYRSFTSN
cyrsh
CYRSH
cyrshch
CYRSHCH
cyrshha
CYRSHHA
cyrt
CYRT
cyrtdsc
CYRTDSC
cyrtetse
CYRTETSE
cyrtshe
CYRTSHE
cyru
CYRU
cyrushrt
CYRUSHRT
cyrv
CYRV
cyry
CYRY
cyrya
CYRYA
cyryhcrs
CYRYHCRS
cyryi
CYRYI
cyryo
CYRYO
cyryu
CYRYU
cyrz
CYRZ
cyrzdsc
CYRZDSC
cyrzh
CYRZH
cyrzhdsc
CYRZHDSC

View File

@ -0,0 +1,157 @@
#include:datatool-base
#include:etex
#include:ifthen
#include:substr
#include:xfor
#include:xkeyval
datatoolparenstart
datatoolpersoncomma
datatoolplacecomma
datatoolsubjectcomma
dtladdalign
DTLaddcolumn
DTLaddentryforrow
dtlaftercols
dtlafterrow
dtlappendentrytocurrentrow
DTLappendtorow
DTLassign
DTLassignfirstmatch
dtlbeforecols
dtlbeforerow
dtlbetweencols
dtlbreak
DTLcleardb
DTLcolumncount
dtlcolumnindex
DTLcomputebounds
dtlcurrencyalign
dtlcurrencyformat
DTLcurrencytype
DTLcurrentindex
dtldbname
dtldefaultkey
DTLdeletedb
dtldisplayafterhead
dtldisplaycr
DTLdisplaydb
dtldisplayendtab
DTLdisplaylongdb
dtldisplaystartrow
dtldisplaystarttab
dtldisplayvalign
dtlexpandnewvalue
DTLfetch
dtlforcolumn
dtlforcolumnidx
DTLforeach
DTLforeach*
dtlforeachkey
DTLforeachkeyinrow
DTLgcleardb
DTLgdeletedb
DTLgetcolumnindex
DTLgetdatatype
dtlgetentryfromcurrentrow
dtlgetentryfromrow
DTLgetkeydata
DTLgetkeyforcolumn
DTLgetlocation
dtlgetrow
DTLgetrowforkey
dtlgetrowforvalue
dtlgetrowindex
DTLgetrowindex
DTLgetvalue
DTLgetvalueforkey
DTLgnewdb
dtlheaderformat
DTLifdbempty
DTLifdbexists
DTLiffirstrow
DTLifhaskey
DTLiflastrow
DTLifnull
DTLifnullorempty
DTLifoddrow
dtlintalign
dtlintformat
DTLinttype
dtllastloadeddb
DTLloaddb
DTLloadrawdb
DTLloadsbtex
DTLmaxforcolumn
DTLmaxforkeys
DTLmeanforcolumn
DTLmeanforkeys
DTLminforcolumn
DTLminforkeys
DTLnewdb
DTLnewdbentry
DTLnewdbonloadfalse
DTLnewdbonloadtrue
DTLnewrow
dtlnoexpandnewvalue
dtlnovalue
DTLnumbernull
DTLpar
DTLprotectedsaverawdb
DTLrawmap
dtlrealalign
dtlrealformat
DTLrealtype
dtlrecombine
dtlrecombineomitcurrent
DTLremovecurrentrow
DTLremoveentryfromrow
dtlremoveentryincurrentrow
DTLremoverow
DTLreplaceentryforrow
dtlreplaceentryincurrentrow
DTLrowcount
DTLsavedb
DTLsavelastrowcount
DTLsaverawdb
DTLsavetexdb
DTLsdforcolumn
DTLsdforkeys
DTLsetdelimiter
DTLsetheader
DTLsetseparator
DTLsettabseparator
dtlshowdb
dtlshowdbkeys
dtlshowtype
dtlsort
DTLsort
DTLsort*
dtlsplitrow
dtlstringalign
dtlstringformat
DTLstringnull
DTLstringtype
DTLsumcolumn
DTLsumforkeys
dtlswapentriesincurrentrow
dtlswaprows
DTLswaprows
DTLunsettype
dtlupdateentryincurrentrow
DTLvarianceforcolumn
DTLvarianceforkeys
dtlwordindexcompare
edtlgetrowforvalue
ifdtlnoheader
ifdtlverbose
theDTLrow
theDTLrowi
theDTLrowii
theDTLrowiii
theHDTLrow
theHDTLrowi
theHDTLrowii
theHDTLrowiii
xDTLassignfirstmatch
\begin{DTLenvforeach}
\begin{DTLenvforeach*}

View File

@ -0,0 +1,144 @@
#include:amsmath
#include:datatool-\@dtl@mathprocessor
#include:etoolbox
#include:ifthen
#include:substr
#include:xfor
#include:xkeyval
datatoolparenstart
datatoolpersoncomma
datatoolplacecomma
datatoolsubjectcomma
DTLabs
DTLadd
DTLaddall
DTLafterinitialbeforehyphen
DTLafterinitials
DTLbetweeninitials
dtlbreak
DTLclip
dtlcompare
dtlcomparewords
DTLconverttodecimal
DTLdecimaltocurrency
DTLdecimaltolocale
DTLdiv
dtlforint
DTLgabs
DTLgadd
DTLgaddall
DTLgclip
DTLgdiv
dtlgforint
DTLgmax
DTLgmaxall
DTLgmeanforall
DTLgmin
DTLgminall
DTLgmul
DTLgneg
DTLground
DTLgsdforall
DTLgsqrt
DTLgsub
DTLgtrunc
DTLgvarianceforall
dtlicompare
dtlicomparewords
DTLifAllLowerCase
DTLifAllUpperCase
dtlifcasechargroup
DTLifcasedatatype
DTLifclosedbetween
DTLifclosedbetween*
DTLifcurrency
DTLifcurrencyunit
DTLifeq
DTLifeq*
DTLifFPclosedbetween
DTLifFPopenbetween
DTLifgt
DTLifgt*
DTLifinlist
DTLifint
dtlifintclosedbetween
dtlifintopenbetween
DTLiflt
DTLiflt*
DTLifnumclosedbetween
DTLifnumeq
DTLifnumerical
DTLifnumgt
DTLifnumlt
DTLifnumopenbetween
DTLifopenbetween
DTLifopenbetween*
DTLifreal
DTLifStartsWith
DTLifstring
DTLifstringclosedbetween
DTLifstringclosedbetween*
DTLifstringeq
DTLifstringeq*
DTLifstringgt
DTLifstringgt*
DTLifstringlt
DTLifstringlt*
DTLifstringopenbetween
DTLifstringopenbetween*
DTLifSubString
DTLinitialhyphen
DTLinitials
DTLisclosedbetween
DTLiscurrency
DTLiscurrencyunit
DTLiseq
DTLisFPclosedbetween
DTLisFPeq
DTLisFPgt
DTLisFPgteq
DTLisFPlt
DTLisFPlteq
DTLisFPopenbetween
DTLisgt
DTLisiclosedbetween
DTLisieq
DTLisigt
DTLisilt
DTLisint
DTLisiopenbetween
DTLislt
DTLisnumclosedbetween
DTLisnumerical
DTLisnumopenbetween
DTLisopenbetween
DTLisPrefix
DTLisreal
DTLisstring
DTLisSubString
dtlletterindexcompare
DTLmax
DTLmaxall
DTLmeanforall
DTLmin
DTLminall
DTLmul
DTLneg
DTLnewcurrencysymbol
DTLnumitemsinlist
dtlparsewords
DTLround
DTLsdforall
DTLsetdefaultcurrency
DTLsetnumberchars
DTLsplitstring
DTLsqrt
DTLstoreinitials
DTLsub
DTLsubstitute
DTLsubstituteall
DTLtrunc
DTLvarianceforall
dtlwordindexcompare
ifdtlverbose
\begin{dtlenvgforint}

View File

@ -0,0 +1,820 @@
abovecaptionskip
abstractname
acute ´
addcontentsline
addpenalty
addto
addtocontents
addtocounter
addtolength
addtoversion
addvspace
aleph ℵ
Alph
alph
alpha α
amalg ⨿
and
angle ∠
appendix
appendixname
approx ≈
arabic
arccos
arcsin
arctan
arg
arraycolsep
arrayrulewidthL
arraystretch
Arrowvert ∥
arrowvert ⏐
ast
asymp ≍
AtBeginDocument
AtEndDocument
AtEndOfClass
AtEndOfPackage
author
backslash \
badness
bar ¯
baselinestretch
begin
belowcaptionskip
beta β
bezier
bfseries
bibitem
bibliography
bibliographystyle
Big
big
bigcap ⋂
bigcirc ○
bigcup
Bigg
bigg
Biggl
biggl
Biggm
biggm
Biggr
biggr
Bigl
bigl
Bigm
bigm
bigodot ⨀
bigoplus ⨁
bigotimes ⨂
Bigr
bigr
bigskip
bigsqcup ⨆
bigtriangledown ▽
bigtriangleup △
biguplus ⨄
bigvee
bigwedge ⋀
binoppenalty
boldmath
bot ⊥
botfigrule
bottomfraction
bottomnumber
bracevert ⎪
breve ˘
bullet ∙
cal
cap ∩
caption
cdot ⋅
cdots ⋯
chapter
chapter*
chaptermark
chaptername
check ˇ
CheckCommand
chi χ
circ ∘
circle
circle*
cite
ClassError
ClassInfo
ClassWarning
cleardoublepage
clearpage
cline
clubsuit ♣
colon :
columnsepL
columnseprule
columnwidth#L
columnwidthL
cong ≅
contentsline
contentsname
coprod ∐
cos
cosh
cot
coth
csc
cup
CurrentOption
dag †
dagger †
dashbox
dashv ⊣
date
dblfigrule
dblfloatpagefraction
dblfloatsep
dbltextfloatsep
dbltopfraction
dbltopnumber
ddag ‡
ddagger ‡
ddot ¨
ddots ⋱
DeclareFixedFont
DeclareFontEncoding
DeclareFontEncodingDefaults
DeclareFontFamily
DeclareFontShape
DeclareMathAccent
DeclareMathAlphabet
DeclareMathDelimiter
DeclareMathRadical
DeclareMathSizes
DeclareMathSymbol
DeclareMathVersion
DeclareOldFontCommand
DeclareOption
DeclareOption*
DeclareRobustCommand
DeclareSizeFunction
DeclareSymbolFont
DeclareSymbolFontAlphabet
DeclareTextAccent
DeclareTextCommand
DeclareTextComposite
DeclareTextCompositeCommand
DeclareTextFontCommand
DeclareTextSymbol
defaultscriptratio
defaultscriptscriptratio
deffootnote
deg
Delta Δ
delta δ
depth
descriptionlabel
det
dfrac
diamond ⋄
diamondsuit ♢
dim
div ÷
documentclass
dot ˙
doteq ≐
doublerulesep
Downarrow ⇓
downarrow ↓
ell
emergencystretch
emph
emptyset ∅
end
enlargethispage
enlargethispage*
ensuremath
epsilon ∊
equiv ≡
eta η
evensidemargin
ExecuteOptions
exists ∃
exp
extracolsep
family
fbox
fboxrule
fboxsep
figurename
flat ♭
floatpagefraction
floatsep
flq
flqq
flushbottom
flushleft
flushright
fnsymbol
fontencoding
fontfamily
fontseries
fontshape
fontsize
fontsubfuzz
footheightL
footnote
footnotemark
footnotesep
footnotesize
footnotetext
footskip
forall ∀
frac
frac
frame
framebox
frown ⌢
frq
frqq
Gamma Γ
gamma γ
gcd
geq ≥
gets ←
glossary
glossaryentry
glq
glqq
grave `
grq
grqq
hat ^
hbar ℏ
headheightL
headsepL
heartsuit ♡
heightL
hfill
hline
hlinefill
hom
hookleftarrow ↩
hookrightarrow ↪
hrule
hrulefill
hspace
hspace*
hss
huge
Huge
hyphenation
iff ⟺
IfFileExists
imath 𝚤
include
includeonly
index
indexname
indexspace
inf
infty ∞
input
InputIfFileExists
inputlineno
int ∫
int_
intextsep
iota ι
item
itemindent
itemsepL
iterate
itshape
jmath 𝚥
kappa κ
ker
kill
label
labelenumi
labelitemi
labelitemii
labelitemiii
labelitemiv
labelsepL
labelwidthL
Lambda Λ
lambda λ
land ∧
langle 〈
language
LARGE
Large
large
LastDeclaredEncoding
LaTeX
LaTeXe
lbrace {
lbrack [
lceil ⌈
ldots …
left
Leftarrow ⇐
leftarrow ←
lefteqn
leftharpoondown ↽
leftharpoonup ↼
lefthyphenmin
leftmargin
leftmargini
leftmarginii
leftmarginiii
leftmarginiv
leftmarginv
leftmarginvi
leftmark
Leftrightarrow ⇔
leftrightarrow ↔
leq ≤
lfloor ⌊
lgroup ⟮
lim
liminf
limits
limsup
line
linebreak
lineskiplimits
linethickness
linewidth
listfigurename
listfiles
listoffigures
listoftables
listparindent
listtablename
lmoustache ⎰
lnot ¬
LoadClass
log
Longleftarrow ⟸
longleftarrow ⟵
longleftrightarrow ⟷
Longleftrightarrow ⟺
longmapsto ⟼
Longrightarrow ⟹
longrightarrow ⟶
lor
makeatletter
makeatother
makebox
makeglossary
makeindex
makelabel
makelabels
MakeLowercase
maketitle
MakeUppercase
mapsto ↦
marginpar
marginparpush
marginparsepL
marginparwidthL
markboth
markright
mathbb
mathbf
mathcal
mathds
mathellipsis …
mathfrak
mathgroup
mathit
mathnormal
mathring ˚
mathrm
mathscr
mathsf
mathsterling £
mathtt
mathunderscore
mathversion
max
mbox
mdseries
medskip
mid
min
models ⊨
multicolumn
multiput
nabla ∇
natural ♮
nearrow ↗
NeedsTeXFormat
neg ¬
neq ≠
newblock
newcommand
newcommand*
newcounter
newenvironment
newfont
newlabel
newlength
newline
newpage
newsavebox
newtheorem
newtheorem*
nocite
nocorr
nocorrlist
nofiles
nolinebreak
nonumber
nopagebreak
normalcolor
normalfont
normalmarginpar
normalsize
not /
notin ∉
nouppercase
null
numberline
nwarrow ↖
obeycr
oddsidemargin
odot ⊙
oint ∮
oldstylenums
Omega Ω
omega ω
ominus ⊖
onecolumn
oplus ⊕
OptionNotUsed
oslash ⊘
otimes ⊗
oval
overbrace ⏞
overleftarrow ←
overline ¯
overrightarrow →
PackageError
PackageInfo
PackageWarning
PackageWarningNoLine
pagebreak
pagename
pagenumbering
pageref
pagestyle
pagetotal
paperheightL
paperwidthL
paragraph
paragraph*
paragraphmark
parallel ∥
parbox
parsepL
part
part*
partial 𝜕
partname
partopsepL
PassOptionsToClass
PassOptionsToPackage
pdfadjustspacing
pdfcompresslevel
pdfdecimaldigits
pdfhorigin
pdfimageresolution
pdfinfo
pdflinkmargin
pdfminorversion
pdfmovechars
pdfoutput
pdfpageheight
pdfpagewidth
pdfpkresolution
pdfthreadmargin
pdfvorigin
perp ⊥
Phi Φ
phi ϕ
plus
poptabs
pounds £
prec ≺
preceq ⪯
prime
printindex#n
ProcessOptions
ProcessOptions*
prod ∏
prod_
propto ∝
providecommand
ProvidesClass
ProvidesFile
ProvidesPackage
ProvideTextCommand
Psi Ψ
psi ψ
pushtabs
put
qquad
quad
raisebox
rangle 〉
rbrace }
rbrack ]
rceil ⌉
ref
refname
refstepcounter
renewcommand
renewcommand*
renewenvironment
RequirePackage
restorecr
reversemarginpar
rfloor ⌋
rgroup ⟯
rho ρ
right
Rightarrow ⇒
rightarrow →
rightharpoondown ⇁
rightharpoonup ⇀
righthyphenmin
rightleftharpoons ⇌
rightmargin
rightmark
rmfamily
rmoustache ⎱
Roman
roman
rule
samepage
savebox
sbox
scriptsize
scshape
searrow ↘
sec
section §
section*
sectionmark
selectfont
setcounter
setlanguage
setlength
setminus
setpapersize
settodepth
settoheight
settowidth
sffamily
sharp ♯
shortstack
Sigma ∑
sigma σ
sim
simeq ≃
sin
sinh
slshape
small
smash
smile ⌣
space ␣
spadesuit ♠
sqcup ⊔
sqrt √
sqsupseteq ⊒
stackrel
star ⋆
stepcounter
stop
stretch
subitem
subparagraph
subparagraph*
subparagraphmark
subsection
subsection*
subsectionmark
subset ⊂
subseteq ⊆
subsubitem
subsubsection
subsubsection*
subsubsectionmark
succ ≻
succeq ⪰
sum ∑
sum_
sup
suppressfloats
supset ⊃
supseteq ⊇
surd √
swarrow ↙
symbol
tabbingsep
tabcolsep
tablename
tableofcontents
tan
tanh
tau τ
textasciicircum
textasciitilde
textasteriskcentered
textbackslash
textbar
textbardbl
textbf
textbraceleft
textbraceright
textbullet
textcircled
textcompwordmark
textcopyright
textdagger
textdaggerdbl
textdollar
textellipsis …
textemdash
textendash
textexclamdown
textfloatsepL
textfraction
textgreater
textheight
textit
textless
textmd
textnormal
textparagraph ¶
textperiodcentered ·
textquestiondown
textquotedblleft
textquotedblright
textquoteleft
textquoteright
textregistered ®
textrm
textsc
textsection
textsf
textsl
textsterling
textsubscript
textsuperscript
texttrademark ™
texttt
textunderscore
textup
textvisiblespace
textwidth
thanks
thechapter
theenumi
theenumiv
theequation
thefigure
thefootnote
thefootnotemark
thehours
theminutes
thempfn
thempfootnote
thepage
theparagraph
thepart
thesection
thesubparagraph
thesubsection
thesubsubsection
Theta Θ
theta θ
thetable
thicklines
thinlines
thispagestyle
tilde ~
time
times ×
tiny
title
today
top
topfigrule
topfraction
topmarginL
topnumber
topsepL
totalheightL
totalnumber
triangle △
triangleleft ◁
triangleright ▷
ttfamily
twocolumn
typein
typeout
unboldmath
underbrace ⏟
underline
Uparrow ⇑
uparrow ↑
Updownarrow ⇕
updownarrow ↕
uplus ⊎
upshape
Upsilon Υ
upsilon υ
usebox
usecounter
usefont
usepackage
value
varepsilon ε
varphi φ
varpi ϖ
varrho ϱ
varsigma ς
vartheta ϑ
vdash ⊢
vdots ⋮
vec ⃗
vector
vee
verb
Vert ∥
vert
vline
vspace
vspace*
wedge ∧
widehat ˆ
widetilde ˜
width
zeta ζ
\begin{abstract}
\begin{alltt}
\begin{array}
\begin{bmatrix}
\begin{Bmatrix}
\begin{center}
\begin{description}
\begin{displaymath}
\begin{document}
\begin{enumerate}
\begin{eqnarray}
\begin{equation}
\begin{figure}
\begin{figure*}
\begin{filecontents}
\begin{filecontents*}
\begin{flushleft}
\begin{flushright}
\begin{footnotesize}
\begin{huge}
\begin{Huge}
\begin{itemize}
\begin{large}
\begin{Large}
\begin{LARGE}
\begin{list}
\begin{lrbox}
\begin{math}
\begin{matrix}
\begin{minipage}
\begin{normalsize}
\begin{picture}
\begin{pmatrix}
\begin{quotation}
\begin{quote}
\begin{scriptsize}
\begin{small}
\begin{tabbing}
\begin{table}
\begin{table*}
\begin{tabular}
\begin{tabular*}
\begin{thebibliography}
\begin{theindex}
\begin{theorem}
\begin{tiny}
\begin{titlepage}
\begin{trivlist}
\begin{verbatim}
\begin{verbatim*}
\begin{verse}
\begin{vmatrix}
\begin{Vmatrix}

View File

@ -0,0 +1,33 @@
arrow
Atriangle
Atrianglepair
bfig
btriangle
Ctriangle
Ctrianglepair
cube
dtriangle
Dtriangle
Dtrianglepair
efig
epileft
hsquares
hSquares
iiixii
iiixiii
Loop
monleft
morphism
node
place
ptriangle
pullback ⟓
qtriangle
square □
Square
toleft
twoar
vsquares
vSquares
Vtriangle
Vtrianglepair

View File

@ -0,0 +1 @@
doitext

View File

@ -0,0 +1,46 @@
DeclareLeftDelimiter
DeclareRightDelimiter
empheqbiglangle
empheqbiglbrace
empheqbiglbrack
empheqbiglceil
empheqbiglfloor
empheqbiglparen
empheqbiglvert
empheqbiglVert
empheqbigrangle
empheqbigrbrace
empheqbigrbrack
empheqbigrceil
empheqbigrfloor
empheqbigrparen
empheqbigrvert
empheqbigrVert
EmphEqdelimiterfactor
EmphEqdelimitershortfall
EmphEqdisplaydepth
EmphEqdisplayheight
empheqlangle
empheqlbrace
empheqlbrack
empheqlceil
empheqlfloor
empheqlparen
empheqlvert
empheqlVert
EmphEqMainEnv
empheqrangle
empheqrbrace
empheqrbrack
empheqrceil
empheqrfloor
empheqrparen
empheqrvert
empheqrVert
empheqset
endEmphEqMainEnv
mintagvsep
shadowbox*
shoveleft
shoveright
\begin{empheq}

View File

@ -0,0 +1,15 @@
afterepigraphskip
beforeepigraphskip
cleartoevenpage
dropchapter
epigraph
epigraphflush
epigraphhead
epigraphrule
epigraphsize
epigraphwidth
qitem
sourceflush
textflush
undodrop
\begin{epigraphs}

View File

@ -0,0 +1,10 @@
AppendGraphicsExtensions
DeclareGraphicsRule
epstopdfcall
epstopdfDeclareGraphicsRule
epstopdfsetup
noexpand
OutputFile
PrependGraphicsExtensions
SourceExt
SourceFile

View File

@ -0,0 +1,157 @@
#include:etex
AfterEndDocument
AfterEndEnvironment
AfterEndPreamble
AfterPreamble
appto
apptocmd
AtBeginEnvironment
AtEndEnvironment
AtEndPreamble
BeforeBeginEnvironment
boolfalse
booltrue
csappto
csdef
csdimdef
csdimgdef
cseappto
csedef
csepreto
csexpandonce
csgappto
csgdef
csgluedef
csgluegdef
csgpreto
cslet
csletcs
csmudef
csmugdef
csname
csnumdef
csnumgdef
cspreto
csshow
csundef
csuse
csxappto
csxdef
csxpreto
DeclareListParser
DeclareListParser*
defcounter
deflength
dimdef
dimgdef
docsvlist
dolistcsloop
dolistloop
eappto
epreto
expandonce
forcsvlist
forlistcsloop
forlistloop
gappto
gluedef
gluegdef
gpreto
ifblank
ifbool
ifboolexpe
ifboolexpr
ifcscounter
ifcsdef
ifcsdimen
ifcsempty
ifcsequal
ifcslength
ifcsltxprotect
ifcsmacro
ifcsparam
ifcsprefix
ifcsprotected
ifcsstrequal
ifcsstring
ifcsundef
ifcsvoid
ifdef
ifdefcounter
ifdefdimen
ifdefempty
ifdefequal
ifdeflength
ifdefltxprotect
ifdefmacro
ifdefparam
ifdefprefix
ifdefprotected
ifdefstrequal
ifdefstring
ifdefvoid
ifdimcomp
ifdimequal
ifdimgreater
ifdimless
ifinlist
ifinlistcs
ifltxcounter
ifnumcomp
ifnumequal
ifnumgreater
ifnumless
ifnumodd
ifpatchable
ifpatchable*
ifrmnum
ifstrempty
ifstrequal
iftoggle
ifundef
letcs
listadd
listbreak
listcsadd
listcseadd
listcsgadd
listcsxadd
listeadd
listgadd
listxadd
mudef
mugdef
newbool
newrobustcmd
newtoggle
noexpand
notblank
notbool
nottoggle
numdef
numgdef
patchcmd
preto
pretocmd
protecting
providebool
providerobustcmd
providerobustcmd*
providetoggle
renewrobustcmd
renewrobustcmd*
rmntonum
robustify
setbool
settoggle
string
togglefalse
toggletrue
tracingpatches
undef
unlessboolexpr
whileboolexpr
xappto
xifinlist
xifinlistcs
xpreto

View File

@ -0,0 +1,5 @@
euro €
geneuro
geneuronarrow
geneurowide
officialeuro

View File

@ -0,0 +1,36 @@
boxput
boxput*
BVerbatimInput
cornersize
cornersize*
doublebox
fancypage
fancyput
fancyput*
LVerbatimInput
ovalbox
Ovalbox
shadowbox
shadowsize
TheSbox
thisfancypage
thisfancyput
thisfancyput*
Verb
VerbatimInput
VerbBox
\begin{Bcenter}
\begin{Bdescription}
\begin{Benumerate}
\begin{Beqnarray}
\begin{Beqnarray*}
\begin{Bflushleft}
\begin{Bflushright}
\begin{Bitemize}
\begin{BVerbatim}
\begin{landfloat}
\begin{Landscape}
\begin{LandScape}
\begin{LVerbatim}
\begin{Sbox}
\begin{Verbatim}

View File

@ -0,0 +1,18 @@
cfoot
chead
fancyfoot
fancyfootoffset
fancyhead
fancyheadoffset
fancyhf
fancyhfoffset
fancypagestyle
footrule
footrulewidth
headrule
headrulewidth
iffloatpage
lfoot
lhead
rfoot
rhead

View File

@ -0,0 +1,153 @@
addunit
ampere
angstrom
AstroE
atomicmass
atto
attod
barn
bbar
becquerel
becquerelbase
candela
celsius
celsiusbase
centi
centid
coulomb
coulombbase
cubed
cubic
curie
dday
deca
decad
decaD
deci
decid
degree °
degreecelsius
degreecelsiusbase
deka
dekad
derbecquerel
dercelsius
dercoulomb
derdegreecelsius
derfarad
derGray
derhenry
derhertz
derjoule
derlumen
derlux
dernewton
derohm
derpascal
derradian
dersiemens
dersievert
dersteradian
dertesla
dervolt
derwatt
derweber
electronvolt
exad
farad
faradbase
fempto
femptod
fourth
giga
gigad
gram
Gray
Graybase
hectare
hecto
hectod
henry
henrybase
hertz
hertzbase
hour
joule
joulebase
kelvin
kilo
kilod
kilogram
lightyear
liter
litre
lumen
lumenbase
luxbase
mega
megad
meter
metre
micro
microd
milli
millid
minute
mole
nano
nanod
newton
newtonbase
oersted
ohmbase
paminute
parsec
parsecond
pascal
pascalbase
peta
petad
pico
picod
power
radian
radianbase
reciprocal
roentgen
rpcubed
rpcubic
rpfourth
rpsquare
rpsquared
second
siemensbase
sievert
sievertbase
Square
Squared
sterad
steradian
steradianbase
tera
terad
tesla
teslabase
tonne
ufrac
Ufrac
UFrac
unit
volt
voltbase
watt
wattbase
weber
weberbase
yocto
yoctod
yotta
yottad
zepto
zeptod
zetta
zettad

View File

@ -0,0 +1,56 @@
amperepermetrenp
amperepersquaremetrenp
candelapersquaremetrenp
coulombpercubicmetrenp
coulombperkilogramnp
coulombpermolnp
coulombpersquaremetrenp
cubicmetreperkilogramnp
cubicmetrepersecondnp
faradpermetrenp
Graypersecondnp
henrypermetrenp
joulepercubicmetrenp
jouleperkelvinnp
jouleperkilogramkelvinnp
jouleperkilogramnp
joulepermolekelvinnp
joulepermolenp
joulepersquaremetrenp
jouleperteslanp
kilogrammetrepersecondnp
kilogrammetrepersquaresecondnp
kilogrampercubicmetrecoulombnp
kilogrampercubicmetrenp
kilogramperkilomolenp
kilogrampermetrenp
kilogrampersecondcubicmetrenp
kilogrampersecondnp
kilogrampersquaremetrenp
kilogrampersquaremetresecondnp
kilogramsquaremetrenp
kilogramsquaremetrepersecondnp
metrepersecondnp
metrepersquaresecondnp
molepercubicmetrenp
newtonmetrenp
newtonpercubicmetrenp
newtonperkilogramnp
newtonpermetrenp
newtonpersquaremetrenp
pascalsecondnp
persquaremetresecondnp
radianpersecondnp
radianpersquaresecondnp
Squaremetrepercubicmetrenp
Squaremetrepercubicsecondnp
Squaremetreperkilogramnp
Squaremetrepernewtonsecondnp
Squaremetrepersecondnp
Squaremetrepersquaresecondnp
voltpermetrenp
wattpercubicmetrenp
wattperkilogramnp
wattpermetrekelvinnp
wattpersquaremetrenp
wattpersquaremetresteradiannp

View File

@ -0,0 +1,67 @@
amperemetresecond
amperepermetre
amperepersquaremetre
candelapersquaremetre
Celsius
coulombpercubicmetre
coulombperkilogram
coulombpermol
coulombpersquaremetre
cubicmetre
cubicmetreperkilogram
cubicmetrepersecond
faradpermetre
Graypersecond
henrypermetre
joulepercubicmetre
jouleperkelvin
jouleperkilogram
jouleperkilogramkelvin
joulepermole
joulepermolekelvin
joulepersquaremetre
joulepertesla
kilogrammetrepersecond
kilogrammetrepersquaresecond
kilogrampercubicmetre
kilogrampercubicmetrecoulomb
kilogramperkilomole
kilogrampermetre
kilogrampersecond
kilogrampersecondcubicmetre
kilogrampersquaremetre
kilogrampersquaremetresecond
kilogramsquaremetre
kilogramsquaremetrepersecond
kilowatthour
metrepersecond
metrepersquaresecond
molepercubicmetre
newtonmetre
newtonpercubicmetre
newtonperkilogram
newtonpermetre
newtonpersquaremetre
ohmmetre
pascalsecond
persquaremetresecond
radianpersecond
radianpersquaresecond
rpcubicmetreperkilogram
rpcubicmetrepersecond
rpsquaremetreperkilogram
rpsquaremetrepersecond
rpsquaremetrepersquaresecond
Squaremetre
Squaremetrepercubicmetre
Squaremetrepercubicsecond
Squaremetreperkilogram
Squaremetrepernewtonsecond
Squaremetrepersecond
Squaremetrepersquaresecond
voltpermetre
wattpercubicmetre
wattperkilogram
wattpermetrekelvin
wattpersquaremetre
wattpersquaremetresteradian

View File

@ -0,0 +1,54 @@
amperepermetreUF
amperepersquaremetreUF
candelapersquaremetreUF
coulombpercubicmetreUF
coulombperkilogramUF
coulombpermolUF
coulombpersquaremetreUF
cubicmetreperkilogramUF
cubicmetrepersecondUF
faradpermetreUF
GraypersecondUF
henrypermetreUF
joulepercubicmetreUF
jouleperkelvinUF
jouleperkilogramkelvinUF
jouleperkilogramUF
joulepermolekelvinUF
joulepermoleUF
joulepersquaremetreUF
jouleperteslaUF
kilogrammetrepersecondUF
kilogrammetrepersquaresecondUF
kilogrampercubicmetrecoulombUF
kilogrampercubicmetreUF
kilogramperkilomoleUF
kilogrampermetreUF
kilogrampersecondcubicmetreUF
kilogrampersecondUF
kilogrampersquaremetresecondUF
kilogrampersquaremetreUF
kilogramsquaremetrepersecondUF
metrepersecondUF
metrepersquaresecondUF
molepercubicmetreUF
newtonpercubicmetreUF
newtonperkilogramUF
newtonpermetreUF
newtonpersquaremetreUF
pascalsecondUF
persquaremetresecondUF
radianpersecondUF
radianpersquaresecondUF
SquaremetrepercubicmetreUF
SquaremetrepercubicsecondUF
SquaremetreperkilogramUF
SquaremetrepernewtonsecondUF
SquaremetrepersecondUF
SquaremetrepersquaresecondUF
voltpermetreUF
wattpercubicmetreUF
wattperkilogramUF
wattpermetrekelvinUF
wattpersquaremetresteradianUF
wattpersquaremetreUF

View File

@ -0,0 +1,54 @@
amperepermetreUf
amperepersquaremetreUf
candelapersquaremetreUf
coulombpercubicmetreUf
coulombperkilogramUf
coulombpermolUf
coulombpersquaremetreUf
cubicmetreperkilogramUf
cubicmetrepersecondUf
faradpermetreUf
GraypersecondUf
henrypermetreUf
joulepercubicmetreUf
jouleperkelvinUf
jouleperkilogramkelvinUf
jouleperkilogramUf
joulepermolekelvinUf
joulepermoleUf
joulepersquaremetreUf
jouleperteslaUf
kilogrammetrepersecondUf
kilogrammetrepersquaresecondUf
kilogrampercubicmetrecoulombUf
kilogrampercubicmetreUf
kilogramperkilomoleUf
kilogrampermetreUf
kilogrampersecondcubicmetreUf
kilogrampersecondUf
kilogrampersquaremetresecondUf
kilogrampersquaremetreUf
kilogramsquaremetrepersecondUf
metrepersecondUf
metrepersquaresecondUf
molepercubicmetreUf
newtonpercubicmetreUf
newtonperkilogramUf
newtonpermetreUf
newtonpersquaremetreUf
pascalsecondUf
persquaremetresecondUf
radianpersecondUf
radianpersquaresecondUf
SquaremetrepercubicmetreUf
SquaremetrepercubicsecondUf
SquaremetreperkilogramUf
SquaremetrepernewtonsecondUf
SquaremetrepersecondUf
SquaremetrepersquaresecondUf
voltpermetreUf
wattpercubicmetreUf
wattperkilogramUf
wattpermetrekelvinUf
wattpersquaremetresteradianUf
wattpersquaremetreUf

Some files were not shown because too many files have changed in this diff Show More