mirror of
https://github.com/sheerun/vim-polyglot.git
synced 2025-11-08 11:33:52 -05:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e166f741ef | ||
|
|
d4fcef1aa8 | ||
|
|
7972e8eea1 | ||
|
|
6ed481e463 | ||
|
|
c1e1870a3d | ||
|
|
f0d6ecff07 | ||
|
|
15e5df246e | ||
|
|
94ababe91f | ||
|
|
080b8cdc60 | ||
|
|
e47af23f64 | ||
|
|
8f5134aef8 | ||
|
|
be8d039e02 | ||
|
|
38ce8e9cb6 | ||
|
|
55ad5a982a | ||
|
|
b2055afaa7 | ||
|
|
63a175357a | ||
|
|
25db54573a | ||
|
|
d1bfe50419 | ||
|
|
22e8e01c1e | ||
|
|
30bef582ba | ||
|
|
74d940cda3 | ||
|
|
54d2386262 | ||
|
|
a47c315b01 | ||
|
|
ff0ada0dc3 | ||
|
|
e194de5875 | ||
|
|
012cf89210 | ||
|
|
ac71777dc2 | ||
|
|
23defeb610 | ||
|
|
114a93bb7c | ||
|
|
f3ab28a287 | ||
|
|
bc3b36088e | ||
|
|
5d0150e326 | ||
|
|
cf8e31ff7f | ||
|
|
0df1bfa0c5 | ||
|
|
f7302d9262 | ||
|
|
7e38f4288a | ||
|
|
e521ba3ae2 | ||
|
|
ee4f51587d | ||
|
|
20a388cbc8 | ||
|
|
81e61a3c5d | ||
|
|
5670985b3a | ||
|
|
69eae22ea6 | ||
|
|
f8cee0172b | ||
|
|
c6936aeeb1 | ||
|
|
6bb111eaba | ||
|
|
dfecb63078 | ||
|
|
00015bd105 | ||
|
|
d821de3142 | ||
|
|
a3bdbcdb3c | ||
|
|
34e01b8b62 | ||
|
|
1e533e5982 | ||
|
|
56121b4e27 | ||
|
|
9c3c0bc082 | ||
|
|
8500ae8bb9 | ||
|
|
d09a56a494 | ||
|
|
abca7c2014 | ||
|
|
8b6c06e723 | ||
|
|
a86c0179eb | ||
|
|
22095febb7 | ||
|
|
ff066ee9f0 | ||
|
|
5b38663027 | ||
|
|
f0b38f2c1d | ||
|
|
6676d61f61 | ||
|
|
f0da1a9f4d | ||
|
|
298d6b6356 | ||
|
|
62f004c3da | ||
|
|
c73ea49ecb | ||
|
|
b2be47befc | ||
|
|
de38ccabbd | ||
|
|
f0f49cf0fa | ||
|
|
224a6348f9 | ||
|
|
00c3f02945 | ||
|
|
df34b4b4fa | ||
|
|
f3804b0892 | ||
|
|
685aeaaeb1 | ||
|
|
a9cc6fd218 | ||
|
|
3c47f192b5 |
7
.gitattributes
vendored
7
.gitattributes
vendored
@@ -1,7 +0,0 @@
|
||||
.gitignore export-ignore
|
||||
.gitattributes export-ignore
|
||||
README.md export-ignore
|
||||
/spec export-ignore
|
||||
Gemfile export-ignore
|
||||
Gemfile.lock export-ignore
|
||||
.travis.yml export-ignore
|
||||
21
.github/workflows/test.yml
vendored
Normal file
21
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Vim Polyglot CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # weekly
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Vim
|
||||
run: |
|
||||
sudo add-apt-repository ppa:jonathonf/vim -y
|
||||
sudo apt-get update -q
|
||||
sudo apt-get install -y vim
|
||||
vim --version
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run Tests
|
||||
run: make test
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/tmp
|
||||
!*ctags*
|
||||
tags
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -1,11 +0,0 @@
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.6
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- vim-gtk
|
||||
before_script:
|
||||
- "./build"
|
||||
script: xvfb-run bundle exec rspec --format=documentation
|
||||
28
Gemfile.lock
28
Gemfile.lock
@@ -1,28 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
diff-lcs (1.3)
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.0)
|
||||
vimrunner (0.3.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
rspec
|
||||
vimrunner
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.2
|
||||
10
Makefile
Normal file
10
Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
.PHONY: all test dev
|
||||
|
||||
all:
|
||||
@ scripts/build
|
||||
|
||||
test:
|
||||
@ scripts/test
|
||||
|
||||
dev:
|
||||
@ echo "packages.yaml\nheuristics.yaml\nscripts/test\nscripts/build\nscripts/test_extensions.vim" | DEV=1 entr bash -c 'make && make test'
|
||||
371
README.md
371
README.md
@@ -1,22 +1,20 @@
|
||||

|
||||
|
||||
[![Build Status][travis-img-url]][travis-url] []()
|
||||
|
||||
[travis-img-url]: https://travis-ci.org/sheerun/vim-polyglot.svg
|
||||
[travis-url]: https://travis-ci.org/sheerun/vim-polyglot
|
||||
 []()
|
||||
|
||||
A collection of language packs for Vim.
|
||||
|
||||
> One to rule them all, one to find them, one to bring them all and in the darkness bind them.
|
||||
|
||||
- It **won't affect your startup time**, as scripts are loaded only on demand\*.
|
||||
- It **installs and updates 120+ times faster** than the <!--Package Count-->149<!--/Package Count--> packages it consists of.
|
||||
- It **installs and updates 120+ times faster** than the <!--Package Count-->190<!--/Package Count--> packages it consists of.
|
||||
- It is more secure because scripts loaded for all extensions are generated by vim-polyglot (ftdetect).
|
||||
- Solid syntax and indentation support (other features skipped). Only the best language packs.
|
||||
- All unnecessary files are ignored (like enormous documentation from php support).
|
||||
- No support for esoteric languages, only most popular ones (modern too, like `slim`).
|
||||
- Each build is tested by automated vimrunner script on CI. See `spec` directory.
|
||||
|
||||
\*To be completely honest, concatenated `ftdetect` script takes up to `17ms` to load.
|
||||
\*To be completely honest, optimized `ftdetect` script takes around `19ms` to load.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -38,192 +36,229 @@ mkdir -p ~/.vim/pack/default/start
|
||||
git clone https://github.com/sheerun/vim-polyglot ~/.vim/pack/default/start/vim-polyglot
|
||||
```
|
||||
|
||||
NOTE: Not all features of listed language packs are available. We strip them from functionality slowing vim startup in general (for example we ignore `plugins` folder that is loaded regardless of file type, use `ftplugin` instead).
|
||||
NOTE: Not all features of individual language packs are available. We strip them from functionality slowing vim startup (for example we ignore `plugins` folder that is loaded regardless of file type, instead we prefer `ftplugin` which is loaded lazily).
|
||||
|
||||
If you need full functionality of any plugin, please use it directly with your plugin manager.
|
||||
|
||||
## Language packs
|
||||
|
||||
<!--Language Packs-->
|
||||
- [acpiasl](https://github.com/martinlroth/vim-acpi-asl) (syntax)
|
||||
- [ansible](https://github.com/pearofducks/ansible-vim) (syntax, indent, ftplugin)
|
||||
- [apiblueprint](https://github.com/sheerun/apiblueprint.vim) (syntax, ctags)
|
||||
- [applescript](https://github.com/mityu/vim-applescript) (syntax, indent)
|
||||
- [arduino](https://github.com/sudar/vim-arduino-syntax) (syntax, indent)
|
||||
- [asciidoc](https://github.com/asciidoc/vim-asciidoc) (syntax)
|
||||
- [autohotkey](https://github.com/hnamikaw/vim-autohotkey) (indent)
|
||||
- [blade](https://github.com/jwalton512/vim-blade) (syntax, indent, ftplugin)
|
||||
- [brewfile](https://github.com/bfontaine/Brewfile.vim) (syntax)
|
||||
- [c++11](https://github.com/octol/vim-cpp-enhanced-highlight) (syntax)
|
||||
- [c/c++](https://github.com/vim-jp/vim-cpp) (syntax)
|
||||
- [caddyfile](https://github.com/isobit/vim-caddyfile) (syntax, indent, ftplugin)
|
||||
- [carp](https://github.com/hellerve/carp-vim) (syntax)
|
||||
- [cjsx](https://github.com/mtscout6/vim-cjsx) (syntax, ftplugin)
|
||||
- [clojure](https://github.com/guns/vim-clojure-static) (syntax, indent, autoload, ftplugin)
|
||||
- [cmake](https://github.com/pboettch/vim-cmake-syntax) (syntax, indent)
|
||||
- [coffee-script](https://github.com/kchmck/vim-coffee-script) (syntax, compiler, indent, autoload, ftplugin)
|
||||
- [cql](https://github.com/elubow/cql-vim) (syntax)
|
||||
- [cryptol](https://github.com/victoredwardocallaghan/cryptol.vim) (syntax, compiler, ftplugin)
|
||||
- [crystal](https://github.com/rhysd/vim-crystal) (syntax, indent, autoload, ftplugin)
|
||||
- [csv](https://github.com/chrisbra/csv.vim) (syntax, autoload, ftplugin)
|
||||
- [cucumber](https://github.com/tpope/vim-cucumber) (syntax, indent, compiler, ftplugin)
|
||||
- [cue](https://github.com/mgrabovsky/vim-cuesheet) (syntax)
|
||||
- [dart](https://github.com/dart-lang/dart-vim-plugin) (syntax, indent, autoload, ftplugin)
|
||||
- [dhall](https://github.com/vmchale/dhall-vim) (syntax, ftplugin)
|
||||
- [dlang](https://github.com/JesseKPhillips/d.vim) (syntax, indent)
|
||||
- [dockerfile](https://github.com/ekalinin/Dockerfile.vim) (syntax, indent, ftplugin)
|
||||
- [elixir](https://github.com/elixir-lang/vim-elixir) (syntax, indent, compiler, autoload, ftplugin)
|
||||
- [elm](https://github.com/andys8/vim-elm-syntax) (syntax, indent)
|
||||
- [emberscript](https://github.com/yalesov/vim-ember-script) (syntax, indent, ftplugin)
|
||||
- [emblem](https://github.com/yalesov/vim-emblem) (syntax, indent, ftplugin)
|
||||
- [erlang](https://github.com/vim-erlang/vim-erlang-runtime) (syntax, indent)
|
||||
- [ferm](https://github.com/vim-scripts/ferm.vim) (syntax)
|
||||
- [fish](https://github.com/georgewitteman/vim-fish) (syntax, indent, compiler, autoload, ftplugin)
|
||||
- [flatbuffers](https://github.com/dcharbon/vim-flatbuffers) (syntax)
|
||||
- [fsharp](https://github.com/ionide/Ionide-vim) (syntax, indent)
|
||||
- [gdscript](https://github.com/calviken/vim-gdscript3) (syntax, indent, ftplugin)
|
||||
- [git](https://github.com/tpope/vim-git) (syntax, indent, ftplugin)
|
||||
- [glsl](https://github.com/tikhomirov/vim-glsl) (syntax, indent)
|
||||
- [gmpl](https://github.com/maelvalais/gmpl.vim) (syntax)
|
||||
- [gnuplot](https://github.com/vim-scripts/gnuplot-syntax-highlighting) (syntax)
|
||||
- [go](https://github.com/fatih/vim-go) (syntax, compiler, indent)
|
||||
- [gradle](https://github.com/tfnico/vim-gradle) (compiler)
|
||||
- [graphql](https://github.com/jparise/vim-graphql) (syntax, indent, autoload, ftplugin, after)
|
||||
- [haml](https://github.com/sheerun/vim-haml) (syntax, indent, compiler, ftplugin)
|
||||
- [handlebars](https://github.com/mustache/vim-mustache-handlebars) (syntax, indent, ftplugin)
|
||||
- [haproxy](https://github.com/CH-DanReif/haproxy.vim) (syntax)
|
||||
- [haskell](https://github.com/neovimhaskell/haskell-vim) (syntax, indent, ftplugin)
|
||||
- [haxe](https://github.com/yaymukund/vim-haxe) (syntax)
|
||||
- [hcl](https://github.com/b4b4r07/vim-hcl) (syntax, indent, ftplugin)
|
||||
- [helm](https://github.com/towolf/vim-helm) (syntax)
|
||||
- [hive](https://github.com/zebradil/hive.vim) (syntax, ftplugin)
|
||||
- [html5](https://github.com/othree/html5.vim) (syntax, indent, autoload, ftplugin)
|
||||
- [i3](https://github.com/mboughaba/i3config.vim) (syntax, ftplugin)
|
||||
- [idris](https://github.com/idris-hackers/idris-vim) (syntax, indent, ftplugin)
|
||||
- [ion](https://github.com/vmchale/ion-vim) (syntax, ftplugin)
|
||||
- [javascript](https://github.com/pangloss/vim-javascript) (syntax, indent, compiler, ftplugin, extras)
|
||||
- [jenkins](https://github.com/martinda/Jenkinsfile-vim-syntax) (syntax, indent)
|
||||
- [jinja](https://github.com/lepture/vim-jinja) (syntax, indent)
|
||||
- [json5](https://github.com/GutenYe/json5.vim) (syntax)
|
||||
- [json](https://github.com/elzr/vim-json) (syntax, indent, ftplugin)
|
||||
- [jst](https://github.com/briancollins/vim-jst) (syntax, indent)
|
||||
- [jsx](https://github.com/MaxMEllon/vim-jsx-pretty) (autoload, after)
|
||||
- [julia](https://github.com/JuliaEditorSupport/julia-vim) (syntax, indent, autoload, ftplugin)
|
||||
- [kotlin](https://github.com/udalov/kotlin-vim) (syntax, indent, ftplugin)
|
||||
- [latex](https://github.com/lervag/vimtex) (indent, compiler, autoload, ftplugin, syntax)
|
||||
- [less](https://github.com/groenewege/vim-less) (syntax, indent, ftplugin)
|
||||
- [lilypond](https://github.com/anowlcalledjosh/vim-lilypond) (syntax, indent, compiler, ftplugin)
|
||||
- [livescript](https://github.com/gkz/vim-ls) (syntax, indent, compiler, ftplugin)
|
||||
- [llvm](https://github.com/rhysd/vim-llvm) (syntax, indent, ftplugin)
|
||||
- [log](https://github.com/MTDL9/vim-log-highlighting) (syntax)
|
||||
- [lua](https://github.com/tbastos/vim-lua) (syntax, indent)
|
||||
- [mako](https://github.com/sophacles/vim-bundle-mako) (syntax, indent, ftplugin)
|
||||
- [markdown](https://github.com/plasticboy/vim-markdown) (syntax, indent, ftplugin)
|
||||
- [mathematica](https://github.com/voldikss/vim-mma) (syntax, ftplugin)
|
||||
- [mdx](https://github.com/jxnblk/vim-mdx-js) (syntax)
|
||||
- [meson](https://github.com/mesonbuild/meson) (syntax, indent, ftplugin)
|
||||
- [moonscript](https://github.com/leafo/moonscript-vim) (syntax, indent, ftplugin)
|
||||
- [nginx](https://github.com/chr4/nginx.vim) (syntax, indent, ftplugin)
|
||||
- [nim](https://github.com/zah/nim.vim) (syntax, compiler, indent)
|
||||
- [nix](https://github.com/LnL7/vim-nix) (syntax, indent, compiler, ftplugin)
|
||||
- [objc](https://github.com/b4winckler/vim-objc) (ftplugin, syntax, indent)
|
||||
- [ocaml](https://github.com/rgrinberg/vim-ocaml) (syntax, indent, compiler, ftplugin)
|
||||
- [octave](https://github.com/McSinyx/vim-octave) (syntax, indent)
|
||||
- [opencl](https://github.com/petRUShka/vim-opencl) (syntax, indent, ftplugin)
|
||||
- [perl](https://github.com/vim-perl/vim-perl) (syntax, indent, ftplugin)
|
||||
- [pgsql](https://github.com/lifepillar/pgsql.vim) (syntax, indent)
|
||||
- [php](https://github.com/StanAngeloff/php.vim) (syntax)
|
||||
- [plantuml](https://github.com/aklt/plantuml-syntax) (syntax, indent, ftplugin)
|
||||
- [pony](https://github.com/jakwings/vim-pony) (syntax, indent, autoload, ftplugin)
|
||||
- [powershell](https://github.com/PProvost/vim-ps1) (syntax, indent, compiler, ftplugin)
|
||||
- [protobuf](https://github.com/uarun/vim-protobuf) (syntax, indent)
|
||||
- [pug](https://github.com/digitaltoad/vim-pug) (syntax, indent, ftplugin)
|
||||
- [puppet](https://github.com/rodjek/vim-puppet) (syntax, indent, autoload, ftplugin, ctags)
|
||||
- [purescript](https://github.com/purescript-contrib/purescript-vim) (syntax, indent, ftplugin)
|
||||
- [python-compiler](https://github.com/aliev/vim-compiler-python) (compiler, autoload)
|
||||
- [python-indent](https://github.com/Vimjas/vim-python-pep8-indent) (indent)
|
||||
- [python](https://github.com/vim-python/python-syntax) (syntax)
|
||||
- [qmake](https://github.com/artoj/qmake-syntax-vim) (syntax)
|
||||
- [qml](https://github.com/peterhoeg/vim-qml) (syntax, indent, ftplugin)
|
||||
- [r-lang](https://github.com/vim-scripts/R.vim) (syntax)
|
||||
- [racket](https://github.com/wlangstroth/vim-racket) (syntax, indent, ftplugin)
|
||||
- [ragel](https://github.com/jneen/ragel.vim) (syntax)
|
||||
- [raku](https://github.com/Raku/vim-raku) (syntax, indent, ftplugin)
|
||||
- [raml](https://github.com/IN3D/vim-raml) (syntax, ftplugin)
|
||||
- [razor](https://github.com/adamclerk/vim-razor) (syntax, indent, ftplugin)
|
||||
- [reason](https://github.com/reasonml-editor/vim-reason-plus) (syntax, indent)
|
||||
- [rspec](https://github.com/keith/rspec.vim) (syntax)
|
||||
- [rst](https://github.com/marshallward/vim-restructuredtext) (syntax, indent, autoload, ftplugin)
|
||||
- [ruby](https://github.com/vim-ruby/vim-ruby) (syntax, indent, compiler, autoload, ftplugin)
|
||||
- [rust](https://github.com/rust-lang/rust.vim) (syntax, indent, compiler, autoload, ftplugin, ctags)
|
||||
- [sbt](https://github.com/derekwyatt/vim-sbt) (syntax)
|
||||
- [scala](https://github.com/derekwyatt/vim-scala) (syntax, indent, compiler, ftplugin, ctags)
|
||||
- [scss](https://github.com/cakebaker/scss-syntax.vim) (syntax, indent, ftplugin)
|
||||
- [slim](https://github.com/slim-template/vim-slim) (syntax, indent, ftplugin)
|
||||
- [slime](https://github.com/slime-lang/vim-slime-syntax) (syntax, indent)
|
||||
- [smt2](https://github.com/bohlender/vim-smt2) (syntax, autoload, ftplugin)
|
||||
- [solidity](https://github.com/tomlion/vim-solidity) (syntax, indent, ftplugin)
|
||||
- [stylus](https://github.com/wavded/vim-stylus) (syntax, indent, ftplugin)
|
||||
- [svelte](https://github.com/evanleck/vim-svelte) (syntax, indent, ftplugin)
|
||||
- [svg-indent](https://github.com/jasonshell/vim-svg-indent) (indent)
|
||||
- [svg](https://github.com/vim-scripts/svg.vim) (syntax)
|
||||
- [swift](https://github.com/keith/swift.vim) (syntax, indent, compiler, ftplugin, ctags)
|
||||
- [sxhkd](https://github.com/baskerville/vim-sxhkdrc) (syntax)
|
||||
- [systemd](https://github.com/wgwoods/vim-systemd-syntax) (syntax, ftplugin)
|
||||
- [terraform](https://github.com/hashivim/vim-terraform) (syntax, indent, autoload, ftplugin)
|
||||
- [textile](https://github.com/timcharper/textile.vim) (syntax, ftplugin)
|
||||
- [thrift](https://github.com/solarnz/thrift.vim) (syntax)
|
||||
- [tmux](https://github.com/ericpruitt/tmux.vim) (syntax, ftplugin)
|
||||
- [tomdoc](https://github.com/wellbredgrapefruit/tomdoc.vim) (syntax)
|
||||
- [toml](https://github.com/cespare/vim-toml) (syntax, ftplugin)
|
||||
- [tptp](https://github.com/c-cube/vim-tptp) (syntax)
|
||||
- [twig](https://github.com/lumiliet/vim-twig) (syntax, indent, ftplugin)
|
||||
- [typescript](https://github.com/HerringtonDarkholme/yats.vim) (syntax, indent, compiler, ftplugin, ctags)
|
||||
- [v](https://github.com/ollykel/v-vim) (syntax, indent, ftplugin)
|
||||
- [vala](https://github.com/arrufat/vala.vim) (syntax, indent, ftplugin)
|
||||
- [vbnet](https://github.com/vim-scripts/vbnet.vim) (syntax)
|
||||
- [vcl](https://github.com/smerrill/vcl-vim-plugin) (syntax)
|
||||
- [vifm](https://github.com/vifm/vifm.vim) (syntax, autoload, ftplugin)
|
||||
- [vm](https://github.com/lepture/vim-velocity) (syntax, indent)
|
||||
- [vue](https://github.com/posva/vim-vue) (syntax, indent, ftplugin)
|
||||
- [xdc](https://github.com/amal-khailtash/vim-xdc-syntax) (syntax)
|
||||
- [xls](https://github.com/vim-scripts/XSLT-syntax) (syntax)
|
||||
- [xml](https://github.com/amadeus/vim-xml) (syntax)
|
||||
- [yaml](https://github.com/stephpy/vim-yaml) (syntax, ftplugin)
|
||||
- [yard](https://github.com/sheerun/vim-yardoc) (syntax)
|
||||
- [zephir](https://github.com/xwsoul/vim-zephir) (syntax)
|
||||
- [zig](https://github.com/ziglang/zig.vim) (syntax, autoload, ftplugin)
|
||||
- [zinit](https://github.com/zinit-zsh/zplugin-vim-syntax) (syntax)
|
||||
- [8th](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [a2ps](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [a65](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [aap](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [abap](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [abaqus](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [abc](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [abel](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [acedb](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [acpiasl](https://github.com/martinlroth/vim-acpi-asl)
|
||||
- [ada](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [ahdl](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [aidl](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [alsaconf](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [aml](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [ampl](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [ansible](https://github.com/pearofducks/ansible-vim)
|
||||
- [ant](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [apache](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [apiblueprint](https://github.com/sheerun/apiblueprint.vim)
|
||||
- [applescript](https://github.com/mityu/vim-applescript)
|
||||
- [aptconf](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [arch](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [arduino](https://github.com/sudar/vim-arduino-syntax)
|
||||
- [art](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [asciidoc](https://github.com/asciidoc/vim-asciidoc)
|
||||
- [asn](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [aspperl](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [aspvbs](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [atlas](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [autohotkey](https://github.com/hnamikaw/vim-autohotkey)
|
||||
- [autoit](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [automake](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [ave](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [awk](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [blade](https://github.com/jwalton512/vim-blade)
|
||||
- [brewfile](https://github.com/bfontaine/Brewfile.vim)
|
||||
- [c/c++](https://github.com/vim-jp/vim-cpp)
|
||||
- [caddyfile](https://github.com/isobit/vim-caddyfile)
|
||||
- [carp](https://github.com/hellerve/carp-vim)
|
||||
- [cjsx](https://github.com/mtscout6/vim-cjsx)
|
||||
- [clojure](https://github.com/guns/vim-clojure-static)
|
||||
- [cmake](https://github.com/pboettch/vim-cmake-syntax)
|
||||
- [coffee-script](https://github.com/kchmck/vim-coffee-script)
|
||||
- [cql](https://github.com/elubow/cql-vim)
|
||||
- [cryptol](https://github.com/victoredwardocallaghan/cryptol.vim)
|
||||
- [crystal](https://github.com/rhysd/vim-crystal)
|
||||
- [csv](https://github.com/chrisbra/csv.vim)
|
||||
- [cucumber](https://github.com/tpope/vim-cucumber)
|
||||
- [cue](https://github.com/mgrabovsky/vim-cuesheet)
|
||||
- [dart](https://github.com/dart-lang/dart-vim-plugin)
|
||||
- [dhall](https://github.com/vmchale/dhall-vim)
|
||||
- [dlang](https://github.com/JesseKPhillips/d.vim)
|
||||
- [dockerfile](https://github.com/ekalinin/Dockerfile.vim)
|
||||
- [elf](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [elixir](https://github.com/elixir-lang/vim-elixir)
|
||||
- [elm](https://github.com/andys8/vim-elm-syntax)
|
||||
- [emberscript](https://github.com/yalesov/vim-ember-script)
|
||||
- [emblem](https://github.com/yalesov/vim-emblem)
|
||||
- [erlang](https://github.com/vim-erlang/vim-erlang-runtime)
|
||||
- [fennel](https://github.com/bakpakin/fennel.vim)
|
||||
- [ferm](https://github.com/vim-scripts/ferm.vim)
|
||||
- [fish](https://github.com/georgewitteman/vim-fish)
|
||||
- [flatbuffers](https://github.com/dcharbon/vim-flatbuffers)
|
||||
- [forth](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [fsharp](https://github.com/ionide/Ionide-vim)
|
||||
- [gdscript](https://github.com/calviken/vim-gdscript3)
|
||||
- [git](https://github.com/tpope/vim-git)
|
||||
- [glsl](https://github.com/tikhomirov/vim-glsl)
|
||||
- [gmpl](https://github.com/maelvalais/gmpl.vim)
|
||||
- [gnuplot](https://github.com/vim-scripts/gnuplot-syntax-highlighting)
|
||||
- [go](https://github.com/fatih/vim-go)
|
||||
- [gradle](https://github.com/tfnico/vim-gradle)
|
||||
- [graphql](https://github.com/jparise/vim-graphql)
|
||||
- [grub](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [haml](https://github.com/sheerun/vim-haml)
|
||||
- [handlebars](https://github.com/sheerun/vim-mustache-handlebars)
|
||||
- [haproxy](https://github.com/CH-DanReif/haproxy.vim)
|
||||
- [haskell](https://github.com/neovimhaskell/haskell-vim)
|
||||
- [haxe](https://github.com/yaymukund/vim-haxe)
|
||||
- [hcl](https://github.com/b4b4r07/vim-hcl)
|
||||
- [helm](https://github.com/towolf/vim-helm)
|
||||
- [help](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [hive](https://github.com/zebradil/hive.vim)
|
||||
- [html5](https://github.com/othree/html5.vim)
|
||||
- [i3](https://github.com/mboughaba/i3config.vim)
|
||||
- [icalendar](https://github.com/chutzpah/icalendar.vim)
|
||||
- [idris](https://github.com/idris-hackers/idris-vim)
|
||||
- [ion](https://github.com/vmchale/ion-vim)
|
||||
- [javascript](https://github.com/pangloss/vim-javascript)
|
||||
- [jenkins](https://github.com/martinda/Jenkinsfile-vim-syntax)
|
||||
- [jinja](https://github.com/lepture/vim-jinja)
|
||||
- [jq](https://github.com/vito-c/jq.vim)
|
||||
- [json5](https://github.com/GutenYe/json5.vim)
|
||||
- [json](https://github.com/elzr/vim-json)
|
||||
- [jsonnet](https://github.com/google/vim-jsonnet)
|
||||
- [jst](https://github.com/briancollins/vim-jst)
|
||||
- [jsx](https://github.com/MaxMEllon/vim-jsx-pretty)
|
||||
- [julia](https://github.com/JuliaEditorSupport/julia-vim)
|
||||
- [kotlin](https://github.com/udalov/kotlin-vim)
|
||||
- [ledger](https://github.com/ledger/vim-ledger)
|
||||
- [less](https://github.com/groenewege/vim-less)
|
||||
- [lilypond](https://github.com/anowlcalledjosh/vim-lilypond)
|
||||
- [livescript](https://github.com/gkz/vim-ls)
|
||||
- [llvm](https://github.com/rhysd/vim-llvm)
|
||||
- [log](https://github.com/MTDL9/vim-log-highlighting)
|
||||
- [lua](https://github.com/tbastos/vim-lua)
|
||||
- [m4](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [mako](https://github.com/sophacles/vim-bundle-mako)
|
||||
- [markdown](https://github.com/plasticboy/vim-markdown)
|
||||
- [mathematica](https://github.com/voldikss/vim-mma)
|
||||
- [mdx](https://github.com/jxnblk/vim-mdx-js)
|
||||
- [meson](https://github.com/mesonbuild/meson/tree/master/data/syntax-highlighting/vim)
|
||||
- [moonscript](https://github.com/leafo/moonscript-vim)
|
||||
- [murphi](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [nginx](https://github.com/chr4/nginx.vim)
|
||||
- [nim](https://github.com/zah/nim.vim)
|
||||
- [nix](https://github.com/LnL7/vim-nix)
|
||||
- [objc](https://github.com/b4winckler/vim-objc)
|
||||
- [ocaml](https://github.com/rgrinberg/vim-ocaml)
|
||||
- [octave](https://github.com/McSinyx/vim-octave)
|
||||
- [opencl](https://github.com/petRUShka/vim-opencl)
|
||||
- [perl](https://github.com/vim-perl/vim-perl)
|
||||
- [pgsql](https://github.com/lifepillar/pgsql.vim)
|
||||
- [php](https://github.com/StanAngeloff/php.vim)
|
||||
- [plantuml](https://github.com/aklt/plantuml-syntax)
|
||||
- [pony](https://github.com/jakwings/vim-pony)
|
||||
- [powershell](https://github.com/PProvost/vim-ps1)
|
||||
- [protobuf](https://github.com/uarun/vim-protobuf)
|
||||
- [pug](https://github.com/digitaltoad/vim-pug)
|
||||
- [puppet](https://github.com/rodjek/vim-puppet)
|
||||
- [purescript](https://github.com/purescript-contrib/purescript-vim)
|
||||
- [python-compiler](https://github.com/aliev/vim-compiler-python)
|
||||
- [python-indent](https://github.com/Vimjas/vim-python-pep8-indent)
|
||||
- [python](https://github.com/vim-python/python-syntax)
|
||||
- [qmake](https://github.com/artoj/qmake-syntax-vim)
|
||||
- [qml](https://github.com/peterhoeg/vim-qml)
|
||||
- [r-lang](https://github.com/vim-scripts/R.vim)
|
||||
- [racket](https://github.com/wlangstroth/vim-racket)
|
||||
- [ragel](https://github.com/jneen/ragel.vim)
|
||||
- [raku](https://github.com/Raku/vim-raku)
|
||||
- [raml](https://github.com/IN3D/vim-raml)
|
||||
- [razor](https://github.com/adamclerk/vim-razor)
|
||||
- [reason](https://github.com/reasonml-editor/vim-reason-plus)
|
||||
- [requirements](https://github.com/raimon49/requirements.txt.vim)
|
||||
- [rspec](https://github.com/keith/rspec.vim)
|
||||
- [rst](https://github.com/marshallward/vim-restructuredtext)
|
||||
- [ruby](https://github.com/vim-ruby/vim-ruby)
|
||||
- [rust](https://github.com/rust-lang/rust.vim)
|
||||
- [sbt](https://github.com/derekwyatt/vim-sbt)
|
||||
- [scala](https://github.com/derekwyatt/vim-scala)
|
||||
- [scss](https://github.com/cakebaker/scss-syntax.vim)
|
||||
- [sh](https://github.com/arzg/vim-sh)
|
||||
- [slim](https://github.com/slim-template/vim-slim)
|
||||
- [slime](https://github.com/slime-lang/vim-slime-syntax)
|
||||
- [smt2](https://github.com/bohlender/vim-smt2)
|
||||
- [solidity](https://github.com/tomlion/vim-solidity)
|
||||
- [sql](https://github.com/shmup/vim-sql-syntax)
|
||||
- [stylus](https://github.com/wavded/vim-stylus)
|
||||
- [svelte](https://github.com/evanleck/vim-svelte/tree/main)
|
||||
- [svg-indent](https://github.com/jasonshell/vim-svg-indent)
|
||||
- [svg](https://github.com/vim-scripts/svg.vim)
|
||||
- [swift](https://github.com/keith/swift.vim)
|
||||
- [sxhkd](https://github.com/baskerville/vim-sxhkdrc)
|
||||
- [systemd](https://github.com/wgwoods/vim-systemd-syntax)
|
||||
- [terraform](https://github.com/hashivim/vim-terraform)
|
||||
- [textile](https://github.com/timcharper/textile.vim)
|
||||
- [thrift](https://github.com/solarnz/thrift.vim)
|
||||
- [tmux](https://github.com/ericpruitt/tmux.vim/tree/master/vim)
|
||||
- [toml](https://github.com/cespare/vim-toml)
|
||||
- [tptp](https://github.com/c-cube/vim-tptp)
|
||||
- [trasys](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [twig](https://github.com/lumiliet/vim-twig)
|
||||
- [typescript](https://github.com/HerringtonDarkholme/yats.vim)
|
||||
- [unison](https://github.com/unisonweb/unison/tree/trunk/editor-support/vim)
|
||||
- [v](https://github.com/ollykel/v-vim)
|
||||
- [vala](https://github.com/arrufat/vala.vim)
|
||||
- [vbnet](https://github.com/vim-scripts/vbnet.vim)
|
||||
- [vcl](https://github.com/smerrill/vcl-vim-plugin)
|
||||
- [velocity](https://github.com/lepture/vim-velocity)
|
||||
- [vmasm](https://github.com/vim/vim/tree/master/runtime)
|
||||
- [vue](https://github.com/posva/vim-vue)
|
||||
- [xdc](https://github.com/amal-khailtash/vim-xdc-syntax)
|
||||
- [xml](https://github.com/amadeus/vim-xml)
|
||||
- [xsl](https://github.com/vim-scripts/XSLT-syntax)
|
||||
- [yaml](https://github.com/stephpy/vim-yaml)
|
||||
- [yard](https://github.com/sheerun/vim-yardoc)
|
||||
- [zephir](https://github.com/xwsoul/vim-zephir)
|
||||
- [zig](https://github.com/ziglang/zig.vim)
|
||||
- [zinit](https://github.com/zinit-zsh/zplugin-vim-syntax)
|
||||
<!--/Language Packs-->
|
||||
|
||||
## Updating
|
||||
|
||||
You can either wait for new patch release with updates or run the `./build` script by yourself.
|
||||
You can either wait for new patch release with updates or run `make` by yourself.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Please make sure you have `syntax on` in your `.vimrc`, otherwise syntax files are not loaded at all.
|
||||
Please make sure you have `syntax on` in your `.vimrc` (or use something like [sheerun/vimrc](https://github.com/sheerun/vimrc))
|
||||
|
||||
Individual language packs can be disabled by setting `g:polyglot_disabled` as follows:
|
||||
|
||||
```viml
|
||||
" ~/.vimrc, declare this variable before polyglot is loaded
|
||||
let g:polyglot_disabled = ['css']
|
||||
```
|
||||
|
||||
Note that disabling languages won't make in general your vim startup any faster / slower (only for specific file type). Vim-polyglot is selection of language plugins that are loaded only on demand.
|
||||
*Please declare this variable before polyglot is loaded (at the top of .vimrc)*
|
||||
|
||||
Please note that disabling a language won't make in your vim startup any faster / slower (only for specific this specific filetype). All plugins are loaded lazily, on demand.
|
||||
|
||||
## Contributing
|
||||
|
||||
Language packs are periodically updated using automated `build` script.
|
||||
Language packs are periodically updated using automated `scripts/build` script.
|
||||
|
||||
Feel free to add your language, and send pull-request. In your pull request, please include:
|
||||
1. How you chose the particular repo from which to pull support for this language.
|
||||
2. An updated https://github.com/sheerun/vim-polyglot/blob/master/build .
|
||||
3. If at all possible, absolutely nothing else (in particular, please don't run `build` and include that in your PR).
|
||||
|
||||
The easier it is to validate that the new language won't do anything wacky, the faster it'll be merged. In particular, languages that utilize global plugins (loaded for every filetype), or plugins with dangerous features (like `call` based on the contents of a file being edited), will never be merged, as they will be slow or dangerous, respectively.
|
||||
Feel free to add your language to `packages.yaml`, and send pull-request. Please don't run `make` and include that in your PR, send just changes to `packages.yaml` and build scripts if really necessary. You can run `make test` to run rough tests.
|
||||
|
||||
## License
|
||||
|
||||
See linked repositories for detailed license information.
|
||||
See linked repositories for detailed license information. This repository is MIT-licensed.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" 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
|
||||
|
||||
call vimtex#check_plugin_clash()
|
||||
|
||||
endif
|
||||
@@ -1,3 +1,50 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'graphql') == -1
|
||||
|
||||
" Copyright (c) 2016-2020 Jon Parise <jon@indelible.org>
|
||||
"
|
||||
" 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.
|
||||
"
|
||||
" Language: GraphQL
|
||||
" Maintainer: Jon Parise <jon@indelible.org>
|
||||
|
||||
runtime! indent/graphql.vim
|
||||
|
||||
" Don't redefine our function and also require the standard Javascript indent
|
||||
" function to exist.
|
||||
if exists('*GetJavascriptGraphQLIndent') || !exists('*GetJavascriptIndent')
|
||||
finish
|
||||
endif
|
||||
|
||||
" Set the indentexpr with our own version that will call GetGraphQLIndent when
|
||||
" we're inside of a GraphQL string and otherwise defer to GetJavascriptIndent.
|
||||
setlocal indentexpr=GetJavascriptGraphQLIndent()
|
||||
|
||||
function GetJavascriptGraphQLIndent()
|
||||
let l:stack = map(synstack(v:lnum, 1), "synIDattr(v:val,'name')")
|
||||
if !empty(l:stack) && l:stack[0] ==# 'graphqlTemplateString'
|
||||
return GetGraphQLIndent()
|
||||
endif
|
||||
|
||||
return GetJavascriptIndent()
|
||||
endfunction
|
||||
|
||||
endif
|
||||
if !exists('g:polyglot_disabled') || !(index(g:polyglot_disabled, 'typescript') != -1 || index(g:polyglot_disabled, 'typescript') != -1 || index(g:polyglot_disabled, 'jsx') != -1)
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
47
after/indent/typescript.vim
Normal file
47
after/indent/typescript.vim
Normal file
@@ -0,0 +1,47 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'graphql') == -1
|
||||
|
||||
" Copyright (c) 2016-2020 Jon Parise <jon@indelible.org>
|
||||
"
|
||||
" 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.
|
||||
"
|
||||
" Language: GraphQL
|
||||
" Maintainer: Jon Parise <jon@indelible.org>
|
||||
|
||||
runtime! indent/graphql.vim
|
||||
|
||||
" Don't redefine our function and also require the standard Typescript indent
|
||||
" function to exist.
|
||||
if exists('*GetTypescriptGraphQLIndent') || !exists('*GetTypescriptIndent')
|
||||
finish
|
||||
endif
|
||||
|
||||
" Set the indentexpr with our own version that will call GetGraphQLIndent when
|
||||
" we're inside of a GraphQL string and otherwise defer to GetTypescriptIndent.
|
||||
setlocal indentexpr=GetTypescriptGraphQLIndent()
|
||||
|
||||
function GetTypescriptGraphQLIndent()
|
||||
let l:stack = map(synstack(v:lnum, 1), "synIDattr(v:val,'name')")
|
||||
if !empty(l:stack) && l:stack[0] ==# 'graphqlTemplateString'
|
||||
return GetGraphQLIndent()
|
||||
endif
|
||||
|
||||
return GetTypescriptIndent()
|
||||
endfunction
|
||||
|
||||
endif
|
||||
@@ -1,321 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'c++11') == -1
|
||||
|
||||
" Vim syntax file
|
||||
" Language: C Additions
|
||||
" Maintainer: Jon Haggblad <jon@haeggblad.com>
|
||||
" Contributor: Mikhail Wolfson <mywolfson@gmail.com>
|
||||
" URL: http://www.haeggblad.com
|
||||
" Last Change: 6 Sep 2014
|
||||
" Version: 0.3
|
||||
" Changelog:
|
||||
" 0.3 - integration of aftersyntaxc.vim
|
||||
" 0.2 - Cleanup
|
||||
" 0.1 - initial version.
|
||||
"
|
||||
" Syntax highlighting for functions in C.
|
||||
"
|
||||
" Based on:
|
||||
" http://stackoverflow.com/questions/736701/class-function-names-highlighting-in-vim
|
||||
|
||||
" -----------------------------------------------------------------------------
|
||||
" Highlight function names.
|
||||
" -----------------------------------------------------------------------------
|
||||
if !exists('g:cpp_no_function_highlight')
|
||||
syn match cCustomParen transparent "(" contains=cParen contains=cCppParen
|
||||
syn match cCustomFunc "\w\+\s*(\@=" contains=cCustomParen
|
||||
hi def link cCustomFunc Function
|
||||
endif
|
||||
|
||||
" -----------------------------------------------------------------------------
|
||||
" Highlight member variable names.
|
||||
" -----------------------------------------------------------------------------
|
||||
if exists('g:cpp_member_variable_highlight') && g:cpp_member_variable_highlight
|
||||
syn match cCustomDot "\." contained
|
||||
syn match cCustomPtr "->" contained
|
||||
syn match cCustomMemVar "\(\.\|->\)\h\w*" contains=cCustomDot,cCustomPtr
|
||||
hi def link cCustomMemVar Function
|
||||
endif
|
||||
|
||||
" -----------------------------------------------------------------------------
|
||||
" Highlight POSIX functions.
|
||||
" -----------------------------------------------------------------------------
|
||||
if exists('g:cpp_posix_standard') && g:cpp_posix_standard
|
||||
syn keyword cPOSIXFunction socket accept bind connect getsockname
|
||||
syn keyword cPOSIXFunction listen recv recvfrom recvmsg
|
||||
syn keyword cPOSIXFunction send sendto sendmsg setsockopt socketpair
|
||||
syn keyword cPOSIXFunction htonl htons ntohl ntohs
|
||||
syn keyword cPOSIXFunction inet_ntop inet_pton getaddrinfo
|
||||
syn keyword cPOSIXFunction poll select pselect
|
||||
hi def link cPOSIXFunction Function
|
||||
endif
|
||||
|
||||
" -----------------------------------------------------------------------------
|
||||
" Source: aftersyntaxc.vim
|
||||
" -----------------------------------------------------------------------------
|
||||
|
||||
" Common ANSI-standard functions
|
||||
syn keyword cAnsiFunction MULU_ DIVU_ MODU_ MUL_ DIV_ MOD_
|
||||
syn keyword cAnsiFunction main typeof
|
||||
syn keyword cAnsiFunction open close read write lseek dup dup2
|
||||
syn keyword cAnsiFunction fcntl ioctl
|
||||
syn keyword cAnsiFunction wctrans towctrans towupper
|
||||
syn keyword cAnsiFunction towlower wctype iswctype
|
||||
syn keyword cAnsiFunction iswxdigit iswupper iswspace
|
||||
syn keyword cAnsiFunction iswpunct iswprint iswlower
|
||||
syn keyword cAnsiFunction iswgraph iswdigit iswcntrl
|
||||
syn keyword cAnsiFunction iswalpha iswalnum wcsrtombs
|
||||
syn keyword cAnsiFunction mbsrtowcs wcrtomb mbrtowc
|
||||
syn keyword cAnsiFunction mbrlen mbsinit wctob
|
||||
syn keyword cAnsiFunction btowc wcsfxtime wcsftime
|
||||
syn keyword cAnsiFunction wmemset wmemmove wmemcpy
|
||||
syn keyword cAnsiFunction wmemcmp wmemchr wcstok
|
||||
syn keyword cAnsiFunction wcsstr wcsspn wcsrchr
|
||||
syn keyword cAnsiFunction wcspbrk wcslen wcscspn
|
||||
syn keyword cAnsiFunction wcschr wcsxfrm wcsncmp
|
||||
syn keyword cAnsiFunction wcscoll wcscmp wcsncat
|
||||
syn keyword cAnsiFunction wcscat wcsncpy wcscpy
|
||||
syn keyword cAnsiFunction wcstoull wcstoul wcstoll
|
||||
syn keyword cAnsiFunction wcstol wcstold wcstof
|
||||
syn keyword cAnsiFunction wcstod ungetwc putwchar
|
||||
syn keyword cAnsiFunction putwc getwchar getwc
|
||||
syn keyword cAnsiFunction fwide fputws fputwc
|
||||
syn keyword cAnsiFunction fgetws fgetwc wscanf
|
||||
syn keyword cAnsiFunction wprintf vwscanf vwprintf
|
||||
syn keyword cAnsiFunction vswscanf vswprintf vfwscanf
|
||||
syn keyword cAnsiFunction vfwprintf swscanf swprintf
|
||||
syn keyword cAnsiFunction fwscanf fwprintf zonetime
|
||||
syn keyword cAnsiFunction strfxtime strftime localtime
|
||||
syn keyword cAnsiFunction gmtime ctime asctime
|
||||
syn keyword cAnsiFunction time mkxtime mktime
|
||||
syn keyword cAnsiFunction difftime clock strlen
|
||||
syn keyword cAnsiFunction strerror memset strtok
|
||||
syn keyword cAnsiFunction strstr strspn strrchr
|
||||
syn keyword cAnsiFunction strpbrk strcspn strchr
|
||||
syn keyword cAnsiFunction memchr strxfrm strncmp
|
||||
syn keyword cAnsiFunction strcoll strcmp memcmp
|
||||
syn keyword cAnsiFunction strncat strcat strncpy
|
||||
syn keyword cAnsiFunction strcpy memmove memcpy
|
||||
syn keyword cAnsiFunction wcstombs mbstowcs wctomb
|
||||
syn keyword cAnsiFunction mbtowc mblen lldiv
|
||||
syn keyword cAnsiFunction ldiv div llabs
|
||||
syn keyword cAnsiFunction labs abs qsort
|
||||
"syn keyword cAnsiFunction bsearch system getenv
|
||||
syn keyword cAnsiFunction bsearch getenv
|
||||
syn keyword cAnsiFunction exit atexit abort
|
||||
syn keyword cAnsiFunction realloc malloc free
|
||||
syn keyword cAnsiFunction calloc srand rand
|
||||
syn keyword cAnsiFunction strtoull strtoul strtoll
|
||||
syn keyword cAnsiFunction strtol strtold strtof
|
||||
syn keyword cAnsiFunction strtod atoll atol
|
||||
syn keyword cAnsiFunction atoi atof perror
|
||||
syn keyword cAnsiFunction ferror feof clearerr
|
||||
syn keyword cAnsiFunction rewind ftell fsetpos
|
||||
syn keyword cAnsiFunction fseek fgetpos fwrite
|
||||
syn keyword cAnsiFunction fread ungetc puts
|
||||
syn keyword cAnsiFunction putchar putc gets
|
||||
syn keyword cAnsiFunction getchar getc fputs
|
||||
syn keyword cAnsiFunction fputc fgets fgetc
|
||||
syn keyword cAnsiFunction vsscanf vsprintf vsnprintf
|
||||
syn keyword cAnsiFunction vscanf vprintf vfscanf
|
||||
syn keyword cAnsiFunction vfprintf sscanf sprintf
|
||||
syn keyword cAnsiFunction snprintf scanf printf
|
||||
syn keyword cAnsiFunction fscanf fprintf setvbuf
|
||||
syn keyword cAnsiFunction setbuf freopen fopen
|
||||
syn keyword cAnsiFunction fflush fclose tmpnam
|
||||
syn keyword cAnsiFunction tmpfile rename remove
|
||||
syn keyword cAnsiFunction offsetof va_start va_end
|
||||
syn keyword cAnsiFunction va_copy va_arg raise signal
|
||||
syn keyword cAnsiFunction longjmp setjmp isunordered
|
||||
syn keyword cAnsiFunction islessgreater islessequal isless
|
||||
syn keyword cAnsiFunction isgreaterequal isgreater fmal
|
||||
syn keyword cAnsiFunction fmaf fma fminl
|
||||
syn keyword cAnsiFunction fminf fmin fmaxl
|
||||
syn keyword cAnsiFunction fmaxf fmax fdiml
|
||||
syn keyword cAnsiFunction fdimf fdim nextafterxl
|
||||
syn keyword cAnsiFunction nextafterxf nextafterx nextafterl
|
||||
syn keyword cAnsiFunction nextafterf nextafter nanl
|
||||
syn keyword cAnsiFunction nanf nan copysignl
|
||||
syn keyword cAnsiFunction copysignf copysign remquol
|
||||
syn keyword cAnsiFunction remquof remquo remainderl
|
||||
syn keyword cAnsiFunction remainderf remainder fmodl
|
||||
syn keyword cAnsiFunction fmodf fmod truncl
|
||||
syn keyword cAnsiFunction truncf trunc llroundl
|
||||
syn keyword cAnsiFunction llroundf llround lroundl
|
||||
syn keyword cAnsiFunction lroundf lround roundl
|
||||
syn keyword cAnsiFunction roundf round llrintl
|
||||
syn keyword cAnsiFunction llrintf llrint lrintl
|
||||
syn keyword cAnsiFunction lrintf lrint rintl
|
||||
syn keyword cAnsiFunction rintf rint nearbyintl
|
||||
syn keyword cAnsiFunction nearbyintf nearbyint floorl
|
||||
syn keyword cAnsiFunction floorf floor ceill
|
||||
syn keyword cAnsiFunction ceilf ceil tgammal
|
||||
syn keyword cAnsiFunction tgammaf tgamma lgammal
|
||||
syn keyword cAnsiFunction lgammaf lgamma erfcl
|
||||
syn keyword cAnsiFunction erfcf erfc erfl
|
||||
syn keyword cAnsiFunction erff erf sqrtl
|
||||
syn keyword cAnsiFunction sqrtf sqrt powl
|
||||
syn keyword cAnsiFunction powf pow hypotl
|
||||
syn keyword cAnsiFunction hypotf hypot fabsl
|
||||
syn keyword cAnsiFunction fabsf fabs cbrtl
|
||||
syn keyword cAnsiFunction cbrtf cbrt scalblnl
|
||||
syn keyword cAnsiFunction scalblnf scalbln scalbnl
|
||||
syn keyword cAnsiFunction scalbnf scalbn modfl
|
||||
syn keyword cAnsiFunction modff modf logbl
|
||||
syn keyword cAnsiFunction logbf logb log2l
|
||||
syn keyword cAnsiFunction log2f log2 log1pl
|
||||
syn keyword cAnsiFunction log1pf log1p log10l
|
||||
syn keyword cAnsiFunction log10f log10 logl
|
||||
syn keyword cAnsiFunction logf log ldexpl
|
||||
syn keyword cAnsiFunction ldexpf ldexp ilogbl
|
||||
syn keyword cAnsiFunction ilogbf ilogb frexpl
|
||||
syn keyword cAnsiFunction frexpf frexp expm1l
|
||||
syn keyword cAnsiFunction expm1f expm1 exp2l
|
||||
syn keyword cAnsiFunction exp2f exp2 expl
|
||||
syn keyword cAnsiFunction expf exp tanhl
|
||||
syn keyword cAnsiFunction tanhf tanh sinhl
|
||||
syn keyword cAnsiFunction sinhf sinh coshl
|
||||
syn keyword cAnsiFunction coshf cosh atanhl
|
||||
syn keyword cAnsiFunction atanhf atanh asinhl
|
||||
syn keyword cAnsiFunction asinhf asinh acoshl
|
||||
syn keyword cAnsiFunction acoshf acosh tanl
|
||||
syn keyword cAnsiFunction tanf tan sinl
|
||||
syn keyword cAnsiFunction sinf sin cosl
|
||||
syn keyword cAnsiFunction cosf cos atan2l
|
||||
syn keyword cAnsiFunction atan2f atan2 atanl
|
||||
syn keyword cAnsiFunction atanf atan asinl
|
||||
syn keyword cAnsiFunction asinf asin acosl
|
||||
syn keyword cAnsiFunction acosf acos signbit
|
||||
syn keyword cAnsiFunction isnormal isnan isinf
|
||||
syn keyword cAnsiFunction isfinite fpclassify localeconv
|
||||
syn keyword cAnsiFunction setlocale wcstoumax wcstoimax
|
||||
syn keyword cAnsiFunction strtoumax strtoimax feupdateenv
|
||||
syn keyword cAnsiFunction fesetenv feholdexcept fegetenv
|
||||
syn keyword cAnsiFunction fesetround fegetround fetestexcept
|
||||
syn keyword cAnsiFunction fesetexceptflag feraiseexcept fegetexceptflag
|
||||
syn keyword cAnsiFunction feclearexcept toupper tolower
|
||||
syn keyword cAnsiFunction isxdigit isupper isspace
|
||||
syn keyword cAnsiFunction ispunct isprint islower
|
||||
syn keyword cAnsiFunction isgraph isdigit iscntrl
|
||||
syn keyword cAnsiFunction isalpha isalnum creall
|
||||
syn keyword cAnsiFunction crealf creal cprojl
|
||||
syn keyword cAnsiFunction cprojf cproj conjl
|
||||
syn keyword cAnsiFunction conjf conj cimagl
|
||||
syn keyword cAnsiFunction cimagf cimag cargl
|
||||
syn keyword cAnsiFunction cargf carg csqrtl
|
||||
syn keyword cAnsiFunction csqrtf csqrt cpowl
|
||||
syn keyword cAnsiFunction cpowf cpow cabsl
|
||||
syn keyword cAnsiFunction cabsf cabs clogl
|
||||
syn keyword cAnsiFunction clogf clog cexpl
|
||||
syn keyword cAnsiFunction cexpf cexp ctanhl
|
||||
syn keyword cAnsiFunction ctanhf ctanh csinhl
|
||||
syn keyword cAnsiFunction csinhf csinh ccoshl
|
||||
syn keyword cAnsiFunction ccoshf ccosh catanhl
|
||||
syn keyword cAnsiFunction catanhf catanh casinhl
|
||||
syn keyword cAnsiFunction casinhf casinh cacoshl
|
||||
syn keyword cAnsiFunction cacoshf cacosh ctanl
|
||||
syn keyword cAnsiFunction ctanf ctan csinl
|
||||
syn keyword cAnsiFunction csinf csin ccosl
|
||||
syn keyword cAnsiFunction ccosf ccos catanl
|
||||
syn keyword cAnsiFunction catanf catan casinl
|
||||
syn keyword cAnsiFunction casinf casin cacosl
|
||||
syn keyword cAnsiFunction cacosf cacos assert
|
||||
syn keyword cAnsiFunction UINTMAX_C INTMAX_C UINT64_C
|
||||
syn keyword cAnsiFunction UINT32_C UINT16_C UINT8_C
|
||||
syn keyword cAnsiFunction INT64_C INT32_C INT16_C INT8_C
|
||||
|
||||
" Common ANSI-standard Names
|
||||
syn keyword cAnsiName PRId8 PRIi16 PRIo32 PRIu64
|
||||
syn keyword cAnsiName PRId16 PRIi32 PRIo64 PRIuLEAST8
|
||||
syn keyword cAnsiName PRId32 PRIi64 PRIoLEAST8 PRIuLEAST16
|
||||
syn keyword cAnsiName PRId64 PRIiLEAST8 PRIoLEAST16 PRIuLEAST32
|
||||
syn keyword cAnsiName PRIdLEAST8 PRIiLEAST16 PRIoLEAST32 PRIuLEAST64
|
||||
syn keyword cAnsiName PRIdLEAST16 PRIiLEAST32 PRIoLEAST64 PRIuFAST8
|
||||
syn keyword cAnsiName PRIdLEAST32 PRIiLEAST64 PRIoFAST8 PRIuFAST16
|
||||
syn keyword cAnsiName PRIdLEAST64 PRIiFAST8 PRIoFAST16 PRIuFAST32
|
||||
syn keyword cAnsiName PRIdFAST8 PRIiFAST16 PRIoFAST32 PRIuFAST64
|
||||
syn keyword cAnsiName PRIdFAST16 PRIiFAST32 PRIoFAST64 PRIuMAX
|
||||
syn keyword cAnsiName PRIdFAST32 PRIiFAST64 PRIoMAX PRIuPTR
|
||||
syn keyword cAnsiName PRIdFAST64 PRIiMAX PRIoPTR PRIx8
|
||||
syn keyword cAnsiName PRIdMAX PRIiPTR PRIu8 PRIx16
|
||||
syn keyword cAnsiName PRIdPTR PRIo8 PRIu16 PRIx32
|
||||
syn keyword cAnsiName PRIi8 PRIo16 PRIu32 PRIx64
|
||||
|
||||
syn keyword cAnsiName PRIxLEAST8 SCNd8 SCNiFAST32 SCNuLEAST32
|
||||
syn keyword cAnsiName PRIxLEAST16 SCNd16 SCNiFAST64 SCNuLEAST64
|
||||
syn keyword cAnsiName PRIxLEAST32 SCNd32 SCNiMAX SCNuFAST8
|
||||
syn keyword cAnsiName PRIxLEAST64 SCNd64 SCNiPTR SCNuFAST16
|
||||
syn keyword cAnsiName PRIxFAST8 SCNdLEAST8 SCNo8 SCNuFAST32
|
||||
syn keyword cAnsiName PRIxFAST16 SCNdLEAST16 SCNo16 SCNuFAST64
|
||||
syn keyword cAnsiName PRIxFAST32 SCNdLEAST32 SCNo32 SCNuMAX
|
||||
syn keyword cAnsiName PRIxFAST64 SCNdLEAST64 SCNo64 SCNuPTR
|
||||
syn keyword cAnsiName PRIxMAX SCNdFAST8 SCNoLEAST8 SCNx8
|
||||
syn keyword cAnsiName PRIxPTR SCNdFAST16 SCNoLEAST16 SCNx16
|
||||
syn keyword cAnsiName PRIX8 SCNdFAST32 SCNoLEAST32 SCNx32
|
||||
syn keyword cAnsiName PRIX16 SCNdFAST64 SCNoLEAST64 SCNx64
|
||||
syn keyword cAnsiName PRIX32 SCNdMAX SCNoFAST8 SCNxLEAST8
|
||||
syn keyword cAnsiName PRIX64 SCNdPTR SCNoFAST16 SCNxLEAST16
|
||||
syn keyword cAnsiName PRIXLEAST8 SCNi8 SCNoFAST32 SCNxLEAST32
|
||||
syn keyword cAnsiName PRIXLEAST16 SCNi16 SCNoFAST64 SCNxLEAST64
|
||||
syn keyword cAnsiName PRIXLEAST32 SCNi32 SCNoMAX SCNxFAST8
|
||||
syn keyword cAnsiName PRIXLEAST64 SCNi64 SCNoPTR SCNxFAST16
|
||||
syn keyword cAnsiName PRIXFAST8 SCNiLEAST8 SCNu8 SCNxFAST32
|
||||
syn keyword cAnsiName PRIXFAST16 SCNiLEAST16 SCNu16 SCNxFAST64
|
||||
syn keyword cAnsiName PRIXFAST32 SCNiLEAST32 SCNu32 SCNxMAX
|
||||
syn keyword cAnsiName PRIXFAST64 SCNiLEAST64 SCNu64 SCNxPTR
|
||||
syn keyword cAnsiName PRIXMAX SCNiFAST8 SCNuLEAST8
|
||||
syn keyword cAnsiName PRIXPTR SCNiFAST16 SCNuLEAST16
|
||||
|
||||
syn keyword cAnsiName errno environ
|
||||
|
||||
syn keyword cAnsiName STDC CX_LIMITED_RANGE
|
||||
syn keyword cAnsiName STDC FENV_ACCESS
|
||||
syn keyword cAnsiName STDC FP_CONTRACT
|
||||
|
||||
syn keyword cAnsiName and bitor not_eq xor
|
||||
syn keyword cAnsiName and_eq compl or xor_eq
|
||||
syn keyword cAnsiName bitand not or_eq
|
||||
|
||||
hi def link cAnsiFunction cFunction
|
||||
hi def link cAnsiName cIdentifier
|
||||
hi def link cFunction Function
|
||||
hi def link cIdentifier Identifier
|
||||
|
||||
" Booleans
|
||||
syn keyword cBoolean true false TRUE FALSE
|
||||
hi def link cBoolean Boolean
|
||||
|
||||
" -----------------------------------------------------------------------------
|
||||
" Additional optional highlighting
|
||||
" -----------------------------------------------------------------------------
|
||||
|
||||
" Operators
|
||||
"syn match cOperator "\(<<\|>>\|[-+*/%&^|<>!=]\)="
|
||||
"syn match cOperator "<<\|>>\|&&\|||\|++\|--\|->"
|
||||
"syn match cOperator "[.!~*&%<>^|=,+-]"
|
||||
"syn match cOperator "/[^/*=]"me=e-1
|
||||
"syn match cOperator "/$"
|
||||
"syn match cOperator "&&\|||"
|
||||
"syn match cOperator "[][]"
|
||||
"
|
||||
"" Preprocs
|
||||
"syn keyword cDefined defined contained containedin=cDefine
|
||||
"hi def link cDefined cDefine
|
||||
|
||||
"" Functions
|
||||
"syn match cUserFunction "\<\h\w*\>\(\s\|\n\)*("me=e-1 contains=cType,cDelimiter,cDefine
|
||||
"syn match cUserFunctionPointer "(\s*\*\s*\h\w*\s*)\(\s\|\n\)*(" contains=cDelimiter,cOperator
|
||||
"
|
||||
"hi def link cUserFunction cFunction
|
||||
"hi def link cUserFunctionPointer cFunction
|
||||
"
|
||||
"" Delimiters
|
||||
"syn match cDelimiter "[();\\]"
|
||||
"" foldmethod=syntax fix, courtesy of Ivan Freitas
|
||||
"syn match cBraces display "[{}]"
|
||||
|
||||
" Links
|
||||
"hi def link cDelimiter Delimiter
|
||||
" foldmethod=syntax fix, courtesy of Ivan Freitas
|
||||
"hi def link cBraces Delimiter
|
||||
|
||||
endif
|
||||
2297
after/syntax/cpp.vim
2297
after/syntax/cpp.vim
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ let s:highlight_close_tag = get(g:, 'vim_jsx_pretty_highlight_close_tag', 0)
|
||||
|
||||
" detect jsx region
|
||||
syntax region jsxRegion
|
||||
\ start=+\%(\%(\_[([,?:=+\-*/>{}]\|<\s\+\|&&\|||\|=>\|\<return\|\<default\|\<await\|\<yield\)\_s*\)\@<=<\_s*\%(>\|\z(\%(script\|T\s*>\s*(\)\@!\<[_$A-Za-z][-:._$A-Za-z0-9]*\>\)\%(\_s*\%([-+*)\]}&|?,]\|/\%([/*]\|\_s*>\)\@!\)\)\@!\)+
|
||||
\ start=+\%(\%(\_[([,?:=+\-*/>{}]\|<\s\+\|&&\|||\|=>\|\<return\|\<default\|\<await\|\<yield\)\_s*\)\@<=<\_s*\%(>\|\z(\%(script\|\s*\<T\>\)\@!\<[_$A-Za-z][-:._$A-Za-z0-9]*\>\)\%(\_s*\%([-+*)\]}&|?,]\|/\%([/*]\|\_s*>\)\@!\)\)\@!\)+
|
||||
\ end=++
|
||||
\ contains=jsxElement
|
||||
|
||||
|
||||
37
after/syntax/reason/graphql.vim
Normal file
37
after/syntax/reason/graphql.vim
Normal file
@@ -0,0 +1,37 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'graphql') == -1
|
||||
|
||||
" Copyright (c) 2016-2020 Jon Parise <jon@indelible.org>
|
||||
"
|
||||
" 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.
|
||||
"
|
||||
" Language: GraphQL
|
||||
" Maintainer: Jon Parise <jon@indelible.org>
|
||||
|
||||
if exists('b:current_syntax')
|
||||
let s:current_syntax = b:current_syntax
|
||||
unlet b:current_syntax
|
||||
endif
|
||||
syn include @GraphQLSyntax syntax/graphql.vim
|
||||
if exists('s:current_syntax')
|
||||
let b:current_syntax = s:current_syntax
|
||||
endif
|
||||
|
||||
syntax region graphqlMultilineString matchgroup=reasonMultilineString start=+graphql\_s*\zs{|+ end=+|}+ contains=@GraphQLSyntax,reasonEscape,reasonEscapeUnicode,reasonEscapeError,reasonStringContinuation keepend
|
||||
|
||||
endif
|
||||
@@ -1,11 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
call vimtex#syntax#init()
|
||||
|
||||
endif
|
||||
641
autoload/ada.vim
Normal file
641
autoload/ada.vim
Normal file
@@ -0,0 +1,641 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ada') == -1
|
||||
|
||||
"------------------------------------------------------------------------------
|
||||
" Description: Perform Ada specific completion & tagging.
|
||||
" Language: Ada (2005)
|
||||
" $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $
|
||||
" Maintainer: Mathias Brousset <mathiasb17@gmail.com>
|
||||
" Martin Krischik <krischik@users.sourceforge.net>
|
||||
" Taylor Venable <taylor@metasyntax.net>
|
||||
" Neil Bird <neil@fnxweb.com>
|
||||
" Ned Okie <nokie@radford.edu>
|
||||
" $Author: krischik $
|
||||
" $Date: 2017-01-31 20:20:05 +0200 (Mon, 01 Jan 2017) $
|
||||
" Version: 4.6
|
||||
" $Revision: 887 $
|
||||
" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $
|
||||
" History: 24.05.2006 MK Unified Headers
|
||||
" 26.05.2006 MK ' should not be in iskeyword.
|
||||
" 16.07.2006 MK Ada-Mode as vim-ball
|
||||
" 02.10.2006 MK Better folding.
|
||||
" 15.10.2006 MK Bram's suggestion for runtime integration
|
||||
" 05.11.2006 MK Bram suggested not to use include protection for
|
||||
" autoload
|
||||
" 05.11.2006 MK Bram suggested to save on spaces
|
||||
" 08.07.2007 TV fix mapleader problems.
|
||||
" 09.05.2007 MK Session just won't work no matter how much
|
||||
" tweaking is done
|
||||
" 19.09.2007 NO still some mapleader problems
|
||||
" 31.01.2017 MB fix more mapleader problems
|
||||
" Help Page: ft-ada-functions
|
||||
"------------------------------------------------------------------------------
|
||||
|
||||
if version < 700
|
||||
finish
|
||||
endif
|
||||
let s:keepcpo= &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Section: Constants {{{1
|
||||
"
|
||||
let g:ada#DotWordRegex = '\a\w*\(\_s*\.\_s*\a\w*\)*'
|
||||
let g:ada#WordRegex = '\a\w*'
|
||||
let g:ada#Comment = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*"
|
||||
let g:ada#Keywords = []
|
||||
|
||||
" Section: g:ada#Keywords {{{1
|
||||
"
|
||||
" Section: add Ada keywords {{{2
|
||||
"
|
||||
for Item in ['abort', 'else', 'new', 'return', 'abs', 'elsif', 'not', 'reverse', 'abstract', 'end', 'null', 'accept', 'entry', 'select', 'access', 'exception', 'of', 'separate', 'aliased', 'exit', 'or', 'subtype', 'all', 'others', 'synchronized', 'and', 'for', 'out', 'array', 'function', 'overriding', 'tagged', 'at', 'task', 'generic', 'package', 'terminate', 'begin', 'goto', 'pragma', 'then', 'body', 'private', 'type', 'if', 'procedure', 'case', 'in', 'protected', 'until', 'constant', 'interface', 'use', 'is', 'raise', 'declare', 'range', 'when', 'delay', 'limited', 'record', 'while', 'delta', 'loop', 'rem', 'with', 'digits', 'renames', 'do', 'mod', 'requeue', 'xor']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'keyword',
|
||||
\ 'info': 'Ada keyword.',
|
||||
\ 'kind': 'k',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
|
||||
" Section: GNAT Project Files {{{3
|
||||
"
|
||||
if exists ('g:ada_with_gnat_project_files')
|
||||
for Item in ['project']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'keyword',
|
||||
\ 'info': 'GNAT projectfile keyword.',
|
||||
\ 'kind': 'k',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Section: add standart exception {{{2
|
||||
"
|
||||
for Item in ['Constraint_Error', 'Program_Error', 'Storage_Error', 'Tasking_Error', 'Status_Error', 'Mode_Error', 'Name_Error', 'Use_Error', 'Device_Error', 'End_Error', 'Data_Error', 'Layout_Error', 'Length_Error', 'Pattern_Error', 'Index_Error', 'Translation_Error', 'Time_Error', 'Argument_Error', 'Tag_Error', 'Picture_Error', 'Terminator_Error', 'Conversion_Error', 'Pointer_Error', 'Dereference_Error', 'Update_Error']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'exception',
|
||||
\ 'info': 'Ada standart exception.',
|
||||
\ 'kind': 'x',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
|
||||
" Section: add GNAT exception {{{3
|
||||
"
|
||||
if exists ('g:ada_gnat_extensions')
|
||||
for Item in ['Assert_Failure']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'exception',
|
||||
\ 'info': 'GNAT exception.',
|
||||
\ 'kind': 'x',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Section: add Ada buildin types {{{2
|
||||
"
|
||||
for Item in ['Boolean', 'Integer', 'Natural', 'Positive', 'Float', 'Character', 'Wide_Character', 'Wide_Wide_Character', 'String', 'Wide_String', 'Wide_Wide_String', 'Duration']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'type',
|
||||
\ 'info': 'Ada buildin type.',
|
||||
\ 'kind': 't',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
|
||||
" Section: add GNAT buildin types {{{3
|
||||
"
|
||||
if exists ('g:ada_gnat_extensions')
|
||||
for Item in ['Short_Integer', 'Short_Short_Integer', 'Long_Integer', 'Long_Long_Integer', 'Short_Float', 'Short_Short_Float', 'Long_Float', 'Long_Long_Float']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'type',
|
||||
\ 'info': 'GNAT buildin type.',
|
||||
\ 'kind': 't',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Section: add Ada Attributes {{{2
|
||||
"
|
||||
for Item in ['''Access', '''Address', '''Adjacent', '''Aft', '''Alignment', '''Base', '''Bit_Order', '''Body_Version', '''Callable', '''Caller', '''Ceiling', '''Class', '''Component_Size', '''Compose', '''Constrained', '''Copy_Sign', '''Count', '''Definite', '''Delta', '''Denorm', '''Digits', '''Emax', '''Exponent', '''External_Tag', '''Epsilon', '''First', '''First_Bit', '''Floor', '''Fore', '''Fraction', '''Identity', '''Image', '''Input', '''Large', '''Last', '''Last_Bit', '''Leading_Part', '''Length', '''Machine', '''Machine_Emax', '''Machine_Emin', '''Machine_Mantissa', '''Machine_Overflows', '''Machine_Radix', '''Machine_Rounding', '''Machine_Rounds', '''Mantissa', '''Max', '''Max_Size_In_Storage_Elements', '''Min', '''Mod', '''Model', '''Model_Emin', '''Model_Epsilon', '''Model_Mantissa', '''Model_Small', '''Modulus', '''Output', '''Partition_ID', '''Pos', '''Position', '''Pred', '''Priority', '''Range', '''Read', '''Remainder', '''Round', '''Rounding', '''Safe_Emax', '''Safe_First', '''Safe_Large', '''Safe_Last', '''Safe_Small', '''Scale', '''Scaling', '''Signed_Zeros', '''Size', '''Small', '''Storage_Pool', '''Storage_Size', '''Stream_Size', '''Succ', '''Tag', '''Terminated', '''Truncation', '''Unbiased_Rounding', '''Unchecked_Access', '''Val', '''Valid', '''Value', '''Version', '''Wide_Image', '''Wide_Value', '''Wide_Wide_Image', '''Wide_Wide_Value', '''Wide_Wide_Width', '''Wide_Width', '''Width', '''Write']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'attribute',
|
||||
\ 'info': 'Ada attribute.',
|
||||
\ 'kind': 'a',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
|
||||
" Section: add GNAT Attributes {{{3
|
||||
"
|
||||
if exists ('g:ada_gnat_extensions')
|
||||
for Item in ['''Abort_Signal', '''Address_Size', '''Asm_Input', '''Asm_Output', '''AST_Entry', '''Bit', '''Bit_Position', '''Code_Address', '''Default_Bit_Order', '''Elaborated', '''Elab_Body', '''Elab_Spec', '''Emax', '''Enum_Rep', '''Epsilon', '''Fixed_Value', '''Has_Access_Values', '''Has_Discriminants', '''Img', '''Integer_Value', '''Machine_Size', '''Max_Interrupt_Priority', '''Max_Priority', '''Maximum_Alignment', '''Mechanism_Code', '''Null_Parameter', '''Object_Size', '''Passed_By_Reference', '''Range_Length', '''Storage_Unit', '''Target_Name', '''Tick', '''To_Address', '''Type_Class', '''UET_Address', '''Unconstrained_Array', '''Universal_Literal_String', '''Unrestricted_Access', '''VADS_Size', '''Value_Size', '''Wchar_T_Size', '''Word_Size']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'attribute',
|
||||
\ 'info': 'GNAT attribute.',
|
||||
\ 'kind': 'a',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Section: add Ada Pragmas {{{2
|
||||
"
|
||||
for Item in ['All_Calls_Remote', 'Assert', 'Assertion_Policy', 'Asynchronous', 'Atomic', 'Atomic_Components', 'Attach_Handler', 'Controlled', 'Convention', 'Detect_Blocking', 'Discard_Names', 'Elaborate', 'Elaborate_All', 'Elaborate_Body', 'Export', 'Import', 'Inline', 'Inspection_Point', 'Interface (Obsolescent)', 'Interrupt_Handler', 'Interrupt_Priority', 'Linker_Options', 'List', 'Locking_Policy', 'Memory_Size (Obsolescent)', 'No_Return', 'Normalize_Scalars', 'Optimize', 'Pack', 'Page', 'Partition_Elaboration_Policy', 'Preelaborable_Initialization', 'Preelaborate', 'Priority', 'Priority_Specific_Dispatching', 'Profile', 'Pure', 'Queueing_Policy', 'Relative_Deadline', 'Remote_Call_Interface', 'Remote_Types', 'Restrictions', 'Reviewable', 'Shared (Obsolescent)', 'Shared_Passive', 'Storage_Size', 'Storage_Unit (Obsolescent)', 'Suppress', 'System_Name (Obsolescent)', 'Task_Dispatching_Policy', 'Unchecked_Union', 'Unsuppress', 'Volatile', 'Volatile_Components']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'pragma',
|
||||
\ 'info': 'Ada pragma.',
|
||||
\ 'kind': 'p',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
|
||||
" Section: add GNAT Pragmas {{{3
|
||||
"
|
||||
if exists ('g:ada_gnat_extensions')
|
||||
for Item in ['Abort_Defer', 'Ada_83', 'Ada_95', 'Ada_05', 'Annotate', 'Ast_Entry', 'C_Pass_By_Copy', 'Comment', 'Common_Object', 'Compile_Time_Warning', 'Complex_Representation', 'Component_Alignment', 'Convention_Identifier', 'CPP_Class', 'CPP_Constructor', 'CPP_Virtual', 'CPP_Vtable', 'Debug', 'Elaboration_Checks', 'Eliminate', 'Export_Exception', 'Export_Function', 'Export_Object', 'Export_Procedure', 'Export_Value', 'Export_Valued_Procedure', 'Extend_System', 'External', 'External_Name_Casing', 'Finalize_Storage_Only', 'Float_Representation', 'Ident', 'Import_Exception', 'Import_Function', 'Import_Object', 'Import_Procedure', 'Import_Valued_Procedure', 'Initialize_Scalars', 'Inline_Always', 'Inline_Generic', 'Interface_Name', 'Interrupt_State', 'Keep_Names', 'License', 'Link_With', 'Linker_Alias', 'Linker_Section', 'Long_Float', 'Machine_Attribute', 'Main_Storage', 'Obsolescent', 'Passive', 'Polling', 'Profile_Warnings', 'Propagate_Exceptions', 'Psect_Object', 'Pure_Function', 'Restriction_Warnings', 'Source_File_Name', 'Source_File_Name_Project', 'Source_Reference', 'Stream_Convert', 'Style_Checks', 'Subtitle', 'Suppress_All', 'Suppress_Exception_Locations', 'Suppress_Initialization', 'Task_Info', 'Task_Name', 'Task_Storage', 'Thread_Body', 'Time_Slice', 'Title', 'Unimplemented_Unit', 'Universal_Data', 'Unreferenced', 'Unreserve_All_Interrupts', 'Use_VADS_Size', 'Validity_Checks', 'Warnings', 'Weak_External']
|
||||
let g:ada#Keywords += [{
|
||||
\ 'word': Item,
|
||||
\ 'menu': 'pragma',
|
||||
\ 'info': 'GNAT pragma.',
|
||||
\ 'kind': 'p',
|
||||
\ 'icase': 1}]
|
||||
endfor
|
||||
endif
|
||||
" 1}}}
|
||||
|
||||
" Section: g:ada#Ctags_Kinds {{{1
|
||||
"
|
||||
let g:ada#Ctags_Kinds = {
|
||||
\ 'P': ["packspec", "package specifications"],
|
||||
\ 'p': ["package", "packages"],
|
||||
\ 'T': ["typespec", "type specifications"],
|
||||
\ 't': ["type", "types"],
|
||||
\ 'U': ["subspec", "subtype specifications"],
|
||||
\ 'u': ["subtype", "subtypes"],
|
||||
\ 'c': ["component", "record type components"],
|
||||
\ 'l': ["literal", "enum type literals"],
|
||||
\ 'V': ["varspec", "variable specifications"],
|
||||
\ 'v': ["variable", "variables"],
|
||||
\ 'f': ["formal", "generic formal parameters"],
|
||||
\ 'n': ["constant", "constants"],
|
||||
\ 'x': ["exception", "user defined exceptions"],
|
||||
\ 'R': ["subprogspec", "subprogram specifications"],
|
||||
\ 'r': ["subprogram", "subprograms"],
|
||||
\ 'K': ["taskspec", "task specifications"],
|
||||
\ 'k': ["task", "tasks"],
|
||||
\ 'O': ["protectspec", "protected data specifications"],
|
||||
\ 'o': ["protected", "protected data"],
|
||||
\ 'E': ["entryspec", "task/protected data entry specifications"],
|
||||
\ 'e': ["entry", "task/protected data entries"],
|
||||
\ 'b': ["label", "labels"],
|
||||
\ 'i': ["identifier", "loop/declare identifiers"],
|
||||
\ 'a': ["autovar", "automatic variables"],
|
||||
\ 'y': ["annon", "loops and blocks with no identifier"]}
|
||||
|
||||
" Section: ada#Word (...) {{{1
|
||||
"
|
||||
" Extract current Ada word across multiple lines
|
||||
" AdaWord ([line, column])\
|
||||
"
|
||||
function ada#Word (...)
|
||||
if a:0 > 1
|
||||
let l:Line_Nr = a:1
|
||||
let l:Column_Nr = a:2 - 1
|
||||
else
|
||||
let l:Line_Nr = line('.')
|
||||
let l:Column_Nr = col('.') - 1
|
||||
endif
|
||||
|
||||
let l:Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
|
||||
|
||||
" Cope with tag searching for items in comments; if we are, don't loop
|
||||
" backards looking for previous lines
|
||||
if l:Column_Nr > strlen(l:Line)
|
||||
" We were in a comment
|
||||
let l:Line = getline(l:Line_Nr)
|
||||
let l:Search_Prev_Lines = 0
|
||||
else
|
||||
let l:Search_Prev_Lines = 1
|
||||
endif
|
||||
|
||||
" Go backwards until we find a match (Ada ID) that *doesn't* include our
|
||||
" location - i.e., the previous ID. This is because the current 'correct'
|
||||
" match will toggle matching/not matching as we traverse characters
|
||||
" backwards. Thus, we have to find the previous unrelated match, exclude
|
||||
" it, then use the next full match (ours).
|
||||
" Remember to convert vim column 'l:Column_Nr' [1..n] to string offset [0..(n-1)]
|
||||
" ... but start, here, one after the required char.
|
||||
let l:New_Column = l:Column_Nr + 1
|
||||
while 1
|
||||
let l:New_Column = l:New_Column - 1
|
||||
if l:New_Column < 0
|
||||
" Have to include previous l:Line from file
|
||||
let l:Line_Nr = l:Line_Nr - 1
|
||||
if l:Line_Nr < 1 || !l:Search_Prev_Lines
|
||||
" Start of file or matching in a comment
|
||||
let l:Line_Nr = 1
|
||||
let l:New_Column = 0
|
||||
let l:Our_Match = match (l:Line, g:ada#WordRegex )
|
||||
break
|
||||
endif
|
||||
" Get previous l:Line, and prepend it to our search string
|
||||
let l:New_Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
|
||||
let l:New_Column = strlen (l:New_Line) - 1
|
||||
let l:Column_Nr = l:Column_Nr + l:New_Column
|
||||
let l:Line = l:New_Line . l:Line
|
||||
endif
|
||||
" Check to see if this is a match excluding 'us'
|
||||
let l:Match_End = l:New_Column +
|
||||
\ matchend (strpart (l:Line,l:New_Column), g:ada#WordRegex ) - 1
|
||||
if l:Match_End >= l:New_Column &&
|
||||
\ l:Match_End < l:Column_Nr
|
||||
" Yes
|
||||
let l:Our_Match = l:Match_End+1 +
|
||||
\ match (strpart (l:Line,l:Match_End+1), g:ada#WordRegex )
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
" Got anything?
|
||||
if l:Our_Match < 0
|
||||
return ''
|
||||
else
|
||||
let l:Line = strpart (l:Line, l:Our_Match)
|
||||
endif
|
||||
|
||||
" Now simply add further lines until the match gets no bigger
|
||||
let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
|
||||
let l:Last_Line = line ('$')
|
||||
let l:Line_Nr = line ('.') + 1
|
||||
while l:Line_Nr <= l:Last_Line
|
||||
let l:Last_Match = l:Match_String
|
||||
let l:Line = l:Line .
|
||||
\ substitute (getline (l:Line_Nr), g:ada#Comment, '', '')
|
||||
let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
|
||||
if l:Match_String == l:Last_Match
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
" Strip whitespace & return
|
||||
return substitute (l:Match_String, '\s\+', '', 'g')
|
||||
endfunction ada#Word
|
||||
|
||||
" Section: ada#List_Tag (...) {{{1
|
||||
"
|
||||
" List tags in quickfix window
|
||||
"
|
||||
function ada#List_Tag (...)
|
||||
if a:0 > 1
|
||||
let l:Tag_Word = ada#Word (a:1, a:2)
|
||||
elseif a:0 > 0
|
||||
let l:Tag_Word = a:1
|
||||
else
|
||||
let l:Tag_Word = ada#Word ()
|
||||
endif
|
||||
|
||||
echo "Searching for" l:Tag_Word
|
||||
|
||||
let l:Pattern = '^' . l:Tag_Word . '$'
|
||||
let l:Tag_List = taglist (l:Pattern)
|
||||
let l:Error_List = []
|
||||
"
|
||||
" add symbols
|
||||
"
|
||||
for Tag_Item in l:Tag_List
|
||||
if l:Tag_Item['kind'] == ''
|
||||
let l:Tag_Item['kind'] = 's'
|
||||
endif
|
||||
|
||||
let l:Error_List += [
|
||||
\ l:Tag_Item['filename'] . '|' .
|
||||
\ l:Tag_Item['cmd'] . '|' .
|
||||
\ l:Tag_Item['kind'] . "\t" .
|
||||
\ l:Tag_Item['name'] ]
|
||||
endfor
|
||||
set errorformat=%f\|%l\|%m
|
||||
cexpr l:Error_List
|
||||
cwindow
|
||||
endfunction ada#List_Tag
|
||||
|
||||
" Section: ada#Jump_Tag (Word, Mode) {{{1
|
||||
"
|
||||
" Word tag - include '.' and if Ada make uppercase
|
||||
"
|
||||
function ada#Jump_Tag (Word, Mode)
|
||||
if a:Word == ''
|
||||
" Get current word
|
||||
let l:Word = ada#Word()
|
||||
if l:Word == ''
|
||||
throw "NOT_FOUND: no identifier found."
|
||||
endif
|
||||
else
|
||||
let l:Word = a:Word
|
||||
endif
|
||||
|
||||
echo "Searching for " . l:Word
|
||||
|
||||
try
|
||||
execute a:Mode l:Word
|
||||
catch /.*:E426:.*/
|
||||
let ignorecase = &ignorecase
|
||||
set ignorecase
|
||||
execute a:Mode l:Word
|
||||
let &ignorecase = ignorecase
|
||||
endtry
|
||||
|
||||
return
|
||||
endfunction ada#Jump_Tag
|
||||
|
||||
" Section: ada#Insert_Backspace () {{{1
|
||||
"
|
||||
" Backspace at end of line after auto-inserted commentstring '-- ' wipes it
|
||||
"
|
||||
function ada#Insert_Backspace ()
|
||||
let l:Line = getline ('.')
|
||||
if col ('.') > strlen (l:Line) &&
|
||||
\ match (l:Line, '-- $') != -1 &&
|
||||
\ match (&comments,'--') != -1
|
||||
return "\<bs>\<bs>\<bs>"
|
||||
else
|
||||
return "\<bs>"
|
||||
endif
|
||||
|
||||
return
|
||||
endfunction ada#InsertBackspace
|
||||
|
||||
" Section: Insert Completions {{{1
|
||||
"
|
||||
" Section: ada#User_Complete(findstart, base) {{{2
|
||||
"
|
||||
" This function is used for the 'complete' option.
|
||||
"
|
||||
function! ada#User_Complete(findstart, base)
|
||||
if a:findstart == 1
|
||||
"
|
||||
" locate the start of the word
|
||||
"
|
||||
let line = getline ('.')
|
||||
let start = col ('.') - 1
|
||||
while start > 0 && line[start - 1] =~ '\i\|'''
|
||||
let start -= 1
|
||||
endwhile
|
||||
return start
|
||||
else
|
||||
"
|
||||
" look up matches
|
||||
"
|
||||
let l:Pattern = '^' . a:base . '.*$'
|
||||
"
|
||||
" add keywords
|
||||
"
|
||||
for Tag_Item in g:ada#Keywords
|
||||
if l:Tag_Item['word'] =~? l:Pattern
|
||||
if complete_add (l:Tag_Item) == 0
|
||||
return []
|
||||
endif
|
||||
if complete_check ()
|
||||
return []
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return []
|
||||
endif
|
||||
endfunction ada#User_Complete
|
||||
|
||||
" Section: ada#Completion (cmd) {{{2
|
||||
"
|
||||
" Word completion (^N/^R/^X^]) - force '.' inclusion
|
||||
function ada#Completion (cmd)
|
||||
set iskeyword+=46
|
||||
return a:cmd . "\<C-R>=ada#Completion_End ()\<CR>"
|
||||
endfunction ada#Completion
|
||||
|
||||
" Section: ada#Completion_End () {{{2
|
||||
"
|
||||
function ada#Completion_End ()
|
||||
set iskeyword-=46
|
||||
return ''
|
||||
endfunction ada#Completion_End
|
||||
|
||||
" Section: ada#Create_Tags {{{1
|
||||
"
|
||||
function ada#Create_Tags (option)
|
||||
if a:option == 'file'
|
||||
let l:Filename = fnamemodify (bufname ('%'), ':p')
|
||||
elseif a:option == 'dir'
|
||||
let l:Filename =
|
||||
\ fnamemodify (bufname ('%'), ':p:h') . "*.ada " .
|
||||
\ fnamemodify (bufname ('%'), ':p:h') . "*.adb " .
|
||||
\ fnamemodify (bufname ('%'), ':p:h') . "*.ads"
|
||||
else
|
||||
let l:Filename = a:option
|
||||
endif
|
||||
execute '!ctags --excmd=number ' . l:Filename
|
||||
endfunction ada#Create_Tags
|
||||
|
||||
" Section: ada#Switch_Session {{{1
|
||||
"
|
||||
function ada#Switch_Session (New_Session)
|
||||
"
|
||||
" you should not save to much date into the seession since they will
|
||||
" be sourced
|
||||
"
|
||||
let l:sessionoptions=&sessionoptions
|
||||
|
||||
try
|
||||
set sessionoptions=buffers,curdir,folds,globals,resize,slash,tabpages,tabpages,unix,winpos,winsize
|
||||
|
||||
if a:New_Session != v:this_session
|
||||
"
|
||||
" We actually got a new session - otherwise there
|
||||
" is nothing to do.
|
||||
"
|
||||
if strlen (v:this_session) > 0
|
||||
execute 'mksession! ' . v:this_session
|
||||
endif
|
||||
|
||||
let v:this_session = a:New_Session
|
||||
|
||||
"if filereadable (v:this_session)
|
||||
"execute 'source ' . v:this_session
|
||||
"endif
|
||||
|
||||
augroup ada_session
|
||||
autocmd!
|
||||
autocmd VimLeavePre * execute 'mksession! ' . v:this_session
|
||||
augroup END
|
||||
|
||||
"if exists ("g:Tlist_Auto_Open") && g:Tlist_Auto_Open
|
||||
"TlistOpen
|
||||
"endif
|
||||
|
||||
endif
|
||||
finally
|
||||
let &sessionoptions=l:sessionoptions
|
||||
endtry
|
||||
|
||||
return
|
||||
endfunction ada#Switch_Session
|
||||
|
||||
" Section: GNAT Pretty Printer folding {{{1
|
||||
"
|
||||
if exists('g:ada_folding') && g:ada_folding[0] == 'g'
|
||||
"
|
||||
" Lines consisting only of ')' ';' are due to a gnat pretty bug and
|
||||
" have the same level as the line above (can't happen in the first
|
||||
" line).
|
||||
"
|
||||
let s:Fold_Collate = '^\([;)]*$\|'
|
||||
|
||||
"
|
||||
" some lone statements are folded with the line above
|
||||
"
|
||||
if stridx (g:ada_folding, 'i') >= 0
|
||||
let s:Fold_Collate .= '\s\+\<is\>$\|'
|
||||
endif
|
||||
if stridx (g:ada_folding, 'b') >= 0
|
||||
let s:Fold_Collate .= '\s\+\<begin\>$\|'
|
||||
endif
|
||||
if stridx (g:ada_folding, 'p') >= 0
|
||||
let s:Fold_Collate .= '\s\+\<private\>$\|'
|
||||
endif
|
||||
if stridx (g:ada_folding, 'x') >= 0
|
||||
let s:Fold_Collate .= '\s\+\<exception\>$\|'
|
||||
endif
|
||||
|
||||
" We also handle empty lines and
|
||||
" comments here.
|
||||
let s:Fold_Collate .= '--\)'
|
||||
|
||||
function ada#Pretty_Print_Folding (Line) " {{{2
|
||||
let l:Text = getline (a:Line)
|
||||
|
||||
if l:Text =~ s:Fold_Collate
|
||||
"
|
||||
" fold with line above
|
||||
"
|
||||
let l:Level = "="
|
||||
elseif l:Text =~ '^\s\+('
|
||||
"
|
||||
" gnat outdents a line which stards with a ( by one characters so
|
||||
" that parameters which follow are aligned.
|
||||
"
|
||||
let l:Level = (indent (a:Line) + 1) / &shiftwidth
|
||||
else
|
||||
let l:Level = indent (a:Line) / &shiftwidth
|
||||
endif
|
||||
|
||||
return l:Level
|
||||
endfunction ada#Pretty_Print_Folding " }}}2
|
||||
endif
|
||||
|
||||
" Section: Options and Menus {{{1
|
||||
"
|
||||
" Section: ada#Switch_Syntax_Options {{{2
|
||||
"
|
||||
function ada#Switch_Syntax_Option (option)
|
||||
syntax off
|
||||
if exists ('g:ada_' . a:option)
|
||||
unlet g:ada_{a:option}
|
||||
echo a:option . 'now off'
|
||||
else
|
||||
let g:ada_{a:option}=1
|
||||
echo a:option . 'now on'
|
||||
endif
|
||||
syntax on
|
||||
endfunction ada#Switch_Syntax_Option
|
||||
|
||||
" Section: ada#Map_Menu {{{2
|
||||
"
|
||||
function ada#Map_Menu (Text, Keys, Command)
|
||||
if a:Keys[0] == ':'
|
||||
execute
|
||||
\ "50amenu " .
|
||||
\ "Ada." . escape(a:Text, ' ') .
|
||||
\ "<Tab>" . a:Keys .
|
||||
\ " :" . a:Command . "<CR>"
|
||||
execute
|
||||
\ "command -buffer " .
|
||||
\ a:Keys[1:] .
|
||||
\" :" . a:Command . "<CR>"
|
||||
elseif a:Keys[0] == '<'
|
||||
execute
|
||||
\ "50amenu " .
|
||||
\ "Ada." . escape(a:Text, ' ') .
|
||||
\ "<Tab>" . a:Keys .
|
||||
\ " :" . a:Command . "<CR>"
|
||||
execute
|
||||
\ "nnoremap <buffer> " .
|
||||
\ a:Keys .
|
||||
\" :" . a:Command . "<CR>"
|
||||
execute
|
||||
\ "inoremap <buffer> " .
|
||||
\ a:Keys .
|
||||
\" <C-O>:" . a:Command . "<CR>"
|
||||
else
|
||||
if exists("g:mapleader")
|
||||
let l:leader = g:mapleader
|
||||
else
|
||||
let l:leader = '\'
|
||||
endif
|
||||
execute
|
||||
\ "50amenu " .
|
||||
\ "Ada." . escape(a:Text, ' ') .
|
||||
\ "<Tab>" . escape(l:leader . "a" . a:Keys , '\') .
|
||||
\ " :" . a:Command . "<CR>"
|
||||
execute
|
||||
\ "nnoremap <buffer>" .
|
||||
\ " <Leader>a" . a:Keys .
|
||||
\" :" . a:Command
|
||||
execute
|
||||
\ "inoremap <buffer>" .
|
||||
\ " <Leader>a" . a:Keys .
|
||||
\" <C-O>:" . a:Command
|
||||
endif
|
||||
return
|
||||
endfunction
|
||||
|
||||
" Section: ada#Map_Popup {{{2
|
||||
"
|
||||
function ada#Map_Popup (Text, Keys, Command)
|
||||
if exists("g:mapleader")
|
||||
let l:leader = g:mapleader
|
||||
else
|
||||
let l:leader = '\'
|
||||
endif
|
||||
execute
|
||||
\ "50amenu " .
|
||||
\ "PopUp." . escape(a:Text, ' ') .
|
||||
\ "<Tab>" . escape(l:leader . "a" . a:Keys , '\') .
|
||||
\ " :" . a:Command . "<CR>"
|
||||
|
||||
call ada#Map_Menu (a:Text, a:Keys, a:Command)
|
||||
return
|
||||
endfunction ada#Map_Popup
|
||||
|
||||
" }}}1
|
||||
|
||||
lockvar g:ada#WordRegex
|
||||
lockvar g:ada#DotWordRegex
|
||||
lockvar g:ada#Comment
|
||||
lockvar! g:ada#Keywords
|
||||
lockvar! g:ada#Ctags_Kinds
|
||||
|
||||
let &cpo = s:keepcpo
|
||||
unlet s:keepcpo
|
||||
|
||||
finish " 1}}}
|
||||
|
||||
"------------------------------------------------------------------------------
|
||||
" Copyright (C) 2006 Martin Krischik
|
||||
"
|
||||
" Vim is Charityware - see ":help license" or uganda.txt for licence details.
|
||||
"------------------------------------------------------------------------------
|
||||
" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
|
||||
" vim: foldmethod=marker
|
||||
|
||||
endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,5 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:V = vital#crystal#new()
|
||||
let s:P = s:V.import('Process')
|
||||
let s:C = s:V.import('ColorEcho')
|
||||
@@ -365,9 +362,6 @@ function! crystal_lang#expand(file, pos, ...) abort
|
||||
return crystal_lang#tool('expand', a:file, a:pos, get(a:, 1, ''))
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim: sw=2 sts=2 et:
|
||||
|
||||
endif
|
||||
|
||||
@@ -267,7 +267,7 @@ fu! csv#GetPat(colnr, maxcolnr, pat, allowmore) "{{{3
|
||||
" Allow space in front of the pattern, so that it works correctly
|
||||
" even if :Arrange Col has been used #100
|
||||
return '^' . csv#GetColPat(a:colnr - 1,0) .
|
||||
\ '\s*\zs' . a:pat . '\ze' . (a:allowmore ? '' : '$')
|
||||
\ '.*\zs' . a:pat . '\ze' . (a:allowmore ? '' : '$')
|
||||
else
|
||||
return '\%' . b:csv_fixed_width_cols[-1] .
|
||||
\ 'c\zs' . a:pat . '\ze' . (a:allowmore ? '' : '$')
|
||||
@@ -504,7 +504,7 @@ fu! csv#WColumn(...) "{{{3
|
||||
" Return on which column the cursor is
|
||||
let _cur = getpos('.')
|
||||
if !exists("b:csv_fixed_width_cols")
|
||||
if line('.') > 1 && mode('') != 'n'
|
||||
if line('.') > 1 && mode('') != 'n' && empty(getline('.')[0:col('.')-1])
|
||||
" in insert mode, get line from above, just in case the current
|
||||
" line is empty
|
||||
let line = getline(line('.')-1)
|
||||
@@ -1507,10 +1507,10 @@ fu! csv#AvgColumn(list) "{{{3
|
||||
endfor
|
||||
if has("float")
|
||||
let b:csv_result = printf("%.2f", sum/cnt)
|
||||
return b:csv_result
|
||||
return str2float(b:csv_result)
|
||||
else
|
||||
let b:csv_result = printf("%s", sum/cnt)
|
||||
return sum/cnt
|
||||
return b:csv_result + 0
|
||||
endif
|
||||
endif
|
||||
endfu
|
||||
@@ -1543,7 +1543,7 @@ fu! csv#VarianceColumn(list, is_population) "{{{3
|
||||
let cnt = cnt-1
|
||||
endif
|
||||
if has("float")
|
||||
let b:csv_result = printf("%.2f", sum/cnt)
|
||||
let b:csv_result = printf("%." . get(b:, 'csv_accuracy', get(g:, 'csv_accuracy', 2)) . "f", sum/cnt)
|
||||
return b:csv_result
|
||||
else
|
||||
let b:csv_result = printf("%s", sum/cnt)
|
||||
@@ -1956,8 +1956,12 @@ fu! csv#CheckHeaderLine() "{{{3
|
||||
endfu
|
||||
fu! csv#AnalyzeColumn(...) "{{{3
|
||||
let maxcolnr = csv#MaxColumns()
|
||||
if len(a:000) == 1
|
||||
let topn = 5
|
||||
if len(a:000) > 0
|
||||
let colnr = a:1
|
||||
if len(a:000) == 2
|
||||
let topn = a:2
|
||||
endif
|
||||
else
|
||||
let colnr = csv#WColumn()
|
||||
endif
|
||||
@@ -1985,8 +1989,8 @@ fu! csv#AnalyzeColumn(...) "{{{3
|
||||
let max_items = reverse(sort(values(res), s:csv_numeric_sort ? 'n' : 'csv#CSVSortValues'))
|
||||
" What about the minimum 5 items?
|
||||
let count_items = keys(res)
|
||||
if len(max_items) > 5
|
||||
call remove(max_items, 5, -1)
|
||||
if len(max_items) > topn
|
||||
call remove(max_items, topn, -1)
|
||||
call map(max_items, 'printf(''\V%s\m'', escape(v:val, ''\\''))')
|
||||
call filter(res, 'v:val =~ ''^''.join(max_items, ''\|'').''$''')
|
||||
endif
|
||||
@@ -2263,7 +2267,7 @@ fu! csv#CommandDefinitions() "{{{3
|
||||
\ ':echo csv#EvalColumn(<q-args>, "csv#SmplStdDevColumn", <line1>,<line2>)',
|
||||
\ '-nargs=? -range=% -complete=custom,csv#SortComplete')
|
||||
call csv#LocalCmd("PopStdCol",
|
||||
\ ':echo csv#EvalColumn(<q-args>, "csv#SmplStdDevColumn", <line1>,<line2>)',
|
||||
\ ':echo csv#EvalColumn(<q-args>, "csv#PopStdDevColumn", <line1>,<line2>)',
|
||||
\ '-nargs=? -range=% -complete=custom,csv#SortComplete')
|
||||
call csv#LocalCmd("UnArrangeColumn",
|
||||
\':call csv#PrepUnArrangeCol(<line1>, <line2>)',
|
||||
@@ -2311,8 +2315,8 @@ fu! csv#CommandDefinitions() "{{{3
|
||||
\ '-bang -nargs=? -range=%')
|
||||
call csv#LocalCmd("Filters", ':call csv#OutputFilters(<bang>0)',
|
||||
\ '-nargs=0 -bang')
|
||||
call csv#LocalCmd("Analyze", ':call csv#AnalyzeColumn(<args>)',
|
||||
\ '-nargs=?')
|
||||
call csv#LocalCmd("Analyze", ':call csv#AnalyzeColumn(<f-args>)',
|
||||
\ '-nargs=*' )
|
||||
call csv#LocalCmd("VertFold", ':call csv#Vertfold(<bang>0,<q-args>)',
|
||||
\ '-bang -nargs=? -range=% -complete=custom,csv#SortComplete')
|
||||
call csv#LocalCmd("CSVFixed", ':call csv#InitCSVFixedWidth()', '')
|
||||
|
||||
@@ -27,12 +27,16 @@ function! s:clearQfList(reason) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! dart#fmt(q_args) abort
|
||||
let cmd = s:FindDartFmt()
|
||||
if type(cmd) != type('') | return | endif
|
||||
function! dart#fmt(...) abort
|
||||
let l:dartfmt = s:FindDartFmt()
|
||||
if type(l:dartfmt) != type('') | return | endif
|
||||
let buffer_content = getline(1, '$')
|
||||
let args = '--stdin-name '.expand('%').' '.a:q_args
|
||||
let lines = systemlist(printf('%s %s', cmd, args), join(buffer_content, "\n"))
|
||||
let l:cmd = [l:dartfmt, '--stdin-name', shellescape(expand('%'))]
|
||||
if exists('g:dartfmt_options')
|
||||
call extend(l:cmd, g:dartfmt_options)
|
||||
endif
|
||||
call extend(l:cmd, a:000)
|
||||
let lines = systemlist(join(l:cmd), join(buffer_content, "\n"))
|
||||
" TODO(https://github.com/dart-lang/sdk/issues/38507) - Remove once the
|
||||
" tool no longer emits this line on SDK upgrades.
|
||||
if lines[-1] ==# 'Isolate creation failed'
|
||||
|
||||
@@ -1,25 +1,43 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'fish') == -1
|
||||
|
||||
function! fish#Indent()
|
||||
let l:shiftwidth = shiftwidth()
|
||||
let l:prevlnum = prevnonblank(v:lnum - 1)
|
||||
if l:prevlnum ==# 0
|
||||
return 0
|
||||
endif
|
||||
let l:indent = 0
|
||||
let l:prevline = getline(l:prevlnum)
|
||||
if l:prevline =~# '\v^\s*switch>'
|
||||
return indent(l:prevlnum) + l:shiftwidth
|
||||
elseif l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case)>'
|
||||
let l:indent = l:shiftwidth
|
||||
endif
|
||||
let l:line = getline(v:lnum)
|
||||
if l:line =~# '\v^\s*end>'
|
||||
return indent(l:prevlnum) - (l:indent ==# 0 ? l:shiftwidth : l:indent)
|
||||
elseif l:line =~# '\v^\s*%(case|else)>'
|
||||
return indent(l:prevlnum) - l:shiftwidth
|
||||
let l:shiftwidth = shiftwidth()
|
||||
let l:previndent = indent(l:prevlnum)
|
||||
let l:indent = l:previndent
|
||||
if l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|switch|case)>'
|
||||
let l:indent += l:shiftwidth
|
||||
endif
|
||||
return indent(l:prevlnum) + l:indent
|
||||
if l:line =~# '\v^\s*end>'
|
||||
let l:indent -= l:shiftwidth
|
||||
" If we're inside a case, dedent twice because it ends the switch.
|
||||
if l:prevline =~# '\v^\s*case>'
|
||||
" Previous line starts the case.
|
||||
let l:indent -= l:shiftwidth
|
||||
else
|
||||
" Scan back to a dedented line to find whether we're in a case.
|
||||
let l:i = l:prevlnum
|
||||
while l:i >= 1 && indent(l:i) >= l:previndent
|
||||
let l:i = prevnonblank(l:i - 1)
|
||||
endwhile
|
||||
if indent(l:i) < l:previndent && getline(l:i) =~# '\v^\s*case>'
|
||||
let l:indent -= l:shiftwidth
|
||||
endif
|
||||
endif
|
||||
elseif l:line =~# '\v^\s*else>'
|
||||
let l:indent -= l:shiftwidth
|
||||
elseif l:prevline !~# '\v^\s*switch>' && l:line =~# '\v^\s*case>'
|
||||
let l:indent -= l:shiftwidth
|
||||
endif
|
||||
if l:indent < 0
|
||||
return 0
|
||||
endif
|
||||
return l:indent
|
||||
endfunction
|
||||
|
||||
function! fish#Format()
|
||||
|
||||
517
autoload/fsharp.vim
Normal file
517
autoload/fsharp.vim
Normal file
@@ -0,0 +1,517 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'fsharp') == -1
|
||||
|
||||
" Vim autoload functions
|
||||
|
||||
if exists('g:loaded_autoload_fsharp')
|
||||
finish
|
||||
endif
|
||||
let g:loaded_autoload_fsharp = 1
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:prompt(msg)
|
||||
let height = &cmdheight
|
||||
if height < 2
|
||||
set cmdheight=2
|
||||
endif
|
||||
echom a:msg
|
||||
let &cmdheight = height
|
||||
endfunction
|
||||
|
||||
function! s:PlainNotification(content)
|
||||
return { 'Content': a:content }
|
||||
endfunction
|
||||
|
||||
function! s:TextDocumentIdentifier(path)
|
||||
let usr_ss_opt = &shellslash
|
||||
set shellslash
|
||||
let uri = fnamemodify(a:path, ":p")
|
||||
if uri[0] == "/"
|
||||
let uri = "file://" . uri
|
||||
else
|
||||
let uri = "file:///" . uri
|
||||
endif
|
||||
let &shellslash = usr_ss_opt
|
||||
return { 'Uri': uri }
|
||||
endfunction
|
||||
|
||||
function! s:Position(line, character)
|
||||
return { 'Line': a:line, 'Character': a:character }
|
||||
endfunction
|
||||
|
||||
function! s:TextDocumentPositionParams(documentUri, line, character)
|
||||
return {
|
||||
\ 'TextDocument': s:TextDocumentIdentifier(a:documentUri),
|
||||
\ 'Position': s:Position(a:line, a:character)
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! s:DocumentationForSymbolRequest(xmlSig, assembly)
|
||||
return {
|
||||
\ 'XmlSig': a:xmlSig,
|
||||
\ 'Assembly': a:assembly
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! s:ProjectParms(projectUri)
|
||||
return { 'Project': s:TextDocumentIdentifier(a:projectUri) }
|
||||
endfunction
|
||||
|
||||
function! s:WorkspacePeekRequest(directory, deep, excludedDirs)
|
||||
return {
|
||||
\ 'Directory': fnamemodify(a:directory, ":p"),
|
||||
\ 'Deep': a:deep,
|
||||
\ 'ExcludedDirs': a:excludedDirs
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! s:WorkspaceLoadParms(files)
|
||||
let prm = []
|
||||
for file in a:files
|
||||
call add(prm, s:TextDocumentIdentifier(file))
|
||||
endfor
|
||||
return { 'TextDocuments': prm }
|
||||
endfunction
|
||||
|
||||
function! s:FsdnRequest(query)
|
||||
return { 'Query': a:query }
|
||||
endfunction
|
||||
|
||||
function! s:call(method, params, cont)
|
||||
call LanguageClient#Call(a:method, a:params, a:cont)
|
||||
endfunction
|
||||
|
||||
function! s:signature(filePath, line, character, cont)
|
||||
return s:call('fsharp/signature', s:TextDocumentPositionParams(a:filePath, a:line, a:character), a:cont)
|
||||
endfunction
|
||||
function! s:signatureData(filePath, line, character, cont)
|
||||
return s:call('fsharp/signatureData', s:TextDocumentPositionParams(a:filePath, a:line, a:character), a:cont)
|
||||
endfunction
|
||||
function! s:lineLens(projectPath, cont)
|
||||
return s:call('fsharp/lineLens', s:ProjectParms(a:projectPath), a:cont)
|
||||
endfunction
|
||||
function! s:compilerLocation(cont)
|
||||
return s:call('fsharp/compilerLocation', {}, a:cont)
|
||||
endfunction
|
||||
function! s:compile(projectPath, cont)
|
||||
return s:call('fsharp/compile', s:ProjectParms(a:projectPath), a:cont)
|
||||
endfunction
|
||||
function! s:workspacePeek(directory, depth, excludedDirs, cont)
|
||||
return s:call('fsharp/workspacePeek', s:WorkspacePeekRequest(a:directory, a:depth, a:excludedDirs), a:cont)
|
||||
endfunction
|
||||
function! s:workspaceLoad(files, cont)
|
||||
return s:call('fsharp/workspaceLoad', s:WorkspaceLoadParms(a:files), a:cont)
|
||||
endfunction
|
||||
function! s:project(projectPath, cont)
|
||||
return s:call('fsharp/project', s:ProjectParms(a:projectPath), a:cont)
|
||||
endfunction
|
||||
function! s:fsdn(signature, cont)
|
||||
return s:call('fsharp/fsdn', s:FsdnRequest(a:signature), a:cont)
|
||||
endfunction
|
||||
function! s:f1Help(filePath, line, character, cont)
|
||||
return s:call('fsharp/f1Help', s:TextDocumentPositionParams(a:filePath, a:line, a:character), a:cont)
|
||||
endfunction
|
||||
function! fsharp#documentation(filePath, line, character, cont)
|
||||
return s:call('fsharp/documentation', s:TextDocumentPositionParams(a:filePath, a:line, a:character), a:cont)
|
||||
endfunction
|
||||
function! s:documentationSymbol(xmlSig, assembly, cont)
|
||||
return s:call('fsharp/documentationSymbol', s:DocumentationForSymbolRequest(a:xmlSig, a:assembly), a:cont)
|
||||
endfunction
|
||||
|
||||
" FSharpConfigDto from https://github.com/fsharp/FsAutoComplete/blob/master/src/FsAutoComplete/LspHelpers.fs
|
||||
"
|
||||
" * The following options seems not working with workspace/didChangeConfiguration
|
||||
" since the initialization has already completed?
|
||||
" 'AutomaticWorkspaceInit',
|
||||
" 'WorkspaceModePeekDeepLevel',
|
||||
"
|
||||
" * Changes made to linter/unused analyzer settings seems not reflected after sending them to FSAC?
|
||||
"
|
||||
let s:config_keys_camel =
|
||||
\ [
|
||||
\ {'key': 'AutomaticWorkspaceInit', 'default': 1},
|
||||
\ {'key': 'WorkspaceModePeekDeepLevel', 'default': 2},
|
||||
\ {'key': 'ExcludeProjectDirectories', 'default': []},
|
||||
\ {'key': 'keywordsAutocomplete', 'default': 1},
|
||||
\ {'key': 'ExternalAutocomplete', 'default': 0},
|
||||
\ {'key': 'Linter', 'default': 1},
|
||||
\ {'key': 'UnionCaseStubGeneration', 'default': 1},
|
||||
\ {'key': 'UnionCaseStubGenerationBody'},
|
||||
\ {'key': 'RecordStubGeneration', 'default': 1},
|
||||
\ {'key': 'RecordStubGenerationBody'},
|
||||
\ {'key': 'InterfaceStubGeneration', 'default': 1},
|
||||
\ {'key': 'InterfaceStubGenerationObjectIdentifier', 'default': 'this'},
|
||||
\ {'key': 'InterfaceStubGenerationMethodBody'},
|
||||
\ {'key': 'UnusedOpensAnalyzer', 'default': 1},
|
||||
\ {'key': 'UnusedDeclarationsAnalyzer', 'default': 1},
|
||||
\ {'key': 'SimplifyNameAnalyzer', 'default': 0},
|
||||
\ {'key': 'ResolveNamespaces', 'default': 1},
|
||||
\ {'key': 'EnableReferenceCodeLens', 'default': 1},
|
||||
\ {'key': 'EnableAnalyzers', 'default': 0},
|
||||
\ {'key': 'AnalyzersPath'},
|
||||
\ {'key': 'DisableInMemoryProjectReferences', 'default': 0},
|
||||
\ {'key': 'LineLens', 'default': {'enabled': 'replaceCodeLens', 'prefix': '//'}},
|
||||
\ {'key': 'UseSdkScripts', 'default': 1},
|
||||
\ {'key': 'dotNetRoot'},
|
||||
\ {'key': 'fsiExtraParameters', 'default': []},
|
||||
\ ]
|
||||
let s:config_keys = []
|
||||
|
||||
function! fsharp#toSnakeCase(str)
|
||||
let sn = substitute(a:str, '\(\<\u\l\+\|\l\+\)\(\u\)', '\l\1_\l\2', 'g')
|
||||
if sn == a:str | return tolower(a:str) | endif
|
||||
return sn
|
||||
endfunction
|
||||
|
||||
function! s:buildConfigKeys()
|
||||
if len(s:config_keys) == 0
|
||||
for key_camel in s:config_keys_camel
|
||||
let key = {}
|
||||
let key.snake = fsharp#toSnakeCase(key_camel.key)
|
||||
let key.camel = key_camel.key
|
||||
if has_key(key_camel, 'default')
|
||||
let key.default = key_camel.default
|
||||
endif
|
||||
call add(s:config_keys, key)
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! g:fsharp#getServerConfig()
|
||||
let fsharp = {}
|
||||
call s:buildConfigKeys()
|
||||
for key in s:config_keys
|
||||
if exists('g:fsharp#' . key.snake)
|
||||
let fsharp[key.camel] = g:fsharp#{key.snake}
|
||||
elseif exists('g:fsharp#' . key.camel)
|
||||
let fsharp[key.camel] = g:fsharp#{key.camel}
|
||||
elseif has_key(key, 'default') && g:fsharp#use_recommended_server_config
|
||||
let g:fsharp#{key.snake} = key.default
|
||||
let fsharp[key.camel] = key.default
|
||||
endif
|
||||
endfor
|
||||
return fsharp
|
||||
endfunction
|
||||
|
||||
function! g:fsharp#updateServerConfig()
|
||||
let fsharp = fsharp#getServerConfig()
|
||||
let settings = {'settings': {'FSharp': fsharp}}
|
||||
call LanguageClient#Notify('workspace/didChangeConfiguration', settings)
|
||||
endfunction
|
||||
|
||||
function! s:findWorkspace(dir, cont)
|
||||
let s:cont_findWorkspace = a:cont
|
||||
function! s:callback_findWorkspace(result)
|
||||
let result = a:result
|
||||
let content = json_decode(result.result.content)
|
||||
if len(content.Data.Found) < 1
|
||||
return []
|
||||
endif
|
||||
let workspace = { 'Type': 'none' }
|
||||
for found in content.Data.Found
|
||||
if workspace.Type == 'none'
|
||||
let workspace = found
|
||||
elseif found.Type == 'solution'
|
||||
if workspace.Type == 'project'
|
||||
let workspace = found
|
||||
else
|
||||
let curLen = len(workspace.Data.Items)
|
||||
let newLen = len(found.Data.Items)
|
||||
if newLen > curLen
|
||||
let workspace = found
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if workspace.Type == 'solution'
|
||||
call s:cont_findWorkspace([workspace.Data.Path])
|
||||
else
|
||||
call s:cont_findWorkspace(workspace.Data.Fsprojs)
|
||||
endif
|
||||
endfunction
|
||||
call s:workspacePeek(a:dir, g:fsharp#workspace_mode_peek_deep_level, g:fsharp#exclude_project_directories, function("s:callback_findWorkspace"))
|
||||
endfunction
|
||||
|
||||
let s:workspace = []
|
||||
|
||||
function! s:load(arg)
|
||||
let s:loading_workspace = a:arg
|
||||
function! s:callback_load(_)
|
||||
echo "[FSAC] Workspace loaded: " . join(s:loading_workspace, ', ')
|
||||
let s:workspace = s:workspace + s:loading_workspace
|
||||
endfunction
|
||||
call s:workspaceLoad(a:arg, function("s:callback_load"))
|
||||
endfunction
|
||||
|
||||
function! fsharp#loadProject(...)
|
||||
let prjs = []
|
||||
for proj in a:000
|
||||
call add(prjs, fnamemodify(proj, ':p'))
|
||||
endfor
|
||||
call s:load(prjs)
|
||||
endfunction
|
||||
|
||||
function! fsharp#loadWorkspaceAuto()
|
||||
if &ft == 'fsharp'
|
||||
call fsharp#updateServerConfig()
|
||||
if g:fsharp#automatic_workspace_init
|
||||
echom "[FSAC] Loading workspace..."
|
||||
let bufferDirectory = fnamemodify(resolve(expand('%:p')), ':h')
|
||||
call s:findWorkspace(bufferDirectory, function("s:load"))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#reloadProjects()
|
||||
if len(s:workspace) > 0
|
||||
function! s:callback_reloadProjects(_)
|
||||
call s:prompt("[FSAC] Workspace reloaded.")
|
||||
endfunction
|
||||
call s:workspaceLoad(s:workspace, function("s:callback_reloadProjects"))
|
||||
else
|
||||
echom "[FSAC] Workspace is empty"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#OnFSProjSave()
|
||||
if &ft == "fsharp_project" && exists('g:fsharp#automatic_reload_workspace') && g:fsharp#automatic_reload_workspace
|
||||
call fsharp#reloadProjects()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#showSignature()
|
||||
function! s:callback_showSignature(result)
|
||||
let result = a:result
|
||||
if exists('result.result.content')
|
||||
let content = json_decode(result.result.content)
|
||||
if exists('content.Data')
|
||||
echom substitute(content.Data, '\n\+$', ' ', 'g')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
call s:signature(expand('%:p'), line('.') - 1, col('.') - 1, function("s:callback_showSignature"))
|
||||
endfunction
|
||||
|
||||
function! fsharp#OnCursorMove()
|
||||
if g:fsharp#show_signature_on_cursor_move
|
||||
call fsharp#showSignature()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#showF1Help()
|
||||
let result = s:f1Help(expand('%:p'), line('.') - 1, col('.') - 1)
|
||||
echo result
|
||||
endfunction
|
||||
|
||||
function! fsharp#showTooltip()
|
||||
function! s:callback_showTooltip(result)
|
||||
let result = a:result
|
||||
if exists('result.result.content')
|
||||
let content = json_decode(result.result.content)
|
||||
if exists('content.Data')
|
||||
call LanguageClient#textDocument_hover()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
" show hover only if signature exists for the current position
|
||||
call s:signature(expand('%:p'), line('.') - 1, col('.') - 1, function("s:callback_showTooltip"))
|
||||
endfunction
|
||||
|
||||
let s:script_root_dir = expand('<sfile>:p:h') . "/../"
|
||||
let s:fsac = fnamemodify(s:script_root_dir . "fsac/fsautocomplete.dll", ":p")
|
||||
let g:fsharp#languageserver_command =
|
||||
\ ['dotnet', s:fsac,
|
||||
\ '--background-service-enabled'
|
||||
\ ]
|
||||
|
||||
function! s:download(branch)
|
||||
echom "[FSAC] Downloading FSAC. This may take a while..."
|
||||
let zip = s:script_root_dir . "fsac.zip"
|
||||
call system(
|
||||
\ 'curl -fLo ' . zip . ' --create-dirs ' .
|
||||
\ '"https://ci.appveyor.com/api/projects/fsautocomplete/fsautocomplete/artifacts/bin/pkgs/fsautocomplete.netcore.zip?branch=' . a:branch . '"'
|
||||
\ )
|
||||
if v:shell_error == 0
|
||||
call system('unzip -o -d ' . s:script_root_dir . "/fsac " . zip)
|
||||
echom "[FSAC] Updated FsAutoComplete to version " . a:branch . ""
|
||||
else
|
||||
echom "[FSAC] Failed to update FsAutoComplete"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#updateFSAC(...)
|
||||
if len(a:000) == 0
|
||||
let branch = "master"
|
||||
else
|
||||
let branch = a:000[0]
|
||||
endif
|
||||
call s:download(branch)
|
||||
endfunction
|
||||
|
||||
let s:fsi_buffer = -1
|
||||
let s:fsi_job = -1
|
||||
let s:fsi_width = 0
|
||||
let s:fsi_height = 0
|
||||
|
||||
function! s:win_gotoid_safe(winid)
|
||||
function! s:vimReturnFocus(window)
|
||||
call win_gotoid(a:window)
|
||||
redraw!
|
||||
endfunction
|
||||
if has('nvim')
|
||||
call win_gotoid(a:winid)
|
||||
else
|
||||
call timer_start(1, { -> s:vimReturnFocus(a:winid) })
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:get_fsi_command()
|
||||
let cmd = g:fsharp#fsi_command
|
||||
for prm in g:fsharp#fsi_extra_parameters
|
||||
let cmd = cmd . " " . prm
|
||||
endfor
|
||||
return cmd
|
||||
endfunction
|
||||
|
||||
function! fsharp#openFsi(returnFocus)
|
||||
if bufwinid(s:fsi_buffer) <= 0
|
||||
let fsi_command = s:get_fsi_command()
|
||||
" Neovim
|
||||
if exists('*termopen') || exists('*term_start')
|
||||
let current_win = win_getid()
|
||||
execute g:fsharp#fsi_window_command
|
||||
if s:fsi_width > 0 | execute 'vertical resize' s:fsi_width | endif
|
||||
if s:fsi_height > 0 | execute 'resize' s:fsi_height | endif
|
||||
" if window is closed but FSI is still alive then reuse it
|
||||
if s:fsi_buffer >= 0 && bufexists(str2nr(s:fsi_buffer))
|
||||
exec 'b' s:fsi_buffer
|
||||
normal G
|
||||
if !has('nvim') && mode() == 'n' | execute "normal A" | endif
|
||||
if a:returnFocus | call s:win_gotoid_safe(current_win) | endif
|
||||
" open FSI: Neovim
|
||||
elseif has('nvim')
|
||||
let s:fsi_job = termopen(fsi_command)
|
||||
if s:fsi_job > 0
|
||||
let s:fsi_buffer = bufnr("%")
|
||||
else
|
||||
close
|
||||
echom "[FSAC] Failed to open FSI."
|
||||
return -1
|
||||
endif
|
||||
" open FSI: Vim
|
||||
else
|
||||
let options = {
|
||||
\ "term_name": "F# Interactive",
|
||||
\ "curwin": 1,
|
||||
\ "term_finish": "close"
|
||||
\ }
|
||||
let s:fsi_buffer = term_start(fsi_command, options)
|
||||
if s:fsi_buffer != 0
|
||||
if exists('*term_setkill') | call term_setkill(s:fsi_buffer, "term") | endif
|
||||
let s:fsi_job = term_getjob(s:fsi_buffer)
|
||||
else
|
||||
close
|
||||
echom "[FSAC] Failed to open FSI."
|
||||
return -1
|
||||
endif
|
||||
endif
|
||||
setlocal bufhidden=hide
|
||||
normal G
|
||||
if a:returnFocus | call s:win_gotoid_safe(current_win) | endif
|
||||
return s:fsi_buffer
|
||||
else
|
||||
echom "[FSAC] Your Vim does not support terminal".
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
return s:fsi_buffer
|
||||
endfunction
|
||||
|
||||
function! fsharp#toggleFsi()
|
||||
let fsiWindowId = bufwinid(s:fsi_buffer)
|
||||
if fsiWindowId > 0
|
||||
let current_win = win_getid()
|
||||
call win_gotoid(fsiWindowId)
|
||||
let s:fsi_width = winwidth('%')
|
||||
let s:fsi_height = winheight('%')
|
||||
close
|
||||
call win_gotoid(current_win)
|
||||
else
|
||||
call fsharp#openFsi(0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#quitFsi()
|
||||
if s:fsi_buffer >= 0 && bufexists(str2nr(s:fsi_buffer))
|
||||
if has('nvim')
|
||||
let winid = bufwinid(s:fsi_buffer)
|
||||
if winid > 0 | execute "close " . winid | endif
|
||||
call jobstop(s:fsi_job)
|
||||
else
|
||||
call job_stop(s:fsi_job, "term")
|
||||
endif
|
||||
let s:fsi_buffer = -1
|
||||
let s:fsi_job = -1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! fsharp#resetFsi()
|
||||
call fsharp#quitFsi()
|
||||
return fsharp#openFsi(1)
|
||||
endfunction
|
||||
|
||||
function! fsharp#sendFsi(text)
|
||||
if fsharp#openFsi(!g:fsharp#fsi_focus_on_send) > 0
|
||||
" Neovim
|
||||
if has('nvim')
|
||||
call chansend(s:fsi_job, a:text . ";;". "\n")
|
||||
" Vim 8
|
||||
else
|
||||
call term_sendkeys(s:fsi_buffer, a:text . ";;" . "\<cr>")
|
||||
call term_wait(s:fsi_buffer)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" https://stackoverflow.com/a/6271254
|
||||
function! s:get_visual_selection()
|
||||
let [line_start, column_start] = getpos("'<")[1:2]
|
||||
let [line_end, column_end] = getpos("'>")[1:2]
|
||||
let lines = getline(line_start, line_end)
|
||||
if len(lines) == 0
|
||||
return ''
|
||||
endif
|
||||
let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
|
||||
let lines[0] = lines[0][column_start - 1:]
|
||||
return lines
|
||||
endfunction
|
||||
|
||||
function! s:get_complete_buffer()
|
||||
return join(getline(1, '$'), "\n")
|
||||
endfunction
|
||||
|
||||
function! fsharp#sendSelectionToFsi() range
|
||||
let lines = s:get_visual_selection()
|
||||
exec 'normal' len(lines) . 'j'
|
||||
let text = join(lines, "\n")
|
||||
return fsharp#sendFsi(text)
|
||||
endfunction
|
||||
|
||||
function! fsharp#sendLineToFsi()
|
||||
let text = getline('.')
|
||||
exec 'normal j'
|
||||
return fsharp#sendFsi(text)
|
||||
endfunction
|
||||
|
||||
function! fsharp#sendAllToFsi()
|
||||
let text = s:get_complete_buffer()
|
||||
return fsharp#sendFsi(text)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: sw=4 et sts=4
|
||||
|
||||
endif
|
||||
@@ -55,6 +55,10 @@ function! go#config#TermCloseOnExit() abort
|
||||
return get(g:, 'go_term_close_on_exit', 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#TermReuse() abort
|
||||
return get(g:, 'go_term_reuse', 0)
|
||||
endfunction
|
||||
|
||||
function! go#config#SetTermCloseOnExit(value) abort
|
||||
let g:go_term_close_on_exit = a:value
|
||||
endfunction
|
||||
@@ -170,8 +174,8 @@ function! go#config#EchoCommandInfo() abort
|
||||
endfunction
|
||||
|
||||
function! go#config#DocUrl() abort
|
||||
let godoc_url = get(g:, 'go_doc_url', 'https://godoc.org')
|
||||
if godoc_url isnot 'https://godoc.org'
|
||||
let godoc_url = get(g:, 'go_doc_url', 'https://pkg.go.dev')
|
||||
if godoc_url isnot 'https://pkg.go.dev'
|
||||
" strip last '/' character if available
|
||||
let last_char = strlen(godoc_url) - 1
|
||||
if godoc_url[last_char] == '/'
|
||||
@@ -266,23 +270,11 @@ function! go#config#MetalinterCommand() abort
|
||||
endfunction
|
||||
|
||||
function! go#config#MetalinterAutosaveEnabled() abort
|
||||
let l:default_enabled = ["vet", "golint"]
|
||||
|
||||
if go#config#MetalinterCommand() == "golangci-lint"
|
||||
let l:default_enabled = ["govet", "golint"]
|
||||
endif
|
||||
|
||||
return get(g:, "go_metalinter_autosave_enabled", default_enabled)
|
||||
return get(g:, "go_metalinter_autosave_enabled", ["govet", "golint"])
|
||||
endfunction
|
||||
|
||||
function! go#config#MetalinterEnabled() abort
|
||||
let l:default_enabled = ["vet", "golint", "errcheck"]
|
||||
|
||||
if go#config#MetalinterCommand() == "golangci-lint"
|
||||
let l:default_enabled = ["govet", "golint"]
|
||||
endif
|
||||
|
||||
return get(g:, "go_metalinter_enabled", default_enabled)
|
||||
return get(g:, "go_metalinter_enabled", ["vet", "golint", "errcheck"])
|
||||
endfunction
|
||||
|
||||
function! go#config#GolintBin() abort
|
||||
@@ -383,7 +375,7 @@ function! go#config#RenameCommand() abort
|
||||
endfunction
|
||||
|
||||
function! go#config#GorenameBin() abort
|
||||
return get(g:, "go_gorename_bin", "gorename")
|
||||
return get(g:, "go_gorename_bin", "gopls")
|
||||
endfunction
|
||||
|
||||
function! go#config#GorenamePrefill() abort
|
||||
@@ -508,6 +500,10 @@ function! go#config#CodeCompletionEnabled() abort
|
||||
return get(g:, "go_code_completion_enabled", 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#CodeCompletionIcase() abort
|
||||
return get(g:, "go_code_completion_icase", 0)
|
||||
endfunction
|
||||
|
||||
function! go#config#Updatetime() abort
|
||||
let go_updatetime = get(g:, 'go_updatetime', 800)
|
||||
return go_updatetime == 0 ? &updatetime : go_updatetime
|
||||
@@ -565,7 +561,7 @@ function! go#config#DiagnosticsEnabled() abort
|
||||
endfunction
|
||||
|
||||
function! go#config#GoplsOptions() abort
|
||||
return get(g:, 'go_gopls_options', [])
|
||||
return get(g:, 'go_gopls_options', ['-remote=auto'])
|
||||
endfunction
|
||||
|
||||
" Set the default value. A value of "1" is a shortcut for this, for
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
function! health#vimtex#check() abort
|
||||
call vimtex#init_options()
|
||||
|
||||
call health#report_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 health#report_warn('vimtex works best with Vim 8 or neovim')
|
||||
else
|
||||
call health#report_ok('Vim version should have full support!')
|
||||
endif
|
||||
|
||||
if !executable('bibtex')
|
||||
call health#report_warn('bibtex is not executable, so bibtex completions are disabled.')
|
||||
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 health#report_error(printf(
|
||||
\ '|g:vimtex_compiler_method| (`%s`) is not executable!',
|
||||
\ g:vimtex_compiler_method))
|
||||
return
|
||||
endif
|
||||
|
||||
let l:ok = 1
|
||||
if !executable(g:vimtex_compiler_progname)
|
||||
call health#report_warn(printf(
|
||||
\ '|g:vimtex_compiler_progname| (`%s`) is not executable!',
|
||||
\ g:vimtex_compiler_progname))
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if has('nvim')
|
||||
\ && fnamemodify(g:vimtex_compiler_progname, ':t') !=# 'nvr'
|
||||
call health#report_warn('Compiler callbacks will not work!', [
|
||||
\ '`neovim-remote` / `nvr` is required for callbacks to work with neovim',
|
||||
\ "Please also set |g:vimtex_compiler_progname| = 'nvr'",
|
||||
\ 'For more info, see :help |vimtex-faq-neovim|',
|
||||
\])
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if l:ok
|
||||
call health#report_ok('Compiler should work!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:check_plugin_clash() abort " {{{1
|
||||
let l:scriptnames = split(execute('scriptnames'), "\n")
|
||||
|
||||
let l:latexbox = !empty(filter(copy(l:scriptnames), "v:val =~# 'latex-box'"))
|
||||
if l:latexbox
|
||||
call health#report_warn('Conflicting plugin detected: LaTeX-Box')
|
||||
call health#report_info('vimtex does not work as expected when LaTeX-Box is installed!')
|
||||
call health#report_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 health#report_warn('pstree is not available',
|
||||
\ 'vimtex#view#reverse_goto is better if pstree is available.')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:check_view_general() abort " {{{1
|
||||
if executable(g:vimtex_view_general_viewer)
|
||||
call health#report_ok('General viewer should work properly!')
|
||||
else
|
||||
call health#report_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 health#report_error('Zathura is not executable!')
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if !executable('xdotool')
|
||||
call health#report_warn('Zathura requires xdotool for forward search!')
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if l:ok
|
||||
call health#report_ok('Zathura should work properly!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:check_view_mupdf() abort " {{{1
|
||||
let l:ok = 1
|
||||
|
||||
if !executable('mupdf')
|
||||
call health#report_error('MuPDF is not executable!')
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if !executable('xdotool')
|
||||
call health#report_warn('MuPDF requires xdotool for forward search!')
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if !executable('synctex')
|
||||
call health#report_warn('MuPDF requires synctex for forward search!')
|
||||
let l:ok = 0
|
||||
endif
|
||||
|
||||
if l:ok
|
||||
call health#report_ok('MuPDF should work properly!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:check_view_skim() abort " {{{1
|
||||
let l:cmd = join([
|
||||
\ 'osascript -e ',
|
||||
\ '''tell application "Finder" to POSIX path of ',
|
||||
\ '(get application file id (id of application "Skim") as alias)''',
|
||||
\])
|
||||
|
||||
if system(l:cmd)
|
||||
call health#report_error('Skim is not installed!')
|
||||
else
|
||||
call health#report_ok('Skim viewer should work!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
129
autoload/jsonnet.vim
Normal file
129
autoload/jsonnet.vim
Normal file
@@ -0,0 +1,129 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'jsonnet') == -1
|
||||
|
||||
|
||||
|
||||
" Options.
|
||||
|
||||
if !exists("g:jsonnet_command")
|
||||
let g:jsonnet_command = "jsonnet"
|
||||
endif
|
||||
|
||||
if !exists("g:jsonnet_fmt_command")
|
||||
let g:jsonnet_fmt_command = "jsonnetfmt"
|
||||
endif
|
||||
|
||||
if !exists('g:jsonnet_fmt_options')
|
||||
let g:jsonnet_fmt_options = ''
|
||||
endif
|
||||
|
||||
if !exists('g:jsonnet_fmt_fail_silently')
|
||||
let g:jsonnet_fmt_fail_silently = 1
|
||||
endif
|
||||
|
||||
|
||||
" System runs a shell command. It will reset the shell to /bin/sh for Unix-like
|
||||
" systems if it is executable.
|
||||
function! jsonnet#System(str, ...)
|
||||
let l:shell = &shell
|
||||
if executable('/bin/sh')
|
||||
let &shell = '/bin/sh'
|
||||
endif
|
||||
|
||||
try
|
||||
let l:output = call("system", [a:str] + a:000)
|
||||
return l:output
|
||||
finally
|
||||
let &shell = l:shell
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
|
||||
" CheckBinPath checks whether the given binary exists or not and returns the
|
||||
" path of the binary. It returns an empty string if it doesn't exists.
|
||||
function! jsonnet#CheckBinPath(binName)
|
||||
|
||||
if executable(a:binName)
|
||||
if exists('*exepath')
|
||||
let binPath = exepath(a:binName)
|
||||
return binPath
|
||||
else
|
||||
return a:binName
|
||||
endif
|
||||
else
|
||||
echo "vim-jsonnet: could not find '" . a:binName . "'."
|
||||
return ""
|
||||
endif
|
||||
|
||||
endfunction
|
||||
|
||||
" Format calls `jsonnetfmt ... ` on the file and replaces the file with the
|
||||
" auto formatted version. Does some primitive error checking of the
|
||||
" jsonnetfmt command too.
|
||||
function! jsonnet#Format()
|
||||
|
||||
" Save cursor position and many other things.
|
||||
let l:curw = winsaveview()
|
||||
|
||||
" Write current unsaved buffer to a temp file
|
||||
let l:tmpname = tempname()
|
||||
call writefile(getline(1, '$'), l:tmpname)
|
||||
|
||||
" get the command first so we can test it
|
||||
let l:binName = g:jsonnet_fmt_command
|
||||
|
||||
" check if the user has installed command binary.
|
||||
let l:binPath = jsonnet#CheckBinPath(l:binName)
|
||||
if empty(l:binPath)
|
||||
return
|
||||
endif
|
||||
|
||||
|
||||
" Populate the final command.
|
||||
let l:command = l:binPath
|
||||
" The inplace modification is default. Makes file management easier
|
||||
let l:command = l:command . ' -i '
|
||||
let l:command = l:command . g:jsonnet_fmt_options
|
||||
|
||||
" Execute the compiled jsonnetfmt command and save the return value
|
||||
let l:out = jsonnet#System(l:command . " " . l:tmpname)
|
||||
let l:errorCode = v:shell_error
|
||||
|
||||
if l:errorCode == 0
|
||||
" The format command succeeded Move the formatted temp file over the
|
||||
" current file and restore other settings
|
||||
|
||||
" stop undo recording
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
let l:originalFileFormat = &fileformat
|
||||
if exists("*getfperm")
|
||||
" save old file permissions
|
||||
let l:originalFPerm = getfperm(expand('%'))
|
||||
endif
|
||||
" Overwrite current file with the formatted temp file
|
||||
call rename(l:tmpname, expand('%'))
|
||||
|
||||
if exists("*setfperm") && l:originalFPerm != ''
|
||||
call setfperm(expand('%'), l:originalFPerm)
|
||||
endif
|
||||
" the file has been changed outside of vim, enable reedit
|
||||
silent edit!
|
||||
let &fileformat = l:originalFileFormat
|
||||
let &syntax = &syntax
|
||||
elseif g:jsonnet_fmt_fail_silently == 0
|
||||
" FixMe: We could leverage the errors coming from the `jsonnetfmt` and
|
||||
" give immediate feedback to the user at every save time.
|
||||
" Our inspiration, vim-go, opens a new list below the current edit
|
||||
" window and shows the errors (the output of the fmt command).
|
||||
" We are not sure whether this is desired in the vim-jsonnet community
|
||||
" or not. Nevertheless, this else block is a suitable place to benefit
|
||||
" from the `jsonnetfmt` errors.
|
||||
endif
|
||||
|
||||
" Restore our cursor/windows positions.
|
||||
call winrestview(l:curw)
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
endif
|
||||
744
autoload/ledger.vim
Normal file
744
autoload/ledger.vim
Normal file
@@ -0,0 +1,744 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ledger') == -1
|
||||
|
||||
scriptencoding utf-8
|
||||
" vim:ts=2:sw=2:sts=2:foldmethod=marker
|
||||
function! ledger#transaction_state_toggle(lnum, ...) abort
|
||||
if a:0 == 1
|
||||
let chars = a:1
|
||||
else
|
||||
let chars = ' *'
|
||||
endif
|
||||
let trans = s:transaction.from_lnum(a:lnum)
|
||||
if empty(trans) || has_key(trans, 'expr')
|
||||
return
|
||||
endif
|
||||
|
||||
let old = has_key(trans, 'state') ? trans['state'] : ' '
|
||||
let i = stridx(chars, old) + 1
|
||||
let new = chars[i >= len(chars) ? 0 : i]
|
||||
|
||||
call trans.set_state(new)
|
||||
|
||||
call setline(trans['head'], trans.format_head())
|
||||
endf
|
||||
|
||||
function! ledger#transaction_state_set(lnum, char) abort
|
||||
" modifies or sets the state of the transaction at the cursor,
|
||||
" removing the state altogether if a:char is empty
|
||||
let trans = s:transaction.from_lnum(a:lnum)
|
||||
if empty(trans) || has_key(trans, 'expr')
|
||||
return
|
||||
endif
|
||||
|
||||
call trans.set_state(a:char)
|
||||
|
||||
call setline(trans['head'], trans.format_head())
|
||||
endf
|
||||
|
||||
function! ledger#transaction_date_set(lnum, type, ...) abort
|
||||
let time = a:0 == 1 ? a:1 : localtime()
|
||||
let trans = s:transaction.from_lnum(a:lnum)
|
||||
if empty(trans) || has_key(trans, 'expr')
|
||||
return
|
||||
endif
|
||||
|
||||
let formatted = strftime(g:ledger_date_format, time)
|
||||
if has_key(trans, 'date') && ! empty(trans['date'])
|
||||
let date = split(trans['date'], '=')
|
||||
else
|
||||
let date = [formatted]
|
||||
endif
|
||||
|
||||
if a:type =~? 'effective\|actual'
|
||||
echoerr 'actual/effective arguments were replaced by primary/auxiliary'
|
||||
return
|
||||
endif
|
||||
|
||||
if a:type ==? 'primary'
|
||||
let date[0] = formatted
|
||||
elseif a:type ==? 'auxiliary'
|
||||
if time < 0
|
||||
" remove auxiliary date
|
||||
let date = [date[0]]
|
||||
else
|
||||
" set auxiliary date
|
||||
if len(date) >= 2
|
||||
let date[1] = formatted
|
||||
else
|
||||
call add(date, formatted)
|
||||
endif
|
||||
endif
|
||||
elseif a:type ==? 'unshift'
|
||||
let date = [formatted, date[0]]
|
||||
endif
|
||||
|
||||
let trans['date'] = join(date[0:1], '=')
|
||||
|
||||
call setline(trans['head'], trans.format_head())
|
||||
endf
|
||||
|
||||
" == get transactions ==
|
||||
|
||||
function! ledger#transaction_from_lnum(lnum) abort
|
||||
return s:transaction.from_lnum(a:lnum)
|
||||
endf
|
||||
|
||||
function! ledger#transactions(...) abort
|
||||
if a:0 == 2
|
||||
let lnum = a:1
|
||||
let end = a:2
|
||||
elseif a:0 == 0
|
||||
let lnum = 1
|
||||
let end = line('$')
|
||||
else
|
||||
throw 'wrong number of arguments for get_transactions()'
|
||||
return []
|
||||
endif
|
||||
|
||||
" safe view / position
|
||||
let view = winsaveview()
|
||||
let fe = &foldenable
|
||||
set nofoldenable
|
||||
|
||||
let transactions = []
|
||||
call cursor(lnum, 0)
|
||||
while lnum && lnum < end
|
||||
let trans = s:transaction.from_lnum(lnum)
|
||||
if ! empty(trans)
|
||||
call add(transactions, trans)
|
||||
call cursor(trans['tail'], 0)
|
||||
endif
|
||||
let lnum = search('^[~=[:digit:]]', 'cW')
|
||||
endw
|
||||
|
||||
" restore view / position
|
||||
let &foldenable = fe
|
||||
call winrestview(view)
|
||||
|
||||
return transactions
|
||||
endf
|
||||
|
||||
" == transaction object implementation ==
|
||||
|
||||
let s:transaction = {} "{{{1
|
||||
function! s:transaction.new() abort dict
|
||||
return copy(s:transaction)
|
||||
endf
|
||||
|
||||
function! s:transaction.from_lnum(lnum) abort dict "{{{2
|
||||
let [head, tail] = s:get_transaction_extents(a:lnum)
|
||||
if ! head
|
||||
return {}
|
||||
endif
|
||||
|
||||
let trans = copy(s:transaction)
|
||||
let trans['head'] = head
|
||||
let trans['tail'] = tail
|
||||
|
||||
" split off eventual comments at the end of line
|
||||
let line = split(getline(head), '\ze\s*\%(\t\| \);', 1)
|
||||
if len(line) > 1
|
||||
let trans['appendix'] = join(line[1:], '')
|
||||
endif
|
||||
|
||||
" parse rest of line
|
||||
" FIXME (minor): will not preserve spacing (see 'join(parts)')
|
||||
let parts = split(line[0], '\s\+')
|
||||
if parts[0] ==# '~'
|
||||
let trans['expr'] = join(parts[1:])
|
||||
return trans
|
||||
elseif parts[0] ==# '='
|
||||
let trans['auto'] = join(parts[1:])
|
||||
return trans
|
||||
elseif parts[0] !~# '^\d'
|
||||
" this case is avoided in s:get_transaction_extents(),
|
||||
" but we'll check anyway.
|
||||
return {}
|
||||
endif
|
||||
|
||||
for part in parts
|
||||
if ! has_key(trans, 'date') && part =~# '^\d'
|
||||
let trans['date'] = part
|
||||
elseif ! has_key(trans, 'code') && part =~# '^([^)]*)$'
|
||||
let trans['code'] = part[1:-2]
|
||||
elseif ! has_key(trans, 'state') && part =~# '^[[:punct:]]$'
|
||||
" the first character by itself is assumed to be the state of the transaction.
|
||||
let trans['state'] = part
|
||||
else
|
||||
" everything after date/code or state belongs to the description
|
||||
break
|
||||
endif
|
||||
call remove(parts, 0)
|
||||
endfor
|
||||
|
||||
let trans['description'] = join(parts)
|
||||
return trans
|
||||
endf "}}}
|
||||
|
||||
function! s:transaction.set_state(char) abort dict "{{{2
|
||||
if has_key(self, 'state') && a:char =~# '^\s*$'
|
||||
call remove(self, 'state')
|
||||
else
|
||||
let self['state'] = a:char
|
||||
endif
|
||||
endf "}}}
|
||||
|
||||
function! s:transaction.parse_body(...) abort dict "{{{2
|
||||
if a:0 == 2
|
||||
let head = a:1
|
||||
let tail = a:2
|
||||
elseif a:0 == 0
|
||||
let head = self['head']
|
||||
let tail = self['tail']
|
||||
else
|
||||
throw 'wrong number of arguments for parse_body()'
|
||||
return []
|
||||
endif
|
||||
|
||||
if ! head || tail <= head
|
||||
return []
|
||||
endif
|
||||
|
||||
let lnum = head
|
||||
let tags = {}
|
||||
let postings = []
|
||||
while lnum <= tail
|
||||
let line = split(getline(lnum), '\s*\%(\t\| \);', 1)
|
||||
|
||||
if line[0] =~# '^\s\+[^[:blank:];]'
|
||||
" posting
|
||||
let [state, rest] = matchlist(line[0], '^\s\+\([*!]\?\)\s*\(.*\)$')[1:2]
|
||||
if rest =~# '\t\| '
|
||||
let [account, amount] = matchlist(rest, '^\(.\{-}\)\%(\t\| \)\s*\(.\{-}\)\s*$')[1:2]
|
||||
else
|
||||
let amount = ''
|
||||
let account = matchstr(rest, '^\s*\zs.\{-}\ze\s*$')
|
||||
endif
|
||||
call add(postings, {'account': account, 'amount': amount, 'state': state})
|
||||
end
|
||||
|
||||
" where are tags to be stored?
|
||||
if empty(postings)
|
||||
" they belong to the transaction
|
||||
let tag_container = tags
|
||||
else
|
||||
" they belong to last posting
|
||||
if ! has_key(postings[-1], 'tags')
|
||||
let postings[-1]['tags'] = {}
|
||||
endif
|
||||
let tag_container = postings[-1]['tags']
|
||||
endif
|
||||
|
||||
let comment = join(line[1:], ' ;')
|
||||
if comment =~# '^\s*:'
|
||||
" tags without values
|
||||
for t in s:findall(comment, ':\zs[^:[:blank:]]\([^:]*[^:[:blank:]]\)\?\ze:')
|
||||
let tag_container[t] = ''
|
||||
endfor
|
||||
elseif comment =~# '^\s*[^:[:blank:]][^:]\+:'
|
||||
" tag with value
|
||||
let key = matchstr(comment, '^\s*\zs[^:]\+\ze:')
|
||||
if ! empty(key)
|
||||
let val = matchstr(comment, ':\s*\zs.*\ze\s*$')
|
||||
let tag_container[key] = val
|
||||
endif
|
||||
endif
|
||||
let lnum += 1
|
||||
endw
|
||||
return [tags, postings]
|
||||
endf "}}}
|
||||
|
||||
function! s:transaction.format_head() abort dict "{{{2
|
||||
if has_key(self, 'expr')
|
||||
return '~ '.self['expr']
|
||||
elseif has_key(self, 'auto')
|
||||
return '= '.self['auto']
|
||||
endif
|
||||
|
||||
let parts = []
|
||||
if has_key(self, 'date') | call add(parts, self['date']) | endif
|
||||
if has_key(self, 'state') | call add(parts, self['state']) | endif
|
||||
if has_key(self, 'code') | call add(parts, '('.self['code'].')') | endif
|
||||
if has_key(self, 'description') | call add(parts, self['description']) | endif
|
||||
|
||||
let line = join(parts)
|
||||
if has_key(self, 'appendix') | let line .= self['appendix'] | endif
|
||||
|
||||
return line
|
||||
endf "}}}
|
||||
"}}}
|
||||
|
||||
" == helper functions ==
|
||||
|
||||
" get a list of declared accounts in the buffer
|
||||
function! ledger#declared_accounts(...) abort
|
||||
if a:0 == 2
|
||||
let lnum = a:1
|
||||
let lend = a:2
|
||||
elseif a:0 == 0
|
||||
let lnum = 1
|
||||
let lend = line('$')
|
||||
else
|
||||
throw 'wrong number of arguments for ledger#declared_accounts()'
|
||||
return []
|
||||
endif
|
||||
|
||||
" save view / position
|
||||
let view = winsaveview()
|
||||
let fe = &foldenable
|
||||
set nofoldenable
|
||||
|
||||
let accounts = []
|
||||
call cursor(lnum, 0)
|
||||
while 1
|
||||
let lnum = search('^account\s', 'cW', lend)
|
||||
if !lnum || lnum > lend
|
||||
break
|
||||
endif
|
||||
|
||||
" remove comments at the end and "account" at the front
|
||||
let line = split(getline(lnum), '\s\+;')[0]
|
||||
let line = matchlist(line, 'account\s\+\(.\+\)')[1]
|
||||
|
||||
if len(line) > 1
|
||||
call add(accounts, line)
|
||||
endif
|
||||
|
||||
call cursor(lnum+1,0)
|
||||
endw
|
||||
|
||||
" restore view / position
|
||||
let &foldenable = fe
|
||||
call winrestview(view)
|
||||
|
||||
return accounts
|
||||
endf
|
||||
|
||||
function! s:get_transaction_extents(lnum) abort
|
||||
if ! (indent(a:lnum) || getline(a:lnum) =~# '^[~=[:digit:]]')
|
||||
" only do something if lnum is in a transaction
|
||||
return [0, 0]
|
||||
endif
|
||||
|
||||
" safe view / position
|
||||
let view = winsaveview()
|
||||
let fe = &foldenable
|
||||
set nofoldenable
|
||||
|
||||
call cursor(a:lnum, 0)
|
||||
let head = search('^[~=[:digit:]]', 'bcnW')
|
||||
let tail = search('^[^;[:blank:]]\S\+', 'nW')
|
||||
let tail = tail > head ? tail - 1 : line('$')
|
||||
|
||||
" restore view / position
|
||||
let &foldenable = fe
|
||||
call winrestview(view)
|
||||
|
||||
return head ? [head, tail] : [0, 0]
|
||||
endf
|
||||
|
||||
function! ledger#find_in_tree(tree, levels) abort
|
||||
if empty(a:levels)
|
||||
return []
|
||||
endif
|
||||
let results = []
|
||||
let currentlvl = a:levels[0]
|
||||
let nextlvls = a:levels[1:]
|
||||
let branches = ledger#filter_items(keys(a:tree), currentlvl)
|
||||
for branch in branches
|
||||
let exact = empty(nextlvls)
|
||||
call add(results, [branch, exact])
|
||||
if ! empty(nextlvls)
|
||||
for [result, exact] in ledger#find_in_tree(a:tree[branch], nextlvls)
|
||||
call add(results, [branch.':'.result, exact])
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
return results
|
||||
endf
|
||||
|
||||
function! ledger#filter_items(list, keyword) abort
|
||||
" return only those items that start with a specified keyword
|
||||
return filter(copy(a:list), 'v:val =~ ''^\V'.substitute(a:keyword, '\\', '\\\\', 'g').'''')
|
||||
endf
|
||||
|
||||
function! s:findall(text, rx) abort
|
||||
" returns all the matches in a string,
|
||||
" there will be overlapping matches according to :help match()
|
||||
let matches = []
|
||||
|
||||
while 1
|
||||
let m = matchstr(a:text, a:rx, 0, len(matches)+1)
|
||||
if empty(m)
|
||||
break
|
||||
endif
|
||||
|
||||
call add(matches, m)
|
||||
endw
|
||||
|
||||
return matches
|
||||
endf
|
||||
|
||||
" Move the cursor to the specified column, filling the line with spaces if necessary.
|
||||
" Ensure that at least min_spaces are added, and go to the end of the line if
|
||||
" the line is already too long
|
||||
function! s:goto_col(pos, min_spaces) abort
|
||||
exec 'normal!' '$'
|
||||
let diff = max([a:min_spaces, a:pos - virtcol('.')])
|
||||
if diff > 0 | exec 'normal!' diff . 'a ' | endif
|
||||
endf
|
||||
|
||||
" Return character position of decimal separator (multibyte safe)
|
||||
function! s:decimalpos(expr) abort
|
||||
let pos = match(a:expr, '\V' . g:ledger_decimal_sep)
|
||||
if pos > 0
|
||||
let pos = strchars(a:expr[:pos]) - 1
|
||||
endif
|
||||
return pos
|
||||
endf
|
||||
|
||||
" Align the amount expression after an account name at the decimal point.
|
||||
"
|
||||
" This function moves the amount expression of a posting so that the decimal
|
||||
" separator is aligned at the column specified by g:ledger_align_at.
|
||||
"
|
||||
" For example, after selecting:
|
||||
"
|
||||
" 2015/05/09 Some Payee
|
||||
" Expenses:Other $120,23 ; Tags here
|
||||
" Expenses:Something $-4,99
|
||||
" Expenses:More ($12,34 + $16,32)
|
||||
"
|
||||
" :'<,'>call ledger#align_commodity() produces:
|
||||
"
|
||||
" 2015/05/09 Some Payee
|
||||
" Expenses:Other $120,23 ; Tags here
|
||||
" Expenses:Something $-4,99
|
||||
" Expenses:More ($12,34 + $16,32)
|
||||
"
|
||||
function! ledger#align_commodity() abort
|
||||
" Extract the part of the line after the account name (excluding spaces):
|
||||
let l:line = getline('.')
|
||||
let rhs = matchstr(l:line, '\m^\s\+[^;[:space:]].\{-}\(\t\| \)\s*\zs.*$')
|
||||
if rhs !=# ''
|
||||
" Remove everything after the account name (including spaces):
|
||||
call setline('.', substitute(l:line, '\m^\s\+[^[:space:]].\{-}\zs\(\t\| \).*$', '', ''))
|
||||
let pos = -1
|
||||
if g:ledger_decimal_sep !=# ''
|
||||
" Find the position of the first decimal separator:
|
||||
let pos = s:decimalpos(rhs)
|
||||
endif
|
||||
if pos < 0
|
||||
" Find the position after the first digits
|
||||
let pos = matchend(rhs, '\m\d[^[:space:]]*')
|
||||
endif
|
||||
" Go to the column that allows us to align the decimal separator at g:ledger_align_at:
|
||||
if pos > 0
|
||||
call s:goto_col(g:ledger_align_at - pos - 1, 2)
|
||||
else
|
||||
call s:goto_col(g:ledger_align_at - strdisplaywidth(rhs) - 2, 2)
|
||||
endif " Append the part of the line that was previously removed:
|
||||
exe 'normal! a' . rhs
|
||||
endif
|
||||
endf
|
||||
|
||||
" Align the amount under the cursor and append/prepend the default currency.
|
||||
function! ledger#align_amount_at_cursor() abort
|
||||
" Select and cut text:
|
||||
normal! viWd
|
||||
" Find the position of the decimal separator
|
||||
let pos = s:decimalpos(@") " Returns zero when the separator is the empty string
|
||||
if pos <= 0
|
||||
let pos = len(@")
|
||||
endif
|
||||
" Paste text at the correct column and append/prepend default commodity:
|
||||
if g:ledger_commodity_before
|
||||
call s:goto_col(g:ledger_align_at - pos - len(g:ledger_default_commodity) - len(g:ledger_commodity_sep) - 1, 2)
|
||||
exe 'normal! a' . g:ledger_default_commodity . g:ledger_commodity_sep
|
||||
normal! p
|
||||
else
|
||||
call s:goto_col(g:ledger_align_at - pos - 1, 2)
|
||||
exe 'normal! pa' . g:ledger_commodity_sep . g:ledger_default_commodity
|
||||
endif
|
||||
endf
|
||||
|
||||
" Report generation {{{1
|
||||
|
||||
" Helper functions and variables {{{2
|
||||
" Position of report windows
|
||||
let s:winpos_map = {
|
||||
\ 'T': 'to new', 't': 'abo new', 'B': 'bo new', 'b': 'bel new',
|
||||
\ 'L': 'to vnew', 'l': 'abo vnew', 'R': 'bo vnew', 'r': 'bel vnew'
|
||||
\ }
|
||||
|
||||
function! s:error_message(msg) abort
|
||||
redraw " See h:echo-redraw
|
||||
echohl ErrorMsg
|
||||
echo "\r"
|
||||
echomsg a:msg
|
||||
echohl NONE
|
||||
endf
|
||||
|
||||
function! s:warning_message(msg) abort
|
||||
redraw " See h:echo-redraw
|
||||
echohl WarningMsg
|
||||
echo "\r"
|
||||
echomsg a:msg
|
||||
echohl NONE
|
||||
endf
|
||||
|
||||
" Open the quickfix/location window when it is not empty,
|
||||
" closes it if it is empty.
|
||||
"
|
||||
" Optional parameters:
|
||||
" a:1 Quickfix window title.
|
||||
" a:2 Message to show when the window is empty.
|
||||
"
|
||||
" Returns 0 if the quickfix window is empty, 1 otherwise.
|
||||
function! s:quickfix_toggle(...) abort
|
||||
if g:ledger_use_location_list
|
||||
let l:list = 'l'
|
||||
let l:open = (len(getloclist(winnr())) > 0)
|
||||
else
|
||||
let l:list = 'c'
|
||||
let l:open = (len(getqflist()) > 0)
|
||||
endif
|
||||
|
||||
if l:open
|
||||
execute (g:ledger_qf_vertical ? 'vert' : 'botright') l:list.'open' g:ledger_qf_size
|
||||
" Set local mappings to quit the quickfix window or lose focus.
|
||||
nnoremap <silent> <buffer> <tab> <c-w><c-w>
|
||||
execute 'nnoremap <silent> <buffer> q :' l:list.'close<CR>'
|
||||
" Note that the following settings do not persist (e.g., when you close and re-open the quickfix window).
|
||||
" See: https://superuser.com/questions/356912/how-do-i-change-the-quickix-title-status-bar-in-vim
|
||||
if g:ledger_qf_hide_file
|
||||
setl conceallevel=2
|
||||
setl concealcursor=nc
|
||||
syntax match qfFile /^[^|]*/ transparent conceal
|
||||
endif
|
||||
if a:0 > 0
|
||||
let w:quickfix_title = a:1
|
||||
endif
|
||||
return 1
|
||||
endif
|
||||
|
||||
execute l:list.'close'
|
||||
call s:warning_message((a:0 > 1) ? a:2 : 'No results')
|
||||
return 0
|
||||
endf
|
||||
|
||||
" Populate a quickfix/location window with data. The argument must be a String
|
||||
" or a List.
|
||||
function! s:quickfix_populate(data) abort
|
||||
" Note that cexpr/lexpr always uses the global value of errorformat
|
||||
let l:efm = &errorformat " Save global errorformat
|
||||
set errorformat=%EWhile\ parsing\ file\ \"%f\"\\,\ line\ %l:,%ZError:\ %m,%-C%.%#
|
||||
set errorformat+=%tarning:\ \"%f\"\\,\ line\ %l:\ %m
|
||||
" Format to parse command-line errors:
|
||||
set errorformat+=Error:\ %m
|
||||
" Format to parse reports:
|
||||
set errorformat+=%f:%l\ %m
|
||||
set errorformat+=%-G%.%#
|
||||
execute (g:ledger_use_location_list ? 'l' : 'c').'getexpr' 'a:data'
|
||||
let &errorformat = l:efm " Restore global errorformat
|
||||
return
|
||||
endf
|
||||
|
||||
" Build a ledger command to process the given file.
|
||||
function! s:ledger_cmd(file, args) abort
|
||||
let l:options = g:ledger_extra_options
|
||||
if len(g:ledger_date_format) > 0 && !g:ledger_is_hledger
|
||||
let l:options = join([l:options, '--date-format', g:ledger_date_format,
|
||||
\ '--input-date-format', g:ledger_date_format])
|
||||
endif
|
||||
return join([g:ledger_bin, l:options, '-f', shellescape(expand(a:file)), a:args])
|
||||
endf
|
||||
" }}}
|
||||
|
||||
function! ledger#autocomplete_and_align() abort
|
||||
if pumvisible()
|
||||
return "\<c-n>"
|
||||
endif
|
||||
" Align an amount only if there is a digit immediately before the cursor and
|
||||
" such digit is preceded by at least one space (the latter condition is
|
||||
" necessary to avoid situations where a date starting at the first column is
|
||||
" confused with a commodity to be aligned).
|
||||
if match(getline('.'), '\s.*\d\%'.col('.').'c') > -1
|
||||
normal! h
|
||||
call ledger#align_amount_at_cursor()
|
||||
return "\<c-o>A"
|
||||
endif
|
||||
return "\<c-x>\<c-o>"
|
||||
endf
|
||||
|
||||
" Use current line as input to ledger entry and replace with output. If there
|
||||
" are errors, they are echoed instead.
|
||||
function! ledger#entry() abort
|
||||
let l:output = systemlist(s:ledger_cmd(g:ledger_main, join(['entry', getline('.')])))
|
||||
" Filter out warnings
|
||||
let l:output = filter(l:output, "v:val !~? '^Warning: '")
|
||||
" Errors may occur
|
||||
if v:shell_error
|
||||
echomsg join(l:output)
|
||||
return
|
||||
endif
|
||||
" Append output so we insert instead of overwrite, then delete line
|
||||
call append('.', l:output)
|
||||
normal! "_dd
|
||||
endfunc
|
||||
|
||||
" Run an arbitrary ledger command and show the output in a new buffer. If
|
||||
" there are errors, no new buffer is opened: the errors are displayed in a
|
||||
" quickfix window instead.
|
||||
"
|
||||
" Parameters:
|
||||
" file The file to be processed.
|
||||
" args A string of Ledger command-line arguments.
|
||||
"
|
||||
" Returns:
|
||||
" Ledger's output as a String.
|
||||
function! ledger#report(file, args) abort
|
||||
let l:output = systemlist(s:ledger_cmd(a:file, a:args))
|
||||
if v:shell_error " If there are errors, show them in a quickfix/location list.
|
||||
call s:quickfix_populate(l:output)
|
||||
call s:quickfix_toggle('Errors', 'Unable to parse errors')
|
||||
endif
|
||||
return l:output
|
||||
endf
|
||||
|
||||
" Open the output of a Ledger's command in a new buffer.
|
||||
"
|
||||
" Parameters:
|
||||
" report A String containing the output of a Ledger's command.
|
||||
"
|
||||
" Returns:
|
||||
" 1 if a new buffer is created; 0 otherwise.
|
||||
function! ledger#output(report) abort
|
||||
if empty(a:report)
|
||||
call s:warning_message('No results')
|
||||
return 0
|
||||
endif
|
||||
" Open a new buffer to show Ledger's output.
|
||||
execute get(s:winpos_map, g:ledger_winpos, 'bo new')
|
||||
setlocal buftype=nofile bufhidden=wipe modifiable nobuflisted noswapfile nowrap
|
||||
call append(0, a:report)
|
||||
setlocal nomodifiable
|
||||
" Set local mappings to quit window or lose focus.
|
||||
nnoremap <silent> <buffer> <tab> <c-w><c-p>
|
||||
nnoremap <silent> <buffer> q <c-w><c-p>@=winnr('#')<cr><c-w>c
|
||||
" Add some coloring to the report
|
||||
syntax match LedgerNumber /-\@1<!\d\+\([,.]\d\+\)*/
|
||||
syntax match LedgerNegativeNumber /-\d\+\([,.]\d\+\)*/
|
||||
syntax match LedgerImproperPerc /\d\d\d\+%/
|
||||
return 1
|
||||
endf
|
||||
|
||||
" Show an arbitrary register report in a quickfix list.
|
||||
"
|
||||
" Parameters:
|
||||
" file The file to be processed
|
||||
" args A string of Ledger command-line arguments.
|
||||
function! ledger#register(file, args) abort
|
||||
let l:cmd = s:ledger_cmd(a:file, join([
|
||||
\ 'register',
|
||||
\ "--format='" . g:ledger_qf_register_format . "'",
|
||||
\ "--prepend-format='%(filename):%(beg_line) '",
|
||||
\ a:args
|
||||
\ ]))
|
||||
call s:quickfix_populate(systemlist(l:cmd))
|
||||
call s:quickfix_toggle('Register report')
|
||||
endf
|
||||
|
||||
" Reconcile the given account.
|
||||
" This function accepts a file path as a third optional argument.
|
||||
" The default is to use the value of g:ledger_main.
|
||||
"
|
||||
" Parameters:
|
||||
" file The file to be processed
|
||||
" account An account name (String)
|
||||
" target_amount The target amount (Float)
|
||||
function! ledger#reconcile(file, account, target_amount) abort
|
||||
let l:cmd = s:ledger_cmd(a:file, join([
|
||||
\ 'register',
|
||||
\ '--uncleared',
|
||||
\ "--format='" . g:ledger_qf_reconcile_format . "'",
|
||||
\ "--prepend-format='%(filename):%(beg_line) %(pending ? \"P\" : \"U\") '",
|
||||
\ shellescape(a:account)
|
||||
\ ]))
|
||||
let l:file = expand(a:file) " Needed for #show_balance() later
|
||||
call s:quickfix_populate(systemlist(l:cmd))
|
||||
if s:quickfix_toggle('Reconcile ' . a:account, 'Nothing to reconcile')
|
||||
let g:ledger_target_amount = a:target_amount
|
||||
" Show updated account balance upon saving, as long as the quickfix window is open
|
||||
augroup reconcile
|
||||
autocmd!
|
||||
execute "autocmd BufWritePost *.ldg,*.ledger call ledger#show_balance('" . l:file . "','" . a:account . "')"
|
||||
autocmd BufWipeout <buffer> call <sid>finish_reconciling()
|
||||
augroup END
|
||||
" Add refresh shortcut
|
||||
execute "nnoremap <silent> <buffer> <c-l> :<c-u>call ledger#reconcile('"
|
||||
\ . l:file . "','" . a:account . "'," . string(a:target_amount) . ')<cr>'
|
||||
call ledger#show_balance(l:file, a:account)
|
||||
endif
|
||||
endf
|
||||
|
||||
function! s:finish_reconciling() abort
|
||||
unlet g:ledger_target_amount
|
||||
augroup reconcile
|
||||
autocmd!
|
||||
augroup END
|
||||
augroup! reconcile
|
||||
endf
|
||||
|
||||
" Show the pending/cleared balance of an account.
|
||||
" This function has an optional parameter:
|
||||
"
|
||||
" a:1 An account name
|
||||
"
|
||||
" If no account if given, the account in the current line is used.
|
||||
function! ledger#show_balance(file, ...) abort
|
||||
let l:account = a:0 > 0 && !empty(a:1) ? a:1 : matchstr(getline('.'), '\m\( \|\t\)\zs\S.\{-}\ze\( \|\t\|$\)')
|
||||
if empty(l:account)
|
||||
call s:error_message('No account found')
|
||||
return
|
||||
endif
|
||||
let l:cmd = s:ledger_cmd(a:file, join([
|
||||
\ 'cleared',
|
||||
\ shellescape(l:account),
|
||||
\ '--empty',
|
||||
\ '--collapse',
|
||||
\ "--format='%(scrub(get_at(display_total, 0)))|%(scrub(get_at(display_total, 1)))|%(quantity(scrub(get_at(display_total, 1))))'",
|
||||
\ (empty(g:ledger_default_commodity) ? '' : '-X ' . shellescape(g:ledger_default_commodity))
|
||||
\ ]))
|
||||
let l:output = systemlist(l:cmd)
|
||||
" Errors may occur, for example, when the account has multiple commodities
|
||||
" and g:ledger_default_commodity is empty.
|
||||
if v:shell_error
|
||||
call s:quickfix_populate(l:output)
|
||||
call s:quickfix_toggle('Errors', 'Unable to parse errors')
|
||||
return
|
||||
endif
|
||||
let l:amounts = split(l:output[-1], '|')
|
||||
redraw " Necessary in some cases to overwrite previous messages. See :h echo-redraw
|
||||
if len(l:amounts) < 3
|
||||
call s:error_message('Could not determine balance. Did you use a valid account?')
|
||||
return
|
||||
endif
|
||||
echo g:ledger_pending_string
|
||||
echohl LedgerPending
|
||||
echon l:amounts[0]
|
||||
echohl NONE
|
||||
echon ' ' g:ledger_cleared_string
|
||||
echohl LedgerCleared
|
||||
echon l:amounts[1]
|
||||
echohl NONE
|
||||
if exists('g:ledger_target_amount')
|
||||
echon ' ' g:ledger_target_string
|
||||
echohl LedgerTarget
|
||||
echon printf('%.2f', (g:ledger_target_amount - str2float(l:amounts[2])))
|
||||
echohl NONE
|
||||
endif
|
||||
endf
|
||||
" }}}
|
||||
|
||||
endif
|
||||
244
autoload/nim.vim
Normal file
244
autoload/nim.vim
Normal file
@@ -0,0 +1,244 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nim') == -1
|
||||
|
||||
let g:nim_log = []
|
||||
let s:plugin_path = escape(expand('<sfile>:p:h'), '\')
|
||||
|
||||
if !exists("g:nim_caas_enabled")
|
||||
let g:nim_caas_enabled = 0
|
||||
endif
|
||||
|
||||
if !executable('nim')
|
||||
echoerr "the Nim compiler must be in your system's PATH"
|
||||
endif
|
||||
|
||||
if has("python3")
|
||||
exe 'py3file ' . fnameescape(s:plugin_path) . '/nim_vim.py'
|
||||
elseif has("python")
|
||||
exe 'pyfile ' . fnameescape(s:plugin_path) . '/nim_vim.py'
|
||||
endif
|
||||
|
||||
fun! nim#init()
|
||||
let cmd = printf("nim --dump.format:json --verbosity:0 dump %s", s:CurrentNimFile())
|
||||
let raw_dumpdata = system(cmd)
|
||||
if !v:shell_error && expand("%:e") == "nim"
|
||||
let false = 0 " Needed for eval of json
|
||||
let true = 1 " Needed for eval of json
|
||||
let dumpdata = eval(substitute(raw_dumpdata, "\n", "", "g"))
|
||||
|
||||
let b:nim_project_root = dumpdata['project_path']
|
||||
let b:nim_defined_symbols = dumpdata['defined_symbols']
|
||||
let b:nim_caas_enabled = g:nim_caas_enabled || index(dumpdata['defined_symbols'], 'forcecaas') != -1
|
||||
|
||||
for path in dumpdata['lib_paths']
|
||||
if finddir(path) == path
|
||||
let &l:path = path . "," . &l:path
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
let b:nim_caas_enabled = 0
|
||||
endif
|
||||
endf
|
||||
|
||||
fun! s:UpdateNimLog()
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=hide
|
||||
setlocal noswapfile
|
||||
|
||||
for entry in g:nim_log
|
||||
call append(line('$'), split(entry, "\n"))
|
||||
endfor
|
||||
|
||||
let g:nim_log = []
|
||||
|
||||
match Search /^nim\ .*/
|
||||
endf
|
||||
|
||||
augroup NimVim
|
||||
au!
|
||||
au BufEnter log://nim call s:UpdateNimLog()
|
||||
if has("python3") || has("python")
|
||||
" au QuitPre * :py nimTerminateAll()
|
||||
au VimLeavePre * :py nimTerminateAll()
|
||||
endif
|
||||
augroup END
|
||||
|
||||
command! NimLog :e log://nim
|
||||
|
||||
command! NimTerminateService
|
||||
\ :exe printf("py nimTerminateService('%s')", b:nim_project_root)
|
||||
|
||||
command! NimRestartService
|
||||
\ :exe printf("py nimRestartService('%s')", b:nim_project_root)
|
||||
|
||||
fun! s:CurrentNimFile()
|
||||
let save_cur = getpos('.')
|
||||
call cursor(0, 0, 0)
|
||||
|
||||
let PATTERN = "\\v^\\#\\s*included from \\zs.*\\ze"
|
||||
let l = search(PATTERN, "n")
|
||||
|
||||
if l != 0
|
||||
let f = matchstr(getline(l), PATTERN)
|
||||
let l:to_check = expand('%:h') . "/" . f
|
||||
else
|
||||
let l:to_check = expand("%")
|
||||
endif
|
||||
|
||||
call setpos('.', save_cur)
|
||||
return l:to_check
|
||||
endf
|
||||
|
||||
let g:nim_symbol_types = {
|
||||
\ 'skParam': 'v',
|
||||
\ 'skVar': 'v',
|
||||
\ 'skLet': 'v',
|
||||
\ 'skTemp': 'v',
|
||||
\ 'skForVar': 'v',
|
||||
\ 'skConst': 'v',
|
||||
\ 'skResult': 'v',
|
||||
\ 'skGenericParam': 't',
|
||||
\ 'skType': 't',
|
||||
\ 'skField': 'm',
|
||||
\ 'skProc': 'f',
|
||||
\ 'skMethod': 'f',
|
||||
\ 'skIterator': 'f',
|
||||
\ 'skConverter': 'f',
|
||||
\ 'skMacro': 'f',
|
||||
\ 'skTemplate': 'f',
|
||||
\ 'skEnumField': 'v',
|
||||
\ }
|
||||
|
||||
fun! NimExec(op)
|
||||
let isDirty = getbufvar(bufnr('%'), "&modified")
|
||||
if isDirty
|
||||
let tmp = tempname() . bufname("%") . "_dirty.nim"
|
||||
silent! exe ":w " . tmp
|
||||
|
||||
let cmd = printf("idetools %s --trackDirty:\"%s,%s,%d,%d\" \"%s\"",
|
||||
\ a:op, tmp, expand('%:p'), line('.'), col('.')-1, s:CurrentNimFile())
|
||||
else
|
||||
let cmd = printf("idetools %s --track:\"%s,%d,%d\" \"%s\"",
|
||||
\ a:op, expand('%:p'), line('.'), col('.')-1, s:CurrentNimFile())
|
||||
endif
|
||||
|
||||
if b:nim_caas_enabled
|
||||
exe printf("py nimExecCmd('%s', '%s', False)", b:nim_project_root, cmd)
|
||||
let output = l:py_res
|
||||
else
|
||||
let output = system("nim " . cmd)
|
||||
endif
|
||||
|
||||
call add(g:nim_log, "nim " . cmd . "\n" . output)
|
||||
return output
|
||||
endf
|
||||
|
||||
fun! NimExecAsync(op, Handler)
|
||||
let result = NimExec(a:op)
|
||||
call a:Handler(result)
|
||||
endf
|
||||
|
||||
fun! NimComplete(findstart, base)
|
||||
if b:nim_caas_enabled == 0
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:findstart
|
||||
if synIDattr(synIDtrans(synID(line("."),col("."),1)), "name") == 'Comment'
|
||||
return -1
|
||||
endif
|
||||
let line = getline('.')
|
||||
let start = col('.') - 1
|
||||
while start > 0 && line[start - 1] =~? '\w'
|
||||
let start -= 1
|
||||
endwhile
|
||||
return start
|
||||
else
|
||||
let result = []
|
||||
let sugOut = NimExec("--suggest")
|
||||
for line in split(sugOut, '\n')
|
||||
let lineData = split(line, '\t')
|
||||
if len(lineData) > 0 && lineData[0] == "sug"
|
||||
let word = split(lineData[2], '\.')[-1]
|
||||
if a:base ==? '' || word =~# '^' . a:base
|
||||
let kind = get(g:nim_symbol_types, lineData[1], '')
|
||||
let c = { 'word': word, 'kind': kind, 'menu': lineData[3], 'dup': 1 }
|
||||
call add(result, c)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endif
|
||||
endf
|
||||
|
||||
if !exists("g:neocomplcache_omni_patterns")
|
||||
let g:neocomplcache_omni_patterns = {}
|
||||
endif
|
||||
let g:neocomplcache_omni_patterns['nim'] = '[^. *\t]\.\w*'
|
||||
|
||||
if !exists('g:neocomplete#sources#omni#input_patterns')
|
||||
let g:neocomplete#sources#omni#input_patterns = {}
|
||||
endif
|
||||
let g:neocomplete#sources#omni#input_patterns['nim'] = '[^. *\t]\.\w*'
|
||||
|
||||
let g:nim_completion_callbacks = {}
|
||||
|
||||
fun! NimAsyncCmdComplete(cmd, output)
|
||||
call add(g:nim_log, a:output)
|
||||
echom g:nim_completion_callbacks
|
||||
if has_key(g:nim_completion_callbacks, a:cmd)
|
||||
let Callback = get(g:nim_completion_callbacks, a:cmd)
|
||||
call Callback(a:output)
|
||||
" remove(g:nim_completion_callbacks, a:cmd)
|
||||
else
|
||||
echom "ERROR, Unknown Command: " . a:cmd
|
||||
endif
|
||||
return 1
|
||||
endf
|
||||
|
||||
fun! GotoDefinition_nim_ready(def_output)
|
||||
if v:shell_error
|
||||
echo "nim was unable to locate the definition. exit code: " . v:shell_error
|
||||
" echoerr a:def_output
|
||||
return 0
|
||||
endif
|
||||
|
||||
let rawDef = matchstr(a:def_output, 'def\t\([^\n]*\)')
|
||||
if rawDef == ""
|
||||
echo "the current cursor position does not match any definitions"
|
||||
return 0
|
||||
endif
|
||||
|
||||
let defBits = split(rawDef, '\t')
|
||||
let file = defBits[4]
|
||||
let line = defBits[5]
|
||||
exe printf("e +%d %s", line, file)
|
||||
return 1
|
||||
endf
|
||||
|
||||
fun! GotoDefinition_nim()
|
||||
call NimExecAsync("--def", function("GotoDefinition_nim_ready"))
|
||||
endf
|
||||
|
||||
fun! FindReferences_nim()
|
||||
setloclist()
|
||||
endf
|
||||
|
||||
" Syntastic syntax checking
|
||||
fun! SyntaxCheckers_nim_nim_GetLocList()
|
||||
let makeprg = 'nim check --hints:off --listfullpaths ' . s:CurrentNimFile()
|
||||
let errorformat = &errorformat
|
||||
|
||||
return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat })
|
||||
endf
|
||||
|
||||
function! SyntaxCheckers_nim_nim_IsAvailable()
|
||||
return executable("nim")
|
||||
endfunction
|
||||
|
||||
if exists("g:SyntasticRegistry")
|
||||
call g:SyntasticRegistry.CreateAndRegisterChecker({
|
||||
\ 'filetype': 'nim',
|
||||
\ 'name': 'nim'})
|
||||
endif
|
||||
|
||||
endif
|
||||
207
autoload/polyglot.vim
Normal file
207
autoload/polyglot.vim
Normal file
@@ -0,0 +1,207 @@
|
||||
" Line continuation is used here, remove 'C' from 'cpoptions'
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
func! polyglot#Heuristics()
|
||||
" Try to detect filetype from shebang
|
||||
let l:filetype = polyglot#Shebang()
|
||||
if l:filetype != ""
|
||||
exec "setf " . l:filetype
|
||||
return
|
||||
endif
|
||||
endfunc
|
||||
|
||||
let s:interpreters = {
|
||||
\ 'osascript': 'applescript',
|
||||
\ 'tcc': 'c',
|
||||
\ 'coffee': 'coffee',
|
||||
\ 'crystal': 'crystal',
|
||||
\ 'dart': 'dart',
|
||||
\ 'elixir': 'elixir',
|
||||
\ 'escript': 'erlang',
|
||||
\ 'fish': 'fish',
|
||||
\ 'gnuplot': 'gnuplot',
|
||||
\ 'runhaskell': 'haskell',
|
||||
\ 'chakra': 'javascript',
|
||||
\ 'd8': 'javascript',
|
||||
\ 'gjs': 'javascript',
|
||||
\ 'js': 'javascript',
|
||||
\ 'node': 'javascript',
|
||||
\ 'nodejs': 'javascript',
|
||||
\ 'qjs': 'javascript',
|
||||
\ 'rhino': 'javascript',
|
||||
\ 'v8': 'javascript',
|
||||
\ 'v8-shell': 'javascript',
|
||||
\ 'julia': 'julia',
|
||||
\ 'lua': 'lua',
|
||||
\ 'moon': 'moon',
|
||||
\ 'ocaml': 'ocaml',
|
||||
\ 'ocamlrun': 'ocaml',
|
||||
\ 'ocamlscript': 'ocaml',
|
||||
\ 'cperl': 'perl',
|
||||
\ 'perl': 'perl',
|
||||
\ 'php': 'php',
|
||||
\ 'pwsh': 'ps1',
|
||||
\ 'python': 'python',
|
||||
\ 'python2': 'python',
|
||||
\ 'python3': 'python',
|
||||
\ 'qmake': 'qmake',
|
||||
\ 'Rscript': 'r',
|
||||
\ 'racket': 'racket',
|
||||
\ 'perl6': 'raku',
|
||||
\ 'raku': 'raku',
|
||||
\ 'rakudo': 'raku',
|
||||
\ 'ruby': 'ruby',
|
||||
\ 'macruby': 'ruby',
|
||||
\ 'rake': 'ruby',
|
||||
\ 'jruby': 'ruby',
|
||||
\ 'rbx': 'ruby',
|
||||
\ 'scala': 'scala',
|
||||
\ 'ash': 'sh',
|
||||
\ 'bash': 'sh',
|
||||
\ 'dash': 'sh',
|
||||
\ 'ksh': 'sh',
|
||||
\ 'mksh': 'sh',
|
||||
\ 'pdksh': 'sh',
|
||||
\ 'rc': 'sh',
|
||||
\ 'sh': 'sh',
|
||||
\ 'zsh': 'sh',
|
||||
\ 'boolector': 'smt2',
|
||||
\ 'cvc4': 'smt2',
|
||||
\ 'mathsat5': 'smt2',
|
||||
\ 'opensmt': 'smt2',
|
||||
\ 'smtinterpol': 'smt2',
|
||||
\ 'smt-rat': 'smt2',
|
||||
\ 'stp': 'smt2',
|
||||
\ 'verit': 'smt2',
|
||||
\ 'yices2': 'smt2',
|
||||
\ 'z3': 'smt2',
|
||||
\ 'deno': 'typescript',
|
||||
\ 'ts-node': 'typescript',
|
||||
\ }
|
||||
|
||||
let s:r_hashbang = '^#!\s*\(\S\+\)\s*\(.*\)\s*'
|
||||
let s:r_envflag = '%(\S\+=\S\+\|-[iS]\|--ignore-environment\|--split-string\)'
|
||||
let s:r_env = '^\%(\' . s:r_envflag . '\s\+\)*\(\S\+\)'
|
||||
|
||||
func! polyglot#Shebang()
|
||||
let l:line1 = getline(1)
|
||||
|
||||
if l:line1 !~# "^#!"
|
||||
return
|
||||
endif
|
||||
|
||||
let l:pathrest = matchlist(l:line1, s:r_hashbang)
|
||||
|
||||
if len(l:pathrest) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
let [_, l:path, l:rest; __] = l:pathrest
|
||||
|
||||
let l:script = split(l:path, "/")[-1]
|
||||
|
||||
if l:script == "env"
|
||||
let l:argspath = matchlist(l:rest, s:r_env)
|
||||
if len(l:argspath) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
let l:script = l:argspath[1]
|
||||
endif
|
||||
|
||||
if has_key(s:interpreters, l:script)
|
||||
return s:interpreters[l:script]
|
||||
endif
|
||||
|
||||
for interpreter in keys(s:interpreters)
|
||||
if l:script =~# '^' . interpreter
|
||||
return s:interpreters[interpreter]
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
func! polyglot#DetectInpFiletype()
|
||||
let line = getline(1)
|
||||
if line =~# '^\*'
|
||||
setf abaqus | return
|
||||
endif
|
||||
for lnum in range(1, min([line("$"), 500]))
|
||||
let line = getline(lnum)
|
||||
if line =~? '^header surface data'
|
||||
setf trasys | return
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
func! polyglot#DetectAsaFiletype()
|
||||
if exists("g:filetype_asa")
|
||||
exe "setf " . g:filetype_asa | return
|
||||
endif
|
||||
setf aspvbs | return
|
||||
endfunc
|
||||
|
||||
func! polyglot#DetectAspFiletype()
|
||||
if exists("g:filetype_asp")
|
||||
exe "setf " . g:filetype_asp | return
|
||||
endif
|
||||
for lnum in range(1, min([line("$"), 3]))
|
||||
let line = getline(lnum)
|
||||
if line =~? 'perlscript'
|
||||
setf aspperl | return
|
||||
endif
|
||||
endfor
|
||||
setf aspvbs | return
|
||||
endfunc
|
||||
|
||||
func! polyglot#DetectMFiletype()
|
||||
let saw_comment = 0
|
||||
for lnum in range(1, min([line("$"), 100]))
|
||||
let line = getline(lnum)
|
||||
if line =~# '^\s*/\*'
|
||||
let saw_comment = 1
|
||||
endif
|
||||
if line =~# '^\s*\(@\(interface\|class\|protocol\|property\|end\|synchronised\|selector\|implementation\)\(\<\|\>\)\|#import\s\+.\+\.h[">]\)'
|
||||
setf objc | return
|
||||
endif
|
||||
if line =~# '^\s*%'
|
||||
setf octave | return
|
||||
endif
|
||||
if line =~# '^\s*(\*'
|
||||
setf mma | return
|
||||
endif
|
||||
if line =~? '^\s*\(\(type\|var\)\(\<\|\>\)\|--\)'
|
||||
setf murphi | return
|
||||
endif
|
||||
endfor
|
||||
if saw_comment
|
||||
setf objc | return
|
||||
endif
|
||||
if exists("g:filetype_m")
|
||||
exe "setf " . g:filetype_m | return
|
||||
endif
|
||||
setf octave | return
|
||||
endfunc
|
||||
|
||||
func! polyglot#DetectFsFiletype()
|
||||
for lnum in range(1, min([line("$"), 50]))
|
||||
let line = getline(lnum)
|
||||
if line =~# '^\(: \|new-device\)'
|
||||
setf forth | return
|
||||
endif
|
||||
if line =~# '^\s*\(#light\|import\|let\|module\|namespace\|open\|type\)'
|
||||
setf fsharp | return
|
||||
endif
|
||||
if line =~# '\s*\(#version\|precision\|uniform\|varying\|vec[234]\)'
|
||||
setf glsl | return
|
||||
endif
|
||||
endfor
|
||||
if exists("g:filetype_fs")
|
||||
exe "setf " . g:filetype_fs | return
|
||||
endif
|
||||
setf forth | return
|
||||
endfunc
|
||||
|
||||
" Restore 'cpoptions'
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
36
autoload/requirements.vim
Normal file
36
autoload/requirements.vim
Normal file
@@ -0,0 +1,36 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'requirements') == -1
|
||||
|
||||
" the Requirements File Format syntax support for Vim
|
||||
" Version: 1.5.3
|
||||
" Author: raimon <raimon49@hotmail.com>
|
||||
" License: MIT LICENSE
|
||||
" The MIT License (MIT)
|
||||
"
|
||||
" Copyright (c) 2015 raimon
|
||||
"
|
||||
" 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.
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" vim: et sw=4 ts=4 sts=4:
|
||||
|
||||
endif
|
||||
@@ -55,6 +55,8 @@ function! terraform#commands(ArgLead, CmdLine, CursorPos) abort
|
||||
\ 'graph',
|
||||
\ 'import',
|
||||
\ 'init',
|
||||
\ 'login',
|
||||
\ 'logout',
|
||||
\ 'output',
|
||||
\ 'plan',
|
||||
\ 'providers',
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" 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
|
||||
|
||||
endif
|
||||
@@ -1,18 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vifm') == -1
|
||||
|
||||
" common functions for vifm command-line editing buffer filetype plugins
|
||||
" Maintainer: xaizek <xaizek@posteo.net>
|
||||
" Last Change: August 18, 2013
|
||||
|
||||
" Prepare buffer
|
||||
function! vifm#edit#Init()
|
||||
" Mappings for quick leaving the buffer (behavior similar to Command line
|
||||
" buffer in Vim)
|
||||
nnoremap <buffer> <cr> :copy 0 \| wq<cr>
|
||||
imap <buffer> <cr> <esc><cr>
|
||||
|
||||
" Start buffer editing in insert mode
|
||||
startinsert
|
||||
endfunction
|
||||
|
||||
endif
|
||||
@@ -1,35 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'vifm') == -1
|
||||
|
||||
" common functions for vifm plugin related to globals
|
||||
" Maintainer: xaizek <xaizek@posteo.net>
|
||||
" Last Change: November 03, 2018
|
||||
|
||||
" Initializes global variables to defaults unless they are already set
|
||||
function! vifm#globals#Init()
|
||||
if !exists('g:vifm_exec')
|
||||
let g:vifm_exec = 'vifm'
|
||||
endif
|
||||
|
||||
if !exists('g:vifm_exec_args')
|
||||
let g:vifm_exec_args = ''
|
||||
endif
|
||||
|
||||
if !exists('g:vifm_term')
|
||||
if has('win32')
|
||||
if filereadable('C:\Windows\system32\cmd.exe')
|
||||
let g:vifm_term = 'C:\Windows\system32\cmd.exe /C'
|
||||
else
|
||||
" If don't find use the integrate shell it work too
|
||||
let g:vifm_term = ''
|
||||
endif
|
||||
else
|
||||
let g:vifm_term = 'xterm -e'
|
||||
endif
|
||||
endif
|
||||
|
||||
if !exists('g:vifm_embed_term')
|
||||
let g:vifm_embed_term = has('gui_running')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
endif
|
||||
@@ -1,705 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#init() abort " {{{1
|
||||
call vimtex#init_options()
|
||||
|
||||
call s:init_highlights()
|
||||
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! vimtex#init_options() abort " {{{1
|
||||
call s:init_option('vimtex_compiler_enabled', 1)
|
||||
call s:init_option('vimtex_compiler_method', 'latexmk')
|
||||
call s:init_option('vimtex_compiler_progname',
|
||||
\ has('nvim') && executable('nvr')
|
||||
\ ? 'nvr'
|
||||
\ : get(v:, 'progpath', get(v:, 'progname', '')))
|
||||
call s:init_option('vimtex_compiler_callback_hooks', [])
|
||||
call s:init_option('vimtex_compiler_latexmk_engines', {})
|
||||
call s:init_option('vimtex_compiler_latexrun_engines', {})
|
||||
|
||||
call s:init_option('vimtex_complete_enabled', 1)
|
||||
call s:init_option('vimtex_complete_close_braces', 0)
|
||||
call s:init_option('vimtex_complete_ignore_case', &ignorecase)
|
||||
call s:init_option('vimtex_complete_smart_case', &smartcase)
|
||||
call s:init_option('vimtex_complete_bib', {
|
||||
\ 'simple': 0,
|
||||
\ 'menu_fmt': '[@type] @author_short (@year), "@title"',
|
||||
\ 'abbr_fmt': '',
|
||||
\ 'custom_patterns': [],
|
||||
\})
|
||||
call s:init_option('vimtex_complete_ref', {
|
||||
\ 'custom_patterns': [],
|
||||
\})
|
||||
|
||||
call s:init_option('vimtex_delim_timeout', 300)
|
||||
call s:init_option('vimtex_delim_insert_timeout', 60)
|
||||
call s:init_option('vimtex_delim_stopline', 500)
|
||||
|
||||
call s:init_option('vimtex_include_search_enabled', 1)
|
||||
|
||||
call s:init_option('vimtex_doc_enabled', 1)
|
||||
call s:init_option('vimtex_doc_handlers', [])
|
||||
|
||||
call s:init_option('vimtex_echo_verbose_input', 1)
|
||||
|
||||
call s:init_option('vimtex_env_change_autofill', 0)
|
||||
|
||||
if &diff
|
||||
let g:vimtex_fold_enabled = 0
|
||||
else
|
||||
call s:init_option('vimtex_fold_enabled', 0)
|
||||
endif
|
||||
call s:init_option('vimtex_fold_manual', 0)
|
||||
call s:init_option('vimtex_fold_levelmarker', '*')
|
||||
call s:init_option('vimtex_fold_types', {})
|
||||
call s:init_option('vimtex_fold_types_defaults', {
|
||||
\ 'preamble' : {},
|
||||
\ 'comments' : { 'enabled' : 0 },
|
||||
\ 'envs' : {
|
||||
\ 'blacklist' : [],
|
||||
\ 'whitelist' : [],
|
||||
\ },
|
||||
\ 'env_options' : {},
|
||||
\ 'markers' : {},
|
||||
\ 'sections' : {
|
||||
\ 'parse_levels' : 0,
|
||||
\ 'sections' : [
|
||||
\ 'part',
|
||||
\ 'chapter',
|
||||
\ 'section',
|
||||
\ 'subsection',
|
||||
\ 'subsubsection',
|
||||
\ ],
|
||||
\ 'parts' : [
|
||||
\ 'appendix',
|
||||
\ 'frontmatter',
|
||||
\ 'mainmatter',
|
||||
\ 'backmatter',
|
||||
\ ],
|
||||
\ },
|
||||
\ 'cmd_single' : {
|
||||
\ 'cmds' : [
|
||||
\ 'hypersetup',
|
||||
\ 'tikzset',
|
||||
\ 'pgfplotstableread',
|
||||
\ 'lstset',
|
||||
\ ],
|
||||
\ },
|
||||
\ 'cmd_single_opt' : {
|
||||
\ 'cmds' : [
|
||||
\ 'usepackage',
|
||||
\ 'includepdf',
|
||||
\ ],
|
||||
\ },
|
||||
\ 'cmd_multi' : {
|
||||
\ 'cmds' : [
|
||||
\ '%(re)?new%(command|environment)',
|
||||
\ 'providecommand',
|
||||
\ 'presetkeys',
|
||||
\ 'Declare%(Multi|Auto)?CiteCommand',
|
||||
\ 'Declare%(Index)?%(Field|List|Name)%(Format|Alias)',
|
||||
\ ],
|
||||
\ },
|
||||
\ 'cmd_addplot' : {
|
||||
\ 'cmds' : [
|
||||
\ 'addplot[+3]?',
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
call s:init_option('vimtex_format_enabled', 0)
|
||||
|
||||
call s:init_option('vimtex_imaps_enabled', 1)
|
||||
call s:init_option('vimtex_imaps_disabled', [])
|
||||
call s:init_option('vimtex_imaps_list', [
|
||||
\ { 'lhs' : '0', 'rhs' : '\emptyset' },
|
||||
\ { 'lhs' : '6', 'rhs' : '\partial' },
|
||||
\ { 'lhs' : '8', 'rhs' : '\infty' },
|
||||
\ { 'lhs' : '=', 'rhs' : '\equiv' },
|
||||
\ { 'lhs' : '\', 'rhs' : '\setminus' },
|
||||
\ { 'lhs' : '.', 'rhs' : '\cdot' },
|
||||
\ { 'lhs' : '*', 'rhs' : '\times' },
|
||||
\ { 'lhs' : '<', 'rhs' : '\langle' },
|
||||
\ { 'lhs' : '>', 'rhs' : '\rangle' },
|
||||
\ { 'lhs' : 'H', 'rhs' : '\hbar' },
|
||||
\ { 'lhs' : '+', 'rhs' : '\dagger' },
|
||||
\ { 'lhs' : '[', 'rhs' : '\subseteq' },
|
||||
\ { 'lhs' : ']', 'rhs' : '\supseteq' },
|
||||
\ { 'lhs' : '(', 'rhs' : '\subset' },
|
||||
\ { 'lhs' : ')', 'rhs' : '\supset' },
|
||||
\ { 'lhs' : 'A', 'rhs' : '\forall' },
|
||||
\ { 'lhs' : 'E', 'rhs' : '\exists' },
|
||||
\ { 'lhs' : 'jj', 'rhs' : '\downarrow' },
|
||||
\ { 'lhs' : 'jJ', 'rhs' : '\Downarrow' },
|
||||
\ { 'lhs' : 'jk', 'rhs' : '\uparrow' },
|
||||
\ { 'lhs' : 'jK', 'rhs' : '\Uparrow' },
|
||||
\ { 'lhs' : 'jh', 'rhs' : '\leftarrow' },
|
||||
\ { 'lhs' : 'jH', 'rhs' : '\Leftarrow' },
|
||||
\ { 'lhs' : 'jl', 'rhs' : '\rightarrow' },
|
||||
\ { 'lhs' : 'jL', 'rhs' : '\Rightarrow' },
|
||||
\ { 'lhs' : 'a', 'rhs' : '\alpha' },
|
||||
\ { 'lhs' : 'b', 'rhs' : '\beta' },
|
||||
\ { 'lhs' : 'c', 'rhs' : '\chi' },
|
||||
\ { 'lhs' : 'd', 'rhs' : '\delta' },
|
||||
\ { 'lhs' : 'e', 'rhs' : '\epsilon' },
|
||||
\ { 'lhs' : 'f', 'rhs' : '\phi' },
|
||||
\ { 'lhs' : 'g', 'rhs' : '\gamma' },
|
||||
\ { 'lhs' : 'h', 'rhs' : '\eta' },
|
||||
\ { 'lhs' : 'i', 'rhs' : '\iota' },
|
||||
\ { 'lhs' : 'k', 'rhs' : '\kappa' },
|
||||
\ { 'lhs' : 'l', 'rhs' : '\lambda' },
|
||||
\ { 'lhs' : 'm', 'rhs' : '\mu' },
|
||||
\ { 'lhs' : 'n', 'rhs' : '\nu' },
|
||||
\ { 'lhs' : 'p', 'rhs' : '\pi' },
|
||||
\ { 'lhs' : 'q', 'rhs' : '\theta' },
|
||||
\ { 'lhs' : 'r', 'rhs' : '\rho' },
|
||||
\ { 'lhs' : 's', 'rhs' : '\sigma' },
|
||||
\ { 'lhs' : 't', 'rhs' : '\tau' },
|
||||
\ { 'lhs' : 'y', 'rhs' : '\psi' },
|
||||
\ { 'lhs' : 'u', 'rhs' : '\upsilon' },
|
||||
\ { 'lhs' : 'w', 'rhs' : '\omega' },
|
||||
\ { 'lhs' : 'z', 'rhs' : '\zeta' },
|
||||
\ { 'lhs' : 'x', 'rhs' : '\xi' },
|
||||
\ { 'lhs' : 'G', 'rhs' : '\Gamma' },
|
||||
\ { 'lhs' : 'D', 'rhs' : '\Delta' },
|
||||
\ { 'lhs' : 'F', 'rhs' : '\Phi' },
|
||||
\ { 'lhs' : 'G', 'rhs' : '\Gamma' },
|
||||
\ { 'lhs' : 'L', 'rhs' : '\Lambda' },
|
||||
\ { 'lhs' : 'P', 'rhs' : '\Pi' },
|
||||
\ { 'lhs' : 'Q', 'rhs' : '\Theta' },
|
||||
\ { 'lhs' : 'S', 'rhs' : '\Sigma' },
|
||||
\ { 'lhs' : 'U', 'rhs' : '\Upsilon' },
|
||||
\ { 'lhs' : 'W', 'rhs' : '\Omega' },
|
||||
\ { 'lhs' : 'X', 'rhs' : '\Xi' },
|
||||
\ { 'lhs' : 'Y', 'rhs' : '\Psi' },
|
||||
\ { 'lhs' : 've', 'rhs' : '\varepsilon' },
|
||||
\ { 'lhs' : 'vf', 'rhs' : '\varphi' },
|
||||
\ { 'lhs' : 'vk', 'rhs' : '\varkappa' },
|
||||
\ { 'lhs' : 'vq', 'rhs' : '\vartheta' },
|
||||
\ { 'lhs' : 'vr', 'rhs' : '\varrho' },
|
||||
\ { 'lhs' : '/', 'rhs' : 'vimtex#imaps#style_math("slashed")', 'expr' : 1, 'leader' : '#'},
|
||||
\ { 'lhs' : 'b', 'rhs' : 'vimtex#imaps#style_math("mathbf")', 'expr' : 1, 'leader' : '#'},
|
||||
\ { 'lhs' : 'f', 'rhs' : 'vimtex#imaps#style_math("mathfrak")', 'expr' : 1, 'leader' : '#'},
|
||||
\ { 'lhs' : 'c', 'rhs' : 'vimtex#imaps#style_math("mathcal")', 'expr' : 1, 'leader' : '#'},
|
||||
\ { 'lhs' : '-', 'rhs' : 'vimtex#imaps#style_math("overline")', 'expr' : 1, 'leader' : '#'},
|
||||
\ { 'lhs' : 'B', 'rhs' : 'vimtex#imaps#style_math("mathbb")', 'expr' : 1, 'leader' : '#'},
|
||||
\])
|
||||
|
||||
call s:init_option('vimtex_mappings_enabled', 1)
|
||||
call s:init_option('vimtex_mappings_disable', {})
|
||||
|
||||
call s:init_option('vimtex_matchparen_enabled', 1)
|
||||
call s:init_option('vimtex_motion_enabled', 1)
|
||||
|
||||
call s:init_option('vimtex_labels_enabled', 1)
|
||||
call s:init_option('vimtex_labels_refresh_always', 1)
|
||||
|
||||
call s:init_option('vimtex_parser_bib_backend', 'bibtex')
|
||||
|
||||
call s:init_option('vimtex_quickfix_enabled', 1)
|
||||
call s:init_option('vimtex_quickfix_method', 'latexlog')
|
||||
call s:init_option('vimtex_quickfix_autojump', '0')
|
||||
call s:init_option('vimtex_quickfix_ignore_filters', [])
|
||||
call s:init_option('vimtex_quickfix_mode', '2')
|
||||
call s:init_option('vimtex_quickfix_open_on_warning', '1')
|
||||
call s:init_option('vimtex_quickfix_blgparser', {})
|
||||
call s:init_option('vimtex_quickfix_autoclose_after_keystrokes', '0')
|
||||
|
||||
call s:init_option('vimtex_syntax_enabled', 1)
|
||||
call s:init_option('vimtex_syntax_nested', {
|
||||
\ 'aliases' : {
|
||||
\ 'C' : 'c',
|
||||
\ 'csharp' : 'cs',
|
||||
\ },
|
||||
\ 'ignored' : {
|
||||
\ 'cs' : [
|
||||
\ 'csBraces',
|
||||
\ ],
|
||||
\ 'python' : [
|
||||
\ 'pythonEscape',
|
||||
\ 'pythonBEscape',
|
||||
\ 'pythonBytesEscape',
|
||||
\ ],
|
||||
\ 'java' : [
|
||||
\ 'javaError',
|
||||
\ ],
|
||||
\ 'haskell' : [
|
||||
\ 'hsVarSym',
|
||||
\ ],
|
||||
\ }
|
||||
\})
|
||||
call s:init_option('vimtex_syntax_autoload_packages', ['amsmath'])
|
||||
|
||||
call s:init_option('vimtex_texcount_custom_arg', '')
|
||||
|
||||
call s:init_option('vimtex_text_obj_enabled', 1)
|
||||
call s:init_option('vimtex_text_obj_variant', 'auto')
|
||||
call s:init_option('vimtex_text_obj_linewise_operators', ['d', 'y'])
|
||||
|
||||
call s:init_option('vimtex_toc_enabled', 1)
|
||||
call s:init_option('vimtex_toc_custom_matchers', [])
|
||||
call s:init_option('vimtex_toc_show_preamble', 1)
|
||||
call s:init_option('vimtex_toc_todo_labels', {
|
||||
\ 'TODO': 'TODO: ',
|
||||
\ 'FIXME': 'FIXME: '
|
||||
\})
|
||||
call s:init_option('vimtex_toc_config', {
|
||||
\ 'name' : 'Table of contents (vimtex)',
|
||||
\ 'mode' : 1,
|
||||
\ 'fold_enable' : 0,
|
||||
\ 'fold_level_start' : -1,
|
||||
\ 'hide_line_numbers' : 1,
|
||||
\ 'hotkeys_enabled' : 0,
|
||||
\ 'hotkeys' : 'abcdeilmnopuvxyz',
|
||||
\ 'hotkeys_leader' : ';',
|
||||
\ 'layer_status' : {
|
||||
\ 'content': 1,
|
||||
\ 'label': 1,
|
||||
\ 'todo': 1,
|
||||
\ 'include': 1,
|
||||
\ },
|
||||
\ 'layer_keys' : {
|
||||
\ 'content': 'C',
|
||||
\ 'label': 'L',
|
||||
\ 'todo': 'T',
|
||||
\ 'include': 'I',
|
||||
\ },
|
||||
\ 'resize' : 0,
|
||||
\ 'refresh_always' : 1,
|
||||
\ 'show_help' : 1,
|
||||
\ 'show_numbers' : 1,
|
||||
\ 'split_pos' : 'vert leftabove',
|
||||
\ 'split_width' : 30,
|
||||
\ 'tocdepth' : 3,
|
||||
\ 'todo_sorted' : 1,
|
||||
\})
|
||||
|
||||
call s:init_option('vimtex_view_enabled', 1)
|
||||
call s:init_option('vimtex_view_automatic', 1)
|
||||
call s:init_option('vimtex_view_method', 'general')
|
||||
call s:init_option('vimtex_view_use_temp_files', 0)
|
||||
call s:init_option('vimtex_view_forward_search_on_start', 1)
|
||||
|
||||
" OS dependent defaults
|
||||
let l:os = vimtex#util#get_os()
|
||||
if l:os ==# 'win'
|
||||
if executable('SumatraPDF')
|
||||
call s:init_option('vimtex_view_general_viewer', 'SumatraPDF')
|
||||
call s:init_option('vimtex_view_general_options',
|
||||
\ '-reuse-instance -forward-search @tex @line @pdf')
|
||||
call s:init_option('vimtex_view_general_options_latexmk',
|
||||
\ 'reuse-instance')
|
||||
elseif executable('mupdf')
|
||||
call s:init_option('vimtex_view_general_viewer', 'mupdf')
|
||||
else
|
||||
call s:init_option('vimtex_view_general_viewer', '')
|
||||
endif
|
||||
else
|
||||
call s:init_option('vimtex_view_general_viewer', get({
|
||||
\ 'linux' : 'xdg-open',
|
||||
\ 'mac' : 'open',
|
||||
\ 'win' : 'start',
|
||||
\}, l:os, ''))
|
||||
call s:init_option('vimtex_view_general_options', '@pdf')
|
||||
call s:init_option('vimtex_view_general_options_latexmk', '')
|
||||
endif
|
||||
|
||||
call s:init_option('vimtex_view_mupdf_options', '')
|
||||
call s:init_option('vimtex_view_mupdf_send_keys', '')
|
||||
call s:init_option('vimtex_view_skim_activate', 0)
|
||||
call s:init_option('vimtex_view_skim_reading_bar', 1)
|
||||
call s:init_option('vimtex_view_zathura_options', '')
|
||||
call s:init_option('vimtex_view_zathura_check_libsynctex', 1)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#check_plugin_clash() abort " {{{1
|
||||
let l:scriptnames = vimtex#util#command('scriptnames')
|
||||
|
||||
let l:latexbox = !empty(filter(copy(l:scriptnames), "v:val =~# 'latex-box'"))
|
||||
if l: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
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:init_option(option, default) abort " {{{1
|
||||
let l:option = 'g:' . a:option
|
||||
if !exists(l:option)
|
||||
let {l:option} = a:default
|
||||
elseif type(a:default) == type({})
|
||||
call vimtex#util#extend_recursive({l:option}, a:default, 'keep')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:init_highlights() abort " {{{1
|
||||
for [l:name, l:target] in [
|
||||
\ ['VimtexImapsArrow', 'Comment'],
|
||||
\ ['VimtexImapsLhs', 'ModeMsg'],
|
||||
\ ['VimtexImapsRhs', 'ModeMsg'],
|
||||
\ ['VimtexImapsWrapper', 'Type'],
|
||||
\ ['VimtexInfo', 'Question'],
|
||||
\ ['VimtexInfoTitle', 'PreProc'],
|
||||
\ ['VimtexInfoKey', 'PreProc'],
|
||||
\ ['VimtexInfoValue', 'Statement'],
|
||||
\ ['VimtexInfoOther', 'Normal'],
|
||||
\ ['VimtexMsg', 'ModeMsg'],
|
||||
\ ['VimtexSuccess', 'Statement'],
|
||||
\ ['VimtexTocHelp', 'helpVim'],
|
||||
\ ['VimtexTocHelpKey', 'ModeMsg'],
|
||||
\ ['VimtexTocHelpLayerOn', 'Statement'],
|
||||
\ ['VimtexTocHelpLayerOff', 'Comment'],
|
||||
\ ['VimtexTocTodo', 'Todo'],
|
||||
\ ['VimtexTocNum', 'Number'],
|
||||
\ ['VimtexTocSec0', 'Title'],
|
||||
\ ['VimtexTocSec1', 'Normal'],
|
||||
\ ['VimtexTocSec2', 'helpVim'],
|
||||
\ ['VimtexTocSec3', 'NonText'],
|
||||
\ ['VimtexTocSec4', 'Comment'],
|
||||
\ ['VimtexTocHotkey', 'Comment'],
|
||||
\ ['VimtexTocLabelsSecs', 'Statement'],
|
||||
\ ['VimtexTocLabelsEq', 'PreProc'],
|
||||
\ ['VimtexTocLabelsFig', 'Identifier'],
|
||||
\ ['VimtexTocLabelsTab', 'String'],
|
||||
\ ['VimtexTocIncl', 'Number'],
|
||||
\ ['VimtexTocInclPath', 'Normal'],
|
||||
\ ['VimtexWarning', 'WarningMsg'],
|
||||
\ ['VimtexError', 'ErrorMsg'],
|
||||
\]
|
||||
if !hlexists(l:name)
|
||||
silent execute 'highlight default link' l:name l:target
|
||||
endif
|
||||
endfor
|
||||
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
|
||||
" Set Vim options
|
||||
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=.sty,.tex,.cls
|
||||
setlocal comments=sO:%\ -,mO:%\ \ ,eO:%%,:%
|
||||
setlocal commentstring=%%s
|
||||
setlocal iskeyword+=:
|
||||
setlocal includeexpr=vimtex#include#expr()
|
||||
let &l:include = g:vimtex#re#tex_include
|
||||
let &l:define = '\\\([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip'
|
||||
let &l:define .= '\|toks\)\=def\|\\font\|\\\(future\)\=let'
|
||||
let &l:define .= '\|\\new\(count\|dimen\|skip'
|
||||
let &l:define .= '\|muskip\|box\|toks\|read\|write\|fam\|insert\)'
|
||||
let &l:define .= '\|\\\(re\)\=new\(boolean\|command\|counter\|environment'
|
||||
let &l:define .= '\|font\|if\|length\|savebox'
|
||||
let &l:define .= '\|theorem\(style\)\=\)\s*\*\=\s*{\='
|
||||
let &l:define .= '\|DeclareMathOperator\s*{\=\s*'
|
||||
|
||||
" 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
|
||||
for l:mod in s:modules
|
||||
if index(get(b:vimtex, 'disabled_modules', []), l:mod) >= 0 | continue | endif
|
||||
|
||||
try
|
||||
call vimtex#{l:mod}#init_buffer()
|
||||
catch /E117.*#init_/
|
||||
catch /E127.*vimtex#profile#/
|
||||
endtry
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:init_default_mappings() abort " {{{1
|
||||
if !g:vimtex_mappings_enabled | return | endif
|
||||
|
||||
function! s:map(mode, lhs, rhs, ...) abort
|
||||
if !hasmapto(a:rhs, a:mode)
|
||||
\ && index(get(g:vimtex_mappings_disable, a:mode, []), a:lhs) < 0
|
||||
\ && (empty(maparg(a:lhs, a:mode)) || a:0 > 0)
|
||||
silent execute a:mode . 'map <silent><nowait><buffer>' a:lhs a:rhs
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:map('n', '<localleader>li', '<plug>(vimtex-info)')
|
||||
call s:map('n', '<localleader>lI', '<plug>(vimtex-info-full)')
|
||||
call s:map('n', '<localleader>lx', '<plug>(vimtex-reload)')
|
||||
call s:map('n', '<localleader>lX', '<plug>(vimtex-reload-state)')
|
||||
call s:map('n', '<localleader>ls', '<plug>(vimtex-toggle-main)')
|
||||
call s:map('n', '<localleader>lq', '<plug>(vimtex-log)')
|
||||
|
||||
call s:map('n', 'ds$', '<plug>(vimtex-env-delete-math)')
|
||||
call s:map('n', 'cs$', '<plug>(vimtex-env-change-math)')
|
||||
call s:map('n', 'dse', '<plug>(vimtex-env-delete)')
|
||||
call s:map('n', 'cse', '<plug>(vimtex-env-change)')
|
||||
call s:map('n', 'tse', '<plug>(vimtex-env-toggle-star)')
|
||||
|
||||
call s:map('n', 'dsc', '<plug>(vimtex-cmd-delete)')
|
||||
call s:map('n', 'csc', '<plug>(vimtex-cmd-change)')
|
||||
call s:map('n', 'tsc', '<plug>(vimtex-cmd-toggle-star)')
|
||||
call s:map('n', 'tsf', '<plug>(vimtex-cmd-toggle-frac)')
|
||||
call s:map('x', 'tsf', '<plug>(vimtex-cmd-toggle-frac)')
|
||||
call s:map('i', '<F7>', '<plug>(vimtex-cmd-create)')
|
||||
call s:map('n', '<F7>', '<plug>(vimtex-cmd-create)')
|
||||
call s:map('x', '<F7>', '<plug>(vimtex-cmd-create)')
|
||||
|
||||
call s:map('n', 'dsd', '<plug>(vimtex-delim-delete)')
|
||||
call s:map('n', 'csd', '<plug>(vimtex-delim-change-math)')
|
||||
call s:map('n', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
|
||||
call s:map('x', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
|
||||
call s:map('n', 'tsD', '<plug>(vimtex-delim-toggle-modifier-reverse)')
|
||||
call s:map('x', 'tsD', '<plug>(vimtex-delim-toggle-modifier-reverse)')
|
||||
call s:map('i', ']]', '<plug>(vimtex-delim-close)')
|
||||
|
||||
if g:vimtex_compiler_enabled
|
||||
call s:map('n', '<localleader>ll', '<plug>(vimtex-compile)')
|
||||
call s:map('n', '<localleader>lo', '<plug>(vimtex-compile-output)')
|
||||
call s:map('n', '<localleader>lL', '<plug>(vimtex-compile-selected)')
|
||||
call s:map('x', '<localleader>lL', '<plug>(vimtex-compile-selected)')
|
||||
call s:map('n', '<localleader>lk', '<plug>(vimtex-stop)')
|
||||
call s:map('n', '<localleader>lK', '<plug>(vimtex-stop-all)')
|
||||
call s:map('n', '<localleader>le', '<plug>(vimtex-errors)')
|
||||
call s:map('n', '<localleader>lc', '<plug>(vimtex-clean)')
|
||||
call s:map('n', '<localleader>lC', '<plug>(vimtex-clean-full)')
|
||||
call s:map('n', '<localleader>lg', '<plug>(vimtex-status)')
|
||||
call s:map('n', '<localleader>lG', '<plug>(vimtex-status-all)')
|
||||
endif
|
||||
|
||||
if g:vimtex_motion_enabled
|
||||
" These are forced in order to overwrite matchit mappings
|
||||
call s:map('n', '%', '<plug>(vimtex-%)', 1)
|
||||
call s:map('x', '%', '<plug>(vimtex-%)', 1)
|
||||
call s:map('o', '%', '<plug>(vimtex-%)', 1)
|
||||
|
||||
call s:map('n', ']]', '<plug>(vimtex-]])')
|
||||
call s:map('n', '][', '<plug>(vimtex-][)')
|
||||
call s:map('n', '[]', '<plug>(vimtex-[])')
|
||||
call s:map('n', '[[', '<plug>(vimtex-[[)')
|
||||
call s:map('x', ']]', '<plug>(vimtex-]])')
|
||||
call s:map('x', '][', '<plug>(vimtex-][)')
|
||||
call s:map('x', '[]', '<plug>(vimtex-[])')
|
||||
call s:map('x', '[[', '<plug>(vimtex-[[)')
|
||||
call s:map('o', ']]', '<plug>(vimtex-]])')
|
||||
call s:map('o', '][', '<plug>(vimtex-][)')
|
||||
call s:map('o', '[]', '<plug>(vimtex-[])')
|
||||
call s:map('o', '[[', '<plug>(vimtex-[[)')
|
||||
|
||||
call s:map('n', ']M', '<plug>(vimtex-]M)')
|
||||
call s:map('n', ']m', '<plug>(vimtex-]m)')
|
||||
call s:map('n', '[M', '<plug>(vimtex-[M)')
|
||||
call s:map('n', '[m', '<plug>(vimtex-[m)')
|
||||
call s:map('x', ']M', '<plug>(vimtex-]M)')
|
||||
call s:map('x', ']m', '<plug>(vimtex-]m)')
|
||||
call s:map('x', '[M', '<plug>(vimtex-[M)')
|
||||
call s:map('x', '[m', '<plug>(vimtex-[m)')
|
||||
call s:map('o', ']M', '<plug>(vimtex-]M)')
|
||||
call s:map('o', ']m', '<plug>(vimtex-]m)')
|
||||
call s:map('o', '[M', '<plug>(vimtex-[M)')
|
||||
call s:map('o', '[m', '<plug>(vimtex-[m)')
|
||||
|
||||
call s:map('n', ']/', '<plug>(vimtex-]/)')
|
||||
call s:map('n', ']*', '<plug>(vimtex-]*)')
|
||||
call s:map('n', '[/', '<plug>(vimtex-[/)')
|
||||
call s:map('n', '[*', '<plug>(vimtex-[*)')
|
||||
call s:map('x', ']/', '<plug>(vimtex-]/)')
|
||||
call s:map('x', ']*', '<plug>(vimtex-]*)')
|
||||
call s:map('x', '[/', '<plug>(vimtex-[/)')
|
||||
call s:map('x', '[*', '<plug>(vimtex-[*)')
|
||||
call s:map('o', ']/', '<plug>(vimtex-]/)')
|
||||
call s:map('o', ']*', '<plug>(vimtex-]*)')
|
||||
call s:map('o', '[/', '<plug>(vimtex-[/)')
|
||||
call s:map('o', '[*', '<plug>(vimtex-[*)')
|
||||
endif
|
||||
|
||||
if g:vimtex_text_obj_enabled
|
||||
call s:map('x', 'id', '<plug>(vimtex-id)')
|
||||
call s:map('x', 'ad', '<plug>(vimtex-ad)')
|
||||
call s:map('o', 'id', '<plug>(vimtex-id)')
|
||||
call s:map('o', 'ad', '<plug>(vimtex-ad)')
|
||||
call s:map('x', 'i$', '<plug>(vimtex-i$)')
|
||||
call s:map('x', 'a$', '<plug>(vimtex-a$)')
|
||||
call s:map('o', 'i$', '<plug>(vimtex-i$)')
|
||||
call s:map('o', 'a$', '<plug>(vimtex-a$)')
|
||||
call s:map('x', 'iP', '<plug>(vimtex-iP)')
|
||||
call s:map('x', 'aP', '<plug>(vimtex-aP)')
|
||||
call s:map('o', 'iP', '<plug>(vimtex-iP)')
|
||||
call s:map('o', 'aP', '<plug>(vimtex-aP)')
|
||||
call s:map('x', 'im', '<plug>(vimtex-im)')
|
||||
call s:map('x', 'am', '<plug>(vimtex-am)')
|
||||
call s:map('o', 'im', '<plug>(vimtex-im)')
|
||||
call s:map('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('x', 'ic', '<plug>(vimtex-targets-i)c')
|
||||
call s:map('x', 'ac', '<plug>(vimtex-targets-a)c')
|
||||
call s:map('o', 'ic', '<plug>(vimtex-targets-i)c')
|
||||
call s:map('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('x', 'ie', '<plug>(vimtex-ie)')
|
||||
call s:map('x', 'ae', '<plug>(vimtex-ae)')
|
||||
call s:map('o', 'ie', '<plug>(vimtex-ie)')
|
||||
call s:map('o', 'ae', '<plug>(vimtex-ae)')
|
||||
call s:map('x', 'ic', '<plug>(vimtex-ic)')
|
||||
call s:map('x', 'ac', '<plug>(vimtex-ac)')
|
||||
call s:map('o', 'ic', '<plug>(vimtex-ic)')
|
||||
call s:map('o', 'ac', '<plug>(vimtex-ac)')
|
||||
endif
|
||||
endif
|
||||
|
||||
if g:vimtex_toc_enabled
|
||||
call s:map('n', '<localleader>lt', '<plug>(vimtex-toc-open)')
|
||||
call s:map('n', '<localleader>lT', '<plug>(vimtex-toc-toggle)')
|
||||
endif
|
||||
|
||||
if has_key(b:vimtex, 'viewer')
|
||||
call s:map('n', '<localleader>lv', '<plug>(vimtex-view)')
|
||||
if has_key(b:vimtex.viewer, 'reverse_search')
|
||||
call s:map('n', '<localleader>lr', '<plug>(vimtex-reverse-search)')
|
||||
endif
|
||||
endif
|
||||
|
||||
if g:vimtex_imaps_enabled
|
||||
call s:map('n', '<localleader>lm', '<plug>(vimtex-imaps-list)')
|
||||
endif
|
||||
|
||||
if g:vimtex_doc_enabled
|
||||
call s:map('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:base_old = b:vimtex.base
|
||||
let b:vimtex.tex = fnamemodify(expand('%'), ':p')
|
||||
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 filename: ' . l:base_old)
|
||||
call vimtex#log#info('New filename: ' . b:vimtex.base)
|
||||
|
||||
if has_key(b:vimtex, 'compiler')
|
||||
if b:vimtex.compiler.is_running()
|
||||
call vimtex#log#warning('Compilation stopped!')
|
||||
call vimtex#compiler#stop()
|
||||
endif
|
||||
let b:vimtex.compiler.target = b:vimtex.base
|
||||
let b:vimtex.compiler.target_path = b:vimtex.tex
|
||||
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
|
||||
|
||||
|
||||
" {{{1 Initialize module
|
||||
|
||||
let s:modules = map(
|
||||
\ glob(fnamemodify(expand('<sfile>'), ':r') . '/*.vim', 0, 1),
|
||||
\ 'fnamemodify(v:val, '':t:r'')')
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,179 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#cache#open(name, ...) abort " {{{1
|
||||
let l:opts = a:0 > 0 ? a:1 : {}
|
||||
let l:name = get(l:opts, 'local') ? s:local_name(a:name) : a:name
|
||||
|
||||
let s:caches = get(s:, 'caches', {})
|
||||
if has_key(s:caches, l:name)
|
||||
return s:caches[l:name]
|
||||
endif
|
||||
|
||||
let s:caches[l:name] = s:cache.init(l:name, l:opts)
|
||||
return s:caches[l:name]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#cache#close(name) abort " {{{1
|
||||
let s:caches = get(s:, 'caches', {})
|
||||
|
||||
" Try global name first, then local name
|
||||
let l:name = a:name
|
||||
if !has_key(s:caches, l:name)
|
||||
let l:name = s:local_name(l:name)
|
||||
endif
|
||||
if !has_key(s:caches, l:name) | return | endif
|
||||
|
||||
let l:cache = s:caches[l:name]
|
||||
call l:cache.write()
|
||||
unlet s:caches[l: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#clear(name, local) abort " {{{1
|
||||
let l:cache = vimtex#cache#open(a:name, {'local': a:local})
|
||||
|
||||
call l:cache.read()
|
||||
if !empty(l:cache.data)
|
||||
let l:cache.data = {}
|
||||
call l:cache.write()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#cache#write_all() abort " {{{1
|
||||
for l:cache in values(get(s:, 'caches', {}))
|
||||
call l:cache.write()
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:cache = {}
|
||||
|
||||
function! s:cache.init(name, opts) dict abort " {{{1
|
||||
let new = deepcopy(self)
|
||||
unlet new.init
|
||||
|
||||
let l:root = get(g:, 'vimtex_cache_root', $HOME . '/.cache/vimtex')
|
||||
if !isdirectory(l:root)
|
||||
call mkdir(l:root, 'p')
|
||||
endif
|
||||
|
||||
let new.name = a:name
|
||||
let new.path = l:root . '/' . a:name . '.json'
|
||||
let new.local = get(a:opts, 'local')
|
||||
let new.persistent = get(a:opts, 'persistent',
|
||||
\ get(g:, 'vimtex_cache_persistent', 1))
|
||||
|
||||
if has_key(a:opts, 'default')
|
||||
let new.default = a:opts.default
|
||||
endif
|
||||
|
||||
let new.data = {}
|
||||
let new.ftime = -1
|
||||
let new.modified = 0
|
||||
|
||||
return new
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:cache.get(key) dict abort " {{{1
|
||||
call self.read()
|
||||
|
||||
if has_key(self, 'default') && !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.has(key) dict abort " {{{1
|
||||
call self.read()
|
||||
|
||||
return has_key(self.data, a:key)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:cache.set(key, value) dict abort " {{{1
|
||||
call self.read()
|
||||
|
||||
let self.data[a:key] = a:value
|
||||
let self.modified = 1
|
||||
call self.write()
|
||||
|
||||
return a:value
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:cache.write() dict abort " {{{1
|
||||
if !self.persistent
|
||||
let self.modified = 0
|
||||
return
|
||||
endif
|
||||
|
||||
if !self.modified | return | endif
|
||||
|
||||
call self.read()
|
||||
call writefile([json_encode(self.data)], self.path)
|
||||
let self.ftime = getftime(self.path)
|
||||
let self.modified = 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:cache.read() dict abort " {{{1
|
||||
if !self.persistent | return | endif
|
||||
|
||||
if getftime(self.path) > self.ftime
|
||||
let self.ftime = getftime(self.path)
|
||||
call extend(self.data,
|
||||
\ json_decode(join(readfile(self.path))), 'keep')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Utility functions
|
||||
"
|
||||
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
|
||||
|
||||
endif
|
||||
@@ -1,718 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" 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>
|
||||
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+\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#echo#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! s:get_frac_cmd() abort " {{{1
|
||||
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
|
||||
|
||||
if l:cmd.name ==# '\frac'
|
||||
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',
|
||||
\ '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.denominator = l:cmd.args[0].text
|
||||
let l:frac.numerator = l:cmd.args[1].text
|
||||
elseif len(l:cmd.args) == 1
|
||||
let l:consume = ['numerator']
|
||||
let l:frac.denominator = l:cmd.args[0].text
|
||||
let l:frac.numerator = ''
|
||||
else
|
||||
let l:consume = ['denominator', 'numerator']
|
||||
let l:frac.denominator = ''
|
||||
let l:frac.numerator = ''
|
||||
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] = vimtex#util#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] = vimtex#util#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)
|
||||
|
||||
return s:get_frac_cmd_aux(l:frac)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_frac_cmd_visual(selected) abort " {{{1
|
||||
let l:matches = matchlist(a:selected, '^\s*\\frac\s*{\(.*\)}\s*{\(.*\)}\s*$')
|
||||
if empty(l:matches) | return {} | endif
|
||||
|
||||
let l:frac = {
|
||||
\ 'type': 'cmd',
|
||||
\ 'text': a:selected,
|
||||
\ 'denominator': l:matches[1],
|
||||
\ 'numerator': l:matches[2],
|
||||
\}
|
||||
|
||||
return s:get_frac_cmd_aux(l:frac)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_frac_cmd_aux(frac) abort " {{{1
|
||||
let l:denominator = (a:frac.denominator =~# '^\\\?\w*$')
|
||||
\ ? a:frac.denominator
|
||||
\ : '(' . a:frac.denominator . ')'
|
||||
|
||||
let l:numerator = (a:frac.numerator =~# '^\\\?\w*$')
|
||||
\ ? a:frac.numerator
|
||||
\ : '(' . a:frac.numerator . ')'
|
||||
|
||||
let a:frac.text_toggled = l:denominator . '/' . l:numerator
|
||||
|
||||
return a: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.text = strpart(l:line,
|
||||
\ l:frac.col_start,
|
||||
\ l:frac.col_end - l:frac.col_start + 1)
|
||||
let l:frac.text_toggled = printf('\frac{%s}{%s}',
|
||||
\ 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',
|
||||
\ 'text': a:selected,
|
||||
\ 'numerator': s:get_inline_trim(l:parts[0]),
|
||||
\ 'denominator': s:get_inline_trim(l:parts[1]),
|
||||
\}
|
||||
|
||||
let l:frac.text_toggled = printf('\frac{%s}{%s}',
|
||||
\ 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 = vimtex#util#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#echo#input({
|
||||
\ 'info' : ['Change command: ', ['VimtexWarning', l:current.name]],
|
||||
\}), '^\\', '', '')
|
||||
elseif s:operator ==# 'create'
|
||||
let s:operator_cmd_name = substitute(vimtex#echo#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()',
|
||||
\ }[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' : [],
|
||||
\}
|
||||
|
||||
" 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
|
||||
let res.opt = s:get_cmd_part('[', res.pos_end)
|
||||
if !empty(res.opt)
|
||||
let res.pos_end.lnum = res.opt.close.lnum
|
||||
let res.pos_end.cnum = res.opt.close.cnum
|
||||
endif
|
||||
|
||||
" Get arguments
|
||||
let arg = s:get_cmd_part('{', res.pos_end)
|
||||
while !empty(arg)
|
||||
call add(res.args, arg)
|
||||
let res.pos_end.lnum = arg.close.lnum
|
||||
let res.pos_end.cnum = arg.close.cnum
|
||||
let arg = s:get_cmd_part('{', res.pos_end)
|
||||
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 delimiter
|
||||
" 1) exists,
|
||||
" 2) is of the right type,
|
||||
" 3) and is the next non-whitespace character.
|
||||
"
|
||||
if empty(l:open)
|
||||
\ || l:open.match !=# a:part
|
||||
\ || strlen(substitute(
|
||||
\ s:text_between(a:start_pos, l:open), '\_s', '', 'g')) != 0
|
||||
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
|
||||
|
||||
endif
|
||||
@@ -1,334 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" 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 VimtexCompile call vimtex#compiler#compile()
|
||||
command! -buffer -bang VimtexCompileSS call vimtex#compiler#compile_ss()
|
||||
command! -buffer -range VimtexCompileSelected <line1>,<line2>call vimtex#compiler#compile_selected('cmd')
|
||||
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
|
||||
|
||||
try
|
||||
let l:options = {
|
||||
\ 'root': a:state.root,
|
||||
\ 'target' : a:state.base,
|
||||
\ 'target_path' : a:state.tex,
|
||||
\ 'tex_program' : a:state.tex_program,
|
||||
\}
|
||||
let a:state.compiler
|
||||
\ = vimtex#compiler#{g:vimtex_compiler_method}#init(l:options)
|
||||
catch /vimtex: Requirements not met/
|
||||
call vimtex#log#error('Compiler was not initialized!')
|
||||
catch /E117/
|
||||
call vimtex#log#error(
|
||||
\ 'Invalid compiler: ' . g:vimtex_compiler_method,
|
||||
\ 'Please see :h g:vimtex_compiler_method')
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#compiler#callback(status) abort " {{{1
|
||||
if exists('b:vimtex') && get(b:vimtex.compiler, 'silence_next_callback')
|
||||
let b:vimtex.compiler.silence_next_callback = 0
|
||||
return
|
||||
endif
|
||||
|
||||
call vimtex#qf#open(0)
|
||||
redraw
|
||||
|
||||
if exists('s:output')
|
||||
call s:output.update()
|
||||
endif
|
||||
|
||||
if a:status
|
||||
call vimtex#log#info('Compilation completed')
|
||||
else
|
||||
call vimtex#log#warning('Compilation failed!')
|
||||
endif
|
||||
|
||||
if a:status && exists('b:vimtex')
|
||||
call b:vimtex.parse_packages()
|
||||
call vimtex#syntax#load#packages()
|
||||
endif
|
||||
|
||||
for l:hook in g:vimtex_compiler_callback_hooks
|
||||
if exists('*' . l:hook)
|
||||
execute 'call' l:hook . '(' . a:status . ')'
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#compiler#compile() abort " {{{1
|
||||
if get(b:vimtex.compiler, 'continuous')
|
||||
if b:vimtex.compiler.is_running()
|
||||
call vimtex#compiler#stop()
|
||||
else
|
||||
call b:vimtex.compiler.start()
|
||||
let b:vimtex.compiler.check_timer = s:check_if_running_start()
|
||||
endif
|
||||
else
|
||||
call b:vimtex.compiler.start_single()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#compile_ss() abort " {{{1
|
||||
call b:vimtex.compiler.start_single()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#compile_selected(type) abort range " {{{1
|
||||
let l:file = vimtex#parser#selection_to_texfile(a:type)
|
||||
if empty(l:file) | return | endif
|
||||
|
||||
" Create and initialize temporary compiler
|
||||
let l:options = {
|
||||
\ 'root' : l:file.root,
|
||||
\ 'target' : l:file.base,
|
||||
\ 'target_path' : l:file.tex,
|
||||
\ 'backend' : 'process',
|
||||
\ 'tex_program' : b:vimtex.tex_program,
|
||||
\ 'background' : 1,
|
||||
\ 'continuous' : 0,
|
||||
\ 'callback' : 0,
|
||||
\}
|
||||
let l:compiler = vimtex#compiler#{g:vimtex_compiler_method}#init(l:options)
|
||||
|
||||
call vimtex#log#toggle_verbose()
|
||||
call l:compiler.start()
|
||||
|
||||
" Check if successful
|
||||
if vimtex#qf#inquire(l:file.base)
|
||||
call vimtex#log#toggle_verbose()
|
||||
call vimtex#log#warning('Compiling selected lines ... failed!')
|
||||
botright cwindow
|
||||
return
|
||||
else
|
||||
call l:compiler.clean(0)
|
||||
call b:vimtex.viewer.view(l:file.pdf)
|
||||
call vimtex#log#toggle_verbose()
|
||||
call vimtex#log#info('Compiling selected lines ... done')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#output() abort " {{{1
|
||||
let l:file = get(b:vimtex.compiler, 'output', '')
|
||||
if empty(l:file)
|
||||
call vimtex#log#warning('No output exists!')
|
||||
return
|
||||
endif
|
||||
|
||||
" If window already open, then go there
|
||||
if exists('s:output')
|
||||
if bufwinnr(l:file) == s:output.winnr
|
||||
execute s:output.winnr . 'wincmd w'
|
||||
return
|
||||
else
|
||||
call s:output.destroy()
|
||||
endif
|
||||
endif
|
||||
|
||||
" Create new output window
|
||||
silent execute 'split' l:file
|
||||
|
||||
" Create the output object
|
||||
let s:output = {}
|
||||
let s:output.name = l:file
|
||||
let s:output.bufnr = bufnr('%')
|
||||
let s:output.winnr = bufwinnr('%')
|
||||
function! s:output.update() dict abort
|
||||
if bufwinnr(self.name) != self.winnr
|
||||
return
|
||||
endif
|
||||
|
||||
if mode() ==? 'v' || mode() ==# "\<c-v>"
|
||||
return
|
||||
endif
|
||||
|
||||
" Go to last line of file if it is not the current window
|
||||
if bufwinnr('%') != self.winnr
|
||||
let l:return = bufwinnr('%')
|
||||
execute 'keepalt' self.winnr . 'wincmd w'
|
||||
edit
|
||||
normal! Gzb
|
||||
execute 'keepalt' l:return . 'wincmd w'
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
function! s:output.destroy() dict abort
|
||||
autocmd! vimtex_output_window
|
||||
augroup! vimtex_output_window
|
||||
unlet s:output
|
||||
endfunction
|
||||
|
||||
" Better automatic update
|
||||
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
|
||||
|
||||
" Set some mappings
|
||||
nnoremap <silent><nowait><buffer> q :bwipeout<cr>
|
||||
if has('nvim') || has('gui_running')
|
||||
nnoremap <silent><nowait><buffer> <esc> :bwipeout<cr>
|
||||
endif
|
||||
|
||||
" Set some buffer options
|
||||
setlocal autoread
|
||||
setlocal nomodifiable
|
||||
setlocal bufhidden=wipe
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#stop() abort " {{{1
|
||||
call b:vimtex.compiler.stop()
|
||||
silent! call timer_stop(b:vimtex.compiler.check_timer)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#stop_all() abort " {{{1
|
||||
for l:state in vimtex#state#list_all()
|
||||
if exists('l:state.compiler.is_running')
|
||||
\ && l:state.compiler.is_running()
|
||||
call l:state.compiler.stop()
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#clean(full) abort " {{{1
|
||||
call b:vimtex.compiler.clean(a:full)
|
||||
|
||||
if empty(b:vimtex.compiler.build_dir) | return | endif
|
||||
sleep 100m
|
||||
|
||||
" Remove auxilliary output directories if they are empty
|
||||
let l:build_dir = (vimtex#paths#is_abs(b:vimtex.compiler.build_dir)
|
||||
\ ? '' : b:vimtex.root . '/')
|
||||
\ . b:vimtex.compiler.build_dir
|
||||
let l:tree = glob(l:build_dir . '/**/*', 0, 1)
|
||||
let l:files = filter(copy(l:tree), 'filereadable(v:val)')
|
||||
if !empty(l:files) | return | endif
|
||||
|
||||
for l:dir in sort(l:tree) + [l:build_dir]
|
||||
call delete(l:dir, 'd')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#status(detailed) abort " {{{1
|
||||
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#warning('Compiler is not running!')
|
||||
else
|
||||
call vimtex#log#info('Compiler is running', l:running)
|
||||
endif
|
||||
else
|
||||
if b:vimtex.compiler.is_running()
|
||||
call vimtex#log#info('Compiler is running')
|
||||
else
|
||||
call vimtex#log#warning('Compiler is not running!')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:check_timers = {}
|
||||
function! s:check_if_running_start() abort " {{{1
|
||||
if !exists('*timer_start') | return -1 | endif
|
||||
|
||||
let l:timer = timer_start(50, function('s:check_if_running'), {'repeat': 20})
|
||||
|
||||
let s:check_timers[l:timer] = {
|
||||
\ 'compiler' : b:vimtex.compiler,
|
||||
\ 'vimtex_id' : b:vimtex_id,
|
||||
\}
|
||||
|
||||
return l:timer
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:check_if_running(timer) abort " {{{1
|
||||
if s:check_timers[a:timer].compiler.is_running() | return | endif
|
||||
|
||||
call timer_stop(a:timer)
|
||||
|
||||
if get(b:, 'vimtex_id', -1) == s:check_timers[a:timer].vimtex_id
|
||||
call vimtex#compiler#output()
|
||||
endif
|
||||
call vimtex#log#error('Compiler did not start successfully!')
|
||||
|
||||
unlet s:check_timers[a:timer].compiler.check_timer
|
||||
unlet s:check_timers[a:timer]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
" {{{1 Initialize module
|
||||
|
||||
if !g:vimtex_compiler_enabled | finish | endif
|
||||
|
||||
augroup vimtex_compiler
|
||||
autocmd!
|
||||
autocmd VimLeave * call vimtex#compiler#stop_all()
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,218 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#compiler#arara#init(options) abort " {{{1
|
||||
let l:compiler = deepcopy(s:compiler)
|
||||
|
||||
call l:compiler.init(extend(a:options,
|
||||
\ get(g:, 'vimtex_compiler_arara', {}), 'keep'))
|
||||
|
||||
return l:compiler
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler = {
|
||||
\ 'name' : 'arara',
|
||||
\ 'backend' : has('nvim') ? 'nvim'
|
||||
\ : v:version >= 800 ? 'jobs' : 'process',
|
||||
\ 'root' : '',
|
||||
\ 'target' : '',
|
||||
\ 'target_path' : '',
|
||||
\ 'background' : 1,
|
||||
\ 'output' : tempname(),
|
||||
\ 'options' : ['--log'],
|
||||
\}
|
||||
|
||||
function! s:compiler.init(options) abort dict " {{{1
|
||||
call extend(self, a:options)
|
||||
|
||||
if !executable('arara')
|
||||
call vimtex#log#warning('arara is not executable!')
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
|
||||
call extend(self, deepcopy(s:compiler_{self.backend}))
|
||||
|
||||
" Processes run with the new jobs api will not run in the foreground
|
||||
if self.backend !=# 'process'
|
||||
let self.background = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.build_cmd() abort dict " {{{1
|
||||
let l:cmd = 'arara'
|
||||
|
||||
for l:opt in self.options
|
||||
let l:cmd .= ' ' . l:opt
|
||||
endfor
|
||||
|
||||
return l:cmd . ' ' . vimtex#util#shellescape(self.target)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.cleanup() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.pprint_items() abort dict " {{{1
|
||||
let l:configuration = []
|
||||
|
||||
if self.backend ==# 'process'
|
||||
call add(l:configuration, ['background', self.background])
|
||||
endif
|
||||
|
||||
call add(l:configuration, ['arara options', self.options])
|
||||
|
||||
let l:list = []
|
||||
call add(l:list, ['backend', self.backend])
|
||||
if self.background
|
||||
call add(l:list, ['output', self.output])
|
||||
endif
|
||||
|
||||
if self.target_path !=# b:vimtex.tex
|
||||
call add(l:list, ['root', self.root])
|
||||
call add(l:list, ['target', self.target_path])
|
||||
endif
|
||||
|
||||
call add(l:list, ['configuration', l:configuration])
|
||||
|
||||
if has_key(self, 'process')
|
||||
call add(l:list, ['process', self.process])
|
||||
endif
|
||||
|
||||
if has_key(self, 'job')
|
||||
call add(l:list, ['cmd', self.cmd])
|
||||
endif
|
||||
|
||||
return l:list
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.clean(...) abort dict " {{{1
|
||||
call vimtex#log#warning('Clean not implemented for arara')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start(...) abort dict " {{{1
|
||||
call self.exec()
|
||||
|
||||
if self.background
|
||||
call vimtex#log#info('Compiler started in background')
|
||||
else
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(self.target))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start_single() abort dict " {{{1
|
||||
call self.start()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.stop() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.is_running() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.kill() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.get_pid() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_process = {}
|
||||
function! s:compiler_process.exec() abort dict " {{{1
|
||||
let self.process = vimtex#process#new()
|
||||
let self.process.name = 'arara'
|
||||
let self.process.background = self.background
|
||||
let self.process.workdir = self.root
|
||||
let self.process.output = self.output
|
||||
let self.process.cmd = self.build_cmd()
|
||||
call self.process.run()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_jobs = {}
|
||||
function! s:compiler_jobs.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
let l:options = {
|
||||
\ 'out_io' : 'file',
|
||||
\ 'err_io' : 'file',
|
||||
\ 'out_name' : self.output,
|
||||
\ 'err_name' : self.output,
|
||||
\}
|
||||
|
||||
let s:cb_target = self.target_path !=# b:vimtex.tex ? self.target_path : ''
|
||||
let l:options.exit_cb = function('s:callback')
|
||||
|
||||
call vimtex#paths#pushd(self.root)
|
||||
let self.job = job_start(l:cmd, l:options)
|
||||
call vimtex#paths#popd()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback(ch, msg) abort " {{{1
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(s:cb_target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_nvim = {}
|
||||
function! s:compiler_nvim.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
|
||||
let l:shell = {
|
||||
\ 'on_stdout' : function('s:callback_nvim_output'),
|
||||
\ 'on_stderr' : function('s:callback_nvim_output'),
|
||||
\ 'on_exit' : function('s:callback_nvim_exit'),
|
||||
\ 'cwd' : self.root,
|
||||
\ 'target' : self.target_path,
|
||||
\ 'output' : self.output,
|
||||
\}
|
||||
|
||||
let self.job = jobstart(l:cmd, l:shell)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_output(id, data, event) abort dict " {{{1
|
||||
if !empty(a:data)
|
||||
call writefile(filter(a:data, '!empty(v:val)'), self.output, 'a')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_exit(id, data, event) abort dict " {{{1
|
||||
let l:target = self.target !=# b:vimtex.tex ? self.target : ''
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(l:target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,700 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#compiler#latexmk#init(options) abort " {{{1
|
||||
let l:compiler = deepcopy(s:compiler)
|
||||
|
||||
call l:compiler.init(extend(a:options,
|
||||
\ get(g:, 'vimtex_compiler_latexmk', {}), 'keep'))
|
||||
|
||||
return l:compiler
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#compiler#latexmk#wrap_option(name, value) abort " {{{1
|
||||
return has('win32')
|
||||
\ ? ' -e "$' . a:name . ' = ''' . a:value . '''"'
|
||||
\ : ' -e ''$' . a:name . ' = "' . a:value . '"'''
|
||||
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],
|
||||
\]
|
||||
if !empty($XDG_CONFIG_HOME)
|
||||
call add(l:files, [$XDG_CONFIG_HOME . '/latexmk/latexmkrc', 0])
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
let s:compiler = {
|
||||
\ 'name' : 'latexmk',
|
||||
\ 'executable' : 'latexmk',
|
||||
\ 'backend' : has('nvim') ? 'nvim'
|
||||
\ : v:version >= 800 ? 'jobs' : 'process',
|
||||
\ 'root' : '',
|
||||
\ 'target' : '',
|
||||
\ 'target_path' : '',
|
||||
\ 'background' : 1,
|
||||
\ 'build_dir' : '',
|
||||
\ 'callback' : 1,
|
||||
\ 'continuous' : 1,
|
||||
\ 'output' : tempname(),
|
||||
\ 'options' : [
|
||||
\ '-verbose',
|
||||
\ '-file-line-error',
|
||||
\ '-synctex=1',
|
||||
\ '-interaction=nonstopmode',
|
||||
\ ],
|
||||
\ 'hooks' : [],
|
||||
\ 'shell' : fnamemodify(&shell, ':t'),
|
||||
\}
|
||||
|
||||
function! s:compiler.init(options) abort dict " {{{1
|
||||
call extend(self, a:options)
|
||||
|
||||
call self.init_check_requirements()
|
||||
call self.init_build_dir_option()
|
||||
call self.init_pdf_mode_option()
|
||||
|
||||
call extend(self, deepcopy(s:compiler_{self.backend}))
|
||||
|
||||
" Continuous processes can't run in foreground, neither can processes run
|
||||
" with the new jobs api
|
||||
if self.continuous || self.backend !=# 'process'
|
||||
let self.background = 1
|
||||
endif
|
||||
|
||||
if self.backend !=# 'process'
|
||||
let self.shell = 'sh'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.init_build_dir_option() abort dict " {{{1
|
||||
"
|
||||
" Check if .latexmkrc sets the build_dir - if so this should be respected
|
||||
"
|
||||
let l:out_dir =
|
||||
\ vimtex#compiler#latexmk#get_rc_opt(self.root, 'out_dir', 0, '')[0]
|
||||
|
||||
if !empty(l:out_dir)
|
||||
if !empty(self.build_dir) && (self.build_dir !=# l:out_dir)
|
||||
call vimtex#log#warning(
|
||||
\ 'Setting out_dir from latexmkrc overrides build_dir!',
|
||||
\ 'Changed build_dir from: ' . self.build_dir,
|
||||
\ 'Changed build_dir to: ' . l:out_dir)
|
||||
endif
|
||||
let self.build_dir = l:out_dir
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.init_pdf_mode_option() abort dict " {{{1
|
||||
" If the TeX program directive was not set, and if the pdf_mode is set in
|
||||
" a .latexmkrc file, then deduce the compiler engine from the value of
|
||||
" pdf_mode.
|
||||
|
||||
" Parse the pdf_mode option. If not found, it is set to -1.
|
||||
let [l:pdf_mode, l:is_local] =
|
||||
\ vimtex#compiler#latexmk#get_rc_opt(self.root, 'pdf_mode', 1, -1)
|
||||
|
||||
" If pdf_mode has a supported value (1: pdflatex, 4: lualatex, 5: xelatex),
|
||||
" override the value of self.tex_program.
|
||||
if l:pdf_mode == 1
|
||||
let l:tex_program = 'pdflatex'
|
||||
elseif l:pdf_mode == 3
|
||||
let l:tex_program = 'pdfdvi'
|
||||
elseif l:pdf_mode == 4
|
||||
let l:tex_program = 'lualatex'
|
||||
elseif l:pdf_mode == 5
|
||||
let l:tex_program = 'xelatex'
|
||||
else
|
||||
return
|
||||
endif
|
||||
|
||||
if self.tex_program ==# '_'
|
||||
" The TeX program directive was not specified
|
||||
let self.tex_program = l:tex_program
|
||||
elseif l:is_local && self.tex_program !=# l:tex_program
|
||||
call vimtex#log#warning(
|
||||
\ 'Value of pdf_mode from latexmkrc is inconsistent with ' .
|
||||
\ 'TeX program directive!',
|
||||
\ 'TeX program: ' . self.tex_program,
|
||||
\ 'pdf_mode: ' . l:tex_program,
|
||||
\ 'The value of pdf_mode will be ignored.')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.init_check_requirements() abort dict " {{{1
|
||||
" Check option validity
|
||||
if self.callback
|
||||
if !(has('clientserver') || has('nvim') || has('job'))
|
||||
let self.callback = 0
|
||||
call vimtex#log#warning(
|
||||
\ 'Can''t use callbacks without +job, +nvim, or +clientserver',
|
||||
\ 'Callback option has been disabled.')
|
||||
endif
|
||||
endif
|
||||
|
||||
" Check for required executables
|
||||
let l:required = [self.executable]
|
||||
if self.continuous && !(has('win32') || has('win32unix'))
|
||||
let l:required += ['pgrep']
|
||||
endif
|
||||
let l:missing = filter(l:required, '!executable(v:val)')
|
||||
|
||||
" Disable latexmk if required programs are missing
|
||||
if len(l:missing) > 0
|
||||
for l:cmd in l:missing
|
||||
call vimtex#log#warning(l:cmd . ' is not executable')
|
||||
endfor
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.build_cmd() abort dict " {{{1
|
||||
if has('win32')
|
||||
let l:cmd = 'set max_print_line=2000 & ' . self.executable
|
||||
else
|
||||
if self.shell ==# 'fish'
|
||||
let l:cmd = 'set max_print_line 2000; and ' . self.executable
|
||||
else
|
||||
let l:cmd = 'max_print_line=2000 ' . self.executable
|
||||
endif
|
||||
endif
|
||||
|
||||
for l:opt in self.options
|
||||
let l:cmd .= ' ' . l:opt
|
||||
endfor
|
||||
|
||||
let l:cmd .= ' ' . self.get_engine()
|
||||
|
||||
if !empty(self.build_dir)
|
||||
let l:cmd .= ' -outdir=' . fnameescape(self.build_dir)
|
||||
endif
|
||||
|
||||
if self.continuous
|
||||
let l:cmd .= ' -pvc'
|
||||
|
||||
" Set viewer options
|
||||
if !get(g:, 'vimtex_view_automatic', 1)
|
||||
\ || get(get(b:vimtex, 'viewer', {}), 'xwin_id') > 0
|
||||
\ || get(s:, 'silence_next_callback', 0)
|
||||
let l:cmd .= ' -view=none'
|
||||
elseif g:vimtex_view_enabled
|
||||
\ && has_key(b:vimtex.viewer, 'latexmk_append_argument')
|
||||
let l:cmd .= b:vimtex.viewer.latexmk_append_argument()
|
||||
endif
|
||||
|
||||
if self.callback
|
||||
if has('job') || has('nvim')
|
||||
for [l:opt, l:val] in items({
|
||||
\ 'success_cmd' : 'vimtex_compiler_callback_success',
|
||||
\ 'failure_cmd' : 'vimtex_compiler_callback_failure',
|
||||
\})
|
||||
let l:func = 'echo ' . l:val
|
||||
let l:cmd .= vimtex#compiler#latexmk#wrap_option(l:opt, l:func)
|
||||
endfor
|
||||
elseif empty(v:servername)
|
||||
call vimtex#log#warning('Can''t use callbacks with empty v:servername')
|
||||
else
|
||||
" Some notes:
|
||||
" - We excape the v:servername because this seems necessary on Windows
|
||||
" for neovim, see e.g. Github Issue #877
|
||||
for [l:opt, l:val] in items({'success_cmd' : 1, 'failure_cmd' : 0})
|
||||
let l:callback = has('win32')
|
||||
\ ? '"vimtex#compiler#callback(' . l:val . ')"'
|
||||
\ : '\"vimtex\#compiler\#callback(' . l:val . ')\"'
|
||||
let l:func = vimtex#util#shellescape('""')
|
||||
\ . g:vimtex_compiler_progname
|
||||
\ . vimtex#util#shellescape('""')
|
||||
\ . ' --servername ' . vimtex#util#shellescape(v:servername)
|
||||
\ . ' --remote-expr ' . l:callback
|
||||
let l:cmd .= vimtex#compiler#latexmk#wrap_option(l:opt, l:func)
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return l:cmd . ' ' . vimtex#util#shellescape(self.target)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.get_engine() abort dict " {{{1
|
||||
return get(extend(g:vimtex_compiler_latexmk_engines,
|
||||
\ {
|
||||
\ 'pdfdvi' : '-pdfdvi',
|
||||
\ 'pdflatex' : '-pdf',
|
||||
\ 'luatex' : '-lualatex',
|
||||
\ 'lualatex' : '-lualatex',
|
||||
\ 'xelatex' : '-xelatex',
|
||||
\ 'context (pdftex)' : '-pdf -pdflatex=texexec',
|
||||
\ 'context (luatex)' : '-pdf -pdflatex=context',
|
||||
\ 'context (xetex)' : '-pdf -pdflatex=''texexec --xtx''',
|
||||
\ }, 'keep'), self.tex_program, '-pdf')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.cleanup() abort dict " {{{1
|
||||
if self.is_running()
|
||||
call self.kill()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.pprint_items() abort dict " {{{1
|
||||
let l:configuration = [
|
||||
\ ['continuous', self.continuous],
|
||||
\ ['callback', self.callback],
|
||||
\]
|
||||
|
||||
if self.backend ==# 'process' && !self.continuous
|
||||
call add(l:configuration, ['background', self.background])
|
||||
endif
|
||||
|
||||
if !empty(self.build_dir)
|
||||
call add(l:configuration, ['build_dir', self.build_dir])
|
||||
endif
|
||||
call add(l:configuration, ['latexmk options', self.options])
|
||||
call add(l:configuration, ['latexmk engine', self.get_engine()])
|
||||
|
||||
let l:list = []
|
||||
call add(l:list, ['backend', self.backend])
|
||||
if self.executable !=# s:compiler.executable
|
||||
call add(l:list, ['latexmk executable', self.executable])
|
||||
endif
|
||||
if self.background
|
||||
call add(l:list, ['output', self.output])
|
||||
endif
|
||||
|
||||
if self.target_path !=# b:vimtex.tex
|
||||
call add(l:list, ['root', self.root])
|
||||
call add(l:list, ['target', self.target_path])
|
||||
endif
|
||||
|
||||
call add(l:list, ['configuration', l:configuration])
|
||||
|
||||
if has_key(self, 'process')
|
||||
call add(l:list, ['process', self.process])
|
||||
endif
|
||||
|
||||
if has_key(self, 'job')
|
||||
if self.continuous
|
||||
if self.backend ==# 'jobs'
|
||||
call add(l:list, ['job', self.job])
|
||||
else
|
||||
call add(l:list, ['pid', self.get_pid()])
|
||||
endif
|
||||
endif
|
||||
call add(l:list, ['cmd', self.cmd])
|
||||
endif
|
||||
|
||||
return l:list
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.clean(full) abort dict " {{{1
|
||||
let l:restart = self.is_running()
|
||||
if l:restart
|
||||
call self.stop()
|
||||
endif
|
||||
|
||||
" Define and run the latexmk clean cmd
|
||||
let l:cmd = (has('win32')
|
||||
\ ? 'cd /D "' . self.root . '" & '
|
||||
\ : 'cd ' . vimtex#util#shellescape(self.root) . '; ')
|
||||
\ . self.executable . ' ' . (a:full ? '-C ' : '-c ')
|
||||
if !empty(self.build_dir)
|
||||
let l:cmd .= printf(' -outdir=%s ', fnameescape(self.build_dir))
|
||||
endif
|
||||
let l:cmd .= vimtex#util#shellescape(self.target)
|
||||
call vimtex#process#run(l:cmd)
|
||||
|
||||
call vimtex#log#info('Compiler clean finished' . (a:full ? ' (full)' : ''))
|
||||
|
||||
if l:restart
|
||||
let self.silent_next_callback = 1
|
||||
silent call self.start()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start(...) abort dict " {{{1
|
||||
if self.is_running()
|
||||
call vimtex#log#warning(
|
||||
\ 'Compiler is already running for `' . self.target . "'")
|
||||
return
|
||||
endif
|
||||
|
||||
"
|
||||
" Create build dir if it does not exist
|
||||
"
|
||||
if !empty(self.build_dir)
|
||||
let l:dirs = split(glob(self.root . '/**/*.tex'), '\n')
|
||||
call map(l:dirs, 'fnamemodify(v:val, '':h'')')
|
||||
call map(l:dirs, 'strpart(v:val, strlen(self.root) + 1)')
|
||||
call vimtex#util#uniq(sort(filter(l:dirs, "v:val !=# ''")))
|
||||
call map(l:dirs,
|
||||
\ (vimtex#paths#is_abs(self.build_dir) ? '' : "self.root . '/' . ")
|
||||
\ . "self.build_dir . '/' . v:val")
|
||||
call filter(l:dirs, '!isdirectory(v:val)')
|
||||
|
||||
" Create the non-existing directories
|
||||
for l:dir in l:dirs
|
||||
call mkdir(l:dir, 'p')
|
||||
endfor
|
||||
endif
|
||||
|
||||
call self.exec()
|
||||
|
||||
if self.continuous
|
||||
call vimtex#log#info('Compiler started in continuous mode'
|
||||
\ . (a:0 > 0 ? ' (single shot)' : ''))
|
||||
if exists('#User#VimtexEventCompileStarted')
|
||||
doautocmd <nomodeline> User VimtexEventCompileStarted
|
||||
endif
|
||||
else
|
||||
if self.background
|
||||
call vimtex#log#info('Compiler started in background!')
|
||||
else
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(self.target))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.stop() abort dict " {{{1
|
||||
if self.is_running()
|
||||
call self.kill()
|
||||
call vimtex#log#info('Compiler stopped (' . self.target . ')')
|
||||
if exists('#User#VimtexEventCompileStopped')
|
||||
doautocmd <nomodeline> User VimtexEventCompileStopped
|
||||
endif
|
||||
else
|
||||
call vimtex#log#warning(
|
||||
\ 'There is no process to stop (' . self.target . ')')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_process = {}
|
||||
function! s:compiler_process.exec() abort dict " {{{1
|
||||
let l:process = vimtex#process#new()
|
||||
let l:process.name = 'latexmk'
|
||||
let l:process.continuous = self.continuous
|
||||
let l:process.background = self.background
|
||||
let l:process.workdir = self.root
|
||||
let l:process.output = self.output
|
||||
let l:process.cmd = self.build_cmd()
|
||||
|
||||
if l:process.continuous
|
||||
if (has('win32') || has('win32unix'))
|
||||
" Not implemented
|
||||
else
|
||||
for l:pid in split(system(
|
||||
\ 'pgrep -f "^[^ ]*perl.*latexmk.*' . self.target . '"'), "\n")
|
||||
let l:path = resolve('/proc/' . l:pid . '/cwd') . '/' . self.target
|
||||
if l:path ==# self.target_path
|
||||
let l:process.pid = str2nr(l:pid)
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
function! l:process.set_pid() abort dict " {{{2
|
||||
if (has('win32') || has('win32unix'))
|
||||
let pidcmd = 'tasklist /fi "imagename eq latexmk.exe"'
|
||||
let pidinfo = vimtex#process#capture(pidcmd)[-1]
|
||||
let self.pid = str2nr(split(pidinfo,'\s\+')[1])
|
||||
else
|
||||
let self.pid = str2nr(system('pgrep -nf "^[^ ]*perl.*latexmk"')[:-2])
|
||||
endif
|
||||
|
||||
return self.pid
|
||||
endfunction
|
||||
|
||||
" }}}2
|
||||
|
||||
let self.process = l:process
|
||||
call self.process.run()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_process.start_single() abort dict " {{{1
|
||||
let l:continuous = self.continuous
|
||||
let self.continuous = self.background && self.callback && !empty(v:servername)
|
||||
|
||||
if self.continuous
|
||||
let g:vimtex_compiler_callback_hooks += ['VimtexSSCallback']
|
||||
function! VimtexSSCallback(status) abort
|
||||
silent call vimtex#compiler#stop()
|
||||
call remove(g:vimtex_compiler_callback_hooks, 'VimtexSSCallback')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
call self.start(1)
|
||||
let self.continuous = l:continuous
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_process.is_running() abort dict " {{{1
|
||||
return exists('self.process.pid') && self.process.pid > 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_process.kill() abort dict " {{{1
|
||||
call self.process.stop()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_process.get_pid() abort dict " {{{1
|
||||
return has_key(self, 'process') ? self.process.pid : 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_jobs = {}
|
||||
function! s:compiler_jobs.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
|
||||
let l:options = {
|
||||
\ 'out_io' : 'file',
|
||||
\ 'err_io' : 'file',
|
||||
\ 'out_name' : self.output,
|
||||
\ 'err_name' : self.output,
|
||||
\}
|
||||
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')
|
||||
call writefile([], self.output, 'a')
|
||||
else
|
||||
let s:cb_target = self.target_path !=# b:vimtex.tex
|
||||
\ ? self.target_path : ''
|
||||
let l:options.exit_cb = function('s:callback')
|
||||
endif
|
||||
|
||||
call vimtex#paths#pushd(self.root)
|
||||
let self.job = job_start(l:cmd, l:options)
|
||||
call vimtex#paths#popd()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_jobs.start_single() abort dict " {{{1
|
||||
let l:continuous = self.continuous
|
||||
let self.continuous = 0
|
||||
call self.start()
|
||||
let self.continuous = l:continuous
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_jobs.kill() abort dict " {{{1
|
||||
call job_stop(self.job)
|
||||
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
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(s:cb_target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_continuous_output(channel, msg) abort " {{{1
|
||||
if exists('b:vimtex') && filewritable(b:vimtex.compiler.output)
|
||||
call writefile([a:msg], b:vimtex.compiler.output, 'a')
|
||||
endif
|
||||
|
||||
if a:msg ==# 'vimtex_compiler_callback_success'
|
||||
call vimtex#compiler#callback(1)
|
||||
elseif a:msg ==# 'vimtex_compiler_callback_failure'
|
||||
call vimtex#compiler#callback(0)
|
||||
endif
|
||||
|
||||
try
|
||||
for l:Hook in get(get(get(b:, 'vimtex', {}), 'compiler', {}), 'hooks', [])
|
||||
call l:Hook(a:msg)
|
||||
endfor
|
||||
catch /E716/
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_nvim = {}
|
||||
function! s:compiler_nvim.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
|
||||
let l:shell = {
|
||||
\ 'on_stdout' : function('s:callback_nvim_output'),
|
||||
\ 'on_stderr' : function('s:callback_nvim_output'),
|
||||
\ 'cwd' : self.root,
|
||||
\ 'target' : self.target_path,
|
||||
\ 'output' : self.output,
|
||||
\}
|
||||
|
||||
if !self.continuous
|
||||
let l:shell.on_exit = function('s:callback_nvim_exit')
|
||||
endif
|
||||
|
||||
" Initialize output file
|
||||
try
|
||||
call writefile([], self.output)
|
||||
endtry
|
||||
|
||||
let self.job = jobstart(l:cmd, l:shell)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_nvim.start_single() abort dict " {{{1
|
||||
let l:continuous = self.continuous
|
||||
let self.continuous = 0
|
||||
call self.start()
|
||||
let self.continuous = l:continuous
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_nvim.kill() abort dict " {{{1
|
||||
call jobstop(self.job)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler_nvim.is_running() abort dict " {{{1
|
||||
try
|
||||
let pid = jobpid(self.job)
|
||||
return 1
|
||||
catch
|
||||
return 0
|
||||
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
|
||||
|
||||
if match(a:data, 'vimtex_compiler_callback_success') != -1
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(self.target))
|
||||
elseif match(a:data, 'vimtex_compiler_callback_failure') != -1
|
||||
call vimtex#compiler#callback(0)
|
||||
endif
|
||||
|
||||
try
|
||||
for l:Hook in get(get(get(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
|
||||
let l:target = self.target !=# b:vimtex.tex ? self.target : ''
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(l:target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,250 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#compiler#latexrun#init(options) abort " {{{1
|
||||
let l:compiler = deepcopy(s:compiler)
|
||||
|
||||
call l:compiler.init(extend(a:options,
|
||||
\ get(g:, 'vimtex_compiler_latexrun', {}), 'keep'))
|
||||
|
||||
return l:compiler
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler = {
|
||||
\ 'name' : 'latexrun',
|
||||
\ 'backend' : has('nvim') ? 'nvim'
|
||||
\ : v:version >= 800 ? 'jobs' : 'process',
|
||||
\ 'root' : '',
|
||||
\ 'target' : '',
|
||||
\ 'target_path' : '',
|
||||
\ 'background' : 1,
|
||||
\ 'build_dir' : '',
|
||||
\ 'output' : tempname(),
|
||||
\ 'options' : [
|
||||
\ '--verbose-cmds',
|
||||
\ '--latex-args="-synctex=1"',
|
||||
\ ],
|
||||
\}
|
||||
|
||||
function! s:compiler.init(options) abort dict " {{{1
|
||||
call extend(self, a:options)
|
||||
|
||||
if !executable('latexrun')
|
||||
call vimtex#log#warning('latexrun is not executable!')
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
|
||||
call extend(self, deepcopy(s:compiler_{self.backend}))
|
||||
|
||||
" Processes run with the new jobs api will not run in the foreground
|
||||
if self.backend !=# 'process'
|
||||
let self.background = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.build_cmd() abort dict " {{{1
|
||||
let l:cmd = 'latexrun'
|
||||
|
||||
for l:opt in self.options
|
||||
let l:cmd .= ' ' . l:opt
|
||||
endfor
|
||||
|
||||
let l:cmd .= ' --latex-cmd ' . self.get_engine()
|
||||
|
||||
let l:cmd .= ' -O '
|
||||
\ . (empty(self.build_dir) ? '.' : fnameescape(self.build_dir))
|
||||
|
||||
return l:cmd . ' ' . vimtex#util#shellescape(self.target)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.get_engine() abort dict " {{{1
|
||||
return get(extend(g:vimtex_compiler_latexrun_engines,
|
||||
\ {
|
||||
\ '_' : 'pdflatex',
|
||||
\ 'pdflatex' : 'pdflatex',
|
||||
\ 'lualatex' : 'lualatex',
|
||||
\ 'xelatex' : 'xelatex',
|
||||
\ }, 'keep'), self.tex_program, '_')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.cleanup() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.pprint_items() abort dict " {{{1
|
||||
let l:configuration = []
|
||||
|
||||
if self.backend ==# 'process'
|
||||
call add(l:configuration, ['background', self.background])
|
||||
endif
|
||||
|
||||
if !empty(self.build_dir)
|
||||
call add(l:configuration, ['build_dir', self.build_dir])
|
||||
endif
|
||||
call add(l:configuration, ['latexrun options', self.options])
|
||||
call add(l:configuration, ['latexrun engine', self.get_engine()])
|
||||
|
||||
let l:list = []
|
||||
call add(l:list, ['backend', self.backend])
|
||||
if self.background
|
||||
call add(l:list, ['output', self.output])
|
||||
endif
|
||||
|
||||
if self.target_path !=# b:vimtex.tex
|
||||
call add(l:list, ['root', self.root])
|
||||
call add(l:list, ['target', self.target_path])
|
||||
endif
|
||||
|
||||
call add(l:list, ['configuration', l:configuration])
|
||||
|
||||
if has_key(self, 'process')
|
||||
call add(l:list, ['process', self.process])
|
||||
endif
|
||||
|
||||
if has_key(self, 'job')
|
||||
call add(l:list, ['cmd', self.cmd])
|
||||
endif
|
||||
|
||||
return l:list
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.clean(...) abort dict " {{{1
|
||||
let l:cmd = (has('win32')
|
||||
\ ? 'cd /D "' . self.root . '" & '
|
||||
\ : 'cd ' . vimtex#util#shellescape(self.root) . '; ')
|
||||
\ . 'latexrun --clean-all'
|
||||
\ . ' -O '
|
||||
\ . (empty(self.build_dir) ? '.' : fnameescape(self.build_dir))
|
||||
call vimtex#process#run(l:cmd)
|
||||
|
||||
call vimtex#log#info('Compiler clean finished')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start(...) abort dict " {{{1
|
||||
call self.exec()
|
||||
|
||||
if self.background
|
||||
call vimtex#log#info('Compiler started in background')
|
||||
else
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(self.target))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start_single() abort dict " {{{1
|
||||
call self.start()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.stop() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.is_running() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.kill() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.get_pid() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_process = {}
|
||||
function! s:compiler_process.exec() abort dict " {{{1
|
||||
let self.process = vimtex#process#new()
|
||||
let self.process.name = 'latexrun'
|
||||
let self.process.background = self.background
|
||||
let self.process.workdir = self.root
|
||||
let self.process.output = self.output
|
||||
let self.process.cmd = self.build_cmd()
|
||||
call self.process.run()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_jobs = {}
|
||||
function! s:compiler_jobs.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
let l:options = {
|
||||
\ 'out_io' : 'file',
|
||||
\ 'err_io' : 'file',
|
||||
\ 'out_name' : self.output,
|
||||
\ 'err_name' : self.output,
|
||||
\}
|
||||
|
||||
let s:cb_target = self.target_path !=# b:vimtex.tex ? self.target_path : ''
|
||||
let l:options.exit_cb = function('s:callback')
|
||||
|
||||
call vimtex#paths#pushd(self.root)
|
||||
let self.job = job_start(l:cmd, l:options)
|
||||
call vimtex#paths#popd()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback(ch, msg) abort " {{{1
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(s:cb_target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_nvim = {}
|
||||
function! s:compiler_nvim.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
|
||||
let l:shell = {
|
||||
\ 'on_stdout' : function('s:callback_nvim_output'),
|
||||
\ 'on_stderr' : function('s:callback_nvim_output'),
|
||||
\ 'on_exit' : function('s:callback_nvim_exit'),
|
||||
\ 'cwd' : self.root,
|
||||
\ 'target' : self.target_path,
|
||||
\ 'output' : self.output,
|
||||
\}
|
||||
|
||||
let self.job = jobstart(l:cmd, l:shell)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_output(id, data, event) abort dict " {{{1
|
||||
if !empty(a:data)
|
||||
call writefile(filter(a:data, '!empty(v:val)'), self.output, 'a')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_exit(id, data, event) abort dict " {{{1
|
||||
let l:target = self.target !=# b:vimtex.tex ? self.target : ''
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(l:target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,255 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#compiler#tectonic#init(options) abort " {{{1
|
||||
let l:compiler = deepcopy(s:compiler)
|
||||
|
||||
call l:compiler.init(extend(a:options,
|
||||
\ get(g:, 'vimtex_compiler_tectonic', {}), 'keep'))
|
||||
|
||||
return l:compiler
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler = {
|
||||
\ 'name' : 'tectonic',
|
||||
\ 'backend' : has('nvim') ? 'nvim'
|
||||
\ : v:version >= 800 ? 'jobs' : 'process',
|
||||
\ 'root' : '',
|
||||
\ 'target' : '',
|
||||
\ 'target_path' : '',
|
||||
\ 'background' : 1,
|
||||
\ 'build_dir' : '',
|
||||
\ 'output' : tempname(),
|
||||
\ 'options' : [
|
||||
\ '--keep-logs',
|
||||
\ '--synctex'
|
||||
\ ],
|
||||
\}
|
||||
|
||||
function! s:compiler.init(options) abort dict " {{{1
|
||||
call extend(self, a:options)
|
||||
|
||||
if !executable('tectonic')
|
||||
call vimtex#log#warning('tectonic is not executable!')
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
|
||||
call extend(self, deepcopy(s:compiler_{self.backend}))
|
||||
|
||||
" Processes run with the new jobs api will not run in the foreground
|
||||
if self.backend !=# 'process'
|
||||
let self.background = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.build_cmd() abort dict " {{{1
|
||||
let l:cmd = 'tectonic'
|
||||
|
||||
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 build_dir instead, see :help g:vimtex_compiler_tectonic'
|
||||
\ . ' for more details')
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:cmd .= ' ' . l:opt
|
||||
endfor
|
||||
|
||||
if empty(self.build_dir)
|
||||
let self.build_dir = fnamemodify(self.target_path, ':p:h')
|
||||
elseif !isdirectory(self.build_dir)
|
||||
call vimtex#log#warning(
|
||||
\ "build_dir doesn't exist, it will be created: " . self.build_dir)
|
||||
call mkdir(self.build_dir, 'p')
|
||||
endif
|
||||
|
||||
return l:cmd
|
||||
\ . ' --outdir=' . self.build_dir
|
||||
\ . ' ' . vimtex#util#shellescape(self.target)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.cleanup() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.pprint_items() abort dict " {{{1
|
||||
let l:configuration = []
|
||||
|
||||
if self.backend ==# 'process'
|
||||
call add(l:configuration, ['background', self.background])
|
||||
endif
|
||||
|
||||
call add(l:configuration, ['tectonic options', self.options])
|
||||
|
||||
let l:list = []
|
||||
call add(l:list, ['backend', self.backend])
|
||||
if self.background
|
||||
call add(l:list, ['output', self.output])
|
||||
endif
|
||||
|
||||
if self.target_path !=# b:vimtex.tex
|
||||
call add(l:list, ['root', self.root])
|
||||
call add(l:list, ['target', self.target_path])
|
||||
endif
|
||||
|
||||
call add(l:list, ['configuration', l:configuration])
|
||||
|
||||
if has_key(self, 'process')
|
||||
call add(l:list, ['process', self.process])
|
||||
endif
|
||||
|
||||
if has_key(self, 'job')
|
||||
call add(l:list, ['cmd', self.cmd])
|
||||
endif
|
||||
|
||||
return l:list
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compiler.clean(...) abort dict " {{{1
|
||||
let l:files = ['synctex.gz', 'toc', 'out', 'aux', 'log']
|
||||
|
||||
" If a full clean is required
|
||||
if a:0 > 0 && a:1
|
||||
call extend(l:intermediate, ['pdf'])
|
||||
endif
|
||||
|
||||
let l:basename = self.build_dir . '/' . fnamemodify(self.target_path, ':t:r')
|
||||
call map(l:files, 'l:basename . v:val')
|
||||
|
||||
call vimtex#process#run('rm -f ' . join(l:files))
|
||||
call vimtex#log#info('Compiler clean finished')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start(...) abort dict " {{{1
|
||||
call self.exec()
|
||||
|
||||
if self.background
|
||||
call vimtex#log#info('Compiler started in background')
|
||||
else
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(self.target))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.start_single() abort dict " {{{1
|
||||
call self.start()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.stop() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.is_running() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.kill() abort dict " {{{1
|
||||
" Pass
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:compiler.get_pid() abort dict " {{{1
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_process = {}
|
||||
function! s:compiler_process.exec() abort dict " {{{1
|
||||
let self.process = vimtex#process#new()
|
||||
let self.process.name = 'tectonic'
|
||||
let self.process.background = self.background
|
||||
let self.process.workdir = self.root
|
||||
let self.process.output = self.output
|
||||
let self.process.cmd = self.build_cmd()
|
||||
call self.process.run()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_jobs = {}
|
||||
function! s:compiler_jobs.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
let l:options = {
|
||||
\ 'out_io' : 'file',
|
||||
\ 'err_io' : 'file',
|
||||
\ 'out_name' : self.output,
|
||||
\ 'err_name' : self.output,
|
||||
\}
|
||||
|
||||
let s:cb_target = self.target_path !=# b:vimtex.tex ? self.target_path : ''
|
||||
let l:options.exit_cb = function('s:callback')
|
||||
|
||||
if !empty(self.root)
|
||||
let l:save_pwd = getcwd()
|
||||
execute 'lcd' fnameescape(self.root)
|
||||
endif
|
||||
let self.job = job_start(l:cmd, l:options)
|
||||
if !empty(self.root)
|
||||
execute 'lcd' fnameescape(l:save_pwd)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback(ch, msg) abort " {{{1
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(s:cb_target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:compiler_nvim = {}
|
||||
function! s:compiler_nvim.exec() abort dict " {{{1
|
||||
let self.cmd = self.build_cmd()
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'cmd /s /c "' . self.cmd . '"'
|
||||
\ : ['sh', '-c', self.cmd]
|
||||
|
||||
let l:shell = {
|
||||
\ 'on_stdout' : function('s:callback_nvim_output'),
|
||||
\ 'on_stderr' : function('s:callback_nvim_output'),
|
||||
\ 'on_exit' : function('s:callback_nvim_exit'),
|
||||
\ 'cwd' : self.root,
|
||||
\ 'target' : self.target_path,
|
||||
\ 'output' : self.output,
|
||||
\}
|
||||
|
||||
let self.job = jobstart(l:cmd, l:shell)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_output(id, data, event) abort dict " {{{1
|
||||
if !empty(a:data)
|
||||
call writefile(filter(a:data, '!empty(v:val)'), self.output, 'a')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:callback_nvim_exit(id, data, event) abort dict " {{{1
|
||||
let l:target = self.target !=# b:vimtex.tex ? self.target : ''
|
||||
call vimtex#compiler#callback(!vimtex#qf#inquire(l:target))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#debug#stacktrace(...) abort " {{{1
|
||||
"
|
||||
" This function builds on Luc Hermite's answer on Stack Exchange:
|
||||
" http://vi.stackexchange.com/a/6024/21
|
||||
"
|
||||
|
||||
"
|
||||
" Get stack and exception
|
||||
"
|
||||
if empty(v:throwpoint)
|
||||
try
|
||||
throw 'dummy'
|
||||
catch
|
||||
let l:stack = reverse(split(v:throwpoint, '\.\.'))[1:]
|
||||
let l:exception = 'Manual stacktrace'
|
||||
endtry
|
||||
else
|
||||
let l:stack = reverse(split(v:throwpoint, '\.\.'))
|
||||
let l:exception = v:exception
|
||||
endif
|
||||
|
||||
"
|
||||
" Build the quickfix entries
|
||||
"
|
||||
let l:qflist = []
|
||||
let l:files = {}
|
||||
for l:func in l:stack
|
||||
try
|
||||
let [l:name, l:offset] = (l:func =~# '\S\+\[\d')
|
||||
\ ? matchlist(l:func, '\(\S\+\)\[\(\d\+\)\]')[1:2]
|
||||
\ : matchlist(l:func, '\(\S\+\), line \(\d\+\)')[1:2]
|
||||
catch
|
||||
let l:name = l:func
|
||||
let l:offset = 0
|
||||
endtry
|
||||
|
||||
if l:name =~# '\v(\<SNR\>|^)\d+_'
|
||||
let l:sid = matchstr(l:name, '\v(\<SNR\>|^)\zs\d+\ze_')
|
||||
let l:name = substitute(l:name, '\v(\<SNR\>|^)\d+_', 's:', '')
|
||||
let l:filename = substitute(
|
||||
\ vimtex#util#command('scriptnames')[l:sid-1],
|
||||
\ '^\s*\d\+:\s*', '', '')
|
||||
else
|
||||
let l:func_name = l:name =~# '^\d\+$' ? '{' . l:name . '}' : l:name
|
||||
let l:filename = matchstr(
|
||||
\ vimtex#util#command('verbose function ' . l:func_name)[1],
|
||||
\ v:lang[0:1] ==# 'en'
|
||||
\ ? 'Last set from \zs.*\.vim' : '\f\+\.vim')
|
||||
endif
|
||||
|
||||
let l:filename = fnamemodify(l:filename, ':p')
|
||||
if filereadable(l:filename)
|
||||
if !has_key(l:files, l:filename)
|
||||
let l:files[l:filename] = reverse(readfile(l:filename))
|
||||
endif
|
||||
|
||||
if l:name =~# '^\d\+$'
|
||||
let l:lnum = 0
|
||||
let l:output = vimtex#util#command('function {' . l:name . '}')
|
||||
let l:text = substitute(
|
||||
\ matchstr(l:output, '^\s*' . l:offset),
|
||||
\ '^\d\+\s*', '', '')
|
||||
else
|
||||
let l:lnum = l:offset + len(l:files[l:filename])
|
||||
\ - match(l:files[l:filename], '^\s*fu\%[nction]!\=\s\+' . l:name .'(')
|
||||
let l:lnum_rev = len(l:files[l:filename]) - l:lnum
|
||||
let l:text = substitute(l:files[l:filename][l:lnum_rev], '^\s*', '', '')
|
||||
endif
|
||||
else
|
||||
let l:filename = ''
|
||||
let l:lnum = 0
|
||||
let l:text = ''
|
||||
endif
|
||||
|
||||
call add(l:qflist, {
|
||||
\ 'filename': l:filename,
|
||||
\ 'function': l:name,
|
||||
\ 'lnum': l:lnum,
|
||||
\ 'text': len(l:qflist) == 0 ? l:exception : l:text,
|
||||
\ 'nr': len(l:qflist),
|
||||
\})
|
||||
endfor
|
||||
|
||||
" Fill in empty filenames
|
||||
let l:prev_filename = '_'
|
||||
call reverse(l:qflist)
|
||||
for l:entry in l:qflist
|
||||
if empty(l:entry.filename)
|
||||
let l:entry.filename = l:prev_filename
|
||||
endif
|
||||
let l:prev_filename = l:entry.filename
|
||||
endfor
|
||||
call reverse(l:qflist)
|
||||
|
||||
if a:0 > 0
|
||||
call setqflist(l:qflist)
|
||||
execute 'copen' len(l:qflist) + 2
|
||||
wincmd p
|
||||
endif
|
||||
|
||||
return l:qflist
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,251 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#doc#init_buffer() abort " {{{1
|
||||
command! -buffer -nargs=? VimtexDocPackage call vimtex#doc#package(<q-args>)
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-doc-package) :VimtexDocPackage<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#doc#package(word) abort " {{{1
|
||||
let l:context = empty(a:word)
|
||||
\ ? s:packages_get_from_cursor()
|
||||
\ : {
|
||||
\ 'type': 'word',
|
||||
\ 'candidates': [a:word],
|
||||
\ }
|
||||
if empty(l:context) | return | endif
|
||||
|
||||
call s:packages_remove_invalid(l:context)
|
||||
|
||||
for l:handler in g:vimtex_doc_handlers
|
||||
if exists('*' . l:handler)
|
||||
if call(l:handler, [l:context]) | return | endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
call s:packages_open(l:context)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#doc#make_selection(context) abort " {{{1
|
||||
if has_key(a:context, 'selected') | return | endif
|
||||
|
||||
if len(a:context.candidates) == 0
|
||||
if exists('a:context.name')
|
||||
echohl ErrorMsg
|
||||
echo 'Sorry, no doc for '.a:context.name
|
||||
echohl NONE
|
||||
endif
|
||||
let a:context.selected = ''
|
||||
return
|
||||
endif
|
||||
|
||||
if len(a:context.candidates) == 1
|
||||
let a:context.selected = a:context.candidates[0]
|
||||
return
|
||||
endif
|
||||
|
||||
call vimtex#echo#echo('Multiple candidates detected, please select one:')
|
||||
let l:count = 0
|
||||
for l:package in a:context.candidates
|
||||
let l:count += 1
|
||||
call vimtex#echo#formatted([
|
||||
\ ' [' . string(l:count) . '] ',
|
||||
\ ['VimtexSuccess', l:package]
|
||||
\])
|
||||
endfor
|
||||
|
||||
call vimtex#echo#echo('Type number (everything else cancels): ')
|
||||
let l:choice = nr2char(getchar())
|
||||
if l:choice !~# '\d'
|
||||
\ || l:choice == 0
|
||||
\ || l:choice > len(a:context.candidates)
|
||||
echohl VimtexWarning
|
||||
echon l:choice =~# '\d' ? l:choice : '-'
|
||||
echohl NONE
|
||||
let a:context.selected = ''
|
||||
else
|
||||
echon l:choice
|
||||
let a:context.selected = a:context.candidates[l:choice-1]
|
||||
let a:context.ask_before_open = 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:packages_get_from_cursor() abort " {{{1
|
||||
let l:cmd = vimtex#cmd#get_current()
|
||||
if empty(l:cmd) | return {} | endif
|
||||
|
||||
if l:cmd.name ==# '\usepackage'
|
||||
return s:packages_from_usepackage(l:cmd)
|
||||
elseif l:cmd.name ==# '\documentclass'
|
||||
return s:packages_from_documentclass(l:cmd)
|
||||
else
|
||||
return s:packages_from_command(strpart(l:cmd.name, 1))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:packages_from_usepackage(cmd) abort " {{{1
|
||||
try
|
||||
" Gather and clean up candidate list
|
||||
let l:candidates = substitute(a:cmd.args[0].text, '%.\{-}\n', '', 'g')
|
||||
let l:candidates = substitute(l:candidates, '\s*', '', 'g')
|
||||
let l:candidates = split(l:candidates, ',')
|
||||
|
||||
let l:context = {
|
||||
\ 'type': 'usepackage',
|
||||
\ 'candidates': l:candidates,
|
||||
\}
|
||||
|
||||
let l:cword = expand('<cword>')
|
||||
if len(l:context.candidates) > 1 && index(l:context.candidates, l:cword) >= 0
|
||||
let l:context.selected = l:cword
|
||||
endif
|
||||
|
||||
return l:context
|
||||
catch
|
||||
call vimtex#log#warning('Could not parse the package from \usepackage!')
|
||||
return {}
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:packages_from_documentclass(cmd) abort " {{{1
|
||||
try
|
||||
return {
|
||||
\ 'type': 'documentclass',
|
||||
\ 'candidates': [a:cmd.args[0].text],
|
||||
\}
|
||||
catch
|
||||
call vimtex#log#warning('Could not parse the package from \documentclass!')
|
||||
return {}
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:packages_from_command(cmd) abort " {{{1
|
||||
let l:packages = [
|
||||
\ 'default',
|
||||
\ 'class-' . get(b:vimtex, 'documentclass', ''),
|
||||
\] + keys(b:vimtex.packages)
|
||||
call filter(l:packages, 'filereadable(s:complete_dir . v:val)')
|
||||
|
||||
let l:queue = copy(l:packages)
|
||||
while !empty(l:queue)
|
||||
let l:current = remove(l:queue, 0)
|
||||
let l:includes = filter(readfile(s:complete_dir . l:current), 'v:val =~# ''^\#\s*include:''')
|
||||
if empty(l:includes) | continue | endif
|
||||
|
||||
call map(l:includes, 'matchstr(v:val, ''include:\s*\zs.*\ze\s*$'')')
|
||||
call filter(l:includes, 'filereadable(s:complete_dir . v:val)')
|
||||
call filter(l:includes, 'index(l:packages, v:val) < 0')
|
||||
|
||||
let l:packages += l:includes
|
||||
let l:queue += l:includes
|
||||
endwhile
|
||||
|
||||
let l:candidates = []
|
||||
let l:filter = 'v:val =~# ''^' . a:cmd . '\>'''
|
||||
for l:package in l:packages
|
||||
let l:cmds = filter(readfile(s:complete_dir . l:package), l:filter)
|
||||
if empty(l:cmds) | continue | endif
|
||||
|
||||
if l:package ==# 'default'
|
||||
call extend(l:candidates, ['latex2e', 'lshort'])
|
||||
else
|
||||
call add(l:candidates, substitute(l:package, '^class-', '', ''))
|
||||
endif
|
||||
endfor
|
||||
|
||||
return {
|
||||
\ 'type': 'command',
|
||||
\ 'name': a:cmd,
|
||||
\ 'candidates': l:candidates,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:packages_remove_invalid(context) abort " {{{1
|
||||
let l:invalid_packages = filter(copy(a:context.candidates),
|
||||
\ 'empty(vimtex#kpsewhich#find(v:val . ''.sty'')) && '
|
||||
\ . 'empty(vimtex#kpsewhich#find(v:val . ''.cls''))')
|
||||
|
||||
call filter(l:invalid_packages,
|
||||
\ 'index([''latex2e'', ''lshort''], v:val) < 0')
|
||||
|
||||
" Warn about invalid candidates
|
||||
if !empty(l:invalid_packages)
|
||||
if len(l:invalid_packages) == 1
|
||||
call vimtex#log#warning(
|
||||
\ 'Package not recognized: ' . l:invalid_packages[0])
|
||||
else
|
||||
call vimtex#log#warning(
|
||||
\ 'Packages not recognized:',
|
||||
\ map(copy(l:invalid_packages), "'- ' . v:val"))
|
||||
endif
|
||||
endif
|
||||
|
||||
" Remove invalid candidates
|
||||
call filter(a:context.candidates, 'index(l:invalid_packages, v:val) < 0')
|
||||
|
||||
" Reset the selection if the selected candidate is not valid
|
||||
if has_key(a:context, 'selected')
|
||||
\ && index(a:context.candidates, a:context.selected) < 0
|
||||
unlet a:context.selected
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:packages_open(context) abort " {{{1
|
||||
if !has_key(a:context, 'selected')
|
||||
call vimtex#doc#make_selection(a:context)
|
||||
endif
|
||||
|
||||
if empty(a:context.selected) | return | endif
|
||||
|
||||
if get(a:context, 'ask_before_open', 1)
|
||||
call vimtex#echo#formatted([
|
||||
\ 'Open documentation for ',
|
||||
\ ['VimtexSuccess', a:context.selected], ' [y/N]? '
|
||||
\])
|
||||
|
||||
let l:choice = nr2char(getchar())
|
||||
if l:choice ==# 'y'
|
||||
echon 'y'
|
||||
else
|
||||
echohl VimtexWarning
|
||||
echon l:choice =~# '\w' ? l:choice : 'N'
|
||||
echohl NONE
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:os = vimtex#util#get_os()
|
||||
let l:url = 'http://texdoc.net/pkg/' . a:context.selected
|
||||
|
||||
silent execute (l:os ==# 'linux'
|
||||
\ ? '!xdg-open'
|
||||
\ : (l:os ==# 'mac'
|
||||
\ ? '!open'
|
||||
\ : '!start'))
|
||||
\ . ' ' . l:url
|
||||
\ . (l:os ==# 'win' ? '' : ' &')
|
||||
|
||||
redraw!
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:complete_dir = fnamemodify(expand('<sfile>'), ':h') . '/complete/'
|
||||
|
||||
endif
|
||||
@@ -1,121 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#echo#echo(message) abort " {{{1
|
||||
echohl VimtexMsg
|
||||
echo a:message
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#echo#input(opts) abort " {{{1
|
||||
if g:vimtex_echo_verbose_input
|
||||
\ && has_key(a:opts, 'info')
|
||||
call vimtex#echo#formatted(a:opts.info)
|
||||
endif
|
||||
|
||||
let l:args = [get(a:opts, 'prompt', '> ')]
|
||||
let l:args += [get(a:opts, 'default', '')]
|
||||
if has_key(a:opts, 'complete')
|
||||
let l:args += [a:opts.complete]
|
||||
endif
|
||||
|
||||
echohl VimtexMsg
|
||||
let l:reply = call('input', l:args)
|
||||
echohl None
|
||||
return l:reply
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#echo#choose(list_or_dict, prompt) abort " {{{1
|
||||
if empty(a:list_or_dict) | return '' | endif
|
||||
|
||||
return type(a:list_or_dict) == type({})
|
||||
\ ? s:choose_dict(a:list_or_dict, a:prompt)
|
||||
\ : s:choose_list(a:list_or_dict, a:prompt)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#echo#formatted(parts) abort " {{{1
|
||||
echo ''
|
||||
try
|
||||
for part in a:parts
|
||||
if type(part) == type('')
|
||||
echohl VimtexMsg
|
||||
echon part
|
||||
else
|
||||
execute 'echohl' part[0]
|
||||
echon part[1]
|
||||
endif
|
||||
unlet part
|
||||
endfor
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:choose_dict(dict, prompt) abort " {{{1
|
||||
if len(a:dict) == 1
|
||||
return values(a:dict)[0]
|
||||
endif
|
||||
|
||||
while 1
|
||||
redraw!
|
||||
if !empty(a:prompt)
|
||||
echohl VimtexMsg
|
||||
unsilent echo a:prompt
|
||||
echohl None
|
||||
endif
|
||||
|
||||
let l:choice = 0
|
||||
for l:x in values(a:dict)
|
||||
let l:choice += 1
|
||||
unsilent call vimtex#echo#formatted([['VimtexWarning', l:choice], ': ', l:x])
|
||||
endfor
|
||||
|
||||
try
|
||||
let l:choice = str2nr(input('> ')) - 1
|
||||
if l:choice >= 0 && l:choice < len(a:dict)
|
||||
return keys(a:dict)[l:choice]
|
||||
endif
|
||||
endtry
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:choose_list(list, prompt) abort " {{{1
|
||||
if len(a:list) == 1 | return a:list[0] | endif
|
||||
|
||||
while 1
|
||||
redraw!
|
||||
if !empty(a:prompt)
|
||||
echohl VimtexMsg
|
||||
unsilent echo a:prompt
|
||||
echohl None
|
||||
endif
|
||||
|
||||
let l:choice = 0
|
||||
for l:x in a:list
|
||||
let l:choice += 1
|
||||
unsilent call vimtex#echo#formatted([['VimtexWarning', l:choice], ': ', l:x])
|
||||
endfor
|
||||
|
||||
try
|
||||
let l:choice = str2nr(input('> ')) - 1
|
||||
if l:choice >= 0 && l:choice < len(a:list)
|
||||
return a:list[l:choice]
|
||||
endif
|
||||
endtry
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,202 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#env#init_buffer() abort " {{{1
|
||||
nnoremap <silent><buffer> <plug>(vimtex-env-delete)
|
||||
\ :<c-u>call <sid>operator_setup('delete', 'env_tex')<bar>normal! g@l<cr>
|
||||
|
||||
nnoremap <silent><buffer> <plug>(vimtex-env-change)
|
||||
\ :<c-u>call <sid>operator_setup('change', 'env_tex')<bar>normal! g@l<cr>
|
||||
|
||||
nnoremap <silent><buffer> <plug>(vimtex-env-delete-math)
|
||||
\ :<c-u>call <sid>operator_setup('delete', 'env_math')<bar>normal! g@l<cr>
|
||||
|
||||
nnoremap <silent><buffer> <plug>(vimtex-env-change-math)
|
||||
\ :<c-u>call <sid>operator_setup('change', 'env_math')<bar>normal! g@l<cr>
|
||||
|
||||
nnoremap <silent><buffer> <plug>(vimtex-env-toggle-star)
|
||||
\ :<c-u>call <sid>operator_setup('toggle_star', '')<bar>normal! g@l<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#env#change(open, close, new) abort " {{{1
|
||||
"
|
||||
" Set target environment
|
||||
"
|
||||
if a:new ==# ''
|
||||
let [l:beg, l:end] = ['', '']
|
||||
elseif a:new ==# '$'
|
||||
let [l:beg, l:end] = ['$', '$']
|
||||
elseif a:new ==# '$$'
|
||||
let [l:beg, l:end] = ['$$', '$$']
|
||||
elseif a:new ==# '\['
|
||||
let [l:beg, l:end] = ['\[', '\]']
|
||||
elseif a:new ==# '\('
|
||||
let [l:beg, l:end] = ['\(', '\)']
|
||||
else
|
||||
let l:beg = '\begin{' . a:new . '}'
|
||||
let l:end = '\end{' . a:new . '}'
|
||||
endif
|
||||
|
||||
let l:line = getline(a:open.lnum)
|
||||
call setline(a:open.lnum,
|
||||
\ strpart(l:line, 0, a:open.cnum-1)
|
||||
\ . l:beg
|
||||
\ . strpart(l:line, a:open.cnum + len(a:open.match) - 1))
|
||||
|
||||
let l:c1 = a:close.cnum
|
||||
let l:c2 = a:close.cnum + len(a:close.match) - 1
|
||||
if a:open.lnum == a:close.lnum
|
||||
let n = len(l:beg) - len(a:open.match)
|
||||
let l:c1 += n
|
||||
let l:c2 += n
|
||||
let pos = vimtex#pos#get_cursor()
|
||||
if pos[2] > a:open.cnum + len(a:open.match) - 1
|
||||
let pos[2] += n
|
||||
call vimtex#pos#set_cursor(pos)
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:line = getline(a:close.lnum)
|
||||
call setline(a:close.lnum,
|
||||
\ strpart(l:line, 0, l:c1-1) . l:end . strpart(l:line, l:c2))
|
||||
endfunction
|
||||
|
||||
function! vimtex#env#change_surrounding_to(type, new) abort " {{{1
|
||||
let [l:open, l:close] = vimtex#delim#get_surrounding(a:type)
|
||||
if empty(l:open) | return | endif
|
||||
|
||||
return vimtex#env#change(l:open, l:close, a:new)
|
||||
endfunction
|
||||
|
||||
function! vimtex#env#delete(type) abort " {{{1
|
||||
let [l:open, l:close] = vimtex#delim#get_surrounding(a:type)
|
||||
if empty(l:open) | return | endif
|
||||
|
||||
if a:type ==# 'env_tex'
|
||||
call vimtex#cmd#delete_all(l:close)
|
||||
call vimtex#cmd#delete_all(l:open)
|
||||
else
|
||||
call l:close.remove()
|
||||
call l:open.remove()
|
||||
endif
|
||||
|
||||
if getline(l:close.lnum) =~# '^\s*$'
|
||||
execute l:close.lnum . 'd _'
|
||||
endif
|
||||
|
||||
if getline(l:open.lnum) =~# '^\s*$'
|
||||
execute l:open.lnum . 'd _'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! vimtex#env#toggle_star() abort " {{{1
|
||||
let [l:open, l:close] = vimtex#delim#get_surrounding('env_tex')
|
||||
if empty(l:open) | return | endif
|
||||
|
||||
call vimtex#env#change(l:open, l:close,
|
||||
\ l:open.starred ? l:open.name : l:open.name . '*')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#env#is_inside(env) abort " {{{1
|
||||
let l:re_start = '\\begin\s*{' . a:env . '\*\?}'
|
||||
let l:re_end = '\\end\s*{' . a:env . '\*\?}'
|
||||
try
|
||||
return searchpairpos(l:re_start, '', l:re_end, 'bnW', '', 0, 100)
|
||||
catch /E118/
|
||||
let l:stopline = max([line('.') - 500, 1])
|
||||
return searchpairpos(l:re_start, '', l:re_end, 'bnW', '', l:stopline)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#env#input_complete(lead, cmdline, pos) abort " {{{1
|
||||
let l:cands = map(vimtex#complete#complete('env', '', '\begin'), 'v:val.word')
|
||||
|
||||
" Never include document and remove current env (place it first)
|
||||
call filter(l:cands, 'index([''document'', s:env_name], v:val) < 0')
|
||||
|
||||
" Always include current env and displaymath
|
||||
let l:cands = [s:env_name] + l:cands + ['\[']
|
||||
|
||||
return filter(l:cands, 'v:val =~# ''^' . a:lead . '''')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:change_prompt(type) abort " {{{1
|
||||
let [l:open, l:close] = vimtex#delim#get_surrounding(a:type)
|
||||
if empty(l:open) | return | endif
|
||||
|
||||
if g:vimtex_env_change_autofill
|
||||
let l:name = get(l:open, 'name', l:open.match)
|
||||
let s:env_name = l:name
|
||||
return vimtex#echo#input({
|
||||
\ 'prompt' : 'Change surrounding environment: ',
|
||||
\ 'default' : l:name,
|
||||
\ 'complete' : 'customlist,vimtex#env#input_complete',
|
||||
\})
|
||||
else
|
||||
let l:name = get(l:open, 'name', l:open.is_open
|
||||
\ ? l:open.match . ' ... ' . l:open.corr
|
||||
\ : l:open.match . ' ... ' . l:open.corr)
|
||||
let s:env_name = l:name
|
||||
return vimtex#echo#input({
|
||||
\ 'info' :
|
||||
\ ['Change surrounding environment: ', ['VimtexWarning', l:name]],
|
||||
\ 'complete' : 'customlist,vimtex#env#input_complete',
|
||||
\})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:operator_setup(operator, type) abort " {{{1
|
||||
let &opfunc = s:snr() . 'operator_function'
|
||||
|
||||
let s:operator_abort = 0
|
||||
let s:operator = a:operator
|
||||
let s:operator_type = a:type
|
||||
|
||||
" Ask for user input if necessary/relevant
|
||||
if s:operator ==# 'change'
|
||||
let l:new_env = s:change_prompt(s:operator_type)
|
||||
if empty(l:new_env)
|
||||
let s:operator_abort = 1
|
||||
return
|
||||
endif
|
||||
|
||||
let s:operator_name = l:new_env
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:operator_function(_) abort " {{{1
|
||||
if get(s:, 'operator_abort', 0) | return | endif
|
||||
|
||||
let l:type = get(s:, 'operator_type', '')
|
||||
let l:name = get(s:, 'operator_name', '')
|
||||
|
||||
execute 'call vimtex#env#' . {
|
||||
\ 'change': 'change_surrounding_to(l:type, l:name)',
|
||||
\ 'delete': 'delete(l:type)',
|
||||
\ 'toggle_star': 'toggle_star()',
|
||||
\ }[s:operator]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:snr() abort " {{{1
|
||||
return matchstr(expand('<sfile>'), '<SNR>\d\+_')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,143 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#init_buffer() abort " {{{1
|
||||
if !g:vimtex_fold_enabled
|
||||
\ || s:foldmethod_in_modeline() | return | endif
|
||||
|
||||
" Set fold options
|
||||
setlocal foldmethod=expr
|
||||
setlocal foldexpr=vimtex#fold#level(v:lnum)
|
||||
setlocal foldtext=vimtex#fold#text()
|
||||
|
||||
if g:vimtex_fold_manual
|
||||
" Remap zx to refresh fold levels
|
||||
nnoremap <silent><nowait><buffer> zx :call vimtex#fold#refresh('zx')<cr>
|
||||
nnoremap <silent><nowait><buffer> zX :call vimtex#fold#refresh('zX')<cr>
|
||||
|
||||
" Define commands
|
||||
command! -buffer VimtexRefreshFolds call vimtex#fold#refresh('zx')
|
||||
|
||||
" Ensure that folds are refreshed on startup
|
||||
augroup vimtex_temporary
|
||||
autocmd! * <buffer>
|
||||
autocmd CursorMoved <buffer>
|
||||
\ call vimtex#fold#refresh('zx')
|
||||
\ | autocmd! vimtex_temporary CursorMoved <buffer>
|
||||
augroup END
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#fold#init_state(state) abort " {{{1
|
||||
"
|
||||
" Initialize the enabled fold types
|
||||
"
|
||||
let a:state.fold_types_dict = {}
|
||||
for [l:key, l:val] in items(g:vimtex_fold_types_defaults)
|
||||
let l:config = extend(deepcopy(l:val), get(g:vimtex_fold_types, l:key, {}))
|
||||
if get(l:config, 'enabled', 1)
|
||||
let a:state.fold_types_dict[l:key] = vimtex#fold#{l:key}#new(l:config)
|
||||
endif
|
||||
endfor
|
||||
|
||||
"
|
||||
" Define ordered list and the global fold regex
|
||||
"
|
||||
let a:state.fold_types_ordered = []
|
||||
let a:state.fold_re = '\v'
|
||||
\ . '\\%(begin|end)>'
|
||||
\ . '|^\s*\%'
|
||||
\ . '|^\s*\]\s*%(\{|$)'
|
||||
\ . '|^\s*}'
|
||||
for l:name in [
|
||||
\ 'preamble',
|
||||
\ 'cmd_single',
|
||||
\ 'cmd_single_opt',
|
||||
\ 'cmd_multi',
|
||||
\ 'cmd_addplot',
|
||||
\ 'sections',
|
||||
\ 'markers',
|
||||
\ 'comments',
|
||||
\ 'envs',
|
||||
\ 'env_options',
|
||||
\]
|
||||
let l:type = get(a:state.fold_types_dict, l:name, {})
|
||||
if !empty(l:type)
|
||||
call add(a:state.fold_types_ordered, l:type)
|
||||
if exists('l:type.re.fold_re')
|
||||
let a:state.fold_re .= '|' . l:type.re.fold_re
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#fold#refresh(map) abort " {{{1
|
||||
setlocal foldmethod=expr
|
||||
execute 'normal!' a:map
|
||||
setlocal foldmethod=manual
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#fold#level(lnum) abort " {{{1
|
||||
let l:line = getline(a:lnum)
|
||||
|
||||
" Filter out lines that do not start any folds (optimization)
|
||||
if l:line !~# b:vimtex.fold_re | return '=' | endif
|
||||
|
||||
" Never fold \begin|end{document}
|
||||
if l:line =~# '^\s*\\\%(begin\|end\){document}'
|
||||
return 0
|
||||
endif
|
||||
|
||||
for l:type in b:vimtex.fold_types_ordered
|
||||
let l:value = l:type.level(l:line, a:lnum)
|
||||
if !empty(l:value) | return l:value | endif
|
||||
endfor
|
||||
|
||||
" Return foldlevel of previous line
|
||||
return '='
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#fold#text() abort " {{{1
|
||||
let l:line = getline(v:foldstart)
|
||||
let l:level = v:foldlevel > 1
|
||||
\ ? repeat('-', v:foldlevel-2) . g:vimtex_fold_levelmarker
|
||||
\ : ''
|
||||
|
||||
for l:type in b:vimtex.fold_types_ordered
|
||||
if l:line =~# l:type.re.start
|
||||
let l:text = l:type.text(l:line, l:level)
|
||||
if !empty(l:text) | return l:text | endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
function! s:foldmethod_in_modeline() abort " {{{1
|
||||
let l:cursor_pos = vimtex#pos#get_cursor()
|
||||
let l:fdm_modeline = 'vim:.*\%(foldmethod\|fdm\)'
|
||||
|
||||
call vimtex#pos#set_cursor(1, 1)
|
||||
let l:check_top = search(l:fdm_modeline, 'cn', &modelines)
|
||||
|
||||
normal! G$
|
||||
let l:check_btm = search(l:fdm_modeline, 'b', line('$') + 1 - &modelines)
|
||||
|
||||
call vimtex#pos#set_cursor(l:cursor_pos)
|
||||
return l:check_top || l:check_btm
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,51 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#cmd_addplot#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'cmd_addplot',
|
||||
\ 're' : {},
|
||||
\ 'opened' : 0,
|
||||
\ 'cmds' : [],
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\s*%(\[[^\]]*\])?'
|
||||
|
||||
let self.re.start = l:re . '\s*\w+\s*%(\[[^\]]*\])?\s*\ze\{\s*%($|\%)'
|
||||
let self.re.end = '^\s*}'
|
||||
let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')'
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let self.opened = 1
|
||||
return 'a1'
|
||||
elseif self.opened && a:line =~# self.re.end
|
||||
let self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
return matchstr(a:line, self.re.start) . '{...}'
|
||||
\ . substitute(getline(v:foldend), self.re.end, '', '')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,51 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#cmd_multi#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'cmd_multi',
|
||||
\ 're' : {},
|
||||
\ 'opened' : 0,
|
||||
\ 'cmds' : [],
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?'
|
||||
|
||||
let self.re.start = l:re . '.*(\{|\[)\s*(\%.*)?$'
|
||||
let self.re.end = '\v^\s*%(\}\s*\{)*\}\s*%(\%|$)'
|
||||
let self.re.text = l:re . '\{[^}]*\}'
|
||||
let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')'
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let self.opened += 1
|
||||
return 'a1'
|
||||
elseif self.opened > 0 && a:line =~# self.re.end
|
||||
let self.opened -= 1
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
return a:line
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,52 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#cmd_single#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'cmd_single',
|
||||
\ 're' : {},
|
||||
\ 'opened' : 0,
|
||||
\ 'cmds' : [],
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?\s*%(\[.*\])?'
|
||||
|
||||
let self.re.start = l:re . '\s*\{\s*%($|\%)'
|
||||
let self.re.end = '^\s*}'
|
||||
let self.re.text = l:re
|
||||
let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')'
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let self.opened = 1
|
||||
return 'a1'
|
||||
elseif self.opened && a:line =~# self.re.end
|
||||
let self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
return matchstr(a:line, self.re.text) . '{...}'
|
||||
\ . substitute(getline(v:foldend), self.re.end, '', '')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,53 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#cmd_single_opt#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'cmd_single_opt',
|
||||
\ 're' : {},
|
||||
\ 'opened' : 0,
|
||||
\ 'cmds' : [],
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?'
|
||||
|
||||
let self.re.start = l:re . '\s*\[\s*%($|\%)'
|
||||
let self.re.end = '^\s*\]{'
|
||||
let self.re.text = l:re
|
||||
let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')'
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let self.opened = 1
|
||||
return 'a1'
|
||||
elseif self.opened && a:line =~# self.re.end
|
||||
let self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
let l:col = strlen(matchstr(a:line, '^\s*')) + 1
|
||||
return matchstr(a:line, self.re.text) . '[...]{'
|
||||
\ . vimtex#cmd#get_at(v:foldstart, l:col).args[0].text . '}'
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,46 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#comments#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'comments',
|
||||
\ 're' : {'start' : '^\s*%'},
|
||||
\ 'opened' : 0,
|
||||
\}
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if exists('b:vimtex.fold_types_dict.markers.opened')
|
||||
\ && b:vimtex.fold_types_dict.markers.opened | return | endif
|
||||
|
||||
if a:line =~# self.re.start
|
||||
let l:next = getline(a:lnum-1) !~# self.re.start
|
||||
let l:prev = getline(a:lnum+1) !~# self.re.start
|
||||
if l:next && !l:prev
|
||||
let self.opened = 1
|
||||
return 'a1'
|
||||
elseif l:prev && !l:next
|
||||
let self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
let l:lines = map(getline(v:foldstart, v:foldend), 'matchstr(v:val, ''%\s*\zs.*\ze\s*'')')
|
||||
return matchstr(a:line, '^.*\s*%') . join(l:lines, ' ')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,53 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#env_options#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'envs with options',
|
||||
\ 're' : {
|
||||
\ 'start' : g:vimtex#re#not_comment . '\\begin\s*\{.{-}\}\[\s*($|\%)',
|
||||
\ 'end' : '\s*\]\s*$',
|
||||
\ },
|
||||
\ 'opened' : 0,
|
||||
\}
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
return self.opened
|
||||
\ ? self.fold_closed(a:line, a:lnum)
|
||||
\ : self.fold_opened(a:line, a:lnum)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.fold_opened(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let self.opened = 1
|
||||
return 'a1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.fold_closed(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.end
|
||||
let self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
return a:line . '...] '
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,188 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#envs#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'environments',
|
||||
\ 're' : {
|
||||
\ 'start' : g:vimtex#re#not_comment . '\\begin\s*\{.{-}\}',
|
||||
\ 'end' : g:vimtex#re#not_comment . '\\end\s*\{.{-}\}',
|
||||
\ 'name' : g:vimtex#re#not_comment . '\\%(begin|end)\s*\{\zs.{-}\ze\}'
|
||||
\ },
|
||||
\ 'whitelist' : [],
|
||||
\ 'blacklist' : [],
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
" Define the validator as simple as possible
|
||||
if empty(self.whitelist) && empty(self.blacklist)
|
||||
function! self.validate(env) abort dict
|
||||
return 1
|
||||
endfunction
|
||||
elseif empty(self.whitelist)
|
||||
function! self.validate(env) abort dict
|
||||
return index(self.blacklist, a:env) < 0
|
||||
endfunction
|
||||
elseif empty(self.blacklist)
|
||||
function! self.validate(env) abort dict
|
||||
return index(self.whitelist, a:env) >= 0
|
||||
endfunction
|
||||
else
|
||||
function! self.validate(env) abort dict
|
||||
return index(self.whitelist, a:env) >= 0 && index(self.blacklist, a:env) < 0
|
||||
endfunction
|
||||
endif
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
let l:env = matchstr(a:line, self.re.name)
|
||||
|
||||
if !empty(l:env) && self.validate(l:env)
|
||||
if a:line =~# self.re.start
|
||||
if a:line !~# '\\end'
|
||||
return 'a1'
|
||||
endif
|
||||
elseif a:line =~# self.re.end
|
||||
if a:line !~# '\\begin'
|
||||
return 's1'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
let env = matchstr(a:line, self.re.name)
|
||||
if !self.validate(env) | return | endif
|
||||
|
||||
" Set caption/label based on type of environment
|
||||
if env ==# 'frame'
|
||||
let label = ''
|
||||
let caption = self.parse_caption_frame(a:line)
|
||||
elseif env ==# 'table'
|
||||
let label = self.parse_label()
|
||||
let caption = self.parse_caption_table(a:line)
|
||||
else
|
||||
let label = self.parse_label()
|
||||
let caption = self.parse_caption(a:line)
|
||||
endif
|
||||
|
||||
let width_ind = len(matchstr(a:line, '^\s*'))
|
||||
let width = winwidth(0) - (&number ? &numberwidth : 0) - 4 - width_ind
|
||||
|
||||
let width_env = 19
|
||||
let width_lab = len(label) + 2 > width - width_env
|
||||
\ ? width - width_env
|
||||
\ : len(label) + 2
|
||||
let width_cap = width - width_env - width_lab
|
||||
|
||||
if !empty(label)
|
||||
let label = printf('(%.*S)', width_lab, label)
|
||||
endif
|
||||
|
||||
if !empty(caption)
|
||||
if strchars(caption) > width_cap
|
||||
let caption = strpart(caption, 0, width_cap - 4) . '...'
|
||||
endif
|
||||
else
|
||||
let width_env += width_cap
|
||||
let width_cap = 0
|
||||
endif
|
||||
|
||||
if strlen(env) > width_env - 8
|
||||
let env = strpart(env, 0, width_env - 11) . '...'
|
||||
endif
|
||||
let env = '\begin{' . env . '}'
|
||||
|
||||
let title = printf('%*S%-*S %-*S %*S',
|
||||
\ width_ind, '',
|
||||
\ width_env, env,
|
||||
\ width_cap, caption,
|
||||
\ width_lab, label)
|
||||
|
||||
return substitute(title, '\s\+$', '', '')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_label() abort dict " {{{1
|
||||
let i = v:foldend
|
||||
while i >= v:foldstart
|
||||
if getline(i) =~# '^\s*\\label'
|
||||
return matchstr(getline(i), '^\s*\\label\%(\[.*\]\)\?{\zs.*\ze}')
|
||||
end
|
||||
let i -= 1
|
||||
endwhile
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_caption(line) abort dict " {{{1
|
||||
let i = v:foldend
|
||||
while i >= v:foldstart
|
||||
if getline(i) =~# '^\s*\\caption'
|
||||
return matchstr(getline(i),
|
||||
\ '^\s*\\caption\(\[.*\]\)\?{\zs.\{-1,}\ze\(}\s*\)\?$')
|
||||
end
|
||||
let i -= 1
|
||||
endwhile
|
||||
|
||||
" If no caption found, check for a caption comment
|
||||
return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_caption_table(line) abort dict " {{{1
|
||||
let i = v:foldstart
|
||||
while i <= v:foldend
|
||||
if getline(i) =~# '^\s*\\caption'
|
||||
return matchstr(getline(i),
|
||||
\ '^\s*\\caption\s*\(\[.*\]\)\?\s*{\zs.\{-1,}\ze\(}\s*\)\?$')
|
||||
end
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
" If no caption found, check for a caption comment
|
||||
return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_caption_frame(line) abort dict " {{{1
|
||||
" Test simple variants first
|
||||
let caption1 = matchstr(a:line,'\\begin\*\?{.*}\(\[[^]]*\]\)\?{\zs.\+\ze}')
|
||||
let caption2 = matchstr(a:line,'\\begin\*\?{.*}\(\[[^]]*\]\)\?{\zs.\+')
|
||||
if !empty(caption1)
|
||||
return caption1
|
||||
elseif !empty(caption2)
|
||||
return caption2
|
||||
endif
|
||||
|
||||
" Search for \frametitle command
|
||||
let i = v:foldstart
|
||||
while i <= v:foldend
|
||||
if getline(i) =~# '^\s*\\frametitle'
|
||||
return matchstr(getline(i),
|
||||
\ '^\s*\\frametitle\(\[.*\]\)\?{\zs.\{-1,}\ze\(}\s*\)\?$')
|
||||
end
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
" If no caption found, check for a caption comment
|
||||
return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,60 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#markers#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'markers',
|
||||
\ 'open' : '{{{',
|
||||
\ 'close' : '}}}',
|
||||
\ 're' : {},
|
||||
\ 'opened' : 0,
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let self.re.start = '%.*' . self.open
|
||||
let self.re.end = '%.*' . self.close
|
||||
let self.re.text = [
|
||||
\ [self.re.start . '\d\?\s*\zs.*', '% ' . self.open . ' '],
|
||||
\ ['%\s*\zs.*\ze' . self.open, '% ' . self.open . ' '],
|
||||
\ ['^.*\ze\s*%', ''],
|
||||
\]
|
||||
|
||||
let self.re.fold_re = escape(self.open . '|' . self.close, '{}%+*.')
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
let s:self.opened = 1
|
||||
return 'a1'
|
||||
elseif a:line =~# self.re.end
|
||||
let s:self.opened = 0
|
||||
return 's1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
for [l:re, l:pre] in self.re.text
|
||||
let l:text = matchstr(a:line, l:re)
|
||||
if !empty(l:text) | return l:pre . l:text | endif
|
||||
endfor
|
||||
|
||||
return '% ' . self.open . ' ' . getline(v:foldstart + 1)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,36 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#preamble#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'preamble',
|
||||
\ 're' : {
|
||||
\ 'start' : '^\s*\\documentclass',
|
||||
\ 'fold_re' : '\\documentclass',
|
||||
\ },
|
||||
\}
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
if a:line =~# self.re.start
|
||||
return '>1'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
return ' Preamble'
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,180 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fold#sections#new(config) abort " {{{1
|
||||
return extend(deepcopy(s:folder), a:config).init()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:folder = {
|
||||
\ 'name' : 'sections',
|
||||
\ 'parse_levels' : 0,
|
||||
\ 're' : {},
|
||||
\ 'folds' : [],
|
||||
\ 'sections' : [],
|
||||
\ 'parts' : [],
|
||||
\ 'time' : 0,
|
||||
\}
|
||||
function! s:folder.init() abort dict " {{{1
|
||||
let self.re.parts = '\v^\s*\\%(' . join(self.parts, '|') . ')'
|
||||
let self.re.sections = '\v^\s*\\%(' . join(self.sections, '|') . ')'
|
||||
let self.re.fake_sections = '\v^\s*\% Fake%('
|
||||
\ . join(self.sections, '|') . ').*'
|
||||
let self.re.any_sections = '\v^\s*%(\\|\% Fake)%('
|
||||
\ . join(self.sections, '|') . ').*'
|
||||
|
||||
let self.re.start = self.re.parts
|
||||
\ . '|' . self.re.sections
|
||||
\ . '|' . self.re.fake_sections
|
||||
|
||||
let self.re.secpat1 = self.re.sections . '\*?\s*\{\zs.*'
|
||||
let self.re.secpat2 = self.re.sections . '\*?\s*\[\zs.*'
|
||||
|
||||
let self.re.fold_re = '\\%(' . join(self.parts + self.sections, '|') . ')'
|
||||
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.level(line, lnum) abort dict " {{{1
|
||||
call self.refresh()
|
||||
|
||||
" Fold chapters and sections
|
||||
for [l:part, l:level] in self.folds
|
||||
if a:line =~# l:part
|
||||
return '>' . l:level
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.text(line, level) abort dict " {{{1
|
||||
if a:line =~# '\\frontmatter'
|
||||
let l:title = 'Frontmatter'
|
||||
elseif a:line =~# '\\mainmatter'
|
||||
let l:title = 'Mainmatter'
|
||||
elseif a:line =~# '\\backmatter'
|
||||
let l:title = 'Backmatter'
|
||||
elseif a:line =~# '\\appendix'
|
||||
let l:title = 'Appendix'
|
||||
elseif a:line =~# self.re.secpat1
|
||||
let l:title = self.parse_title(matchstr(a:line, self.re.secpat1), 0)
|
||||
elseif a:line =~# self.re.secpat2
|
||||
let l:title = self.parse_title(matchstr(a:line, self.re.secpat2), 1)
|
||||
elseif a:line =~# self.re.fake_sections
|
||||
let l:title = matchstr(a:line, self.re.fake_sections)
|
||||
endif
|
||||
|
||||
let l:level = self.parse_level(v:foldstart, a:level)
|
||||
|
||||
return printf('%-5s %-s', l:level,
|
||||
\ substitute(strpart(l:title, 0, winwidth(0) - 7), '\s\+$', '', ''))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_level(lnum, level) abort dict " {{{1
|
||||
if !self.parse_levels | return a:level | endif
|
||||
|
||||
if !has_key(self, 'toc')
|
||||
let self.toc = vimtex#toc#new({
|
||||
\ 'name' : 'Fold text ToC',
|
||||
\ 'layers' : ['content'],
|
||||
\ 'refresh_always' : 0,
|
||||
\})
|
||||
let self.toc_updated = 0
|
||||
let self.file_updated = {}
|
||||
endif
|
||||
|
||||
let l:file = expand('%')
|
||||
let l:ftime = getftime(l:file)
|
||||
|
||||
if l:ftime > get(self.file_updated, l:file)
|
||||
\ || localtime() > self.toc_updated + 300
|
||||
call self.toc.get_entries(1)
|
||||
let self.toc_entries = filter(
|
||||
\ self.toc.get_visible_entries(),
|
||||
\ '!empty(v:val.number)')
|
||||
let self.file_updated[l:file] = l:ftime
|
||||
let self.toc_updated = localtime()
|
||||
endif
|
||||
|
||||
let l:entries = filter(deepcopy(self.toc_entries), 'v:val.line == a:lnum')
|
||||
if len(l:entries) > 1
|
||||
call filter(l:entries, "v:val.file ==# expand('%:p')")
|
||||
endif
|
||||
|
||||
return empty(l:entries) ? '' : self.toc.print_number(l:entries[0].number)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.parse_title(string, type) abort dict " {{{1
|
||||
let l:idx = -1
|
||||
let l:length = strlen(a:string)
|
||||
let l:level = 1
|
||||
while l:level >= 1
|
||||
let l:idx += 1
|
||||
if l:idx > l:length
|
||||
break
|
||||
elseif a:string[l:idx] ==# ['}',']'][a:type]
|
||||
let l:level -= 1
|
||||
elseif a:string[l:idx] ==# ['{','['][a:type]
|
||||
let l:level += 1
|
||||
endif
|
||||
endwhile
|
||||
let l:parsed = strpart(a:string, 0, l:idx)
|
||||
return empty(l:parsed)
|
||||
\ ? '<untitled>' : l:parsed
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:folder.refresh() abort dict " {{{1
|
||||
"
|
||||
" Parse current buffer to find which sections to fold and their levels. The
|
||||
" patterns are predefined to optimize the folding.
|
||||
"
|
||||
" We ignore top level parts such as \frontmatter, \appendix, \part, and
|
||||
" similar, unless there are at least two such commands in a document.
|
||||
"
|
||||
|
||||
" Only refresh if file has been changed
|
||||
let l:time = getftime(expand('%'))
|
||||
if l:time == self.time | return | endif
|
||||
let self.time = l:time
|
||||
|
||||
" Initialize
|
||||
let self.folds = []
|
||||
let level = 0
|
||||
let buffer = getline(1,'$')
|
||||
|
||||
" Parse part commands (frontmatter, appendix, etc)
|
||||
" Note: We want a minimum of two top level parts
|
||||
let lines = filter(copy(buffer), 'v:val =~ ''' . self.re.parts . '''')
|
||||
if len(lines) >= 2
|
||||
let level += 1
|
||||
call insert(self.folds, [self.re.parts, level])
|
||||
endif
|
||||
|
||||
" Parse section commands (part, chapter, [sub...]section)
|
||||
let lines = filter(copy(buffer), 'v:val =~ ''' . self.re.any_sections . '''')
|
||||
for part in self.sections
|
||||
let partpattern = '^\s*\%(\\\|% Fake\)' . part . ':\?\>'
|
||||
for line in lines
|
||||
if line =~# partpattern
|
||||
let level += 1
|
||||
call insert(self.folds, [partpattern, level])
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,217 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#format#init_buffer() abort " {{{1
|
||||
if !g:vimtex_format_enabled | return | endif
|
||||
|
||||
setlocal formatexpr=vimtex#format#formatexpr()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#format#formatexpr() abort " {{{1
|
||||
if mode() =~# '[iR]' | return -1 | endif
|
||||
|
||||
" Temporary disable folds and save view
|
||||
let l:save_view = winsaveview()
|
||||
let l:foldenable = &l:foldenable
|
||||
setlocal nofoldenable
|
||||
|
||||
let l:top = v:lnum
|
||||
let l:bottom = v:lnum + v:count - 1
|
||||
let l:lines_old = getline(l:top, l:bottom)
|
||||
let l:tries = 5
|
||||
let s:textwidth = &l:textwidth == 0 ? 79 : &l:textwidth
|
||||
|
||||
" This is a hack to make undo restore the correct position
|
||||
if mode() !=# 'i'
|
||||
normal! ix
|
||||
normal! x
|
||||
endif
|
||||
|
||||
" Main formatting algorithm
|
||||
while l:tries > 0
|
||||
" Format the range of lines
|
||||
let l:bottom = s:format(l:top, l:bottom)
|
||||
|
||||
" Ensure proper indentation
|
||||
if l:top < l:bottom
|
||||
silent! execute printf('normal! %sG=%sG', l:top+1, l:bottom)
|
||||
endif
|
||||
|
||||
" Check if any lines have changed
|
||||
let l:lines_new = getline(l:top, l:bottom)
|
||||
let l:index = s:compare_lines(l:lines_new, l:lines_old)
|
||||
let l:top += l:index
|
||||
if l:top > l:bottom | break | endif
|
||||
let l:lines_old = l:lines_new[l:index : -1]
|
||||
let l:tries -= 1
|
||||
endwhile
|
||||
|
||||
" Restore fold and view
|
||||
let &l:foldenable = l:foldenable
|
||||
call winrestview(l:save_view)
|
||||
|
||||
" Set cursor at appropriate position
|
||||
execute 'normal!' l:bottom . 'G^'
|
||||
|
||||
" Don't change the text if the formatting algorithm failed
|
||||
if l:tries == 0
|
||||
silent! undo
|
||||
call vimtex#log#warning('Formatting of selected text failed!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:format(top, bottom) abort " {{{1
|
||||
let l:bottom = a:bottom
|
||||
let l:mark = a:bottom
|
||||
for l:current in range(a:bottom, a:top, -1)
|
||||
let l:line = getline(l:current)
|
||||
|
||||
if vimtex#util#in_mathzone(l:current, 1)
|
||||
\ && vimtex#util#in_mathzone(l:current, col([l:current, '$']))
|
||||
let l:mark = l:current - 1
|
||||
continue
|
||||
endif
|
||||
|
||||
" Skip all lines with comments
|
||||
if l:line =~# '\v%(^|[^\\])\%'
|
||||
if l:current < l:mark
|
||||
let l:bottom += s:format_build_lines(l:current+1, l:mark)
|
||||
endif
|
||||
let l:mark = l:current - 1
|
||||
continue
|
||||
endif
|
||||
|
||||
" Handle long lines
|
||||
if strdisplaywidth(l:line) > s:textwidth
|
||||
let l:bottom += s:format_build_lines(l:current, l:mark)
|
||||
let l:mark = l:current-1
|
||||
endif
|
||||
|
||||
if l:line =~# s:border_end
|
||||
if l:current < l:mark
|
||||
let l:bottom += s:format_build_lines(l:current+1, l:mark)
|
||||
endif
|
||||
let l:mark = l:current
|
||||
endif
|
||||
|
||||
if l:line =~# s:border_beginning
|
||||
if l:current < l:mark
|
||||
let l:bottom += s:format_build_lines(l:current, l:mark)
|
||||
endif
|
||||
let l:mark = l:current-1
|
||||
endif
|
||||
|
||||
if l:line =~# '^\s*$'
|
||||
let l:bottom += s:format_build_lines(l:current+1, l:mark)
|
||||
let l:mark = l:current-1
|
||||
endif
|
||||
endfor
|
||||
|
||||
if a:top <= l:mark
|
||||
let l:bottom += s:format_build_lines(a:top, l:mark)
|
||||
endif
|
||||
|
||||
return l:bottom
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:format_build_lines(start, end) abort " {{{1
|
||||
"
|
||||
" Get the desired text to format as a list of words, but preserve the ending
|
||||
" line spaces
|
||||
"
|
||||
let l:text = join(map(getline(a:start, a:end),
|
||||
\ 'substitute(v:val, ''^\s*'', '''', '''')'), ' ')
|
||||
let l:spaces = matchstr(l:text, '\s*$')
|
||||
let l:words = split(l:text, ' ')
|
||||
if empty(l:words) | return 0 | endif
|
||||
|
||||
"
|
||||
" Add the words in properly indented and formatted lines
|
||||
"
|
||||
let l:lnum = a:start-1
|
||||
let l:current = s:get_indents(indent(a:start))
|
||||
for l:word in l:words
|
||||
if strdisplaywidth(l:word) + strdisplaywidth(l:current) > s:textwidth
|
||||
call append(l:lnum, substitute(l:current, '\s$', '', ''))
|
||||
let l:lnum += 1
|
||||
let l:current = s:get_indents(VimtexIndent(a:start))
|
||||
endif
|
||||
let l:current .= l:word . ' '
|
||||
endfor
|
||||
if l:current !~# '^\s*$'
|
||||
call append(l:lnum, substitute(l:current, '\s$', '', ''))
|
||||
let l:lnum += 1
|
||||
endif
|
||||
|
||||
"
|
||||
" Append the ending line spaces
|
||||
"
|
||||
if !empty(l:spaces)
|
||||
call setline(l:lnum, getline(l:lnum) . l:spaces)
|
||||
endif
|
||||
|
||||
"
|
||||
" Remove old text
|
||||
"
|
||||
silent! execute printf('%s;+%s delete', l:lnum+1, a:end-a:start)
|
||||
|
||||
"
|
||||
" Return the difference between number of lines of old and new text
|
||||
"
|
||||
return l:lnum - a:end
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:compare_lines(new, old) abort " {{{1
|
||||
let l:min_length = min([len(a:new), len(a:old)])
|
||||
for l:i in range(l:min_length)
|
||||
if a:new[l:i] !=# a:old[l:i]
|
||||
return l:i
|
||||
endif
|
||||
endfor
|
||||
return l:min_length
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_indents(number) abort " {{{1
|
||||
return !&l:expandtab && &l:shiftwidth == &l:tabstop
|
||||
\ ? repeat("\t", a:number/&l:tabstop)
|
||||
\ : repeat(' ', a:number)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
" {{{1 Initialize module
|
||||
|
||||
let s:border_beginning = '\v^\s*%(' . join([
|
||||
\ '\\item',
|
||||
\ '\\begin',
|
||||
\ '\\end',
|
||||
\ '%(\\\[|\$\$)\s*$',
|
||||
\], '|') . ')'
|
||||
|
||||
let s:border_end = '\v\\%(' . join([
|
||||
\ '\\\*?',
|
||||
\ 'clear%(double)?page',
|
||||
\ 'linebreak',
|
||||
\ 'new%(line|page)',
|
||||
\ 'pagebreak',
|
||||
\ '%(begin|end)\{[^}]*\}',
|
||||
\ ], '|') . ')\s*$'
|
||||
\ . '|^\s*%(\\\]|\$\$)\s*$'
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,114 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#fzf#run(...) abort " {{{1
|
||||
" Arguments: Two optional arguments
|
||||
"
|
||||
" First argument: ToC filter (default: 'ctli')
|
||||
" This may be used to select certain entry types according to the different
|
||||
" "layers" of vimtex-toc:
|
||||
" c: content: This is the main part and the "real" ToC
|
||||
" t: todo: This shows TODOs from comments and `\todo{...}` commands
|
||||
" l: label: This shows `\label{...}` commands
|
||||
" i: include: This shows included files
|
||||
"
|
||||
" Second argument: Custom options for fzf
|
||||
" It should be an object containing the parameters passed to fzf#run().
|
||||
|
||||
" Note: The '--with-nth 3..' option hides the first two words from the fzf
|
||||
" window. These words are the file name and line number and are used by
|
||||
" the sink.
|
||||
let l:opts = extend({
|
||||
\ 'source': <sid>parse_toc(a:0 == 0 ? 'ctli' : a:1),
|
||||
\ 'sink': function('vimtex#fzf#open_selection'),
|
||||
\ 'options': '--ansi --with-nth 3..',
|
||||
\}, a:0 > 1 ? a:2 : {})
|
||||
|
||||
call fzf#run(l:opts)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#fzf#open_selection(sel) abort " {{{1
|
||||
let line = split(a:sel)[0]
|
||||
let file = split(a:sel)[1]
|
||||
let curr_file = expand('%:p')
|
||||
|
||||
if curr_file == file
|
||||
execute 'normal! ' . line . 'gg'
|
||||
else
|
||||
execute printf('edit +%s %s', line, file)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
function! s:parse_toc(filter) abort " {{{1
|
||||
" Parsing is mostly adapted from the Denite source
|
||||
" (see rplugin/python3/denite/source/vimtex.py)
|
||||
python3 << EOF
|
||||
import vim
|
||||
import json
|
||||
|
||||
def format_number(n):
|
||||
if not n or not type(n) is dict or not 'chapter' in n:
|
||||
return ''
|
||||
|
||||
num = [str(n[k]) for k in [
|
||||
'chapter',
|
||||
'section',
|
||||
'subsection',
|
||||
'subsubsection',
|
||||
'subsubsubsection'] if n[k] != '0']
|
||||
|
||||
if n['appendix'] != '0':
|
||||
num[0] = chr(int(num[0]) + 64)
|
||||
|
||||
return '.'.join(num)
|
||||
|
||||
def colorize(e):
|
||||
try:
|
||||
from colorama import Fore, Style
|
||||
color = {'content' : Fore.WHITE,
|
||||
'include' : Fore.BLUE,
|
||||
'label' : Fore.GREEN,
|
||||
'todo' : Fore.RED}[e['type']]
|
||||
return f"{color}{e['title']:65}{Style.RESET_ALL}"
|
||||
except ModuleNotFoundError:
|
||||
import os
|
||||
if os.name == 'nt':
|
||||
# Colour support on Windows requires Colorama
|
||||
return f"{e['title']:65}"
|
||||
else:
|
||||
color = {'content' : "\u001b[37m",
|
||||
'include' : "\u001b[34m",
|
||||
'label' : "\u001b[32m",
|
||||
'todo' : "\u001b[31m"}[e['type']]
|
||||
return f"{color}{e['title']:65}\u001b[0m"
|
||||
|
||||
def create_candidate(e, depth):
|
||||
number = format_number(dict(e['number']))
|
||||
return f"{e.get('line', 0)} {e['file']} {colorize(e)} {number}"
|
||||
|
||||
entries = vim.eval('vimtex#parser#toc()')
|
||||
depth = max([int(e['level']) for e in entries])
|
||||
filter = vim.eval("a:filter")
|
||||
candidates = [create_candidate(e, depth)
|
||||
for e in entries if e['type'][0] in filter]
|
||||
|
||||
# json.dumps will convert single quotes to double quotes
|
||||
# so that vim understands the ansi escape sequences
|
||||
vim.command(f"let candidates = {json.dumps(candidates)}")
|
||||
EOF
|
||||
|
||||
return candidates
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,193 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#imaps#init_buffer() abort " {{{1
|
||||
if !g:vimtex_imaps_enabled | return | endif
|
||||
|
||||
" Store mappings in buffer
|
||||
if !exists('b:vimtex_imaps')
|
||||
let b:vimtex_imaps = []
|
||||
endif
|
||||
|
||||
"
|
||||
" Create imaps
|
||||
"
|
||||
let l:maps = g:vimtex_imaps_list
|
||||
for l:disable in g:vimtex_imaps_disabled
|
||||
let l:maps = filter(l:maps, 'v:val.lhs !=# ''' . l:disable . '''')
|
||||
endfor
|
||||
for l:map in l:maps + get(s:, 'custom_maps', [])
|
||||
call s:create_map(l:map)
|
||||
endfor
|
||||
|
||||
"
|
||||
" Add mappings and commands
|
||||
"
|
||||
command! -buffer VimtexImapsList call vimtex#imaps#list()
|
||||
nnoremap <buffer> <plug>(vimtex-imaps-list) :call vimtex#imaps#list()<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#imaps#add_map(map) abort " {{{1
|
||||
let s:custom_maps = get(s:, 'custom_maps', []) + [a:map]
|
||||
|
||||
if exists('b:vimtex_imaps')
|
||||
call s:create_map(a:map)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#imaps#list() abort " {{{1
|
||||
let l:maps = b:vimtex_imaps
|
||||
|
||||
silent new vimtex\ imaps
|
||||
|
||||
for l:map in l:maps
|
||||
call append('$', printf('%5S -> %-30S %S',
|
||||
\ get(l:map, 'leader', get(g:, 'vimtex_imaps_leader', '`')) . l:map.lhs,
|
||||
\ l:map.rhs,
|
||||
\ get(l:map, 'wrapper', 'vimtex#imaps#wrap_math')))
|
||||
endfor
|
||||
0delete _
|
||||
|
||||
nnoremap <silent><nowait><buffer> q :bwipeout<cr>
|
||||
nnoremap <silent><nowait><buffer> <esc> :bwipeout<cr>
|
||||
|
||||
setlocal bufhidden=wipe
|
||||
setlocal buftype=nofile
|
||||
setlocal concealcursor=nvic
|
||||
setlocal conceallevel=0
|
||||
setlocal cursorline
|
||||
setlocal nobuflisted
|
||||
setlocal nolist
|
||||
setlocal nospell
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal nonumber
|
||||
setlocal norelativenumber
|
||||
setlocal nomodifiable
|
||||
|
||||
syntax match VimtexImapsLhs /^.*\ze->/ nextgroup=VimtexImapsArrow
|
||||
syntax match VimtexImapsArrow /->/ contained nextgroup=VimtexImapsRhs
|
||||
syntax match VimtexImapsRhs /\s*\S*/ contained nextgroup=VimtexImapsWrapper
|
||||
syntax match VimtexImapsWrapper /.*/ contained
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" The imap generator
|
||||
"
|
||||
function! s:create_map(map) abort " {{{1
|
||||
if index(b:vimtex_imaps, a:map) >= 0 | return | endif
|
||||
let l:map = deepcopy(a:map)
|
||||
|
||||
let l:leader = get(l:map, 'leader', get(g:, 'vimtex_imaps_leader', '`'))
|
||||
if l:leader !=# '' && !hasmapto(l:leader, 'i')
|
||||
silent execute 'inoremap <silent><nowait><buffer>' l:leader . l:leader l:leader
|
||||
endif
|
||||
let l:lhs = l:leader . l:map.lhs
|
||||
|
||||
let l:wrapper = get(l:map, 'wrapper', 'vimtex#imaps#wrap_math')
|
||||
if ! exists('*' . l:wrapper)
|
||||
echoerr 'vimtex error: imaps wrapper does not exist!'
|
||||
echoerr ' ' . l:wrapper
|
||||
return
|
||||
endif
|
||||
|
||||
" Some wrappers use a context which must be made available to the wrapper
|
||||
" function at run time.
|
||||
if has_key(l:map, 'context')
|
||||
execute 'let l:key = "' . escape(l:lhs, '<') . '"'
|
||||
let l:key .= l:map.rhs
|
||||
if !exists('b:vimtex_context')
|
||||
let b:vimtex_context = {}
|
||||
endif
|
||||
let b:vimtex_context[l:key] = l:map.context
|
||||
endif
|
||||
|
||||
" The rhs may be evaluated before being passed to wrapper, unless expr is
|
||||
" disabled (which it is by default)
|
||||
if !get(l:map, 'expr')
|
||||
let l:map.rhs = string(l:map.rhs)
|
||||
endif
|
||||
|
||||
silent execute 'inoremap <expr><silent><nowait><buffer>' l:lhs
|
||||
\ l:wrapper . '("' . escape(l:lhs, '\') . '", ' . l:map.rhs . ')'
|
||||
|
||||
let b:vimtex_imaps += [l:map]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Wrappers
|
||||
"
|
||||
function! vimtex#imaps#wrap_trivial(lhs, rhs) abort " {{{1
|
||||
return a:rhs
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#imaps#wrap_math(lhs, rhs) abort " {{{1
|
||||
return s:is_math() ? a:rhs : a:lhs
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#imaps#wrap_environment(lhs, rhs) abort " {{{1
|
||||
let l:return = a:lhs
|
||||
let l:cursor = vimtex#pos#val(vimtex#pos#get_cursor())
|
||||
let l:value = 0
|
||||
|
||||
for l:context in b:vimtex_context[a:lhs . a:rhs]
|
||||
if type(l:context) == type('')
|
||||
let l:envs = [l:context]
|
||||
let l:rhs = a:rhs
|
||||
elseif type(l:context) == type({})
|
||||
let l:envs = l:context.envs
|
||||
let l:rhs = l:context.rhs
|
||||
endif
|
||||
|
||||
for l:env in l:envs
|
||||
let l:candidate_value = vimtex#pos#val(vimtex#env#is_inside(l:env))
|
||||
if l:candidate_value > l:value
|
||||
let l:value = l:candidate_value
|
||||
let l:return = l:rhs
|
||||
endif
|
||||
endfor
|
||||
|
||||
unlet l:context
|
||||
endfor
|
||||
|
||||
return l:return
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Special rhs styles
|
||||
"
|
||||
function! vimtex#imaps#style_math(command) " {{{1
|
||||
return s:is_math()
|
||||
\ ? '\' . a:command . '{' . nr2char(getchar()) . '}'
|
||||
\ : ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Helpers
|
||||
"
|
||||
function! s:is_math() abort " {{{1
|
||||
return match(map(synstack(line('.'), max([col('.') - 1, 1])),
|
||||
\ 'synIDattr(v:val, ''name'')'), '^texMathZone') >= 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,150 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#include#expr() abort " {{{1
|
||||
call s:visited.timeout()
|
||||
let l:fname = substitute(v:fname, '^\s*\|\s*$', '', 'g')
|
||||
|
||||
"
|
||||
" Check if v:fname matches exactly
|
||||
"
|
||||
if filereadable(l:fname)
|
||||
return s:visited.check(l:fname)
|
||||
endif
|
||||
|
||||
"
|
||||
" Parse \include or \input style lines
|
||||
"
|
||||
let l:file = s:input(l:fname, 'tex')
|
||||
for l:candidate in [l:file, l:file . '.tex']
|
||||
if filereadable(l:candidate)
|
||||
return s:visited.check(l:candidate)
|
||||
endif
|
||||
endfor
|
||||
|
||||
"
|
||||
" Parse \bibliography or \addbibresource
|
||||
"
|
||||
let l:candidate = s:input(l:fname, 'bib')
|
||||
if filereadable(l:candidate)
|
||||
return s:visited.check(l:candidate)
|
||||
endif
|
||||
|
||||
"
|
||||
" Check if v:fname matches in $TEXINPUTS
|
||||
"
|
||||
let l:candidate = s:search_candidates_texinputs(l:fname)
|
||||
if !empty(l:candidate)
|
||||
return s:visited.check(l:candidate)
|
||||
endif
|
||||
|
||||
"
|
||||
" Search for file with kpsewhich
|
||||
"
|
||||
if g:vimtex_include_search_enabled
|
||||
let l:candidate = s:search_candidates_kpsewhich(l:fname)
|
||||
if !empty(l:candidate)
|
||||
return s:visited.check(l:candidate)
|
||||
endif
|
||||
endif
|
||||
|
||||
return s:visited.check(l:fname)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:input(fname, type) abort " {{{1
|
||||
let [l:lnum, l:cnum] = searchpos(g:vimtex#re#{a:type}_input, 'bcn', line('.'))
|
||||
if l:lnum == 0 | return a:fname | endif
|
||||
|
||||
let l:cmd = vimtex#cmd#get_at(l:lnum, l:cnum)
|
||||
if empty(l:cmd) | return a:fname | endif
|
||||
|
||||
let l:file = join(map(
|
||||
\ get(l:cmd, 'args', [{}]),
|
||||
\ "get(v:val, 'text', '')"),
|
||||
\ '')
|
||||
let l:file = substitute(l:file, '^\s*"\|"\s*$', '', 'g')
|
||||
let l:file = substitute(l:file, '\\space', '', 'g')
|
||||
|
||||
if l:file[-3:] !=# a:type
|
||||
let l:file .= '.' . a:type
|
||||
endif
|
||||
|
||||
return l:file
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:search_candidates_texinputs(fname) abort " {{{1
|
||||
for l:suffix in [''] + split(&l:suffixesadd, ',')
|
||||
let l:candidates = glob(b:vimtex.root . '/**/'
|
||||
\ . fnameescape(a:fname) . l:suffix, 0, 1)
|
||||
if !empty(l:candidates)
|
||||
return l:candidates[0]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:search_candidates_kpsewhich(fname) abort " {{{1
|
||||
" Split input list on commas, and if applicable, ensure that the entry that
|
||||
" the cursor is on is placed first in the queue
|
||||
let l:files = split(a:fname, '\s*,\s*')
|
||||
let l:current = expand('<cword>')
|
||||
let l:index = index(l:files, l:current)
|
||||
if l:index >= 0
|
||||
call remove(l:files, l:index)
|
||||
let l:files = [l:current] + l:files
|
||||
endif
|
||||
|
||||
" Add file extensions to create the final list of candidate files
|
||||
let l:candidates = []
|
||||
for l:file in l:files
|
||||
if !empty(fnamemodify(l:file, ':e'))
|
||||
call add(l:candidates, l:file)
|
||||
else
|
||||
call extend(l:candidates, map(split(&l:suffixesadd, ','), 'l:file . v:val'))
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:file in l:candidates
|
||||
let l:candidate = vimtex#kpsewhich#find(l:file)
|
||||
if !empty(l:candidate) && filereadable(l:candidate) | return l:candidate | endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:visited = {
|
||||
\ 'time' : 0,
|
||||
\ 'list' : [],
|
||||
\}
|
||||
function! s:visited.timeout() abort dict " {{{1
|
||||
if localtime() - self.time > 1
|
||||
let self.time = localtime()
|
||||
let self.list = [expand('%:p')]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:visited.check(fname) abort dict " {{{1
|
||||
if index(self.list, fnamemodify(a:fname, ':p')) < 0
|
||||
call add(self.list, fnamemodify(a:fname, ':p'))
|
||||
return a:fname
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,222 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#info#init_buffer() abort " {{{1
|
||||
command! -buffer -bang VimtexInfo call vimtex#info#open(<q-bang> == '!')
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-info) :VimtexInfo<cr>
|
||||
nnoremap <buffer> <plug>(vimtex-info-full) :VimtexInfo!<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#info#open(global) abort " {{{1
|
||||
let s:info.global = a:global
|
||||
call vimtex#scratch#new(s:info)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:info = {
|
||||
\ 'name' : 'VimtexInfo',
|
||||
\ 'global' : 0,
|
||||
\}
|
||||
function! s:info.print_content() abort dict " {{{1
|
||||
for l:line in self.gather_system_info()
|
||||
call append('$', l:line)
|
||||
endfor
|
||||
call append('$', '')
|
||||
for l:line in self.gather_state_info()
|
||||
call append('$', l:line)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:info.gather_system_info() abort dict " {{{1
|
||||
let l:lines = [
|
||||
\ 'System info',
|
||||
\ ' OS: ' . s:get_os_info(),
|
||||
\ ' Vim version: ' . s:get_vim_info(),
|
||||
\]
|
||||
|
||||
if has('clientserver') || has('nvim')
|
||||
call add(l:lines, ' Has clientserver: true')
|
||||
call add(l:lines, ' Servername: '
|
||||
\ . (empty(v:servername) ? 'undefined (vim started without --servername)' : v:servername))
|
||||
else
|
||||
call add(l:lines, ' Has clientserver: false')
|
||||
endif
|
||||
|
||||
return l:lines
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:info.gather_state_info() abort dict " {{{1
|
||||
if self.global
|
||||
let l:lines = []
|
||||
for l:data in vimtex#state#list_all()
|
||||
let l:lines += s:get_info(l:data)
|
||||
let l:lines += ['']
|
||||
endfor
|
||||
call remove(l:lines, -1)
|
||||
else
|
||||
let l:lines = s:get_info(b:vimtex)
|
||||
endif
|
||||
|
||||
return l:lines
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:info.syntax() abort dict " {{{1
|
||||
syntax match VimtexInfoOther /.*/
|
||||
syntax match VimtexInfoKey /^.*:/ nextgroup=VimtexInfoValue
|
||||
syntax match VimtexInfoValue /.*/ contained
|
||||
syntax match VimtexInfoTitle /vimtex project:/ nextgroup=VimtexInfoValue
|
||||
syntax match VimtexInfoTitle /System info/
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Functions to parse the vimtex state data
|
||||
"
|
||||
function! s:get_info(item, ...) abort " {{{1
|
||||
if empty(a:item) | return [] | endif
|
||||
let l:indent = a:0 > 0 ? a:1 : 0
|
||||
|
||||
if type(a:item) == type({})
|
||||
return s:parse_dict(a:item, l:indent)
|
||||
endif
|
||||
|
||||
if type(a:item) == type([])
|
||||
let l:entries = []
|
||||
for [l:title, l:Value] in a:item
|
||||
if type(l:Value) == type({})
|
||||
call extend(l:entries, s:parse_dict(l:Value, l:indent, l:title))
|
||||
elseif type(l:Value) == type([])
|
||||
call extend(l:entries, s:parse_list(l:Value, l:indent, l:title))
|
||||
else
|
||||
call add(l:entries,
|
||||
\ repeat(' ', l:indent) . printf('%s: %s', l:title, l:Value))
|
||||
endif
|
||||
unlet l:Value
|
||||
endfor
|
||||
return l:entries
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_dict(dict, indent, ...) abort " {{{1
|
||||
if empty(a:dict) | return [] | endif
|
||||
let l:dict = a:dict
|
||||
let l:indent = a:indent
|
||||
let l:entries = []
|
||||
|
||||
if a:0 > 0
|
||||
let l:title = a:1
|
||||
let l:name = ''
|
||||
if has_key(a:dict, 'name')
|
||||
let l:dict = deepcopy(a:dict)
|
||||
let l:name = remove(l:dict, 'name')
|
||||
endif
|
||||
call add(l:entries,
|
||||
\ repeat(' ', l:indent) . printf('%s: %s', l:title, l:name))
|
||||
let l:indent += 1
|
||||
endif
|
||||
|
||||
let l:items = has_key(l:dict, 'pprint_items')
|
||||
\ ? l:dict.pprint_items() : items(l:dict)
|
||||
|
||||
return extend(l:entries, s:get_info(l:items, l:indent))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_list(list, indent, title) abort " {{{1
|
||||
if empty(a:list) | return [] | endif
|
||||
|
||||
let l:entries = []
|
||||
let l:indent = repeat(' ', a:indent)
|
||||
if type(a:list[0]) == type([])
|
||||
let l:name = ''
|
||||
let l:index = 0
|
||||
|
||||
" l:entry[0] == title
|
||||
" l:entry[1] == value
|
||||
for l:entry in a:list
|
||||
if l:entry[0] ==# 'name'
|
||||
let l:name = l:entry[1]
|
||||
break
|
||||
endif
|
||||
let l:index += 1
|
||||
endfor
|
||||
|
||||
if empty(l:name)
|
||||
let l:list = a:list
|
||||
else
|
||||
let l:list = deepcopy(a:list)
|
||||
call remove(l:list, l:index)
|
||||
endif
|
||||
|
||||
call add(l:entries, l:indent . printf('%s: %s', a:title, l:name))
|
||||
call extend(l:entries, s:get_info(l:list, a:indent+1))
|
||||
else
|
||||
call add(l:entries, l:indent . printf('%s:', a:title))
|
||||
for l:value in a:list
|
||||
call add(l:entries, l:indent . printf(' %s', l:value))
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Other utility functions
|
||||
"
|
||||
function! s:get_os_info() abort " {{{1
|
||||
let l:os = vimtex#util#get_os()
|
||||
|
||||
if l:os ==# 'linux'
|
||||
let l:result = executable('lsb_release')
|
||||
\ ? system('lsb_release -d')[12:-2]
|
||||
\ : system('uname -sr')[:-2]
|
||||
return substitute(l:result, '^\s*', '', '')
|
||||
elseif l:os ==# 'mac'
|
||||
let l:name = system('sw_vers -productName')[:-2]
|
||||
let l:version = system('sw_vers -productVersion')[:-2]
|
||||
let l:build = system('sw_vers -buildVersion')[:-2]
|
||||
return l:name . ' ' . l:version . ' (' . l:build . ')'
|
||||
else
|
||||
if !exists('s:win_info')
|
||||
let s:win_info = vimtex#process#capture('systeminfo')
|
||||
endif
|
||||
|
||||
let l:name = matchstr(s:win_info[1], ':\s*\zs.*')
|
||||
let l:version = matchstr(s:win_info[2], ':\s*\zs.*')
|
||||
return l:name . ' (' . l:version . ')'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_vim_info() abort " {{{1
|
||||
let l:info = vimtex#util#command('version')
|
||||
|
||||
if has('nvim')
|
||||
return l:info[0]
|
||||
else
|
||||
let l:version = 'VIM ' . strpart(l:info[0], 18, 3) . ' ('
|
||||
let l:index = 2 - (l:info[1] =~# ':\s*\d')
|
||||
let l:version .= matchstr(l:info[l:index], ':\s*\zs.*') . ')'
|
||||
return l:version
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,53 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#kpsewhich#find(file) abort " {{{1
|
||||
return s:find_cached(a:file)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#kpsewhich#run(args) abort " {{{1
|
||||
" kpsewhich should be run at the project root directory
|
||||
if exists('b:vimtex.root')
|
||||
call vimtex#paths#pushd(b:vimtex.root)
|
||||
endif
|
||||
let l:output = vimtex#process#capture('kpsewhich ' . a:args)
|
||||
if exists('b:vimtex.root')
|
||||
call vimtex#paths#popd()
|
||||
endif
|
||||
|
||||
" Remove warning lines from output
|
||||
call filter(l:output, 'stridx(v:val, "kpsewhich: warning: ") == -1')
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:find(file) abort " {{{1
|
||||
let l:output = vimtex#kpsewhich#run(fnameescape(a:file))
|
||||
if empty(l:output) | return '' | endif
|
||||
|
||||
let l:filename = l:output[0]
|
||||
|
||||
" Ensure absolute path
|
||||
if !vimtex#paths#is_abs(l:filename) && exists('b:vimtex.root')
|
||||
let l:filename = simplify(b:vimtex.root . '/' . l:filename)
|
||||
endif
|
||||
|
||||
return l:filename
|
||||
endfunction
|
||||
|
||||
" Use caching if possible (requires 'lambda' feature)
|
||||
let s:find_cached = has('lambda')
|
||||
\ ? vimtex#cache#wrap(function('s:find'), 'kpsewhich')
|
||||
\ : function('s:find')
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,137 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#log#init_buffer() abort " {{{1
|
||||
command! -buffer -bang VimtexLog call vimtex#log#open()
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-log) :VimtexLog<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#log#info(...) abort " {{{1
|
||||
call s:logger.add(a:000, 'info')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#log#warning(...) abort " {{{1
|
||||
call s:logger.add(a:000, 'warning')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#log#error(...) abort " {{{1
|
||||
call s:logger.add(a:000, 'error')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#log#get() abort " {{{1
|
||||
return s:logger.entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#log#open() abort " {{{1
|
||||
call vimtex#scratch#new(s:logger)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#log#toggle_verbose() abort " {{{1
|
||||
if s:logger.verbose
|
||||
let s:logger.verbose = 0
|
||||
call vimtex#log#info('Logging is now quiet')
|
||||
else
|
||||
call vimtex#log#info('Logging is now verbose')
|
||||
let s:logger.verbose = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:logger = {
|
||||
\ 'name' : 'VimtexMessageLog',
|
||||
\ 'entries' : [],
|
||||
\ 'type_to_highlight' : {
|
||||
\ 'info' : 'VimtexInfo',
|
||||
\ 'warning' : 'VimtexWarning',
|
||||
\ 'error' : 'VimtexError',
|
||||
\ },
|
||||
\ 'verbose' : get(g:, 'vimtex_log_verbose', 1),
|
||||
\}
|
||||
function! s:logger.add(msg_arg, type) abort dict " {{{1
|
||||
let l:msg_list = []
|
||||
for l:msg in a:msg_arg
|
||||
if type(l:msg) == type('')
|
||||
call add(l:msg_list, l:msg)
|
||||
elseif type(l:msg) == type([])
|
||||
call extend(l:msg_list, filter(l:msg, "type(v:val) == type('')"))
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:entry = {}
|
||||
let l:entry.type = a:type
|
||||
let l:entry.time = strftime('%T')
|
||||
let l:entry.callstack = vimtex#debug#stacktrace()[1:]
|
||||
let l:entry.msg = l:msg_list
|
||||
call add(self.entries, l:entry)
|
||||
|
||||
if !self.verbose | return | endif
|
||||
|
||||
" Ignore message
|
||||
for l:re in get(g:, 'vimtex_log_ignore', [])
|
||||
if join(l:msg_list) =~# l:re | return | endif
|
||||
endfor
|
||||
|
||||
call vimtex#echo#formatted([
|
||||
\ [self.type_to_highlight[a:type], 'vimtex:'],
|
||||
\ ' ' . l:msg_list[0]
|
||||
\])
|
||||
for l:line in l:msg_list[1:]
|
||||
call vimtex#echo#echo(' ' . l:line)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:logger.print_content() abort dict " {{{1
|
||||
for l:entry in self.entries
|
||||
call append('$', printf('%s: %s', l:entry.time, l:entry.type))
|
||||
for l:stack in l:entry.callstack
|
||||
if l:stack.lnum > 0
|
||||
call append('$', printf(' #%d %s:%d', l:stack.nr, l:stack.filename, l:stack.lnum))
|
||||
else
|
||||
call append('$', printf(' #%d %s', l:stack.nr, l:stack.filename))
|
||||
endif
|
||||
call append('$', printf(' In %s', l:stack.function))
|
||||
if !empty(l:stack.text)
|
||||
call append('$', printf(' %s', l:stack.text))
|
||||
endif
|
||||
endfor
|
||||
for l:msg in l:entry.msg
|
||||
call append('$', printf(' %s', l:msg))
|
||||
endfor
|
||||
call append('$', '')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:logger.syntax() abort dict " {{{1
|
||||
syntax match VimtexInfoOther /.*/
|
||||
|
||||
syntax include @VIM syntax/vim.vim
|
||||
syntax match VimtexInfoVimCode /^ .*/ transparent contains=@VIM
|
||||
|
||||
syntax match VimtexInfoKey /^\S*:/ nextgroup=VimtexInfoValue
|
||||
syntax match VimtexInfoKey /^ #\d\+/ nextgroup=VimtexInfoValue
|
||||
syntax match VimtexInfoKey /^ In/ nextgroup=VimtexInfoValue
|
||||
syntax match VimtexInfoValue /.*/ contained
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,111 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#matchparen#init_buffer() abort " {{{1
|
||||
if !g:vimtex_matchparen_enabled | return | endif
|
||||
|
||||
call vimtex#matchparen#enable()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#matchparen#enable() abort " {{{1
|
||||
call s:matchparen.enable()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#matchparen#disable() abort " {{{1
|
||||
call s:matchparen.disable()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#matchparen#popup_check(...) abort " {{{1
|
||||
if pumvisible()
|
||||
call s:matchparen.highlight()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matchparen = {}
|
||||
|
||||
function! s:matchparen.enable() abort dict " {{{1
|
||||
" vint: -ProhibitAutocmdWithNoGroup
|
||||
|
||||
execute 'augroup vimtex_matchparen' . bufnr('%')
|
||||
autocmd!
|
||||
autocmd CursorMoved <buffer> call s:matchparen.highlight()
|
||||
autocmd CursorMovedI <buffer> call s:matchparen.highlight()
|
||||
try
|
||||
autocmd TextChangedP <buffer> call s:matchparen.highlight()
|
||||
catch /E216/
|
||||
silent! let self.timer =
|
||||
\ timer_start(50, 'vimtex#matchparen#popup_check', {'repeat' : -1})
|
||||
endtry
|
||||
augroup END
|
||||
|
||||
call self.highlight()
|
||||
|
||||
" vint: +ProhibitAutocmdWithNoGroup
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matchparen.disable() abort dict " {{{1
|
||||
call self.clear()
|
||||
execute 'autocmd! vimtex_matchparen' . bufnr('%')
|
||||
silent! call timer_stop(self.timer)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matchparen.clear() abort dict " {{{1
|
||||
silent! call matchdelete(w:vimtex_match_id1)
|
||||
silent! call matchdelete(w:vimtex_match_id2)
|
||||
unlet! w:vimtex_match_id1
|
||||
unlet! w:vimtex_match_id2
|
||||
endfunction
|
||||
function! s:matchparen.highlight() abort dict " {{{1
|
||||
call self.clear()
|
||||
|
||||
if vimtex#util#in_comment() | return | endif
|
||||
|
||||
" This is a hack to ensure that $ in visual block mode adhers to the rule
|
||||
" specified in :help v_$
|
||||
if mode() ==# "\<c-v>"
|
||||
let l:pos = vimtex#pos#get_cursor()
|
||||
if len(l:pos) == 5 && l:pos[-1] == 2147483647
|
||||
call feedkeys('$', 'in')
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:current = vimtex#delim#get_current('all', 'both')
|
||||
if empty(l:current) | return | endif
|
||||
|
||||
let l:corresponding = vimtex#delim#get_matching(l:current)
|
||||
if empty(l:corresponding) | return | endif
|
||||
if empty(l:corresponding.match) | return | endif
|
||||
|
||||
let [l:open, l:close] = l:current.is_open
|
||||
\ ? [l:current, l:corresponding]
|
||||
\ : [l:corresponding, l:current]
|
||||
|
||||
if exists('*matchaddpos')
|
||||
let w:vimtex_match_id1 = matchaddpos('MatchParen',
|
||||
\ [[l:open.lnum, l:open.cnum, strlen(l:open.match)]])
|
||||
let w:vimtex_match_id2 = matchaddpos('MatchParen',
|
||||
\ [[l:close.lnum, l:close.cnum, strlen(l:close.match)]])
|
||||
else
|
||||
let w:vimtex_match_id1 = matchadd('MatchParen',
|
||||
\ '\%' . l:open.lnum . 'l\%' . l:open.cnum . 'c' . l:open.re.this)
|
||||
let w:vimtex_match_id2 = matchadd('MatchParen',
|
||||
\ '\%' . l:close.lnum . 'l\%' . l:close.cnum . 'c' . l:close.re.this)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,158 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#misc#init_buffer() abort " {{{1
|
||||
command! -buffer VimtexReload call vimtex#misc#reload()
|
||||
command! -buffer -bang -range=% VimtexCountWords
|
||||
\ call vimtex#misc#wordcount_display({
|
||||
\ 'range' : [<line1>, <line2>],
|
||||
\ 'detailed' : <q-bang> == '!',
|
||||
\ 'count_letters' : 0,
|
||||
\ })
|
||||
command! -buffer -bang -range=% VimtexCountLetters
|
||||
\ call vimtex#misc#wordcount_display({
|
||||
\ 'range' : [<line1>, <line2>],
|
||||
\ 'detailed' : <q-bang> == '!',
|
||||
\ 'count_letters' : 1,
|
||||
\ })
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-reload) :VimtexReload<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#misc#get_graphicspath(fname) abort " {{{1
|
||||
for l:root in b:vimtex.graphicspath + ['.']
|
||||
let l:candidate = simplify(b:vimtex.root . '/' . l:root . '/' . a:fname)
|
||||
for l:suffix in ['', '.jpg', '.png', '.pdf']
|
||||
if filereadable(l:candidate . l:suffix)
|
||||
return l:candidate . l:suffix
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return a:fname
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#misc#wordcount(...) abort " {{{1
|
||||
let l:opts = a:0 > 0 ? a:1 : {}
|
||||
|
||||
let l:range = get(l:opts, 'range', [1, line('$')])
|
||||
if l:range == [1, line('$')]
|
||||
let l:file = b:vimtex
|
||||
else
|
||||
let l:file = vimtex#parser#selection_to_texfile('arg', l:range)
|
||||
endif
|
||||
|
||||
let cmd = 'cd ' . vimtex#util#shellescape(l:file.root)
|
||||
let cmd .= has('win32') ? '& ' : '; '
|
||||
let cmd .= 'texcount -nosub -sum '
|
||||
let cmd .= get(l:opts, 'count_letters') ? '-letter ' : ''
|
||||
let cmd .= get(l:opts, 'detailed') ? '-inc ' : '-q -1 -merge '
|
||||
let cmd .= g:vimtex_texcount_custom_arg . ' '
|
||||
let cmd .= vimtex#util#shellescape(l:file.base)
|
||||
let lines = vimtex#process#capture(cmd)
|
||||
|
||||
if l:file.base !=# b:vimtex.base
|
||||
call delete(l:file.tex)
|
||||
endif
|
||||
|
||||
if get(l:opts, 'detailed')
|
||||
return lines
|
||||
else
|
||||
call filter(lines, 'v:val !~# ''ERROR\|^\s*$''')
|
||||
return join(lines, '')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#misc#wordcount_display(opts) abort " {{{1
|
||||
let output = vimtex#misc#wordcount(a:opts)
|
||||
|
||||
if !get(a:opts, 'detailed')
|
||||
call vimtex#log#info('Counted '
|
||||
\ . (get(a:opts, 'count_letters') ? 'letters: ' : 'words: ')
|
||||
\ . output)
|
||||
return
|
||||
endif
|
||||
|
||||
" Create wordcount window
|
||||
if bufnr('TeXcount') >= 0
|
||||
bwipeout TeXcount
|
||||
endif
|
||||
split TeXcount
|
||||
|
||||
" Add lines to buffer
|
||||
for line in output
|
||||
call append('$', printf('%s', line))
|
||||
endfor
|
||||
0delete _
|
||||
|
||||
" Set mappings
|
||||
nnoremap <buffer><nowait><silent> q :bwipeout<cr>
|
||||
|
||||
" Set buffer options
|
||||
setlocal bufhidden=wipe
|
||||
setlocal buftype=nofile
|
||||
setlocal cursorline
|
||||
setlocal nobuflisted
|
||||
setlocal nolist
|
||||
setlocal nospell
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal tabstop=8
|
||||
setlocal nomodifiable
|
||||
|
||||
" Set highlighting
|
||||
syntax match TexcountText /^.*:.*/ contains=TexcountValue
|
||||
syntax match TexcountValue /.*:\zs.*/
|
||||
highlight link TexcountText VimtexMsg
|
||||
highlight link TexcountValue Constant
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
" {{{1 function! vimtex#misc#reload()
|
||||
if get(s:, 'reload_guard', 1)
|
||||
function! vimtex#misc#reload() abort
|
||||
let s:reload_guard = 0
|
||||
|
||||
for l:file in glob(fnamemodify(s:file, ':h') . '/../**/*.vim', 0, 1)
|
||||
execute 'source' l:file
|
||||
endfor
|
||||
|
||||
" Temporarily unset b:current_syntax (if active)
|
||||
let l:reload_syntax = get(b:, 'current_syntax', '') ==# 'tex'
|
||||
if l:reload_syntax
|
||||
unlet b:current_syntax
|
||||
endif
|
||||
|
||||
call vimtex#init()
|
||||
|
||||
" Reload syntax
|
||||
if l:reload_syntax
|
||||
runtime! syntax/tex.vim
|
||||
endif
|
||||
|
||||
" Reload indent file
|
||||
if exists('b:did_vimtex_indent')
|
||||
unlet b:did_indent
|
||||
runtime indent/tex.vim
|
||||
endif
|
||||
|
||||
call vimtex#log#info('The plugin has been reloaded!')
|
||||
unlet s:reload_guard
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:file = expand('<sfile>')
|
||||
|
||||
endif
|
||||
@@ -1,207 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#motion#init_buffer() abort " {{{1
|
||||
if !g:vimtex_motion_enabled | return | endif
|
||||
|
||||
" Utility map to avoid conflict with "normal" command
|
||||
nnoremap <buffer> <sid>(v) v
|
||||
nnoremap <buffer> <sid>(V) V
|
||||
|
||||
" Matching pairs
|
||||
nnoremap <silent><buffer> <plug>(vimtex-%) :call vimtex#motion#find_matching_pair()<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-%) :<c-u>call vimtex#motion#find_matching_pair(1)<cr>
|
||||
xmap <silent><buffer> <plug>(vimtex-%) <sid>(vimtex-%)
|
||||
onoremap <silent><buffer> <plug>(vimtex-%) :execute "normal \<sid>(v)\<sid>(vimtex-%)"<cr>
|
||||
|
||||
" Sections
|
||||
nnoremap <silent><buffer> <plug>(vimtex-]]) :<c-u>call vimtex#motion#section(0,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-][) :<c-u>call vimtex#motion#section(1,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[]) :<c-u>call vimtex#motion#section(1,1,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[[) :<c-u>call vimtex#motion#section(0,1,0)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-]]) :<c-u>call vimtex#motion#section(0,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-][) :<c-u>call vimtex#motion#section(1,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[]) :<c-u>call vimtex#motion#section(1,1,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[[) :<c-u>call vimtex#motion#section(0,1,1)<cr>
|
||||
xmap <silent><buffer> <plug>(vimtex-]]) <sid>(vimtex-]])
|
||||
xmap <silent><buffer> <plug>(vimtex-][) <sid>(vimtex-][)
|
||||
xmap <silent><buffer> <plug>(vimtex-[]) <sid>(vimtex-[])
|
||||
xmap <silent><buffer> <plug>(vimtex-[[) <sid>(vimtex-[[)
|
||||
onoremap <silent><buffer> <plug>(vimtex-]])
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-]])"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-][)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-][)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[])
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[])"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[[)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[[)"<cr>
|
||||
|
||||
" Environments
|
||||
nnoremap <silent><buffer> <plug>(vimtex-]m) :<c-u>call vimtex#motion#environment(1,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-]M) :<c-u>call vimtex#motion#environment(0,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[m) :<c-u>call vimtex#motion#environment(1,1,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[M) :<c-u>call vimtex#motion#environment(0,1,0)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-]m) :<c-u>call vimtex#motion#environment(1,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-]M) :<c-u>call vimtex#motion#environment(0,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[m) :<c-u>call vimtex#motion#environment(1,1,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[M) :<c-u>call vimtex#motion#environment(0,1,1)<cr>
|
||||
xmap <silent><buffer> <plug>(vimtex-]m) <sid>(vimtex-]m)
|
||||
xmap <silent><buffer> <plug>(vimtex-]M) <sid>(vimtex-]M)
|
||||
xmap <silent><buffer> <plug>(vimtex-[m) <sid>(vimtex-[m)
|
||||
xmap <silent><buffer> <plug>(vimtex-[M) <sid>(vimtex-[M)
|
||||
onoremap <silent><buffer> <plug>(vimtex-]m)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-]m)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-]M)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-]M)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[m)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[m)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[M)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[M)"<cr>
|
||||
|
||||
" Comments
|
||||
nnoremap <silent><buffer> <plug>(vimtex-]/) :<c-u>call vimtex#motion#comment(1,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-]*) :<c-u>call vimtex#motion#comment(0,0,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[/) :<c-u>call vimtex#motion#comment(1,1,0)<cr>
|
||||
nnoremap <silent><buffer> <plug>(vimtex-[*) :<c-u>call vimtex#motion#comment(0,1,0)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-]/) :<c-u>call vimtex#motion#comment(1,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-]*) :<c-u>call vimtex#motion#comment(0,0,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[/) :<c-u>call vimtex#motion#comment(1,1,1)<cr>
|
||||
xnoremap <silent><buffer> <sid>(vimtex-[*) :<c-u>call vimtex#motion#comment(0,1,1)<cr>
|
||||
xmap <silent><buffer> <plug>(vimtex-]/) <sid>(vimtex-]/)
|
||||
xmap <silent><buffer> <plug>(vimtex-]*) <sid>(vimtex-]*)
|
||||
xmap <silent><buffer> <plug>(vimtex-[/) <sid>(vimtex-[/)
|
||||
xmap <silent><buffer> <plug>(vimtex-[*) <sid>(vimtex-[*)
|
||||
onoremap <silent><buffer> <plug>(vimtex-]/)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-]/)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-]*)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-]*)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[/)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[/)"<cr>
|
||||
onoremap <silent><buffer> <plug>(vimtex-[*)
|
||||
\ :execute "normal \<sid>(V)" . v:count1 . "\<sid>(vimtex-[*)"<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#motion#find_matching_pair(...) abort " {{{1
|
||||
if a:0 > 0
|
||||
normal! gv
|
||||
endif
|
||||
|
||||
let delim = vimtex#delim#get_current('all', 'both')
|
||||
if empty(delim)
|
||||
let delim = vimtex#delim#get_next('all', 'both')
|
||||
if empty(delim) | return | endif
|
||||
endif
|
||||
|
||||
let delim = vimtex#delim#get_matching(delim)
|
||||
if empty(delim) | return | endif
|
||||
if empty(delim.match) | return | endif
|
||||
|
||||
normal! m`
|
||||
call vimtex#pos#set_cursor(delim.lnum,
|
||||
\ (delim.is_open
|
||||
\ ? delim.cnum
|
||||
\ : delim.cnum + strlen(delim.match) - 1))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#motion#section(type, backwards, visual) abort " {{{1
|
||||
let l:count = v:count1
|
||||
if a:visual
|
||||
normal! gv
|
||||
endif
|
||||
|
||||
" Check trivial cases
|
||||
let l:top = search(s:re_sec, 'nbW') == 0
|
||||
let l:bottom = search(a:type == 1 ? s:re_sec_t2 : s:re_sec, 'nW') == 0
|
||||
if a:backwards && l:top
|
||||
return vimtex#pos#set_cursor([1, 1])
|
||||
elseif !a:backwards && l:bottom
|
||||
return vimtex#pos#set_cursor([line('$'), 1])
|
||||
endif
|
||||
|
||||
" Define search pattern and search flag
|
||||
let l:re = a:type == 0 ? s:re_sec : s:re_sec_t1
|
||||
let l:flags = 'W'
|
||||
if a:backwards
|
||||
let l:flags .= 'b'
|
||||
endif
|
||||
|
||||
for l:_ in range(l:count)
|
||||
let l:save_pos = vimtex#pos#get_cursor()
|
||||
|
||||
if a:type == 1
|
||||
call search('\S', 'W')
|
||||
endif
|
||||
|
||||
let l:bottom = search(s:re_sec_t2, 'nW') == 0
|
||||
if a:type == 1 && !a:backwards && l:bottom
|
||||
return vimtex#pos#set_cursor([line('$'), 1])
|
||||
endif
|
||||
|
||||
let l:top = search(s:re_sec, 'ncbW') == 0
|
||||
let l:lnum = search(l:re, l:flags)
|
||||
|
||||
if l:top && l:lnum > 0 && a:type == 1 && !a:backwards
|
||||
let l:lnum = search(l:re, l:flags)
|
||||
endif
|
||||
|
||||
if a:type == 1
|
||||
call search('\S\s*\n\zs', 'Wb')
|
||||
|
||||
" Move to start of file if cursor was moved to top part of document
|
||||
if search(s:re_sec, 'ncbW') == 0
|
||||
call vimtex#pos#set_cursor([1, 1])
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#motion#environment(begin, backwards, visual) abort " {{{1
|
||||
let l:count = v:count1
|
||||
if a:visual
|
||||
normal! gv
|
||||
endif
|
||||
|
||||
let l:re = g:vimtex#re#not_comment . (a:begin ? '\\begin\s*\{' : '\\end\s*\{')
|
||||
let l:flags = 'W' . (a:backwards ? 'b' : '')
|
||||
|
||||
for l:_ in range(l:count)
|
||||
call search(l:re, l:flags)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#motion#comment(begin, backwards, visual) abort " {{{1
|
||||
let l:count = v:count1
|
||||
if a:visual
|
||||
normal! gv
|
||||
endif
|
||||
|
||||
let l:re = a:begin
|
||||
\ ? '\v%(^\s*\%.*\n)@<!\s*\%'
|
||||
\ : '\v^\s*\%.*\n%(^\s*\%)@!'
|
||||
let l:flags = 'W' . (a:backwards ? 'b' : '')
|
||||
|
||||
for l:_ in range(l:count)
|
||||
call search(l:re, l:flags)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
" Patterns to match section/chapter/...
|
||||
let s:re_sec = '\v^\s*\\%(%(sub)?paragraph|%(sub)*section|chapter|part|'
|
||||
\ . 'appendi%(x|ces)|%(front|back|main)matter)>'
|
||||
let s:re_sec_t1 = '\v%(' . s:re_sec . '|^\s*%(\\end\{document\}|%$))'
|
||||
let s:re_sec_t2 = '\v%(' . s:re_sec . '|^\s*\\end\{document\})'
|
||||
|
||||
endif
|
||||
@@ -1,144 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#parser#tex(file, ...) abort " {{{1
|
||||
return vimtex#parser#tex#parse(a:file, a:0 > 0 ? a:1 : {})
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#preamble(file, ...) abort " {{{1
|
||||
return vimtex#parser#tex#parse_preamble(a:file, a:0 > 0 ? a:1 : {})
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#auxiliary(file) abort " {{{1
|
||||
return vimtex#parser#auxiliary#parse(a:file)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#fls(file) abort " {{{1
|
||||
return vimtex#parser#fls#parse(a:file)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#toc(...) abort " {{{1
|
||||
let l:vimtex = a:0 > 0 ? a:1 : b:vimtex
|
||||
|
||||
let l:cache = vimtex#cache#open('parsertoc', {
|
||||
\ 'persistent': 0,
|
||||
\ 'default': {'entries': [], 'ftime': -1},
|
||||
\})
|
||||
let l:current = l:cache.get(l:vimtex.tex)
|
||||
|
||||
" Update cache if relevant
|
||||
let l:ftime = l:vimtex.getftime()
|
||||
if l:ftime > l:current.ftime
|
||||
let l:cache.modified = 1
|
||||
let l:current.ftime = l:ftime
|
||||
let l:current.entries = vimtex#parser#toc#parse(l:vimtex.tex)
|
||||
endif
|
||||
|
||||
return deepcopy(l:current.entries)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#bib(file, ...) abort " {{{1
|
||||
return vimtex#parser#bib#parse(a:file, a:0 > 0 ? a:1 : {})
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#parser#get_externalfiles() abort " {{{1
|
||||
let l:preamble = vimtex#parser#preamble(b:vimtex.tex)
|
||||
|
||||
let l:result = []
|
||||
for l:line in filter(l:preamble, 'v:val =~# ''\\externaldocument''')
|
||||
let l:name = matchstr(l:line, '{\zs[^}]*\ze}')
|
||||
call add(l:result, {
|
||||
\ 'tex' : l:name . '.tex',
|
||||
\ 'aux' : l:name . '.aux',
|
||||
\ 'opt' : matchstr(l:line, '\[\zs[^]]*\ze\]'),
|
||||
\ })
|
||||
endfor
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#selection_to_texfile(type, ...) range abort " {{{1
|
||||
"
|
||||
" Get selected lines. Method depends on type of selection, which may be
|
||||
" either of
|
||||
"
|
||||
" 1. range from argument
|
||||
" 2. Command range
|
||||
" 3. Visual mapping
|
||||
" 4. Operator mapping
|
||||
"
|
||||
if a:type ==# 'arg'
|
||||
let l:lines = getline(a:1[0], a:1[1])
|
||||
elseif a:type ==# 'cmd'
|
||||
let l:lines = getline(a:firstline, a:lastline)
|
||||
elseif a:type ==# 'visual'
|
||||
let l:lines = getline(line("'<"), line("'>"))
|
||||
else
|
||||
let l:lines = getline(line("'["), line("']"))
|
||||
endif
|
||||
|
||||
"
|
||||
" Use only the part of the selection that is within the
|
||||
"
|
||||
" \begin{document} ... \end{document}
|
||||
"
|
||||
" environment.
|
||||
"
|
||||
let l:start = 0
|
||||
let l:end = len(l:lines)
|
||||
for l:n in range(len(l:lines))
|
||||
if l:lines[l:n] =~# '\\begin\s*{document}'
|
||||
let l:start = l:n + 1
|
||||
elseif l:lines[l:n] =~# '\\end\s*{document}'
|
||||
let l:end = l:n - 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
"
|
||||
" Check if the selection has any real content
|
||||
"
|
||||
if l:start >= len(l:lines)
|
||||
\ || l:end < 0
|
||||
\ || empty(substitute(join(l:lines[l:start : l:end], ''), '\s*', '', ''))
|
||||
return {}
|
||||
endif
|
||||
|
||||
"
|
||||
" Define the set of lines to compile
|
||||
"
|
||||
let l:lines = vimtex#parser#preamble(b:vimtex.tex)
|
||||
\ + ['\begin{document}']
|
||||
\ + l:lines[l:start : l:end]
|
||||
\ + ['\end{document}']
|
||||
|
||||
"
|
||||
" Write content to temporary file
|
||||
"
|
||||
let l:file = {}
|
||||
let l:file.root = b:vimtex.root
|
||||
let l:file.base = b:vimtex.name . '_vimtex_selected.tex'
|
||||
let l:file.tex = l:file.root . '/' . l:file.base
|
||||
let l:file.pdf = fnamemodify(l:file.tex, ':r') . '.pdf'
|
||||
let l:file.log = fnamemodify(l:file.tex, ':r') . '.log'
|
||||
call writefile(l:lines, l:file.tex)
|
||||
|
||||
return l:file
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,58 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#parser#auxiliary#parse(file) abort " {{{1
|
||||
return s:parse_recurse(a:file, [])
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_recurse(file, parsed) abort " {{{1
|
||||
if !filereadable(a:file) || index(a:parsed, a:file) >= 0
|
||||
return []
|
||||
endif
|
||||
call add(a:parsed, a:file)
|
||||
|
||||
let l:lines = []
|
||||
for l:line in readfile(a:file)
|
||||
call add(l:lines, l:line)
|
||||
|
||||
if l:line =~# '\\@input{'
|
||||
let l:file = s:input_line_parser(l:line, a:file)
|
||||
call extend(l:lines, s:parse_recurse(l:file, a:parsed))
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:lines
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:input_line_parser(line, file) abort " {{{1
|
||||
let l:file = matchstr(a:line, '\\@input{\zs[^}]\+\ze}')
|
||||
|
||||
" Remove extension to simplify the parsing (e.g. for "my file name".aux)
|
||||
let l:file = substitute(l:file, '\.aux', '', '')
|
||||
|
||||
" Trim whitespaces and quotes from beginning/end of string, append extension
|
||||
let l:file = substitute(l:file, '^\(\s\|"\)*', '', '')
|
||||
let l:file = substitute(l:file, '\(\s\|"\)*$', '', '')
|
||||
let l:file .= '.aux'
|
||||
|
||||
" Use absolute paths
|
||||
if l:file !~# '\v^(\/|[A-Z]:)'
|
||||
let l:file = fnamemodify(a:file, ':p:h') . '/' . l:file
|
||||
endif
|
||||
|
||||
" Only return filename if it is readable
|
||||
return filereadable(l:file) ? l:file : ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,370 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#parser#bib#parse(file, opts) abort " {{{1
|
||||
if !filereadable(a:file) | return [] | endif
|
||||
|
||||
let l:backend = get(a:opts, 'backend', g:vimtex_parser_bib_backend)
|
||||
|
||||
if l:backend ==# 'bibtex'
|
||||
if !executable('bibtex') | let l:backend = 'vim' | endif
|
||||
elseif l:backend ==# 'bibparse'
|
||||
if !executable('bibparse') | let l:backend = 'vim' | endif
|
||||
else
|
||||
let l:backend = 'vim'
|
||||
endif
|
||||
|
||||
return s:parse_with_{l:backend}(a:file)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
function! s:parse_with_bibtex(file) abort " {{{1
|
||||
call s:parse_with_bibtex_init()
|
||||
if s:bibtex_not_executable | return [] | endif
|
||||
|
||||
" Define temporary files
|
||||
let tmp = {
|
||||
\ 'aux' : 'tmpfile.aux',
|
||||
\ 'bbl' : 'tmpfile.bbl',
|
||||
\ 'blg' : 'tmpfile.blg',
|
||||
\ }
|
||||
|
||||
" Write temporary aux file
|
||||
call writefile([
|
||||
\ '\citation{*}',
|
||||
\ '\bibstyle{' . s:bibtex_bstfile . '}',
|
||||
\ '\bibdata{' . fnamemodify(a:file, ':r') . '}',
|
||||
\ ], tmp.aux)
|
||||
|
||||
" Create the temporary bbl file
|
||||
call vimtex#process#run('bibtex -terse ' . fnameescape(tmp.aux), {
|
||||
\ 'background' : 0,
|
||||
\ 'silent' : 1,
|
||||
\})
|
||||
|
||||
" Parse temporary bbl file
|
||||
let lines = join(readfile(tmp.bbl), "\n")
|
||||
let lines = substitute(lines, '\n\n\@!\(\s\=\)\s*\|{\|}', '\1', 'g')
|
||||
let lines = vimtex#util#tex2unicode(lines)
|
||||
let lines = split(lines, "\n")
|
||||
|
||||
let l:entries = []
|
||||
for line in lines
|
||||
let matches = split(line, '||')
|
||||
if empty(matches) || empty(matches[0]) | continue | endif
|
||||
|
||||
let l:entry = {
|
||||
\ 'key': matches[0],
|
||||
\ 'type': matches[1],
|
||||
\}
|
||||
|
||||
if !empty(matches[2])
|
||||
let l:entry.author = matches[2]
|
||||
endif
|
||||
if !empty(matches[3])
|
||||
let l:entry.year = matches[3]
|
||||
endif
|
||||
if !empty(get(matches, 4, ''))
|
||||
let l:entry.title = get(matches, 4, '')
|
||||
endif
|
||||
|
||||
call add(l:entries, l:entry)
|
||||
endfor
|
||||
|
||||
" Clean up
|
||||
call delete(tmp.aux)
|
||||
call delete(tmp.bbl)
|
||||
call delete(tmp.blg)
|
||||
|
||||
return l:entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_with_bibtex_init() abort " {{{1
|
||||
if exists('s:bibtex_init_done') | return | endif
|
||||
|
||||
" Check if bibtex is executable
|
||||
let s:bibtex_not_executable = !executable('bibtex')
|
||||
if s:bibtex_not_executable
|
||||
call vimtex#log#warning(
|
||||
\ 'bibtex is not executable and may not be used to parse bib files!')
|
||||
endif
|
||||
|
||||
" Check if bstfile contains whitespace (not handled by vimtex)
|
||||
if stridx(s:bibtex_bstfile, ' ') >= 0
|
||||
let l:oldbst = s:bibtex_bstfile . '.bst'
|
||||
let s:bibtex_bstfile = tempname()
|
||||
call writefile(readfile(l:oldbst), s:bibtex_bstfile . '.bst')
|
||||
endif
|
||||
|
||||
let s:bibtex_init_done = 1
|
||||
endfunction
|
||||
|
||||
let s:bibtex_bstfile = expand('<sfile>:p:h') . '/vimcomplete'
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_with_bibparse(file) abort " {{{1
|
||||
call s:parse_with_bibparse_init()
|
||||
if s:bibparse_not_executable | return [] | endif
|
||||
|
||||
call vimtex#process#run('bibparse ' . fnameescape(a:file)
|
||||
\ . ' >_vimtex_bibparsed.log', {'background' : 0, 'silent' : 1})
|
||||
let l:lines = readfile('_vimtex_bibparsed.log')
|
||||
call delete('_vimtex_bibparsed.log')
|
||||
|
||||
let l:current = {}
|
||||
let l:entries = []
|
||||
for l:line in l:lines
|
||||
if l:line[0] ==# '@'
|
||||
if !empty(l:current)
|
||||
call add(l:entries, l:current)
|
||||
let l:current = {}
|
||||
endif
|
||||
|
||||
let l:index = stridx(l:line, ' ')
|
||||
if l:index > 0
|
||||
let l:type = l:line[1:l:index-1]
|
||||
let l:current.type = l:type
|
||||
let l:current.key = l:line[l:index+1:]
|
||||
endif
|
||||
elseif !empty(l:current)
|
||||
let l:index = stridx(l:line, '=')
|
||||
if l:index < 0 | continue | endif
|
||||
|
||||
let l:key = l:line[:l:index-1]
|
||||
let l:value = l:line[l:index+1:]
|
||||
let l:current[tolower(l:key)] = l:value
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !empty(l:current)
|
||||
call add(l:entries, l:current)
|
||||
endif
|
||||
|
||||
return l:entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_with_bibparse_init() abort " {{{1
|
||||
if exists('s:bibparse_init_done') | return | endif
|
||||
|
||||
" Check if bibtex is executable
|
||||
let s:bibparse_not_executable = !executable('bibparse')
|
||||
if s:bibparse_not_executable
|
||||
call vimtex#log#warning(
|
||||
\ 'bibparse is not executable and may not be used to parse bib files!')
|
||||
endif
|
||||
|
||||
let s:bibparse_init_done = 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_with_vim(file) abort " {{{1
|
||||
" Adheres to the format description found here:
|
||||
" http://www.bibtex.org/Format/
|
||||
|
||||
if !filereadable(a:file)
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:current = {}
|
||||
let l:strings = {}
|
||||
let l:entries = []
|
||||
for l:line in filter(readfile(a:file), 'v:val !~# ''^\s*\%(%\|$\)''')
|
||||
if empty(l:current)
|
||||
if s:parse_type(l:line, l:current, l:strings)
|
||||
let l:current = {}
|
||||
endif
|
||||
continue
|
||||
endif
|
||||
|
||||
if l:current.type ==# 'string'
|
||||
if s:parse_string(l:line, l:current, l:strings)
|
||||
let l:current = {}
|
||||
endif
|
||||
else
|
||||
if s:parse_entry(l:line, l:current, l:entries)
|
||||
let l:current = {}
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
return map(l:entries, 's:parse_entry_body(v:val, l:strings)')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_type(line, current, strings) abort " {{{1
|
||||
let l:matches = matchlist(a:line, '\v^\@(\w+)\s*\{\s*(.*)')
|
||||
if empty(l:matches) | return 0 | endif
|
||||
|
||||
let l:type = tolower(l:matches[1])
|
||||
if index(['preamble', 'comment'], l:type) >= 0 | return 0 | endif
|
||||
|
||||
let a:current.level = 1
|
||||
let a:current.body = ''
|
||||
|
||||
if l:type ==# 'string'
|
||||
return s:parse_string(l:matches[2], a:current, a:strings)
|
||||
else
|
||||
let a:current.type = l:type
|
||||
let a:current.key = matchstr(l:matches[2], '.*\ze,\s*')
|
||||
return 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_string(line, string, strings) abort " {{{1
|
||||
let a:string.level += s:count(a:line, '{') - s:count(a:line, '}')
|
||||
if a:string.level > 0
|
||||
let a:string.body .= a:line
|
||||
return 0
|
||||
endif
|
||||
|
||||
let a:string.body .= matchstr(a:line, '.*\ze}')
|
||||
|
||||
let l:matches = matchlist(a:string.body, '\v^\s*(\w+)\s*\=\s*"(.*)"\s*$')
|
||||
if !empty(l:matches) && !empty(l:matches[1])
|
||||
let a:strings[l:matches[1]] = l:matches[2]
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_entry(line, entry, entries) abort " {{{1
|
||||
let a:entry.level += s:count(a:line, '{') - s:count(a:line, '}')
|
||||
if a:entry.level > 0
|
||||
let a:entry.body .= a:line
|
||||
return 0
|
||||
endif
|
||||
|
||||
let a:entry.body .= matchstr(a:line, '.*\ze}')
|
||||
|
||||
call add(a:entries, a:entry)
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_entry_body(entry, strings) abort " {{{1
|
||||
unlet a:entry.level
|
||||
|
||||
let l:key = ''
|
||||
let l:pos = matchend(a:entry.body, '^\s*')
|
||||
while l:pos >= 0
|
||||
if empty(l:key)
|
||||
let [l:key, l:pos] = s:get_key(a:entry.body, l:pos)
|
||||
else
|
||||
let [l:value, l:pos] = s:get_value(a:entry.body, l:pos, a:strings)
|
||||
let a:entry[l:key] = l:value
|
||||
let l:key = ''
|
||||
endif
|
||||
endwhile
|
||||
|
||||
unlet a:entry.body
|
||||
return a:entry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_key(body, head) abort " {{{1
|
||||
" Parse the key part of a bib entry tag.
|
||||
" Assumption: a:body is left trimmed and either empty or starts with a key.
|
||||
" Returns: The key and the remaining part of the entry body.
|
||||
|
||||
let l:matches = matchlist(a:body, '^\v(\w+)\s*\=\s*', a:head)
|
||||
return empty(l:matches)
|
||||
\ ? ['', -1]
|
||||
\ : [tolower(l:matches[1]), a:head + strlen(l:matches[0])]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_value(body, head, strings) abort " {{{1
|
||||
" Parse the value part of a bib entry tag, until separating comma or end.
|
||||
" Assumption: a:body is left trimmed and either empty or starts with a value.
|
||||
" Returns: The value and the remaining part of the entry body.
|
||||
"
|
||||
" A bib entry value is either
|
||||
" 1. A number.
|
||||
" 2. A concatenation (with #s) of double quoted strings, curlied strings,
|
||||
" and/or bibvariables,
|
||||
"
|
||||
if a:body[a:head] =~# '\d'
|
||||
let l:value = matchstr(a:body, '^\d\+', a:head)
|
||||
let l:head = matchend(a:body, '^\s*,\s*', a:head + len(l:value))
|
||||
return [l:value, l:head]
|
||||
else
|
||||
return s:get_value_string(a:body, a:head, a:strings)
|
||||
endif
|
||||
|
||||
return ['s:get_value failed', -1]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_value_string(body, head, strings) abort " {{{1
|
||||
if a:body[a:head] ==# '{'
|
||||
let l:sum = 1
|
||||
let l:i1 = a:head + 1
|
||||
let l:i0 = l:i1
|
||||
|
||||
while l:sum > 0
|
||||
let [l:match, l:_, l:i1] = matchstrpos(a:body, '[{}]', l:i1)
|
||||
if l:i1 < 0 | break | endif
|
||||
|
||||
let l:i0 = l:i1
|
||||
let l:sum += l:match ==# '{' ? 1 : -1
|
||||
endwhile
|
||||
|
||||
let l:value = a:body[a:head+1:l:i0-2]
|
||||
let l:head = matchend(a:body, '^\s*', l:i0)
|
||||
elseif a:body[a:head] ==# '"'
|
||||
let l:index = match(a:body, '\\\@<!"', a:head+1)
|
||||
if l:index < 0
|
||||
return ['s:get_value_string failed', '']
|
||||
endif
|
||||
|
||||
let l:value = a:body[a:head+1:l:index-1]
|
||||
let l:head = matchend(a:body, '^\s*', l:index+1)
|
||||
return [l:value, l:head]
|
||||
elseif a:body[a:head:] =~# '^\w'
|
||||
let l:value = matchstr(a:body, '^\w\+', a:head)
|
||||
let l:head = matchend(a:body, '^\s*', a:head + strlen(l:value))
|
||||
let l:value = get(a:strings, l:value, '@(' . l:value . ')')
|
||||
else
|
||||
let l:head = a:head
|
||||
endif
|
||||
|
||||
if a:body[l:head] ==# '#'
|
||||
let l:head = matchend(a:body, '^\s*', l:head + 1)
|
||||
let [l:vadd, l:head] = s:get_value_string(a:body, l:head, a:strings)
|
||||
let l:value .= l:vadd
|
||||
endif
|
||||
|
||||
return [l:value, matchend(a:body, '^,\s*', l:head)]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:count(container, item) abort " {{{1
|
||||
" Necessary because in old Vim versions, count() does not work for strings
|
||||
try
|
||||
let l:count = count(a:container, a:item)
|
||||
catch /E712/
|
||||
let l:count = count(split(a:container, '\zs'), a:item)
|
||||
endtry
|
||||
|
||||
return l:count
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,19 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#parser#fls#parse(file) abort " {{{1
|
||||
if !filereadable(a:file)
|
||||
return []
|
||||
endif
|
||||
|
||||
return readfile(a:file)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,205 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#parser#tex#parse(file, opts) abort " {{{1
|
||||
let l:opts = extend({
|
||||
\ 'detailed': 1,
|
||||
\ 'root' : exists('b:vimtex.root') ? b:vimtex.root : '',
|
||||
\}, a:opts)
|
||||
|
||||
let l:cache = vimtex#cache#open('texparser', {
|
||||
\ 'local': 1,
|
||||
\ 'persistent': 0,
|
||||
\ 'default': {'ftime': -2},
|
||||
\})
|
||||
|
||||
let l:parsed = s:parse(a:file, l:opts, l:cache)
|
||||
|
||||
if !l:opts.detailed
|
||||
call map(l:parsed, 'v:val[2]')
|
||||
endif
|
||||
|
||||
return l:parsed
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#tex#parse_files(file, opts) abort " {{{1
|
||||
let l:opts = extend({
|
||||
\ 'root' : exists('b:vimtex.root') ? b:vimtex.root : '',
|
||||
\}, a:opts)
|
||||
|
||||
let l:cache = vimtex#cache#open('texparser', {
|
||||
\ 'local': 1,
|
||||
\ 'persistent': 0,
|
||||
\ 'default': {'ftime': -2},
|
||||
\})
|
||||
|
||||
return vimtex#util#uniq_unsorted(
|
||||
\ s:parse_files(a:file, l:opts, l:cache))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#tex#parse_preamble(file, opts) abort " {{{1
|
||||
let l:opts = extend({
|
||||
\ 'inclusive' : 0,
|
||||
\ 'root' : exists('b:vimtex.root') ? b:vimtex.root : '',
|
||||
\}, a:opts)
|
||||
|
||||
return s:parse_preamble(a:file, l:opts, [])
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse(file, opts, cache) abort " {{{1
|
||||
let l:current = a:cache.get(a:file)
|
||||
let l:ftime = getftime(a:file)
|
||||
if l:ftime > l:current.ftime
|
||||
let l:current.ftime = l:ftime
|
||||
call s:parse_current(a:file, a:opts, l:current)
|
||||
endif
|
||||
|
||||
let l:parsed = []
|
||||
|
||||
for l:val in l:current.lines
|
||||
if type(l:val) == type([])
|
||||
call add(l:parsed, l:val)
|
||||
else
|
||||
call extend(l:parsed, s:parse(l:val, a:opts, a:cache))
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:parsed
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_files(file, opts, cache) abort " {{{1
|
||||
let l:current = a:cache.get(a:file)
|
||||
let l:ftime = getftime(a:file)
|
||||
if l:ftime > l:current.ftime
|
||||
let l:current.ftime = l:ftime
|
||||
call s:parse_current(a:file, a:opts, l:current)
|
||||
endif
|
||||
|
||||
" Only include existing files
|
||||
if !filereadable(a:file) | return [] | endif
|
||||
|
||||
let l:files = [a:file]
|
||||
for l:file in l:current.includes
|
||||
let l:files += s:parse_files(l:file, a:opts, a:cache)
|
||||
endfor
|
||||
|
||||
return l:files
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_current(file, opts, current) abort " {{{1
|
||||
let a:current.lines = []
|
||||
let a:current.includes = []
|
||||
|
||||
" Also load includes from glsentries
|
||||
let l:re_input = g:vimtex#re#tex_input . '|^\s*\\loadglsentries'
|
||||
|
||||
if filereadable(a:file)
|
||||
let l:lnum = 0
|
||||
for l:line in readfile(a:file)
|
||||
let l:lnum += 1
|
||||
call add(a:current.lines, [a:file, l:lnum, l:line])
|
||||
|
||||
" Minor optimization: Avoid complex regex on "simple" lines
|
||||
if stridx(l:line, '\') < 0 | continue | endif
|
||||
|
||||
if l:line =~# l:re_input
|
||||
let l:file = s:input_parser(l:line, a:file, a:opts.root)
|
||||
call add(a:current.lines, l:file)
|
||||
call add(a:current.includes, l:file)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:parse_preamble(file, opts, parsed_files) abort " {{{1
|
||||
if !filereadable(a:file) || index(a:parsed_files, a:file) >= 0
|
||||
return []
|
||||
endif
|
||||
call add(a:parsed_files, a:file)
|
||||
|
||||
let l:lines = []
|
||||
for l:line in readfile(a:file)
|
||||
if l:line =~# '\\begin\s*{document}'
|
||||
if a:opts.inclusive
|
||||
call add(l:lines, l:line)
|
||||
endif
|
||||
break
|
||||
endif
|
||||
|
||||
call add(l:lines, l:line)
|
||||
|
||||
if l:line =~# g:vimtex#re#tex_input
|
||||
let l:file = s:input_parser(l:line, a:file, a:opts.root)
|
||||
call extend(l:lines, s:parse_preamble(l:file, a:opts, a:parsed_files))
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:lines
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:input_parser(line, current_file, root) abort " {{{1
|
||||
" Handle \space commands
|
||||
let l:file = substitute(a:line, '\\space\s*', ' ', 'g')
|
||||
|
||||
" Handle import package commands
|
||||
if l:file =~# g:vimtex#re#tex_input_import
|
||||
let l:root = l:file =~# '\\sub'
|
||||
\ ? fnamemodify(a:current_file, ':p:h')
|
||||
\ : a:root
|
||||
|
||||
let l:candidate = s:input_to_filename(
|
||||
\ substitute(copy(l:file), '}\s*{', '', 'g'), l:root)
|
||||
if !empty(l:candidate)
|
||||
return l:candidate
|
||||
else
|
||||
return s:input_to_filename(
|
||||
\ substitute(copy(l:file), '{.{-}}', '', ''), l:root)
|
||||
endif
|
||||
else
|
||||
return s:input_to_filename(l:file, a:root)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:input_to_filename(input, root) abort " {{{1
|
||||
let l:file = matchstr(a:input, '\zs[^{}]\+\ze}\s*\%(%\|$\)')
|
||||
|
||||
" Trim whitespaces and quotes from beginning/end of string
|
||||
let l:file = substitute(l:file, '^\(\s\|"\)*', '', '')
|
||||
let l:file = substitute(l:file, '\(\s\|"\)*$', '', '')
|
||||
|
||||
" Ensure that the file name has extension
|
||||
if empty(fnamemodify(l:file, ':e'))
|
||||
let l:file .= '.tex'
|
||||
endif
|
||||
|
||||
if vimtex#paths#is_abs(l:file)
|
||||
return l:file
|
||||
endif
|
||||
|
||||
let l:candidate = a:root . '/' . l:file
|
||||
if filereadable(l:candidate)
|
||||
return l:candidate
|
||||
endif
|
||||
|
||||
let l:candidate = vimtex#kpsewhich#find(l:file)
|
||||
return filereadable(l:candidate) ? l:candidate : l:file
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,782 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
"
|
||||
" Parses tex project for ToC-like entries. Each entry is a dictionary
|
||||
" similar to the following:
|
||||
"
|
||||
" entry = {
|
||||
" title : "Some title",
|
||||
" number : "3.1.2",
|
||||
" file : /path/to/file.tex,
|
||||
" line : 142,
|
||||
" rank : cumulative line number,
|
||||
" level : 2,
|
||||
" type : [content | label | todo | include],
|
||||
" link : [0 | 1],
|
||||
" }
|
||||
"
|
||||
|
||||
function! vimtex#parser#toc#parse(file) abort " {{{1
|
||||
let l:entries = []
|
||||
let l:content = vimtex#parser#tex(a:file)
|
||||
|
||||
let l:max_level = 0
|
||||
for [l:file, l:lnum, l:line] in l:content
|
||||
if l:line =~# s:matcher_sections.re
|
||||
let l:max_level = max([
|
||||
\ l:max_level,
|
||||
\ s:sec_to_value[matchstr(l:line, s:matcher_sections.re_level)]
|
||||
\])
|
||||
endif
|
||||
endfor
|
||||
|
||||
call s:level.reset('preamble', l:max_level)
|
||||
|
||||
" No more parsing if there is no content
|
||||
if empty(l:content) | return l:entries | endif
|
||||
|
||||
"
|
||||
" Begin parsing LaTeX files
|
||||
"
|
||||
let l:lnum_total = 0
|
||||
let l:matchers = s:matchers_preamble
|
||||
for [l:file, l:lnum, l:line] in l:content
|
||||
let l:lnum_total += 1
|
||||
let l:context = {
|
||||
\ 'file' : l:file,
|
||||
\ 'line' : l:line,
|
||||
\ 'lnum' : l:lnum,
|
||||
\ 'lnum_total' : l:lnum_total,
|
||||
\ 'level' : s:level,
|
||||
\ 'max_level' : l:max_level,
|
||||
\ 'entry' : get(l:entries, -1, {}),
|
||||
\ 'num_entries' : len(l:entries),
|
||||
\}
|
||||
|
||||
" Detect end of preamble
|
||||
if s:level.preamble && l:line =~# '\v^\s*\\begin\{document\}'
|
||||
let s:level.preamble = 0
|
||||
let l:matchers = s:matchers_content
|
||||
continue
|
||||
endif
|
||||
|
||||
" Handle multi-line entries
|
||||
if exists('s:matcher_continue')
|
||||
call s:matcher_continue.continue(l:context)
|
||||
continue
|
||||
endif
|
||||
|
||||
" Apply prefilter - this gives considerable speedup for large documents
|
||||
if l:line !~# s:re_prefilter | continue | endif
|
||||
|
||||
" Apply the matchers
|
||||
for l:matcher in l:matchers
|
||||
if l:line =~# l:matcher.re
|
||||
let l:entry = l:matcher.get_entry(l:context)
|
||||
if type(l:entry) == type([])
|
||||
call extend(l:entries, l:entry)
|
||||
elseif !empty(l:entry)
|
||||
call add(l:entries, l:entry)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
for l:matcher in s:matchers
|
||||
try
|
||||
call l:matcher.filter(l:entries)
|
||||
catch /E716/
|
||||
endtry
|
||||
endfor
|
||||
|
||||
return l:entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#toc#get_topmatters() abort " {{{1
|
||||
let l:topmatters = s:level.frontmatter
|
||||
let l:topmatters += s:level.mainmatter
|
||||
let l:topmatters += s:level.appendix
|
||||
let l:topmatters += s:level.backmatter
|
||||
|
||||
for l:level in get(s:level, 'old', [])
|
||||
let l:topmatters += l:level.frontmatter
|
||||
let l:topmatters += l:level.mainmatter
|
||||
let l:topmatters += l:level.appendix
|
||||
let l:topmatters += l:level.backmatter
|
||||
endfor
|
||||
|
||||
return l:topmatters
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#parser#toc#get_entry_general(context) abort dict " {{{1
|
||||
return {
|
||||
\ 'title' : self.title,
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'level' : 0,
|
||||
\ 'type' : 'content',
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" IMPORTANT: The following defines a prefilter for optimizing the toc parser.
|
||||
" Any line that should be parsed has to be matched by this regexp!
|
||||
" {{{1 let s:re_prefilter = ...
|
||||
let s:re_prefilter = '\v%(\\' . join([
|
||||
\ '%(front|main|back)matter',
|
||||
\ 'add%(global|section)?bib',
|
||||
\ 'appendix',
|
||||
\ 'begin',
|
||||
\ 'bibliography',
|
||||
\ 'chapter',
|
||||
\ 'documentclass',
|
||||
\ 'import',
|
||||
\ 'include',
|
||||
\ 'includegraphics',
|
||||
\ 'input',
|
||||
\ 'label',
|
||||
\ 'part',
|
||||
\ 'printbib',
|
||||
\ 'printindex',
|
||||
\ 'paragraph',
|
||||
\ 'section',
|
||||
\ 'subfile',
|
||||
\ 'tableofcontents',
|
||||
\ 'todo',
|
||||
\], '|') . ')'
|
||||
\ . '|\%\s*%(' . join(keys(g:vimtex_toc_todo_labels), '|') . ')'
|
||||
\ . '|\%\s*vimtex-include'
|
||||
for s:m in g:vimtex_toc_custom_matchers
|
||||
if has_key(s:m, 'prefilter')
|
||||
let s:re_prefilter .= '|' . s:m.prefilter
|
||||
endif
|
||||
endfor
|
||||
|
||||
" }}}1
|
||||
|
||||
" Adds entries for included files
|
||||
let s:matcher_include = {
|
||||
\ 're' : vimtex#re#tex_input . '\zs\f{-}\s*\ze\}',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_include.get_entry(context) abort dict " {{{1
|
||||
let l:file = matchstr(a:context.line, self.re)
|
||||
if !vimtex#paths#is_abs(l:file[0])
|
||||
let l:file = b:vimtex.root . '/' . l:file
|
||||
endif
|
||||
let l:file = fnamemodify(l:file, ':~:.')
|
||||
if !filereadable(l:file)
|
||||
let l:file .= '.tex'
|
||||
endif
|
||||
return {
|
||||
\ 'title' : 'tex incl: ' . (strlen(l:file) < 70
|
||||
\ ? l:file
|
||||
\ : l:file[0:30] . '...' . l:file[-36:]),
|
||||
\ 'number' : '',
|
||||
\ 'file' : l:file,
|
||||
\ 'line' : 1,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'include',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" Adds entries for included graphics files (filetype tikz, tex)
|
||||
let s:matcher_include_graphics = {
|
||||
\ 're' : '\v^\s*\\includegraphics\*?%(\s*\[[^]]*\]){0,2}\s*\{\zs[^}]*',
|
||||
\ 'priority' : 1,
|
||||
\}
|
||||
function! s:matcher_include_graphics.get_entry(context) abort dict " {{{1
|
||||
let l:file = matchstr(a:context.line, self.re)
|
||||
if !vimtex#paths#is_abs(l:file)
|
||||
let l:file = vimtex#misc#get_graphicspath(l:file)
|
||||
endif
|
||||
let l:file = fnamemodify(l:file, ':~:.')
|
||||
let l:ext = fnamemodify(l:file, ':e')
|
||||
|
||||
return !filereadable(l:file) || index(['asy', 'tikz'], l:ext) < 0
|
||||
\ ? {}
|
||||
\ : {
|
||||
\ 'title' : 'fig incl: ' . (strlen(l:file) < 70
|
||||
\ ? l:file
|
||||
\ : l:file[0:30] . '...' . l:file[-36:]),
|
||||
\ 'number' : '',
|
||||
\ 'file' : l:file,
|
||||
\ 'line' : 1,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'include',
|
||||
\ 'link' : 1,
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" Adds entries for included files through vimtex specific syntax (this allows
|
||||
" to add entries for any filetype or file)
|
||||
let s:matcher_include_vimtex = {
|
||||
\ 're' : '^\s*%\s*vimtex-include:\?\s\+\zs\f\+',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'priority' : 1,
|
||||
\}
|
||||
function! s:matcher_include_vimtex.get_entry(context) abort dict " {{{1
|
||||
let l:file = matchstr(a:context.line, self.re)
|
||||
if !vimtex#paths#is_abs(l:file)
|
||||
let l:file = b:vimtex.root . '/' . l:file
|
||||
endif
|
||||
let l:file = fnamemodify(l:file, ':~:.')
|
||||
return {
|
||||
\ 'title' : 'vtx incl: ' . (strlen(l:file) < 70
|
||||
\ ? l:file
|
||||
\ : l:file[0:30] . '...' . l:file[-36:]),
|
||||
\ 'number' : '',
|
||||
\ 'file' : l:file,
|
||||
\ 'line' : 1,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'include',
|
||||
\ 'link' : 1,
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_include_bibtex = {
|
||||
\ 're' : '\v^\s*\\bibliography\s*\{\zs[^}]+\ze\}',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_include_bibtex.get_entry(context) abort dict " {{{1
|
||||
let l:entries = []
|
||||
|
||||
for l:file in split(matchstr(a:context.line, self.re), ',')
|
||||
" Ensure that the file name has extension
|
||||
if l:file !~# '\.bib$'
|
||||
let l:file .= '.bib'
|
||||
endif
|
||||
|
||||
call add(l:entries, {
|
||||
\ 'title' : printf('bib incl: %-.67s', fnamemodify(l:file, ':t')),
|
||||
\ 'number' : '',
|
||||
\ 'file' : vimtex#kpsewhich#find(l:file),
|
||||
\ 'line' : 1,
|
||||
\ 'level' : 0,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'include',
|
||||
\ 'link' : 1,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:entries
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_include_biblatex = {
|
||||
\ 're' : '\v^\s*\\add(bibresource|globalbib|sectionbib)\s*\{\zs[^}]+\ze\}',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'in_content' : 0,
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_include_biblatex.get_entry(context) abort dict " {{{1
|
||||
let l:file = matchstr(a:context.line, self.re)
|
||||
|
||||
return {
|
||||
\ 'title' : printf('bib incl: %-.67s', fnamemodify(l:file, ':t')),
|
||||
\ 'number' : '',
|
||||
\ 'file' : vimtex#kpsewhich#find(l:file),
|
||||
\ 'line' : 1,
|
||||
\ 'level' : 0,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'include',
|
||||
\ 'link' : 1,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_preamble = {
|
||||
\ 're' : '\v^\s*\\documentclass',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'in_content' : 0,
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_preamble.get_entry(context) abort " {{{1
|
||||
return g:vimtex_toc_show_preamble
|
||||
\ ? {
|
||||
\ 'title' : 'Preamble',
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : 0,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'content',
|
||||
\ }
|
||||
\ : {}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_parts = {
|
||||
\ 're' : '\v^\s*\\\zs((front|main|back)matter|appendix)>',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_parts.get_entry(context) abort dict " {{{1
|
||||
call a:context.level.reset(
|
||||
\ matchstr(a:context.line, self.re),
|
||||
\ a:context.max_level)
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_sections = {
|
||||
\ 're' : '\v^\s*\\%(part|chapter|%(sub)*section|%(sub)?paragraph)\*?\s*(\[|\{)',
|
||||
\ 're_starred' : '\v^\s*\\%(part|chapter|%(sub)*section)\*',
|
||||
\ 're_level' : '\v^\s*\\\zs%(part|chapter|%(sub)*section|%(sub)?paragraph)',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
let s:matcher_sections.re_title = s:matcher_sections.re . '\zs.{-}\ze\%?\s*$'
|
||||
function! s:matcher_sections.get_entry(context) abort dict " {{{1
|
||||
let level = matchstr(a:context.line, self.re_level)
|
||||
let type = matchlist(a:context.line, self.re)[1]
|
||||
let title = matchstr(a:context.line, self.re_title)
|
||||
let number = ''
|
||||
|
||||
let [l:end, l:count] = s:find_closing(0, title, 1, type)
|
||||
if l:count == 0
|
||||
let title = self.parse_title(strpart(title, 0, l:end+1))
|
||||
else
|
||||
let self.type = type
|
||||
let self.count = l:count
|
||||
let s:matcher_continue = deepcopy(self)
|
||||
endif
|
||||
|
||||
if a:context.line !~# self.re_starred
|
||||
call a:context.level.increment(level)
|
||||
if a:context.line !~# '\v^\s*\\%(sub)?paragraph'
|
||||
let number = deepcopy(a:context.level)
|
||||
endif
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'title' : title,
|
||||
\ 'number' : number,
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'content',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_sections.parse_title(title) abort dict " {{{1
|
||||
let l:title = substitute(a:title, '\v%(\]|\})\s*$', '', '')
|
||||
return s:clear_texorpdfstring(l:title)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_sections.continue(context) abort dict " {{{1
|
||||
let [l:end, l:count] = s:find_closing(0, a:context.line, self.count, self.type)
|
||||
if l:count == 0
|
||||
let a:context.entry.title = self.parse_title(a:context.entry.title . strpart(a:context.line, 0, l:end+1))
|
||||
unlet! s:matcher_continue
|
||||
else
|
||||
let a:context.entry.title .= a:context.line
|
||||
let self.count = l:count
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_table_of_contents = {
|
||||
\ 'title' : 'Table of contents',
|
||||
\ 're' : '\v^\s*\\tableofcontents',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
|
||||
let s:matcher_index = {
|
||||
\ 'title' : 'Alphabetical index',
|
||||
\ 're' : '\v^\s*\\printindex\[?',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
|
||||
let s:matcher_titlepage = {
|
||||
\ 'title' : 'Titlepage',
|
||||
\ 're' : '\v^\s*\\begin\{titlepage\}',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
|
||||
let s:matcher_bibliography = {
|
||||
\ 'title' : 'Bibliography',
|
||||
\ 're' : '\v^\s*\\%('
|
||||
\ . 'printbib%(liography|heading)\s*(\{|\[)?'
|
||||
\ . '|begin\s*\{\s*thebibliography\s*\}'
|
||||
\ . '|bibliography\s*\{)',
|
||||
\ 're_biblatex' : '\v^\s*\\printbib%(liography|heading)',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_bibliography.get_entry(context) abort dict " {{{1
|
||||
let l:entry = call('vimtex#parser#toc#get_entry_general', [a:context], self)
|
||||
|
||||
if a:context.line !~# self.re_biblatex
|
||||
return l:entry
|
||||
endif
|
||||
|
||||
let self.options = matchstr(a:context.line, self.re_biblatex . '\s*\[\zs.*')
|
||||
|
||||
let [l:end, l:count] = s:find_closing(
|
||||
\ 0, self.options, !empty(self.options), '[')
|
||||
if l:count == 0
|
||||
let self.options = strpart(self.options, 0, l:end)
|
||||
call self.parse_options(a:context, l:entry)
|
||||
else
|
||||
let self.count = l:count
|
||||
let s:matcher_continue = deepcopy(self)
|
||||
endif
|
||||
|
||||
return l:entry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_bibliography.continue(context) abort dict " {{{1
|
||||
let [l:end, l:count] = s:find_closing(0, a:context.line, self.count, '[')
|
||||
if l:count == 0
|
||||
let self.options .= strpart(a:context.line, 0, l:end)
|
||||
unlet! s:matcher_continue
|
||||
call self.parse_options(a:context, a:context.entry)
|
||||
else
|
||||
let self.options .= a:context.line
|
||||
let self.count = l:count
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_bibliography.parse_options(context, entry) abort dict " {{{1
|
||||
" Parse the options
|
||||
let l:opt_pairs = map(split(self.options, ','), 'split(v:val, ''='')')
|
||||
let l:opts = {}
|
||||
for [l:key, l:val] in l:opt_pairs
|
||||
let l:key = substitute(l:key, '^\s*\|\s*$', '', 'g')
|
||||
let l:val = substitute(l:val, '^\s*\|\s*$', '', 'g')
|
||||
let l:val = substitute(l:val, '{\|}', '', 'g')
|
||||
let l:opts[l:key] = l:val
|
||||
endfor
|
||||
|
||||
" Check if entry should appear in the TOC
|
||||
let l:heading = get(l:opts, 'heading')
|
||||
let a:entry.added_to_toc = l:heading =~# 'intoc\|numbered'
|
||||
|
||||
" Check if entry should be numbered
|
||||
if l:heading =~# '\v%(sub)?bibnumbered'
|
||||
if a:context.level.chapter > 0
|
||||
let l:levels = ['chapter', 'section']
|
||||
else
|
||||
let l:levels = ['section', 'subsection']
|
||||
endif
|
||||
call a:context.level.increment(l:levels[l:heading =~# '^sub'])
|
||||
let a:entry.level = a:context.max_level - a:context.level.current
|
||||
let a:entry.number = deepcopy(a:context.level)
|
||||
endif
|
||||
|
||||
" Parse title
|
||||
try
|
||||
let a:entry.title = remove(l:opts, 'title')
|
||||
catch /E716/
|
||||
let a:entry.title = l:heading =~# '^sub' ? 'References' : 'Bibliography'
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_bibliography.filter(entries) abort dict " {{{1
|
||||
if !empty(
|
||||
\ filter(deepcopy(a:entries), 'get(v:val, "added_to_toc")'))
|
||||
call filter(a:entries, 'get(v:val, "added_to_toc", 1)')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_todos = {
|
||||
\ 're' : g:vimtex#re#not_bslash . '\%\s+('
|
||||
\ . join(keys(g:vimtex_toc_todo_labels), '|') . ')[ :]+\s*(.*)',
|
||||
\ 'in_preamble' : 1,
|
||||
\ 'priority' : 2,
|
||||
\}
|
||||
function! s:matcher_todos.get_entry(context) abort dict " {{{1
|
||||
let [l:type, l:text] = matchlist(a:context.line, self.re)[1:2]
|
||||
let l:label = g:vimtex_toc_todo_labels[toupper(l:type)]
|
||||
|
||||
return {
|
||||
\ 'title' : l:label . l:text,
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'todo',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_todonotes = {
|
||||
\ 're' : g:vimtex#re#not_comment . '\\\w*todo\w*%(\[[^]]*\])?\{\zs.*',
|
||||
\ 'priority' : 2,
|
||||
\}
|
||||
function! s:matcher_todonotes.get_entry(context) abort dict " {{{1
|
||||
let title = matchstr(a:context.line, self.re)
|
||||
|
||||
let [l:end, l:count] = s:find_closing(0, title, 1, '{')
|
||||
if l:count == 0
|
||||
let title = strpart(title, 0, l:end)
|
||||
else
|
||||
let self.count = l:count
|
||||
let s:matcher_continue = deepcopy(self)
|
||||
endif
|
||||
|
||||
let l:label = get(g:vimtex_toc_todo_labels, 'TODO', 'TODO: ')
|
||||
|
||||
return {
|
||||
\ 'title' : l:label . title,
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'todo',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:matcher_todonotes.continue(context) abort dict " {{{1
|
||||
let [l:end, l:count] = s:find_closing(0, a:context.line, self.count, '{')
|
||||
if l:count == 0
|
||||
let a:context.entry.title .= strpart(a:context.line, 0, l:end)
|
||||
unlet! s:matcher_continue
|
||||
else
|
||||
let a:context.entry.title .= a:context.line
|
||||
let self.count = l:count
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:matcher_labels = {
|
||||
\ 're' : g:vimtex#re#not_comment . '\\label\{\zs.{-}\ze\}',
|
||||
\ 'priority' : 1,
|
||||
\}
|
||||
function! s:matcher_labels.get_entry(context) abort dict " {{{1
|
||||
return {
|
||||
\ 'title' : matchstr(a:context.line, self.re),
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'label',
|
||||
\ }
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
let s:matcher_beamer_frame = {
|
||||
\ 're' : '^\s*\\begin{frame}',
|
||||
\ 'priority' : 0,
|
||||
\}
|
||||
function! s:matcher_beamer_frame.get_entry(context) abort dict " {{{1
|
||||
let l:title = vimtex#util#trim(
|
||||
\ matchstr(a:context.line, self.re . '\s*{\zs.*\ze}\s*$'))
|
||||
|
||||
return {
|
||||
\ 'title' : 'Frame' . (empty(l:title) ? '' : ': ' . l:title),
|
||||
\ 'number' : '',
|
||||
\ 'file' : a:context.file,
|
||||
\ 'line' : a:context.lnum,
|
||||
\ 'level' : a:context.max_level - a:context.level.current,
|
||||
\ 'rank' : a:context.lnum_total,
|
||||
\ 'type' : 'content',
|
||||
\ }
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Utility functions
|
||||
"
|
||||
function! s:clear_texorpdfstring(title) abort " {{{1
|
||||
let l:i1 = match(a:title, '\\texorpdfstring')
|
||||
if l:i1 < 0 | return a:title | endif
|
||||
|
||||
" Find start of included part
|
||||
let [l:i2, l:dummy] = s:find_closing(
|
||||
\ match(a:title, '{', l:i1+1), a:title, 1, '{')
|
||||
let l:i2 = match(a:title, '{', l:i2+1)
|
||||
if l:i2 < 0 | return a:title | endif
|
||||
|
||||
" Find end of included part
|
||||
let [l:i3, l:dummy] = s:find_closing(l:i2, a:title, 1, '{')
|
||||
if l:i3 < 0 | return a:title | endif
|
||||
|
||||
return strpart(a:title, 0, l:i1)
|
||||
\ . strpart(a:title, l:i2+1, l:i3-l:i2-1)
|
||||
\ . s:clear_texorpdfstring(strpart(a:title, l:i3+1))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:find_closing(start, string, count, type) abort " {{{1
|
||||
if a:type ==# '{'
|
||||
let l:re = '{\|}'
|
||||
let l:open = '{'
|
||||
else
|
||||
let l:re = '\[\|\]'
|
||||
let l:open = '['
|
||||
endif
|
||||
let l:i2 = a:start-1
|
||||
let l:count = a:count
|
||||
while l:count > 0
|
||||
let l:i2 = match(a:string, l:re, l:i2+1)
|
||||
if l:i2 < 0 | break | endif
|
||||
|
||||
if a:string[l:i2] ==# l:open
|
||||
let l:count += 1
|
||||
else
|
||||
let l:count -= 1
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return [l:i2, l:count]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:sort_by_priority(d1, d2) abort " {{{1
|
||||
let l:p1 = get(a:d1, 'priority')
|
||||
let l:p2 = get(a:d2, 'priority')
|
||||
return l:p1 >= l:p2 ? l:p1 > l:p2 : -1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Section level counter
|
||||
"
|
||||
let s:level = {}
|
||||
function! s:level.reset(part, level) abort dict " {{{1
|
||||
if a:part ==# 'preamble'
|
||||
let self.old = []
|
||||
else
|
||||
let self.old += [copy(self)]
|
||||
endif
|
||||
|
||||
let self.preamble = 0
|
||||
let self.frontmatter = 0
|
||||
let self.mainmatter = 0
|
||||
let self.appendix = 0
|
||||
let self.backmatter = 0
|
||||
let self.part = 0
|
||||
let self.chapter = 0
|
||||
let self.section = 0
|
||||
let self.subsection = 0
|
||||
let self.subsubsection = 0
|
||||
let self.subsubsubsection = 0
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
let self.current = a:level
|
||||
let self[a:part] = 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:level.increment(level) abort dict " {{{1
|
||||
let self.current = s:sec_to_value[a:level]
|
||||
|
||||
let self.part_toggle = 0
|
||||
|
||||
if a:level ==# 'part'
|
||||
let self.part += 1
|
||||
let self.part_toggle = 1
|
||||
elseif a:level ==# 'chapter'
|
||||
let self.chapter += 1
|
||||
let self.section = 0
|
||||
let self.subsection = 0
|
||||
let self.subsubsection = 0
|
||||
let self.subsubsubsection = 0
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'section'
|
||||
let self.section += 1
|
||||
let self.subsection = 0
|
||||
let self.subsubsection = 0
|
||||
let self.subsubsubsection = 0
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'subsection'
|
||||
let self.subsection += 1
|
||||
let self.subsubsection = 0
|
||||
let self.subsubsubsection = 0
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'subsubsection'
|
||||
let self.subsubsection += 1
|
||||
let self.subsubsubsection = 0
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'subsubsubsection'
|
||||
let self.subsubsubsection += 1
|
||||
let self.paragraph = 0
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'paragraph'
|
||||
let self.paragraph += 1
|
||||
let self.subparagraph = 0
|
||||
elseif a:level ==# 'subparagraph'
|
||||
let self.subparagraph += 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:sec_to_value = {
|
||||
\ '_' : 0,
|
||||
\ 'subparagraph' : 1,
|
||||
\ 'paragraph' : 2,
|
||||
\ 'subsubsubsection' : 3,
|
||||
\ 'subsubsection' : 4,
|
||||
\ 'subsection' : 5,
|
||||
\ 'section' : 6,
|
||||
\ 'chapter' : 7,
|
||||
\ 'part' : 8,
|
||||
\ }
|
||||
|
||||
"
|
||||
" Create the lists of matchers
|
||||
"
|
||||
let s:matchers = map(
|
||||
\ filter(items(s:), 'v:val[0] =~# ''^matcher_'''),
|
||||
\ 'v:val[1]')
|
||||
\ + g:vimtex_toc_custom_matchers
|
||||
call sort(s:matchers, function('s:sort_by_priority'))
|
||||
|
||||
for s:m in s:matchers
|
||||
if !has_key(s:m, 'get_entry')
|
||||
let s:m.get_entry = function('vimtex#parser#toc#get_entry_general')
|
||||
endif
|
||||
endfor
|
||||
unlet! s:m
|
||||
|
||||
let s:matchers_preamble = filter(
|
||||
\ deepcopy(s:matchers), "get(v:val, 'in_preamble')")
|
||||
let s:matchers_content = filter(
|
||||
\ deepcopy(s:matchers), "get(v:val, 'in_content', 1)")
|
||||
|
||||
endif
|
||||
@@ -1,91 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#paths#pushd(path) abort " {{{1
|
||||
if empty(a:path) || getcwd() ==# fnamemodify(a:path, ':p')
|
||||
let s:qpath += ['']
|
||||
else
|
||||
let s:qpath += [getcwd()]
|
||||
execute s:cd fnameescape(a:path)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#paths#popd() abort " {{{1
|
||||
let l:path = remove(s:qpath, -1)
|
||||
if !empty(l:path)
|
||||
execute s:cd fnameescape(l:path)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#paths#is_abs(path) abort " {{{1
|
||||
return a:path =~# s:re_abs
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#paths#shorten_relative(path) abort " {{{1
|
||||
" Input: An absolute path
|
||||
" Output: Relative path with respect to the vimtex root, path relative to
|
||||
" vimtex root (unless absolute path is shorter)
|
||||
|
||||
let l:relative = vimtex#paths#relative(a:path, b:vimtex.root)
|
||||
return strlen(l:relative) < strlen(a:path)
|
||||
\ ? l:relative : a:path
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#paths#relative(path, current) abort " {{{1
|
||||
" Note: This algorithm is based on the one presented by @Offirmo at SO,
|
||||
" http://stackoverflow.com/a/12498485/51634
|
||||
|
||||
let l:target = simplify(substitute(a:path, '\\', '/', 'g'))
|
||||
let l:common = simplify(substitute(a:current, '\\', '/', 'g'))
|
||||
|
||||
" This only works on absolute paths
|
||||
if !vimtex#paths#is_abs(l:target)
|
||||
return substitute(a:path, '^\.\/', '', '')
|
||||
endif
|
||||
|
||||
let l:tries = 50
|
||||
let l:result = ''
|
||||
while stridx(l:target, l:common) != 0 && l:tries > 0
|
||||
let l:common = fnamemodify(l:common, ':h')
|
||||
let l:result = empty(l:result) ? '..' : '../' . l:result
|
||||
let l:tries -= 1
|
||||
endwhile
|
||||
|
||||
if l:tries == 0 | return a:path | endif
|
||||
|
||||
if l:common ==# '/'
|
||||
let l:result .= '/'
|
||||
endif
|
||||
|
||||
let l:forward = strpart(l:target, strlen(l:common))
|
||||
if !empty(l:forward)
|
||||
let l:result = empty(l:result)
|
||||
\ ? l:forward[1:]
|
||||
\ : l:result . l:forward
|
||||
endif
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:cd = exists('*haslocaldir') && haslocaldir()
|
||||
\ ? 'lcd'
|
||||
\ : exists(':tcd') && haslocaldir(-1) ? 'tcd' : 'cd'
|
||||
let s:qpath = get(s:, 'qpath', [])
|
||||
|
||||
let s:re_abs = has('win32') ? '^[A-Z]:[\\/]' : '^/'
|
||||
|
||||
endif
|
||||
@@ -1,97 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#pos#set_cursor(...) abort " {{{1
|
||||
call cursor(s:parse_args(a:000))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#get_cursor() abort " {{{1
|
||||
return exists('*getcurpos') ? getcurpos() : getpos('.')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#get_cursor_line() abort " {{{1
|
||||
let l:pos = vimtex#pos#get_cursor()
|
||||
return l:pos[1]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#pos#val(...) abort " {{{1
|
||||
let [l:lnum, l:cnum; l:rest] = s:parse_args(a:000)
|
||||
|
||||
return 100000*l:lnum + min([l:cnum, 90000])
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#next(...) abort " {{{1
|
||||
let [l:lnum, l:cnum; l:rest] = s:parse_args(a:000)
|
||||
|
||||
return l:cnum < strlen(getline(l:lnum))
|
||||
\ ? [0, l:lnum, l:cnum+1, 0]
|
||||
\ : [0, l:lnum+1, 1, 0]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#prev(...) abort " {{{1
|
||||
let [l:lnum, l:cnum; l:rest] = s:parse_args(a:000)
|
||||
|
||||
return l:cnum > 1
|
||||
\ ? [0, l:lnum, l:cnum-1, 0]
|
||||
\ : [0, max([l:lnum-1, 1]), strlen(getline(l:lnum-1)), 0]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#larger(pos1, pos2) abort " {{{1
|
||||
return vimtex#pos#val(a:pos1) > vimtex#pos#val(a:pos2)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#equal(p1, p2) abort " {{{1
|
||||
let l:pos1 = s:parse_args(a:p1)
|
||||
let l:pos2 = s:parse_args(a:p2)
|
||||
return l:pos1[:1] == l:pos2[:1]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#pos#smaller(pos1, pos2) abort " {{{1
|
||||
return vimtex#pos#val(a:pos1) < vimtex#pos#val(a:pos2)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:parse_args(args) abort " {{{1
|
||||
"
|
||||
" The arguments should be in one of the following forms (when unpacked):
|
||||
"
|
||||
" [lnum, cnum]
|
||||
" [bufnum, lnum, cnum, ...]
|
||||
" {'lnum' : lnum, 'cnum' : cnum}
|
||||
"
|
||||
|
||||
if len(a:args) > 1
|
||||
return s:parse_args([a:args])
|
||||
elseif len(a:args) == 1
|
||||
if type(a:args[0]) == type({})
|
||||
return [get(a:args[0], 'lnum'), get(a:args[0], 'cnum')]
|
||||
else
|
||||
if len(a:args[0]) == 2
|
||||
return a:args[0]
|
||||
else
|
||||
return a:args[0][1:]
|
||||
endif
|
||||
endif
|
||||
else
|
||||
return a:args
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,233 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#process#new(...) abort " {{{1
|
||||
let l:opts = a:0 > 0 ? a:1 : {}
|
||||
return extend(deepcopy(s:process), l:opts)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#process#run(cmd, ...) abort " {{{1
|
||||
let l:opts = a:0 > 0 ? a:1 : {}
|
||||
let l:opts.cmd = a:cmd
|
||||
let l:process = vimtex#process#new(l:opts)
|
||||
|
||||
return l:process.run()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#process#capture(cmd) abort " {{{1
|
||||
return vimtex#process#run(a:cmd, {'capture': 1})
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#process#start(cmd, ...) abort " {{{1
|
||||
let l:opts = a:0 > 0 ? a:1 : {}
|
||||
let l:opts.continuous = 1
|
||||
return vimtex#process#run(a:cmd, l:opts)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:process = {
|
||||
\ 'cmd' : '',
|
||||
\ 'pid' : 0,
|
||||
\ 'background' : 1,
|
||||
\ 'continuous' : 0,
|
||||
\ 'output' : '',
|
||||
\ 'workdir' : '',
|
||||
\ 'silent' : 1,
|
||||
\ 'capture' : 0,
|
||||
\ 'result' : '',
|
||||
\}
|
||||
|
||||
function! s:process.run() abort dict " {{{1
|
||||
if self._do_not_run() | return | endif
|
||||
|
||||
call self._pre_run()
|
||||
call self._prepare()
|
||||
call self._execute()
|
||||
call self._restore()
|
||||
call self._post_run()
|
||||
|
||||
return self.capture ? self.result : self
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process.stop() abort dict " {{{1
|
||||
if !self.pid | return | endif
|
||||
|
||||
let l:cmd = has('win32')
|
||||
\ ? 'taskkill /PID ' . self.pid . ' /T /F'
|
||||
\ : 'kill ' . self.pid
|
||||
call vimtex#process#run(l:cmd, {'background': 0})
|
||||
|
||||
let self.pid = 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process.pprint_items() abort dict " {{{1
|
||||
let l:list = [
|
||||
\ ['pid', self.pid ? self.pid : '-'],
|
||||
\ ['cmd', get(self, 'prepared_cmd', self.cmd)],
|
||||
\]
|
||||
|
||||
return l:list
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:process._do_not_run() abort dict " {{{1
|
||||
if empty(self.cmd)
|
||||
call vimtex#log#warning('Can''t run empty command')
|
||||
return 1
|
||||
endif
|
||||
if self.pid
|
||||
call vimtex#log#warning('Process already running!')
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process._pre_run() abort dict " {{{1
|
||||
if self.capture
|
||||
let self.silent = 0
|
||||
let self.background = 0
|
||||
elseif empty(self.output) && self.background
|
||||
let self.output = 'null'
|
||||
endif
|
||||
|
||||
call vimtex#paths#pushd(self.workdir)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process._execute() abort dict " {{{1
|
||||
if self.capture
|
||||
let self.result = split(system(self.prepared_cmd), '\n')
|
||||
elseif self.silent
|
||||
silent call system(self.prepared_cmd)
|
||||
elseif self.background
|
||||
silent execute '!' . self.prepared_cmd
|
||||
if !has('gui_running')
|
||||
redraw!
|
||||
endif
|
||||
else
|
||||
execute '!' . self.prepared_cmd
|
||||
endif
|
||||
|
||||
" Capture the pid if relevant
|
||||
if has_key(self, 'set_pid') && self.continuous
|
||||
call self.set_pid()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process._post_run() abort dict " {{{1
|
||||
call vimtex#paths#popd()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
if has('win32')
|
||||
function! s:process._prepare() abort dict " {{{1
|
||||
if &shell !~? 'cmd'
|
||||
let self.win32_restore_shell = 1
|
||||
let self.win32_saved_shell = [
|
||||
\ &shell,
|
||||
\ &shellcmdflag,
|
||||
\ &shellxquote,
|
||||
\ &shellxescape,
|
||||
\ &shellquote,
|
||||
\ &shellpipe,
|
||||
\ &shellredir,
|
||||
\ &shellslash
|
||||
\]
|
||||
set shell& shellcmdflag& shellxquote& shellxescape&
|
||||
set shellquote& shellpipe& shellredir& shellslash&
|
||||
else
|
||||
let self.win32_restore_shell = 0
|
||||
endif
|
||||
|
||||
let l:cmd = self.cmd
|
||||
|
||||
if self.background
|
||||
if !empty(self.output)
|
||||
let l:cmd .= self.output ==# 'null'
|
||||
\ ? ' >nul'
|
||||
\ : ' >' . self.output
|
||||
let l:cmd = 'cmd /s /c "' . l:cmd . '"'
|
||||
else
|
||||
let l:cmd = 'cmd /c "' . l:cmd . '"'
|
||||
endif
|
||||
let l:cmd = 'start /b ' . cmd
|
||||
endif
|
||||
|
||||
if self.silent && self.output ==# 'null'
|
||||
let self.prepared_cmd = '"' . l:cmd . '"'
|
||||
else
|
||||
let self.prepared_cmd = l:cmd
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process._restore() abort dict " {{{1
|
||||
if self.win32_restore_shell
|
||||
let [ &shell,
|
||||
\ &shellcmdflag,
|
||||
\ &shellxquote,
|
||||
\ &shellxescape,
|
||||
\ &shellquote,
|
||||
\ &shellpipe,
|
||||
\ &shellredir,
|
||||
\ &shellslash] = self.win32_saved_shell
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process.get_pid() abort dict " {{{1
|
||||
let self.pid = 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
else
|
||||
function! s:process._prepare() abort dict " {{{1
|
||||
let l:cmd = self.cmd
|
||||
|
||||
if self.background
|
||||
if !empty(self.output)
|
||||
let l:cmd .= ' >'
|
||||
\ . (self.output ==# 'null'
|
||||
\ ? '/dev/null'
|
||||
\ : shellescape(self.output))
|
||||
\ . ' 2>&1'
|
||||
endif
|
||||
let l:cmd .= ' &'
|
||||
endif
|
||||
|
||||
if !self.silent
|
||||
let l:cmd = escape(l:cmd, '%#')
|
||||
endif
|
||||
|
||||
let self.prepared_cmd = l:cmd
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process._restore() abort dict " {{{1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:process.get_pid() abort dict " {{{1
|
||||
let self.pid = 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
endif
|
||||
|
||||
endif
|
||||
@@ -1,125 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#profile#start() abort " {{{1
|
||||
profile start prof.log
|
||||
profile func *
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#profile#stop() abort " {{{1
|
||||
profile stop
|
||||
call s:fix_sids()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
"
|
||||
function! vimtex#profile#open() abort " {{{1
|
||||
source ~/.vim/vimrc
|
||||
silent edit prof.log
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#profile#print() abort " {{{1
|
||||
for l:line in readfile('prof.log')
|
||||
echo l:line
|
||||
endfor
|
||||
echo ''
|
||||
quit!
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#profile#file(filename) abort " {{{1
|
||||
call vimtex#profile#start()
|
||||
|
||||
execute 'silent edit' a:filename
|
||||
|
||||
call vimtex#profile#stop()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#profile#command(cmd) abort " {{{1
|
||||
call vimtex#profile#start()
|
||||
|
||||
execute a:cmd
|
||||
|
||||
call vimtex#profile#stop()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#profile#filter(sections) abort " {{{1
|
||||
let l:lines = readfile('prof.log')
|
||||
" call filter(l:lines, 'v:val !~# ''FTtex''')
|
||||
" call filter(l:lines, 'v:val !~# ''LoadFTPlugin''')
|
||||
|
||||
let l:new = []
|
||||
for l:sec in a:sections
|
||||
call extend(l:new, s:get_section(l:sec, l:lines))
|
||||
endfor
|
||||
|
||||
call writefile(l:new, 'prof.log')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:fix_sids() abort " {{{1
|
||||
let l:lines = readfile('prof.log')
|
||||
let l:new = []
|
||||
for l:line in l:lines
|
||||
let l:sid = matchstr(l:line, '\v\<SNR\>\zs\d+\ze_')
|
||||
if !empty(l:sid)
|
||||
let l:filename = map(
|
||||
\ vimtex#util#command('scriptnames'),
|
||||
\ 'split(v:val, "\\v:=\\s+")[1]')[l:sid-1]
|
||||
if l:filename =~# 'vimtex'
|
||||
let l:filename = substitute(l:filename, '^.*autoload\/', '', '')
|
||||
let l:filename = substitute(l:filename, '\.vim$', '#s:', '')
|
||||
let l:filename = substitute(l:filename, '\/', '#', 'g')
|
||||
else
|
||||
let l:filename .= ':'
|
||||
endif
|
||||
call add(l:new, substitute(l:line, '\v\<SNR\>\d+_', l:filename, 'g'))
|
||||
else
|
||||
call add(l:new, substitute(l:line, '\s\+$', '', ''))
|
||||
endif
|
||||
endfor
|
||||
call writefile(l:new, 'prof.log')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_section(name, lines) abort " {{{1
|
||||
let l:active = 0
|
||||
let l:section = []
|
||||
for l:line in a:lines
|
||||
if l:active
|
||||
if l:line =~# '^FUNCTION' && l:line !~# a:name
|
||||
let l:active = 0
|
||||
else
|
||||
call add(l:section, l:line)
|
||||
endif
|
||||
continue
|
||||
endif
|
||||
|
||||
if l:line =~# a:name
|
||||
call add(l:section, l:line)
|
||||
let l:active = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:active
|
||||
call add(l:section, ' ')
|
||||
endif
|
||||
|
||||
return l:section
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,245 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#init_buffer() abort " {{{1
|
||||
if !g:vimtex_quickfix_enabled | return | endif
|
||||
|
||||
command! -buffer VimtexErrors call vimtex#qf#toggle()
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-errors) :call vimtex#qf#toggle()<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#qf#init_state(state) abort " {{{1
|
||||
if !g:vimtex_quickfix_enabled | return | endif
|
||||
|
||||
try
|
||||
let l:qf = vimtex#qf#{g:vimtex_quickfix_method}#new()
|
||||
call l:qf.init(a:state)
|
||||
unlet l:qf.init
|
||||
let a:state.qf = l:qf
|
||||
catch /vimtex: Requirements not met/
|
||||
call vimtex#log#warning(
|
||||
\ 'Quickfix state not initialized!',
|
||||
\ 'Please see :help g:vimtex_quickfix_method')
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#qf#toggle() abort " {{{1
|
||||
if vimtex#qf#is_open()
|
||||
cclose
|
||||
else
|
||||
call vimtex#qf#open(1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#qf#open(force) abort " {{{1
|
||||
if !exists('b:vimtex.qf.addqflist') | return | endif
|
||||
|
||||
try
|
||||
call vimtex#qf#setqflist()
|
||||
catch /Vimtex: No log file found/
|
||||
if a:force
|
||||
call vimtex#log#warning('No log file found')
|
||||
endif
|
||||
if g:vimtex_quickfix_mode > 0
|
||||
cclose
|
||||
endif
|
||||
return
|
||||
catch
|
||||
call vimtex#log#error('Something went wrong when parsing log files!')
|
||||
if g:vimtex_quickfix_mode > 0
|
||||
cclose
|
||||
endif
|
||||
return
|
||||
endtry
|
||||
|
||||
if empty(getqflist())
|
||||
if a:force
|
||||
call vimtex#log#info('No errors!')
|
||||
endif
|
||||
if g:vimtex_quickfix_mode > 0
|
||||
cclose
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
"
|
||||
" There are two options that determine when to open the quickfix window. If
|
||||
" forced, the quickfix window is always opened when there are errors or
|
||||
" warnings (forced typically imply that the functions is called from the
|
||||
" normal mode mapping). Else the behaviour is based on the settings.
|
||||
"
|
||||
let l:errors_or_warnings = s:qf_has_errors()
|
||||
\ || g:vimtex_quickfix_open_on_warning
|
||||
|
||||
if a:force || (g:vimtex_quickfix_mode > 0 && l:errors_or_warnings)
|
||||
call s:window_save()
|
||||
botright cwindow
|
||||
if g:vimtex_quickfix_mode == 2
|
||||
call s:window_restore()
|
||||
endif
|
||||
if g:vimtex_quickfix_autoclose_after_keystrokes > 0
|
||||
augroup vimtex_qf_autoclose
|
||||
autocmd!
|
||||
autocmd CursorMoved,CursorMovedI * call s:qf_autoclose_check()
|
||||
augroup END
|
||||
endif
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#qf#setqflist(...) abort " {{{1
|
||||
if !exists('b:vimtex.qf.addqflist') | return | endif
|
||||
|
||||
if a:0 > 0
|
||||
let l:tex = a:1
|
||||
let l:log = fnamemodify(l:tex, ':r') . '.log'
|
||||
let l:blg = fnamemodify(l:tex, ':r') . '.blg'
|
||||
let l:jump = 0
|
||||
else
|
||||
let l:tex = b:vimtex.tex
|
||||
let l:log = b:vimtex.log()
|
||||
let l:blg = b:vimtex.ext('blg')
|
||||
let l:jump = g:vimtex_quickfix_autojump
|
||||
endif
|
||||
|
||||
try
|
||||
" Initialize the quickfix list
|
||||
" Note: Only create new list if the current list is not a vimtex qf list
|
||||
if get(getqflist({'title': 1}), 'title') =~# 'Vimtex'
|
||||
call setqflist([], 'r')
|
||||
else
|
||||
call setqflist([])
|
||||
endif
|
||||
|
||||
" Parse LaTeX errors
|
||||
call b:vimtex.qf.addqflist(l:tex, l:log)
|
||||
|
||||
" Parse bibliography errors
|
||||
if has_key(b:vimtex.packages, 'biblatex')
|
||||
call vimtex#qf#biblatex#addqflist(l:blg)
|
||||
else
|
||||
call vimtex#qf#bibtex#addqflist(l:blg)
|
||||
endif
|
||||
|
||||
" Ignore entries if desired
|
||||
if !empty(g:vimtex_quickfix_ignore_filters)
|
||||
let l:qflist = getqflist()
|
||||
for l:re in g:vimtex_quickfix_ignore_filters
|
||||
call filter(l:qflist, 'v:val.text !~# l:re')
|
||||
endfor
|
||||
call setqflist(l:qflist, 'r')
|
||||
endif
|
||||
|
||||
" Set title if supported
|
||||
try
|
||||
call setqflist([], 'r', {'title': 'Vimtex errors (' . b:vimtex.qf.name . ')'})
|
||||
catch
|
||||
endtry
|
||||
|
||||
" Jump to first error if wanted
|
||||
if l:jump
|
||||
cfirst
|
||||
endif
|
||||
catch /Vimtex: No log file found/
|
||||
throw 'Vimtex: No log file found'
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#qf#inquire(file) abort " {{{1
|
||||
try
|
||||
call vimtex#qf#setqflist(a:file)
|
||||
return s:qf_has_errors()
|
||||
catch
|
||||
return 0
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#qf#is_open() abort " {{{1
|
||||
redir => l:bufstring
|
||||
silent! ls!
|
||||
redir END
|
||||
|
||||
let l:buflist = filter(split(l:bufstring, '\n'), 'v:val =~# ''Quickfix''')
|
||||
|
||||
for l:line in l:buflist
|
||||
let l:bufnr = str2nr(matchstr(l:line, '^\s*\zs\d\+'))
|
||||
if bufwinnr(l:bufnr) >= 0
|
||||
\ && getbufvar(l:bufnr, '&buftype', '') ==# 'quickfix'
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:window_save() abort " {{{1
|
||||
if exists('*win_gotoid')
|
||||
let s:previous_window = win_getid()
|
||||
else
|
||||
let w:vimtex_remember_window = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:window_restore() abort " {{{1
|
||||
if exists('*win_gotoid')
|
||||
call win_gotoid(s:previous_window)
|
||||
else
|
||||
for l:winnr in range(1, winnr('$'))
|
||||
if getwinvar(l:winnr, 'vimtex_remember_window')
|
||||
execute l:winnr . 'wincmd p'
|
||||
unlet! w:vimtex_remember_window
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:qf_has_errors() abort " {{{1
|
||||
return len(filter(getqflist(), 'v:val.type ==# ''E''')) > 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
"
|
||||
function! s:qf_autoclose_check() abort " {{{1
|
||||
if get(s:, 'keystroke_counter') == 0
|
||||
let s:keystroke_counter = g:vimtex_quickfix_autoclose_after_keystrokes
|
||||
endif
|
||||
|
||||
redir => l:bufstring
|
||||
silent! ls!
|
||||
redir END
|
||||
|
||||
if empty(filter(split(l:bufstring, '\n'), 'v:val =~# ''%a- .*Quickfix'''))
|
||||
let s:keystroke_counter -= 1
|
||||
else
|
||||
let s:keystroke_counter = g:vimtex_quickfix_autoclose_after_keystrokes + 1
|
||||
endif
|
||||
|
||||
if s:keystroke_counter == 0
|
||||
cclose
|
||||
autocmd! vimtex_qf_autoclose
|
||||
augroup! vimtex_qf_autoclose
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,250 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#biblatex#addqflist(blg) abort " {{{1
|
||||
if get(g:vimtex_quickfix_blgparser, 'disable') | return | endif
|
||||
|
||||
try
|
||||
call s:biblatex.addqflist(a:blg)
|
||||
catch /biblatex Aborted/
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:biblatex = {
|
||||
\ 'file' : '',
|
||||
\ 'types' : [],
|
||||
\ 'db_files' : [],
|
||||
\}
|
||||
function! s:biblatex.addqflist(blg) abort " {{{1
|
||||
let self.file = a:blg
|
||||
let self.root = fnamemodify(a:blg, ':h')
|
||||
if empty(self.file) | throw 'biblatex Aborted' | endif
|
||||
|
||||
let self.types = map(
|
||||
\ filter(items(s:), 'v:val[0] =~# ''^type_'''),
|
||||
\ 'v:val[1]')
|
||||
let self.db_files = []
|
||||
|
||||
let self.errorformat_saved = &l:errorformat
|
||||
setlocal errorformat=%+E%.%#\>\ ERROR%m
|
||||
setlocal errorformat+=%+W%.%#\>\ WARN\ -\ Duplicate\ entry%m
|
||||
setlocal errorformat+=%+W%.%#\>\ WARN\ -\ The\ entry%.%#cannot\ be\ encoded%m
|
||||
setlocal errorformat+=%-G%.%#
|
||||
execute 'caddfile' fnameescape(self.file)
|
||||
let &l:errorformat = self.errorformat_saved
|
||||
|
||||
call self.fix_paths()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.fix_paths() abort " {{{1
|
||||
let l:qflist = getqflist()
|
||||
try
|
||||
let l:title = getqflist({'title': 1})
|
||||
catch /E118/
|
||||
let l:title = 'Vimtex errors'
|
||||
endtry
|
||||
|
||||
for l:qf in l:qflist
|
||||
for l:type in self.types
|
||||
if l:type.fix(self, l:qf) | break | endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
call setqflist(l:qflist, 'r')
|
||||
|
||||
" Set title if supported
|
||||
try
|
||||
call setqflist([], 'r', l:title)
|
||||
catch
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.get_db_files() abort " {{{1
|
||||
if empty(self.db_files)
|
||||
let l:preamble = vimtex#parser#preamble(b:vimtex.tex, {
|
||||
\ 'root' : b:vimtex.root,
|
||||
\})
|
||||
let l:files = map(
|
||||
\ filter(l:preamble, 'v:val =~# ''\\addbibresource'''),
|
||||
\ 'matchstr(v:val, ''{\zs.*\ze}'')')
|
||||
let self.db_files = []
|
||||
for l:file in l:files
|
||||
if filereadable(l:file)
|
||||
let self.db_files += [l:file]
|
||||
elseif filereadable(expand(l:file))
|
||||
let self.db_files += [expand(l:file)]
|
||||
else
|
||||
let l:cand = vimtex#kpsewhich#run(l:file)
|
||||
if len(l:cand) == 1
|
||||
let self.db_files += [l:cand[0]]
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return self.db_files
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.get_filename(name) abort " {{{1
|
||||
if !filereadable(a:name)
|
||||
for l:root in [self.root, b:vimtex.root]
|
||||
let l:candidate = fnamemodify(simplify(l:root . '/' . a:name), ':.')
|
||||
if filereadable(l:candidate)
|
||||
return l:candidate
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return a:name
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.get_key_pos(key) abort " {{{1
|
||||
for l:file in self.get_db_files()
|
||||
let l:lnum = self.get_key_lnum(a:key, l:file)
|
||||
if l:lnum > 0
|
||||
return [l:file, l:lnum]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.get_key_lnum(key, filename) abort " {{{1
|
||||
if !filereadable(a:filename) | return 0 | endif
|
||||
|
||||
let l:lines = readfile(a:filename)
|
||||
let l:lnums = range(len(l:lines))
|
||||
let l:annotated_lines = map(l:lnums, '[v:val, l:lines[v:val]]')
|
||||
let l:matches = filter(l:annotated_lines, 'v:val[1] =~# ''^\s*@\w*{\s*\V' . a:key . '''')
|
||||
|
||||
return len(l:matches) > 0 ? l:matches[-1][0]+1 : 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:biblatex.get_entry_key(filename, lnum) abort " {{{1
|
||||
for l:file in self.get_db_files()
|
||||
if fnamemodify(l:file, ':t') !=# a:filename | continue | endif
|
||||
|
||||
let l:entry = get(filter(readfile(l:file, 0, a:lnum), 'v:val =~# ''^@'''), -1)
|
||||
if empty(l:entry) | continue | endif
|
||||
|
||||
return matchstr(l:entry, '{\v\zs.{-}\ze(,|$)')
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Parsers for the various warning types
|
||||
"
|
||||
|
||||
let s:type_parse_error = {}
|
||||
function! s:type_parse_error.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'ERROR - BibTeX subsystem.*expected end of entry'
|
||||
let l:matches = matchlist(a:entry.text, '\v(\S*\.bib).*line (\d+)')
|
||||
let a:entry.filename = a:ctx.get_filename(fnamemodify(l:matches[1], ':t'))
|
||||
let a:entry.lnum = l:matches[2]
|
||||
|
||||
" Use filename and line number to get entry name
|
||||
let l:key = a:ctx.get_entry_key(a:entry.filename, a:entry.lnum)
|
||||
if !empty(l:key)
|
||||
let a:entry.text = 'biblatex: Error parsing entry with key "' . l:key . '"'
|
||||
endif
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_duplicate = {}
|
||||
function! s:type_duplicate.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'WARN - Duplicate entry'
|
||||
let l:matches = matchlist(a:entry.text, '\v: ''(\S*)'' in file ''(.{-})''')
|
||||
let l:key = l:matches[1]
|
||||
let a:entry.filename = a:ctx.get_filename(l:matches[2])
|
||||
let a:entry.lnum = a:ctx.get_key_lnum(l:key, a:entry.filename)
|
||||
let a:entry.text = 'biblatex: Duplicate entry key "' . l:key . '"'
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_no_driver = {}
|
||||
function! s:type_no_driver.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'No driver for entry type'
|
||||
let l:key = matchstr(a:entry.text, 'entry type ''\v\zs.{-}\ze''')
|
||||
let a:entry.text = 'biblatex: Using fallback driver for ''' . l:key . ''''
|
||||
|
||||
let l:pos = a:ctx.get_key_pos(l:key)
|
||||
if !empty(l:pos)
|
||||
let a:entry.filename = a:ctx.get_filename(l:pos[0])
|
||||
let a:entry.lnum = l:pos[1]
|
||||
if has_key(a:entry, 'bufnr')
|
||||
unlet a:entry.bufnr
|
||||
endif
|
||||
endif
|
||||
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_not_found = {}
|
||||
function! s:type_not_found.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'The following entry could not be found'
|
||||
let l:key = split(a:entry.text, ' ')[-1]
|
||||
let a:entry.text = 'biblatex: Entry with key ''' . l:key . ''' not found'
|
||||
|
||||
for [l:file, l:lnum, l:line] in vimtex#parser#tex(b:vimtex.tex)
|
||||
if l:line =~# g:vimtex#re#not_comment . '\\\S*\V' . l:key
|
||||
let a:entry.lnum = l:lnum
|
||||
let a:entry.filename = l:file
|
||||
unlet a:entry.bufnr
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_encoding = {}
|
||||
function! s:type_encoding.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'The entry .* has characters which cannot'
|
||||
let l:key = matchstr(a:entry.text, 'The entry ''\v\zs.{-}\ze''')
|
||||
let a:entry.text = 'biblatex: Entry with key ''' . l:key . ''' has non-ascii characters'
|
||||
|
||||
let l:pos = a:ctx.get_key_pos(l:key)
|
||||
if !empty(l:pos)
|
||||
let a:entry.filename = a:ctx.get_filename(l:pos[0])
|
||||
let a:entry.lnum = l:pos[1]
|
||||
if has_key(a:entry, 'bufnr')
|
||||
unlet a:entry.bufnr
|
||||
endif
|
||||
endif
|
||||
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,187 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#bibtex#addqflist(blg) abort " {{{1
|
||||
if get(g:vimtex_quickfix_blgparser, 'disable') | return | endif
|
||||
|
||||
try
|
||||
call s:bibtex.addqflist(a:blg)
|
||||
catch /BibTeX Aborted/
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:bibtex = {
|
||||
\ 'file' : '',
|
||||
\ 'types' : [],
|
||||
\ 'db_files' : [],
|
||||
\}
|
||||
function! s:bibtex.addqflist(blg) abort " {{{1
|
||||
let self.file = a:blg
|
||||
if empty(self.file) || !filereadable(self.file) | throw 'BibTeX Aborted' | endif
|
||||
|
||||
let self.types = map(
|
||||
\ filter(items(s:), 'v:val[0] =~# ''^type_'''),
|
||||
\ 'v:val[1]')
|
||||
let self.db_files = []
|
||||
|
||||
let self.errorformat_saved = &l:errorformat
|
||||
setlocal errorformat=%+E%.%#---line\ %l\ of\ file\ %f
|
||||
setlocal errorformat+=%+EI\ found\ %.%#---while\ reading\ file\ %f
|
||||
setlocal errorformat+=%+WWarning--empty\ %.%#\ in\ %.%m
|
||||
setlocal errorformat+=%+WWarning--entry\ type\ for%m
|
||||
setlocal errorformat+=%-C--line\ %l\ of\ file\ %f
|
||||
setlocal errorformat+=%-G%.%#
|
||||
execute 'caddfile' fnameescape(self.file)
|
||||
let &l:errorformat = self.errorformat_saved
|
||||
|
||||
call self.fix_paths()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:bibtex.fix_paths() abort " {{{1
|
||||
let l:qflist = getqflist()
|
||||
try
|
||||
let l:title = getqflist({'title': 1})
|
||||
catch /E118/
|
||||
let l:title = 'Vimtex errors'
|
||||
endtry
|
||||
|
||||
for l:qf in l:qflist
|
||||
for l:type in self.types
|
||||
if l:type.fix(self, l:qf) | break | endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
call setqflist(l:qflist, 'r')
|
||||
|
||||
" Set title if supported
|
||||
try
|
||||
call setqflist([], 'r', l:title)
|
||||
catch
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:bibtex.get_db_files() abort " {{{1
|
||||
if empty(self.db_files)
|
||||
let l:build_dir = fnamemodify(b:vimtex.ext('log'), ':.:h') . '/'
|
||||
for l:file in map(
|
||||
\ filter(readfile(self.file), 'v:val =~# ''Database file #\d:'''),
|
||||
\ 'matchstr(v:val, '': \zs.*'')')
|
||||
if filereadable(l:file)
|
||||
call add(self.db_files, l:file)
|
||||
elseif filereadable(l:build_dir . l:file)
|
||||
call add(self.db_files, l:build_dir . l:file)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return self.db_files
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:bibtex.get_key_loc(key) abort " {{{1
|
||||
for l:file in self.get_db_files()
|
||||
let l:lines = readfile(l:file)
|
||||
let l:lnum = 0
|
||||
for l:line in l:lines
|
||||
let l:lnum += 1
|
||||
if l:line =~# '^\s*@\w*{\s*\V' . a:key
|
||||
return [l:file, l:lnum]
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
"
|
||||
" Parsers for the various warning types
|
||||
"
|
||||
|
||||
let s:type_syn_error = {}
|
||||
function! s:type_syn_error.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# '---line \d\+ of file'
|
||||
let a:entry.text = split(a:entry.text, '---')[0]
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_empty = {
|
||||
\ 're' : '\vWarning--empty (.*) in (\S*)',
|
||||
\}
|
||||
function! s:type_empty.fix(ctx, entry) abort " {{{1
|
||||
let l:matches = matchlist(a:entry.text, self.re)
|
||||
if empty(l:matches) | return 0 | endif
|
||||
|
||||
let l:type = l:matches[1]
|
||||
let l:key = l:matches[2]
|
||||
|
||||
unlet a:entry.bufnr
|
||||
let a:entry.text = printf('Missing "%s" in "%s"', l:type, l:key)
|
||||
|
||||
let l:loc = a:ctx.get_key_loc(l:key)
|
||||
if !empty(l:loc)
|
||||
let a:entry.filename = l:loc[0]
|
||||
let a:entry.lnum = l:loc[1]
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_style_file_defined = {
|
||||
\ 're' : '\vWarning--entry type for "(\w+)"',
|
||||
\}
|
||||
function! s:type_style_file_defined.fix(ctx, entry) abort " {{{1
|
||||
let l:matches = matchlist(a:entry.text, self.re)
|
||||
if empty(l:matches) | return 0 | endif
|
||||
|
||||
let l:key = l:matches[1]
|
||||
|
||||
unlet a:entry.bufnr
|
||||
let a:entry.text = 'Entry type for "' . l:key . '" isn''t style-file defined'
|
||||
|
||||
let l:loc = a:ctx.get_key_loc(l:key)
|
||||
if !empty(l:loc)
|
||||
let a:entry.filename = l:loc[0]
|
||||
let a:entry.lnum = l:loc[1]
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:type_no_bibstyle = {}
|
||||
function! s:type_no_bibstyle.fix(ctx, entry) abort " {{{1
|
||||
if a:entry.text =~# 'I found no \\bibstyle'
|
||||
let a:entry.text = 'BibTeX found no \bibstyle command (missing \bibliographystyle?)'
|
||||
let a:entry.filename = b:vimtex.tex
|
||||
unlet a:entry.bufnr
|
||||
for [l:file, l:lnum, l:line] in vimtex#parser#tex(b:vimtex.tex)
|
||||
if l:line =~# g:vimtex#re#not_comment . '\\bibliography'
|
||||
let a:entry.lnum = l:lnum
|
||||
let a:entry.filename = l:file
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,209 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#latexlog#new() abort " {{{1
|
||||
return deepcopy(s:qf)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:qf = {
|
||||
\ 'name' : 'LaTeX logfile',
|
||||
\}
|
||||
|
||||
function! s:qf.init(state) abort dict "{{{1
|
||||
let self.config = get(g:, 'vimtex_quickfix_latexlog', {})
|
||||
let self.config.default = get(self.config, 'default', 1)
|
||||
let self.config.packages = get(self.config, 'packages', {})
|
||||
let self.config.packages.default = get(self.config.packages, 'default',
|
||||
\ self.config.default)
|
||||
|
||||
let self.types = map(
|
||||
\ filter(items(s:), 'v:val[0] =~# ''^type_'''),
|
||||
\ 'v:val[1]')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.set_errorformat() abort dict "{{{1
|
||||
"
|
||||
" Note: The errorformat assumes we're using the -file-line-error with
|
||||
" [pdf]latex. For more info, see |errorformat-LaTeX|.
|
||||
"
|
||||
|
||||
" Push file to file stack
|
||||
setlocal errorformat=%-P**%f
|
||||
setlocal errorformat+=%-P**\"%f\"
|
||||
|
||||
" Match errors
|
||||
setlocal errorformat+=%E!\ LaTeX\ %trror:\ %m
|
||||
setlocal errorformat+=%E%f:%l:\ %m
|
||||
setlocal errorformat+=%E!\ %m
|
||||
|
||||
" More info for undefined control sequences
|
||||
setlocal errorformat+=%Z<argument>\ %m
|
||||
|
||||
" More info for some errors
|
||||
setlocal errorformat+=%Cl.%l\ %m
|
||||
|
||||
"
|
||||
" Define general warnings
|
||||
"
|
||||
let l:default = self.config.default
|
||||
if get(self.config, 'font', l:default)
|
||||
setlocal errorformat+=%+WLaTeX\ Font\ Warning:\ %.%#line\ %l%.%#
|
||||
setlocal errorformat+=%-CLaTeX\ Font\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(Font)%m
|
||||
else
|
||||
setlocal errorformat+=%-WLaTeX\ Font\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if !get(self.config, 'references', l:default)
|
||||
setlocal errorformat+=%-WLaTeX\ %.%#Warning:\ %.%#eference%.%#undefined%.%#line\ %l%.%#
|
||||
setlocal errorformat+=%-WLaTeX\ %.%#Warning:\ %.%#undefined\ references.
|
||||
endif
|
||||
|
||||
if get(self.config, 'general', l:default)
|
||||
setlocal errorformat+=%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#
|
||||
setlocal errorformat+=%+WLaTeX\ %.%#Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config, 'overfull', l:default)
|
||||
setlocal errorformat+=%+WOverfull\ %\\%\\hbox%.%#\ at\ lines\ %l--%*\\d
|
||||
setlocal errorformat+=%+WOverfull\ %\\%\\hbox%.%#\ at\ line\ %l
|
||||
setlocal errorformat+=%+WOverfull\ %\\%\\vbox%.%#\ at\ line\ %l
|
||||
endif
|
||||
|
||||
if get(self.config, 'underfull', l:default)
|
||||
setlocal errorformat+=%+WUnderfull\ %\\%\\hbox%.%#\ at\ lines\ %l--%*\\d
|
||||
setlocal errorformat+=%+WUnderfull\ %\\%\\vbox%.%#\ at\ line\ %l
|
||||
endif
|
||||
|
||||
"
|
||||
" Define package related warnings
|
||||
"
|
||||
let l:default = self.config.packages.default
|
||||
if get(self.config.packages, 'natbib', l:default)
|
||||
setlocal errorformat+=%+WPackage\ natbib\ Warning:\ %m\ on\ input\ line\ %l.
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ natbib\ Warning:\ %m\ on\ input\ line\ %l.
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'biblatex', l:default)
|
||||
setlocal errorformat+=%+WPackage\ biblatex\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(biblatex)%.%#in\ t%.%#
|
||||
setlocal errorformat+=%-C(biblatex)%.%#Please\ v%.%#
|
||||
setlocal errorformat+=%-C(biblatex)%.%#LaTeX\ a%.%#
|
||||
setlocal errorformat+=%-C(biblatex)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ biblatex\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'babel', l:default)
|
||||
setlocal errorformat+=%+WPackage\ babel\ Warning:\ %m
|
||||
setlocal errorformat+=%-Z(babel)%.%#input\ line\ %l.
|
||||
setlocal errorformat+=%-C(babel)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ babel\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'hyperref', l:default)
|
||||
setlocal errorformat+=%+WPackage\ hyperref\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(hyperref)%m\ on\ input\ line\ %l.
|
||||
setlocal errorformat+=%-C(hyperref)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ hyperref\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'scrreprt', l:default)
|
||||
setlocal errorformat+=%+WPackage\ scrreprt\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(scrreprt)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ scrreprt\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'fixltx2e', l:default)
|
||||
setlocal errorformat+=%+WPackage\ fixltx2e\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(fixltx2e)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ fixltx2e\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'titlesec', l:default)
|
||||
setlocal errorformat+=%+WPackage\ titlesec\ Warning:\ %m
|
||||
setlocal errorformat+=%-C(titlesec)%m
|
||||
else
|
||||
setlocal errorformat+=%-WPackage\ titlesec\ Warning:\ %m
|
||||
endif
|
||||
|
||||
if get(self.config.packages, 'general', l:default)
|
||||
setlocal errorformat+=%+WPackage\ %.%#\ Warning:\ %m\ on\ input\ line\ %l.
|
||||
setlocal errorformat+=%+WPackage\ %.%#\ Warning:\ %m
|
||||
setlocal errorformat+=%-Z(%.%#)\ %m\ on\ input\ line\ %l.
|
||||
setlocal errorformat+=%-C(%.%#)\ %m
|
||||
endif
|
||||
|
||||
" Ignore unmatched lines
|
||||
setlocal errorformat+=%-G%.%#
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.addqflist(tex, log) abort dict "{{{1
|
||||
if empty(a:log) || !filereadable(a:log)
|
||||
throw 'Vimtex: No log file found'
|
||||
endif
|
||||
|
||||
let self.errorformat_saved = &l:errorformat
|
||||
call self.set_errorformat()
|
||||
execute 'caddfile' fnameescape(a:log)
|
||||
let &l:errorformat = self.errorformat_saved
|
||||
|
||||
" Apply some post processing of the quickfix list
|
||||
let self.main = a:tex
|
||||
let self.root = b:vimtex.root
|
||||
call self.fix_paths()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.pprint_items() abort dict " {{{1
|
||||
return [[ 'config', self.config ]]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.fix_paths() abort dict " {{{1
|
||||
let l:qflist = getqflist()
|
||||
|
||||
for l:qf in l:qflist
|
||||
" For errors and warnings that don't supply a file, the basename of the
|
||||
" main file is used. However, if the working directory is not the root of
|
||||
" the LaTeX project, than this results in bufnr = 0.
|
||||
if l:qf.bufnr == 0
|
||||
let l:qf.bufnr = bufnr(self.main)
|
||||
continue
|
||||
endif
|
||||
|
||||
" The buffer names of all file:line type errors are relative to the root of
|
||||
" the main LaTeX file.
|
||||
let l:file = fnamemodify(
|
||||
\ simplify(self.root . '/' . bufname(l:qf.bufnr)), ':.')
|
||||
if !filereadable(l:file) | continue | endif
|
||||
|
||||
if !bufexists(l:file)
|
||||
execute 'badd' l:file
|
||||
endif
|
||||
|
||||
let l:qf.filename = l:file
|
||||
let l:qf.bufnr = bufnr(l:file)
|
||||
endfor
|
||||
|
||||
call setqflist(l:qflist, 'r')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,98 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" CreatedBy: Johannes Wienke (languitar@semipol.de)
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#pplatex#new() abort " {{{1
|
||||
return deepcopy(s:qf)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:qf = {
|
||||
\ 'name' : 'LaTeX logfile using pplatex',
|
||||
\}
|
||||
|
||||
function! s:qf.init(state) abort dict "{{{1
|
||||
if !executable('pplatex')
|
||||
call vimtex#log#error('pplatex is not executable!')
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
|
||||
" Automatically remove the -file-line-error option if we use the latexmk
|
||||
" backend (for convenience)
|
||||
if a:state.compiler.name ==# 'latexmk'
|
||||
let l:index = index(a:state.compiler.options, '-file-line-error')
|
||||
if l:index >= 0
|
||||
call remove(a:state.compiler.options, l:index)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:qf.set_errorformat() abort dict "{{{1
|
||||
" Each new item starts with two asterics followed by the file, potentially
|
||||
" a line number and sometimes even the message itself is on the same line.
|
||||
" Please note that the trailing whitspaces in the error formats are
|
||||
" intentional as pplatex produces these.
|
||||
|
||||
" Start of new items with file and line number, message on next line(s).
|
||||
setlocal errorformat=%E**\ Error\ \ \ in\ %f\\,\ Line\ %l:%m
|
||||
setlocal errorformat+=%W**\ Warning\ in\ %f\\,\ Line\ %l:%m
|
||||
setlocal errorformat+=%I**\ BadBox\ \ in\ %f\\,\ Line\ %l:%m
|
||||
|
||||
" Start of items with with file, line and message on the same line. There are
|
||||
" no BadBoxes reported this way.
|
||||
setlocal errorformat+=%E**\ Error\ \ \ in\ %f\\,\ Line\ %l:%m
|
||||
setlocal errorformat+=%W**\ Warning\ in\ %f\\,\ Line\ %l:%m
|
||||
|
||||
" Start of new items with only a file.
|
||||
setlocal errorformat+=%E**\ Error\ \ \ in\ %f:%m
|
||||
setlocal errorformat+=%W**\ Warning\ in\ %f:%m
|
||||
setlocal errorformat+=%I**\ BadBox\ \ in\ %f:%m
|
||||
|
||||
" Start of items with with file and message on the same line. There are
|
||||
" no BadBoxes reported this way.
|
||||
setlocal errorformat+=%E**\ Error\ in\ %f:%m
|
||||
setlocal errorformat+=%W**\ Warning\ in\ %f:%m
|
||||
|
||||
" Some errors are difficult even for pplatex
|
||||
setlocal errorformat+=%E**\ Error\ \ :%m
|
||||
|
||||
" Anything that starts with three spaces is part of the message from a
|
||||
" previously started multiline error item.
|
||||
setlocal errorformat+=%C\ \ \ %m\ on\ input\ line\ %l.
|
||||
setlocal errorformat+=%C\ \ \ %m
|
||||
|
||||
" Items are terminated with two newlines.
|
||||
setlocal errorformat+=%-Z
|
||||
|
||||
" Skip statistical results at the bottom of the output.
|
||||
setlocal errorformat+=%-GResult%.%#
|
||||
setlocal errorformat+=%-G
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.addqflist(tex, log) abort dict " {{{1
|
||||
if empty(a:log) || !filereadable(a:log)
|
||||
throw 'Vimtex: No log file found'
|
||||
endif
|
||||
|
||||
let l:tmp = fnameescape(fnamemodify(a:log, ':r') . '.pplatex')
|
||||
let l:log = fnameescape(a:log)
|
||||
|
||||
silent call system(printf('pplatex -i %s >%s', l:log, l:tmp))
|
||||
let self.errorformat_saved = &l:errorformat
|
||||
call self.set_errorformat()
|
||||
execute 'caddfile' l:tmp
|
||||
let &l:errorformat = self.errorformat_saved
|
||||
silent call system('rm ' . l:tmp)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,67 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#qf#pulp#new() abort " {{{1
|
||||
return deepcopy(s:qf)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:qf = {
|
||||
\ 'name' : 'LaTeX logfile using pulp',
|
||||
\}
|
||||
|
||||
function! s:qf.init(state) abort dict "{{{1
|
||||
if !executable('pulp')
|
||||
call vimtex#log#error('pulp is not executable!')
|
||||
throw 'vimtex: Requirements not met'
|
||||
endif
|
||||
|
||||
" Automatically remove the -file-line-error option if we use the latexmk
|
||||
" backend (for convenience)
|
||||
if a:state.compiler.name ==# 'latexmk'
|
||||
let l:index = index(a:state.compiler.options, '-file-line-error')
|
||||
if l:index >= 0
|
||||
call remove(a:state.compiler.options, l:index)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:qf.set_errorformat() abort dict "{{{1
|
||||
setlocal errorformat=
|
||||
setlocal errorformat+=%-G%*[^\ ])\ %.%#
|
||||
setlocal errorformat+=%-G%.%#For\ some\ reason%.%#
|
||||
setlocal errorformat+=%W%f:%l-%*[0-9?]:\ %*[^\ ]\ warning:\ %m
|
||||
setlocal errorformat+=%E%f:%l-%*[0-9?]:\ %*[^\ ]\ error:\ %m
|
||||
setlocal errorformat+=%W%f:%l-%*[0-9?]:\ %m
|
||||
setlocal errorformat+=%W%l-%*[0-9?]:\ %m
|
||||
setlocal errorformat+=%-G%.%#
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:qf.addqflist(tex, log) abort dict " {{{1
|
||||
if empty(a:log) || !filereadable(a:log)
|
||||
call setqflist([])
|
||||
throw 'Vimtex: No log file found'
|
||||
endif
|
||||
|
||||
let l:tmp = fnameescape(fnamemodify(a:log, ':r') . '.pulp')
|
||||
let l:log = fnameescape(a:log)
|
||||
|
||||
silent call system(printf('pulp %s >%s', l:log, l:tmp))
|
||||
let self.errorformat_saved = &l:errorformat
|
||||
call self.set_errorformat()
|
||||
execute 'caddfile' l:tmp
|
||||
let &l:errorformat = self.errorformat_saved
|
||||
silent call system('rm ' . l:tmp)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,110 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
let g:vimtex#re#not_bslash = '\v%(\\@<!%(\\\\)*)@<='
|
||||
let g:vimtex#re#not_comment = '\v%(' . g:vimtex#re#not_bslash . '\%.*)@<!'
|
||||
|
||||
let g:vimtex#re#tex_input_root =
|
||||
\ '\v^\s*\%\s*!?\s*[tT][eE][xX]\s+[rR][oO][oO][tT]\s*\=\s*\zs.*\ze\s*$'
|
||||
let g:vimtex#re#tex_input_latex = '\v\\%('
|
||||
\ . join(get(g:, 'vimtex_include_indicators',
|
||||
\ ['input', 'include', 'subfile', 'subfileinclude']),
|
||||
\ '|') . ')\s*\{'
|
||||
let g:vimtex#re#tex_input_import =
|
||||
\ '\v\\%(sub)?%(import|%(input|include)from)\*?\{[^\}]*\}\{'
|
||||
let g:vimtex#re#tex_input_package =
|
||||
\ '\v\\%(usepackage|RequirePackage)%(\s*\[[^]]*\])?\s*\{\zs[^}]*\ze\}'
|
||||
|
||||
let g:vimtex#re#tex_input = '\v^\s*\zs%(' . join([
|
||||
\ g:vimtex#re#tex_input_latex,
|
||||
\ g:vimtex#re#tex_input_import,
|
||||
\ ], '|') . ')'
|
||||
|
||||
let g:vimtex#re#bib_input = '\v\\%(addbibresource|bibliography)>'
|
||||
|
||||
let g:vimtex#re#tex_include = g:vimtex#re#tex_input_root
|
||||
\ . '|' . g:vimtex#re#tex_input . '\zs[^\}]*\ze\}?'
|
||||
\ . '|' . g:vimtex#re#tex_input_package
|
||||
|
||||
" {{{1 Completion regexes
|
||||
let g:vimtex#re#neocomplete =
|
||||
\ '\v\\%('
|
||||
\ . '\a*cite\a*%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
|
||||
\ . '|%(text|block)cquote\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
|
||||
\ . '|%(for|hy)\w*cquote\*?\{[^}]*}%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
|
||||
\ . '|\a*ref%(\s*\{[^}]*|range\s*\{[^,}]*%(}\{)?)'
|
||||
\ . '|hyperref\s*\[[^]]*'
|
||||
\ . '|includegraphics\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
|
||||
\ . '|%(include%(only)?|input|subfile)\s*\{[^}]*'
|
||||
\ . '|([cpdr]?(gls|Gls|GLS)|acr|Acr|ACR)\a*\s*\{[^}]*'
|
||||
\ . '|(ac|Ac|AC)\s*\{[^}]*'
|
||||
\ . '|includepdf%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|includestandalone%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|%(usepackage|RequirePackage|PassOptionsToPackage)%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|documentclass%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|begin%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|end%(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|\a*'
|
||||
\ . ')'
|
||||
|
||||
let g:vimtex#re#deoplete = '\\(?:'
|
||||
\ . '\w*cite\w*(?:\s*\[[^]]*\]){0,2}\s*{[^}]*'
|
||||
\ . '|(text|block)cquote\*?(?:\s*\[[^]]*\]){0,2}\s*{[^}]*'
|
||||
\ . '|(for|hy)\w*cquote\*?{[^}]*}(?:\s*\[[^]]*\]){0,2}\s*{[^}]*'
|
||||
\ . '|\w*ref(?:\s*\{[^}]*|range\s*\{[^,}]*(?:}{)?)'
|
||||
\ . '|hyperref\s*\[[^]]*'
|
||||
\ . '|includegraphics\*?(?:\s*\[[^]]*\]){0,2}\s*\{[^}]*'
|
||||
\ . '|(?:include(?:only)?|input|subfile)\s*\{[^}]*'
|
||||
\ . '|([cpdr]?(gls|Gls|GLS)|acr|Acr|ACR)[a-zA-Z]*\s*\{[^}]*'
|
||||
\ . '|(ac|Ac|AC)\s*\{[^}]*'
|
||||
\ . '|includepdf(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|includestandalone(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|(usepackage|RequirePackage|PassOptionsToPackage)(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|documentclass(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|begin(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|end(\s*\[[^]]*\])?\s*\{[^}]*'
|
||||
\ . '|\w*'
|
||||
\ .')'
|
||||
|
||||
let g:vimtex#re#ncm2#cmds = [
|
||||
\ '\\[A-Za-z]+',
|
||||
\ '\\(usepackage|RequirePackage|PassOptionsToPackage)(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\ '\\documentclass(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\ '\\begin(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\ '\\end(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\]
|
||||
let g:vimtex#re#ncm2#bibtex = [
|
||||
\ '\\[A-Za-z]*cite[A-Za-z]*(\[[^]]*\]){0,2}{[^}]*',
|
||||
\ '\\(text|block)cquote\*?(\[[^]]*\]){0,2}{[^}]*',
|
||||
\ '\\(for|hy)[A-Za-z]*cquote\*?{[^}]*}(\[[^]]*\]){0,2}{[^}]*',
|
||||
\]
|
||||
let g:vimtex#re#ncm2#labels = [
|
||||
\ '\\[A-Za-z]*ref({[^}]*|range{([^,{}]*(}{)?))',
|
||||
\ '\\hyperref\[[^]]*',
|
||||
\ '\\([cpdr]?(gls|Gls|GLS)|acr|Acr|ACR)[a-zA-Z]*\s*\{[^}]*',
|
||||
\ '\\(ac|Ac|AC)\s*\{[^}]*',
|
||||
\]
|
||||
let g:vimtex#re#ncm2#files = [
|
||||
\ '\\includegraphics\*?(\[[^]]*\]){0,2}{[^}]*',
|
||||
\ '\\(include(only)?|input|subfile){[^}]*',
|
||||
\ '\\includepdf(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\ '\\includestandalone(\s*\[[^]]*\])?\s*\{[^}]*',
|
||||
\]
|
||||
|
||||
let g:vimtex#re#ncm2 = g:vimtex#re#ncm2#cmds +
|
||||
\ g:vimtex#re#ncm2#bibtex +
|
||||
\ g:vimtex#re#ncm2#labels +
|
||||
\ g:vimtex#re#ncm2#files
|
||||
|
||||
let g:vimtex#re#ncm = copy(g:vimtex#re#ncm2)
|
||||
|
||||
let g:vimtex#re#youcompleteme = map(copy(g:vimtex#re#ncm), "'re!' . v:val")
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,72 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#scratch#new(opts) abort " {{{1
|
||||
let l:buf = extend(deepcopy(s:scratch), a:opts)
|
||||
call l:buf.open()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
let s:scratch = {
|
||||
\ 'name' : 'VimtexScratch'
|
||||
\}
|
||||
function! s:scratch.open() abort dict " {{{1
|
||||
let l:bufnr = bufnr('')
|
||||
let l:vimtex = get(b:, 'vimtex', {})
|
||||
|
||||
silent execute 'keepalt edit' escape(self.name, ' ')
|
||||
|
||||
let self.prev_bufnr = l:bufnr
|
||||
let b:scratch = self
|
||||
let b:vimtex = l:vimtex
|
||||
|
||||
setlocal bufhidden=wipe
|
||||
setlocal buftype=nofile
|
||||
setlocal concealcursor=nvic
|
||||
setlocal conceallevel=0
|
||||
setlocal nobuflisted
|
||||
setlocal nolist
|
||||
setlocal nospell
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal tabstop=8
|
||||
|
||||
nnoremap <silent><nowait><buffer> q :call b:scratch.close()<cr>
|
||||
nnoremap <silent><nowait><buffer> <esc> :call b:scratch.close()<cr>
|
||||
nnoremap <silent><nowait><buffer> <c-6> :call b:scratch.close()<cr>
|
||||
nnoremap <silent><nowait><buffer> <c-^> :call b:scratch.close()<cr>
|
||||
nnoremap <silent><nowait><buffer> <c-e> :call b:scratch.close()<cr>
|
||||
|
||||
if has_key(self, 'syntax')
|
||||
call self.syntax()
|
||||
endif
|
||||
|
||||
call self.fill()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:scratch.close() abort dict " {{{1
|
||||
silent execute 'keepalt buffer' self.prev_bufnr
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:scratch.fill() abort dict " {{{1
|
||||
setlocal modifiable
|
||||
%delete
|
||||
|
||||
call self.print_content()
|
||||
|
||||
0delete _
|
||||
setlocal nomodifiable
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,745 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#state#init_buffer() abort " {{{1
|
||||
command! -buffer VimtexToggleMain call vimtex#state#toggle_main()
|
||||
command! -buffer VimtexReloadState call vimtex#state#reload()
|
||||
|
||||
nnoremap <buffer> <plug>(vimtex-toggle-main) :VimtexToggleMain<cr>
|
||||
nnoremap <buffer> <plug>(vimtex-reload-state) :VimtexReloadState<cr>
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#init() abort " {{{1
|
||||
let [l:main, l:main_type] = s:get_main()
|
||||
let l:id = s:get_main_id(l:main)
|
||||
|
||||
if l:id >= 0
|
||||
let b:vimtex_id = l:id
|
||||
let b:vimtex = s:vimtex_states[l:id]
|
||||
else
|
||||
let b:vimtex_id = s:vimtex_next_id
|
||||
let b:vimtex = s:vimtex.new(l:main, l:main_type, 0)
|
||||
let s:vimtex_next_id += 1
|
||||
let s:vimtex_states[b:vimtex_id] = b:vimtex
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#init_local() abort " {{{1
|
||||
let l:filename = expand('%:p')
|
||||
let l:preserve_root = get(s:, 'subfile_preserve_root')
|
||||
unlet! s:subfile_preserve_root
|
||||
|
||||
if b:vimtex.tex ==# l:filename | return | endif
|
||||
|
||||
let l:vimtex_id = s:get_main_id(l:filename)
|
||||
|
||||
if l:vimtex_id < 0
|
||||
let l:vimtex_id = s:vimtex_next_id
|
||||
let l:vimtex = s:vimtex.new(l:filename, 'local file', l:preserve_root)
|
||||
let s:vimtex_next_id += 1
|
||||
let s:vimtex_states[l:vimtex_id] = l:vimtex
|
||||
|
||||
if !has_key(b:vimtex, 'subids')
|
||||
let b:vimtex.subids = []
|
||||
endif
|
||||
call add(b:vimtex.subids, l:vimtex_id)
|
||||
let l:vimtex.main_id = b:vimtex_id
|
||||
endif
|
||||
|
||||
let b:vimtex_local = {
|
||||
\ 'active' : 0,
|
||||
\ 'main_id' : b:vimtex_id,
|
||||
\ 'sub_id' : l:vimtex_id,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#reload() abort " {{{1
|
||||
let l:id = s:get_main_id(expand('%:p'))
|
||||
if has_key(s:vimtex_states, l:id)
|
||||
let l:vimtex = remove(s:vimtex_states, l:id)
|
||||
call l:vimtex.cleanup()
|
||||
endif
|
||||
|
||||
if has_key(s:vimtex_states, get(b:, 'vimtex_id', -1))
|
||||
let l:vimtex = remove(s:vimtex_states, b:vimtex_id)
|
||||
call l:vimtex.cleanup()
|
||||
endif
|
||||
|
||||
call vimtex#state#init()
|
||||
call vimtex#state#init_local()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! vimtex#state#toggle_main() abort " {{{1
|
||||
if exists('b:vimtex_local')
|
||||
let b:vimtex_local.active = !b:vimtex_local.active
|
||||
|
||||
let b:vimtex_id = b:vimtex_local.active
|
||||
\ ? b:vimtex_local.sub_id
|
||||
\ : b:vimtex_local.main_id
|
||||
let b:vimtex = vimtex#state#get(b:vimtex_id)
|
||||
|
||||
call vimtex#log#info('Changed to `' . b:vimtex.base . "' "
|
||||
\ . (b:vimtex_local.active ? '[local]' : '[main]'))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#list_all() abort " {{{1
|
||||
return values(s:vimtex_states)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#exists(id) abort " {{{1
|
||||
return has_key(s:vimtex_states, a:id)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#get(id) abort " {{{1
|
||||
return s:vimtex_states[a:id]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#get_all() abort " {{{1
|
||||
return s:vimtex_states
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#state#cleanup(id) abort " {{{1
|
||||
if !vimtex#state#exists(a:id) | return | endif
|
||||
|
||||
"
|
||||
" Count the number of open buffers for the given blob
|
||||
"
|
||||
let l:buffers = filter(range(1, bufnr('$')), 'buflisted(v:val)')
|
||||
let l:ids = map(l:buffers, 'getbufvar(v:val, ''vimtex_id'', -1)')
|
||||
let l:count = count(l:ids, a:id)
|
||||
|
||||
"
|
||||
" Don't clean up if there are more than one buffer connected to the current
|
||||
" blob
|
||||
"
|
||||
if l:count > 1 | return | endif
|
||||
let l:vimtex = vimtex#state#get(a:id)
|
||||
|
||||
"
|
||||
" Handle possible subfiles properly
|
||||
"
|
||||
if has_key(l:vimtex, 'subids')
|
||||
let l:subcount = 0
|
||||
for l:sub_id in get(l:vimtex, 'subids', [])
|
||||
let l:subcount += count(l:ids, l:sub_id)
|
||||
endfor
|
||||
if l:count + l:subcount > 1 | return | endif
|
||||
|
||||
for l:sub_id in get(l:vimtex, 'subids', [])
|
||||
call remove(s:vimtex_states, l:sub_id).cleanup()
|
||||
endfor
|
||||
|
||||
call remove(s:vimtex_states, a:id).cleanup()
|
||||
else
|
||||
call remove(s:vimtex_states, a:id).cleanup()
|
||||
|
||||
if has_key(l:vimtex, 'main_id')
|
||||
let l:main = vimtex#state#get(l:vimtex.main_id)
|
||||
|
||||
let l:count_main = count(l:ids, l:vimtex.main_id)
|
||||
for l:sub_id in get(l:main, 'subids', [])
|
||||
let l:count_main += count(l:ids, l:sub_id)
|
||||
endfor
|
||||
|
||||
if l:count_main + l:count <= 1
|
||||
call remove(s:vimtex_states, l:vimtex.main_id).cleanup()
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:get_main_id(main) abort " {{{1
|
||||
for [l:id, l:state] in items(s:vimtex_states)
|
||||
if l:state.tex == a:main
|
||||
return str2nr(l:id)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
function! s:get_main() abort " {{{1
|
||||
if exists('s:disabled_modules')
|
||||
unlet s:disabled_modules
|
||||
endif
|
||||
|
||||
"
|
||||
" Use buffer variable if it exists
|
||||
"
|
||||
if exists('b:vimtex_main') && filereadable(b:vimtex_main)
|
||||
return [fnamemodify(b:vimtex_main, ':p'), 'buffer variable']
|
||||
endif
|
||||
|
||||
"
|
||||
" Search for TEX root specifier at the beginning of file. This is used by
|
||||
" several other plugins and editors.
|
||||
"
|
||||
let l:candidate = s:get_main_from_texroot()
|
||||
if !empty(l:candidate)
|
||||
return [l:candidate, 'texroot specifier']
|
||||
endif
|
||||
|
||||
"
|
||||
" Check if the current file is a main file
|
||||
"
|
||||
if s:file_is_main(expand('%:p'))
|
||||
return [expand('%:p'), 'current file verified']
|
||||
endif
|
||||
|
||||
"
|
||||
" Support for subfiles package
|
||||
"
|
||||
let l:candidate = s:get_main_from_subfile()
|
||||
if !empty(l:candidate)
|
||||
return [l:candidate, 'subfiles']
|
||||
endif
|
||||
|
||||
"
|
||||
" Search for .latexmain-specifier
|
||||
"
|
||||
let l:candidate = s:get_main_latexmain(expand('%:p'))
|
||||
if !empty(l:candidate)
|
||||
return [l:candidate, 'latexmain specifier']
|
||||
endif
|
||||
|
||||
"
|
||||
" Search for .latexmkrc @default_files specifier
|
||||
"
|
||||
let l:candidate = s:get_main_latexmk()
|
||||
if !empty(l:candidate)
|
||||
return [l:candidate, 'latexmkrc @default_files']
|
||||
endif
|
||||
|
||||
"
|
||||
" Check if we are class or style file
|
||||
"
|
||||
if index(['cls', 'sty'], expand('%:e')) >= 0
|
||||
let l:id = getbufvar('#', 'vimtex_id', -1)
|
||||
if l:id >= 0 && has_key(s:vimtex_states, l:id)
|
||||
return [s:vimtex_states[l:id].tex, 'cls/sty file (inherit from alternate)']
|
||||
else
|
||||
let s:disabled_modules = ['latexmk', 'view', 'toc']
|
||||
return [expand('%:p'), 'cls/sty file']
|
||||
endif
|
||||
endif
|
||||
|
||||
"
|
||||
" Search for main file recursively through include specifiers
|
||||
"
|
||||
if !get(g:, 'vimtex_disable_recursive_main_file_detection', 0)
|
||||
let l:candidate = s:get_main_choose(s:get_main_recurse())
|
||||
if !empty(l:candidate)
|
||||
return [l:candidate, 'recursive search']
|
||||
endif
|
||||
endif
|
||||
|
||||
"
|
||||
" Use fallback candidate or the current file
|
||||
"
|
||||
let l:candidate = get(s:, 'cand_fallback', expand('%:p'))
|
||||
if exists('s:cand_fallback')
|
||||
unlet s:cand_fallback
|
||||
return [l:candidate, 'fallback']
|
||||
else
|
||||
return [l:candidate, 'current file']
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_main_from_texroot() abort " {{{1
|
||||
for l:line in getline(1, 5)
|
||||
let l:file_pattern = matchstr(l:line, g:vimtex#re#tex_input_root)
|
||||
if empty(l:file_pattern) | continue | endif
|
||||
|
||||
if !vimtex#paths#is_abs(l:file_pattern)
|
||||
let l:file_pattern = simplify(expand('%:p:h') . '/' . l:file_pattern)
|
||||
endif
|
||||
|
||||
let l:candidates = glob(l:file_pattern, 0, 1)
|
||||
if len(l:candidates) > 1
|
||||
return s:get_main_choose(l:candidates)
|
||||
elseif len(l:candidates) == 1
|
||||
return l:candidates[0]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_main_from_subfile() abort " {{{1
|
||||
for l:line in getline(1, 5)
|
||||
let l:filename = matchstr(l:line,
|
||||
\ '^\C\s*\\documentclass\[\zs.*\ze\]{subfiles}')
|
||||
if len(l:filename) > 0
|
||||
if l:filename !~# '\.tex$'
|
||||
let l:filename .= '.tex'
|
||||
endif
|
||||
|
||||
if vimtex#paths#is_abs(l:filename)
|
||||
" Specified path is absolute
|
||||
if filereadable(l:filename) | return l:filename | endif
|
||||
else
|
||||
" Try specified path as relative to current file path
|
||||
let l:candidate = simplify(expand('%:p:h') . '/' . l:filename)
|
||||
if filereadable(l:candidate) | return l:candidate | endif
|
||||
|
||||
" Try specified path as relative to the project main file. This is
|
||||
" difficult, since the main file is the one we are looking for. We
|
||||
" therefore assume that the main file lives somewhere upwards in the
|
||||
" directory tree.
|
||||
let l:candidate = fnamemodify(findfile(l:filename, '.;'), ':p')
|
||||
if filereadable(l:candidate)
|
||||
\ && s:file_reaches_current(l:candidate)
|
||||
let s:subfile_preserve_root = 1
|
||||
return fnamemodify(candidate, ':p')
|
||||
endif
|
||||
|
||||
" Check the alternate buffer. This seems sensible e.g. in cases where one
|
||||
" enters an "outer" subfile through a 'gf' motion from the main file.
|
||||
let l:vimtex = getbufvar('#', 'vimtex', {})
|
||||
for l:file in get(l:vimtex, 'sources', [])
|
||||
if expand('%:p') ==# simplify(l:vimtex.root . '/' . l:file)
|
||||
let s:subfile_preserve_root = 1
|
||||
return l:vimtex.tex
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_main_latexmain(file) abort " {{{1
|
||||
for l:cand in s:findfiles_recursive('*.latexmain', expand('%:p:h'))
|
||||
let l:cand = fnamemodify(l:cand, ':p:r')
|
||||
if s:file_reaches_current(l:cand)
|
||||
return l:cand
|
||||
else
|
||||
let s:cand_fallback = l:cand
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:get_main_latexmk() abort " {{{1
|
||||
let l:root = expand('%:p:h')
|
||||
let l:results = vimtex#compiler#latexmk#get_rc_opt(
|
||||
\ l:root, 'default_files', 2, [])
|
||||
if l:results[1] < 1 | return '' | endif
|
||||
|
||||
for l:candidate in l:results[0]
|
||||
let l:file = l:root . '/' . l:candidate
|
||||
if filereadable(l:file)
|
||||
return l:file
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:get_main_recurse(...) abort " {{{1
|
||||
" Either start the search from the original file, or check if the supplied
|
||||
" file is a main file (or invalid)
|
||||
if a:0 == 0
|
||||
let l:file = expand('%:p')
|
||||
let l:tried = {}
|
||||
else
|
||||
let l:file = a:1
|
||||
let l:tried = a:2
|
||||
|
||||
if s:file_is_main(l:file)
|
||||
return [l:file]
|
||||
elseif !filereadable(l:file)
|
||||
return []
|
||||
endif
|
||||
endif
|
||||
|
||||
" Create list of candidates that was already tried for the current file
|
||||
if !has_key(l:tried, l:file)
|
||||
let l:tried[l:file] = [l:file]
|
||||
endif
|
||||
|
||||
" Apply filters successively (minor optimization)
|
||||
let l:re_filter1 = fnamemodify(l:file, ':t:r')
|
||||
let l:re_filter2 = g:vimtex#re#tex_input . '\s*\f*' . l:re_filter1
|
||||
|
||||
" Search through candidates found recursively upwards in the directory tree
|
||||
let l:results = []
|
||||
for l:cand in s:findfiles_recursive('*.tex', fnamemodify(l:file, ':p:h'))
|
||||
if index(l:tried[l:file], l:cand) >= 0 | continue | endif
|
||||
call add(l:tried[l:file], l:cand)
|
||||
|
||||
if len(filter(filter(readfile(l:cand),
|
||||
\ 'v:val =~# l:re_filter1'),
|
||||
\ 'v:val =~# l:re_filter2')) > 0
|
||||
let l:results += s:get_main_recurse(fnamemodify(l:cand, ':p'), l:tried)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:results
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_main_choose(list) abort " {{{1
|
||||
let l:list = vimtex#util#uniq_unsorted(a:list)
|
||||
|
||||
if empty(l:list) | return '' | endif
|
||||
if len(l:list) == 1 | return l:list[0] | endif
|
||||
|
||||
let l:all = map(copy(l:list), '[s:get_main_id(v:val), v:val]')
|
||||
let l:new = map(filter(copy(l:all), 'v:val[0] < 0'), 'v:val[1]')
|
||||
let l:existing = {}
|
||||
for [l:key, l:val] in filter(copy(l:all), 'v:val[0] >= 0')
|
||||
let l:existing[l:key] = l:val
|
||||
endfor
|
||||
let l:alternate_id = getbufvar('#', 'vimtex_id', -1)
|
||||
|
||||
if len(l:existing) == 1
|
||||
return values(l:existing)[0]
|
||||
elseif len(l:existing) > 1 && has_key(l:existing, l:alternate_id)
|
||||
return l:existing[l:alternate_id]
|
||||
elseif len(l:existing) < 1 && len(l:new) == 1
|
||||
return l:new[0]
|
||||
else
|
||||
let l:choices = {}
|
||||
for l:tex in l:list
|
||||
let l:choices[l:tex] = vimtex#paths#relative(l:tex, getcwd())
|
||||
endfor
|
||||
|
||||
return vimtex#echo#choose(l:choices,
|
||||
\ 'Please select an appropriate main file:')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:file_is_main(file) abort " {{{1
|
||||
if !filereadable(a:file) | return 0 | endif
|
||||
|
||||
"
|
||||
" Check if a:file is a main file by looking for the \documentclass command,
|
||||
" but ignore the following:
|
||||
"
|
||||
" \documentclass[...]{subfiles}
|
||||
" \documentclass[...]{standalone}
|
||||
"
|
||||
let l:lines = readfile(a:file, 0, 50)
|
||||
call filter(l:lines, 'v:val =~# ''\C\\documentclass\_\s*[\[{]''')
|
||||
call filter(l:lines, 'v:val !~# ''{subfiles}''')
|
||||
call filter(l:lines, 'v:val !~# ''{standalone}''')
|
||||
if len(l:lines) == 0 | return 0 | endif
|
||||
|
||||
" A main file contains `\begin{document}`
|
||||
let l:lines = vimtex#parser#preamble(a:file, {
|
||||
\ 'inclusive' : 1,
|
||||
\ 'root' : fnamemodify(a:file, ':p:h'),
|
||||
\})
|
||||
call filter(l:lines, 'v:val =~# ''\\begin\s*{document}''')
|
||||
return len(l:lines) > 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:file_reaches_current(file) abort " {{{1
|
||||
" Note: This function assumes that the input a:file is an absolute path
|
||||
if !filereadable(a:file) | return 0 | endif
|
||||
|
||||
for l:line in filter(readfile(a:file), 'v:val =~# g:vimtex#re#tex_input')
|
||||
let l:file = matchstr(l:line, g:vimtex#re#tex_input . '\zs\f+')
|
||||
if empty(l:file) | continue | endif
|
||||
|
||||
if !vimtex#paths#is_abs(l:file)
|
||||
let l:file = fnamemodify(a:file, ':h') . '/' . l:file
|
||||
endif
|
||||
|
||||
if l:file !~# '\.tex$'
|
||||
let l:file .= '.tex'
|
||||
endif
|
||||
|
||||
if expand('%:p') ==# l:file
|
||||
\ || s:file_reaches_current(l:file)
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:findfiles_recursive(expr, path) abort " {{{1
|
||||
let l:path = a:path
|
||||
let l:dirs = l:path
|
||||
while l:path != fnamemodify(l:path, ':h')
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
let l:dirs .= ',' . l:path
|
||||
endwhile
|
||||
return split(globpath(fnameescape(l:dirs), a:expr), '\n')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let s:vimtex = {}
|
||||
|
||||
function! s:vimtex.new(main, main_parser, preserve_root) abort dict " {{{1
|
||||
let l:new = deepcopy(self)
|
||||
let l:new.tex = a:main
|
||||
let l:new.root = fnamemodify(l:new.tex, ':h')
|
||||
let l:new.base = fnamemodify(l:new.tex, ':t')
|
||||
let l:new.name = fnamemodify(l:new.tex, ':t:r')
|
||||
let l:new.main_parser = a:main_parser
|
||||
|
||||
if a:preserve_root && exists('b:vimtex')
|
||||
let l:new.root = b:vimtex.root
|
||||
let l:new.base = vimtex#paths#relative(a:main, l:new.root)
|
||||
endif
|
||||
|
||||
if exists('s:disabled_modules')
|
||||
let l:new.disabled_modules = s:disabled_modules
|
||||
endif
|
||||
|
||||
"
|
||||
" The preamble content is used to parse for the engine directive, the
|
||||
" documentclass and the package list; we store it as a temporary shared
|
||||
" object variable
|
||||
"
|
||||
let l:new.preamble = vimtex#parser#preamble(l:new.tex, {
|
||||
\ 'root' : l:new.root,
|
||||
\})
|
||||
|
||||
call l:new.parse_tex_program()
|
||||
call l:new.parse_documentclass()
|
||||
call l:new.parse_graphicspath()
|
||||
call l:new.gather_sources()
|
||||
|
||||
call vimtex#view#init_state(l:new)
|
||||
call vimtex#compiler#init_state(l:new)
|
||||
call vimtex#qf#init_state(l:new)
|
||||
call vimtex#toc#init_state(l:new)
|
||||
call vimtex#fold#init_state(l:new)
|
||||
|
||||
" Parsing packages might depend on the compiler setting for build_dir
|
||||
call l:new.parse_packages()
|
||||
|
||||
unlet l:new.preamble
|
||||
unlet l:new.new
|
||||
return l:new
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.cleanup() abort dict " {{{1
|
||||
if exists('self.compiler.cleanup')
|
||||
call self.compiler.cleanup()
|
||||
endif
|
||||
|
||||
if exists('#User#VimtexEventQuit')
|
||||
if exists('b:vimtex')
|
||||
let b:vimtex_tmp = b:vimtex
|
||||
endif
|
||||
let b:vimtex = self
|
||||
doautocmd <nomodeline> User VimtexEventQuit
|
||||
if exists('b:vimtex_tmp')
|
||||
let b:vimtex = b:vimtex_tmp
|
||||
unlet b:vimtex_tmp
|
||||
else
|
||||
unlet b:vimtex
|
||||
endif
|
||||
endif
|
||||
|
||||
" Close quickfix window
|
||||
silent! cclose
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.parse_tex_program() abort dict " {{{1
|
||||
let l:lines = copy(self.preamble[:20])
|
||||
let l:tex_program_re =
|
||||
\ '\v^\c\s*\%\s*\!?\s*tex\s+%(TS-)?program\s*\=\s*\zs.*\ze\s*$'
|
||||
call map(l:lines, 'matchstr(v:val, l:tex_program_re)')
|
||||
call filter(l:lines, '!empty(v:val)')
|
||||
let self.tex_program = tolower(get(l:lines, -1, '_'))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.parse_documentclass() abort dict " {{{1
|
||||
let self.documentclass = ''
|
||||
for l:line in self.preamble
|
||||
let l:class = matchstr(l:line, '^\s*\\documentclass.*{\zs\w*\ze}')
|
||||
if !empty(l:class)
|
||||
let self.documentclass = l:class
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.parse_graphicspath() abort dict " {{{1
|
||||
" Combine the preamble as one long string of commands
|
||||
let l:preamble = join(map(copy(self.preamble),
|
||||
\ 'substitute(v:val, ''\\\@<!%.*'', '''', '''')'))
|
||||
|
||||
" Extract the graphicspath command from this string
|
||||
let l:graphicspath = matchstr(l:preamble,
|
||||
\ g:vimtex#re#not_bslash
|
||||
\ . '\\graphicspath\s*\{\s*\{\s*\zs.{-}\ze\s*\}\s*\}'
|
||||
\)
|
||||
|
||||
" Add all parsed graphicspaths
|
||||
let self.graphicspath = []
|
||||
for l:path in split(l:graphicspath, '\s*}\s*{\s*')
|
||||
let l:path = substitute(l:path, '\/\s*$', '', '')
|
||||
call add(self.graphicspath, vimtex#paths#is_abs(l:path)
|
||||
\ ? l:path
|
||||
\ : simplify(self.root . '/' . l:path))
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.parse_packages() abort dict " {{{1
|
||||
let self.packages = get(self, 'packages', {})
|
||||
|
||||
" Try to parse .fls file if present, as it is usually more complete. That is,
|
||||
" it contains a generated list of all the packages that are used.
|
||||
for l:line in vimtex#parser#fls(self.fls())
|
||||
let l:package = matchstr(l:line, '^INPUT \zs.\+\ze\.sty$')
|
||||
let l:package = fnamemodify(l:package, ':t')
|
||||
if !empty(l:package)
|
||||
let self.packages[l:package] = {}
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Now parse preamble as well for usepackage and RequirePackage
|
||||
if !has_key(self, 'preamble') | return | endif
|
||||
let l:usepackages = filter(copy(self.preamble), 'v:val =~# ''\v%(usep|RequireP)ackage''')
|
||||
let l:pat = g:vimtex#re#not_comment . g:vimtex#re#not_bslash
|
||||
\ . '\v\\%(usep|RequireP)ackage\s*%(\[[^[\]]*\])?\s*\{\s*\zs%([^{}]+)\ze\s*\}'
|
||||
call map(l:usepackages, 'matchstr(v:val, l:pat)')
|
||||
call map(l:usepackages, 'split(v:val, ''\s*,\s*'')')
|
||||
|
||||
for l:packages in l:usepackages
|
||||
for l:package in l:packages
|
||||
let self.packages[l:package] = {}
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.gather_sources() abort dict " {{{1
|
||||
let self.sources = vimtex#parser#tex#parse_files(
|
||||
\ self.tex, {'root' : self.root})
|
||||
|
||||
call map(self.sources, 'vimtex#paths#relative(v:val, self.root)')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.pprint_items() abort dict " {{{1
|
||||
let l:items = [
|
||||
\ ['name', self.name],
|
||||
\ ['base', self.base],
|
||||
\ ['root', self.root],
|
||||
\ ['tex', self.tex],
|
||||
\ ['out', self.out()],
|
||||
\ ['log', self.log()],
|
||||
\ ['aux', self.aux()],
|
||||
\ ['fls', self.fls()],
|
||||
\ ['main parser', self.main_parser],
|
||||
\]
|
||||
|
||||
if self.tex_program !=# '_'
|
||||
call add(l:items, ['tex program', self.tex_program])
|
||||
endif
|
||||
|
||||
if len(self.sources) >= 2
|
||||
call add(l:items, ['source files', self.sources])
|
||||
endif
|
||||
|
||||
call add(l:items, ['compiler', get(self, 'compiler', {})])
|
||||
call add(l:items, ['viewer', get(self, 'viewer', {})])
|
||||
call add(l:items, ['qf', get(self, 'qf', {})])
|
||||
|
||||
if exists('self.documentclass')
|
||||
call add(l:items, ['document class', self.documentclass])
|
||||
endif
|
||||
|
||||
if !empty(self.packages)
|
||||
call add(l:items, ['packages', sort(keys(self.packages))])
|
||||
endif
|
||||
|
||||
return [['vimtex project', l:items]]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.log() abort dict " {{{1
|
||||
return self.ext('log')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.aux() abort dict " {{{1
|
||||
return self.ext('aux')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.fls() abort dict " {{{1
|
||||
return self.ext('fls')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.out(...) abort dict " {{{1
|
||||
return call(self.ext, ['pdf'] + a:000, self)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.ext(ext, ...) abort dict " {{{1
|
||||
" First check build dir (latexmk -output_directory option)
|
||||
if !empty(get(get(self, 'compiler', {}), 'build_dir', ''))
|
||||
let cand = self.compiler.build_dir . '/' . self.name . '.' . a:ext
|
||||
if !vimtex#paths#is_abs(self.compiler.build_dir)
|
||||
let cand = self.root . '/' . cand
|
||||
endif
|
||||
if a:0 > 0 || filereadable(cand)
|
||||
return fnamemodify(cand, ':p')
|
||||
endif
|
||||
endif
|
||||
|
||||
" Next check for file in project root folder
|
||||
let cand = self.root . '/' . self.name . '.' . a:ext
|
||||
if a:0 > 0 || filereadable(cand)
|
||||
return fnamemodify(cand, ':p')
|
||||
endif
|
||||
|
||||
" Finally return empty string if no entry is found
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:vimtex.getftime() abort dict " {{{1
|
||||
return max(map(copy(self.sources), 'getftime(self.root . ''/'' . v:val)'))
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
|
||||
" Initialize module
|
||||
let s:vimtex_states = {}
|
||||
let s:vimtex_next_id = 0
|
||||
|
||||
endif
|
||||
@@ -1,66 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#init() abort " {{{1
|
||||
if !get(g:, 'vimtex_syntax_enabled', 1) | return | endif
|
||||
|
||||
" The following ensures that syntax addons are not loaded until after the
|
||||
" filetype plugin has been sourced. See e.g. #1428 for more info.
|
||||
if exists('b:vimtex')
|
||||
call vimtex#syntax#load()
|
||||
else
|
||||
augroup vimtex_syntax
|
||||
autocmd!
|
||||
autocmd User VimtexEventInitPost call vimtex#syntax#load()
|
||||
augroup END
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#syntax#load() abort " {{{1
|
||||
if s:is_loaded() | return | endif
|
||||
|
||||
" Initialize project cache (used e.g. for the minted package)
|
||||
if !has_key(b:vimtex, 'syntax')
|
||||
let b:vimtex.syntax = {}
|
||||
endif
|
||||
|
||||
" Initialize b:vimtex_syntax
|
||||
let b:vimtex_syntax = {}
|
||||
|
||||
" Reset included syntaxes (necessary e.g. when doing :e)
|
||||
call vimtex#syntax#misc#include_reset()
|
||||
|
||||
" Set some better defaults
|
||||
syntax spell toplevel
|
||||
syntax sync maxlines=500
|
||||
|
||||
" Load some general syntax improvements
|
||||
call vimtex#syntax#load#general()
|
||||
|
||||
" Load syntax for documentclass and packages
|
||||
call vimtex#syntax#load#packages()
|
||||
|
||||
" Hack to make it possible to determine if vimtex syntax was loaded
|
||||
syntax match texVimtexLoaded 'dummyVimtexLoadedText' contained
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:is_loaded() abort " {{{1
|
||||
if exists('*execute')
|
||||
let l:result = split(execute('syntax'), "\n")
|
||||
return !empty(filter(l:result, 'v:val =~# "texVimtexLoaded"'))
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,95 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#load#general() abort " {{{1
|
||||
if !exists('b:vimtex_syntax') | return | endif
|
||||
|
||||
" I don't see why we can't match Math zones in the MatchNMGroup
|
||||
if !exists('g:tex_no_math')
|
||||
syntax cluster texMatchNMGroup add=@texMathZones
|
||||
endif
|
||||
|
||||
" Todo elements
|
||||
syntax match texStatement '\\todo\w*' contains=texTodo
|
||||
syntax match texTodo '\\todo\w*'
|
||||
|
||||
" Fix strange mistake in main syntax file where \usepackage is added to the
|
||||
" texInputFile group
|
||||
syntax match texDocType /\\usepackage\>/
|
||||
\ nextgroup=texBeginEndName,texDocTypeArgs
|
||||
|
||||
" Improve support for italic font, bold font and some conceals
|
||||
if get(g:, 'tex_fast', 'b') =~# 'b'
|
||||
let s:conceal = (has('conceal') && get(g:, 'tex_conceal', 'b') =~# 'b')
|
||||
\ ? 'concealends' : ''
|
||||
|
||||
for [s:style, s:group, s:commands] in [
|
||||
\ ['texItalStyle', 'texItalGroup', ['emph', 'textit']],
|
||||
\ ['texBoldStyle', 'texBoldGroup', ['textbf']],
|
||||
\]
|
||||
for s:cmd in s:commands
|
||||
execute 'syntax region' s:style 'matchgroup=texTypeStyle'
|
||||
\ 'start="\\' . s:cmd . '\s*{" end="}"'
|
||||
\ 'contains=@Spell,@' . s:group
|
||||
\ s:conceal
|
||||
endfor
|
||||
execute 'syntax cluster texMatchGroup add=' . s:style
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Allow arguments in newenvironments
|
||||
syntax region texEnvName contained matchgroup=Delimiter
|
||||
\ start="{"rs=s+1 end="}"
|
||||
\ nextgroup=texEnvBgn,texEnvArgs contained skipwhite skipnl
|
||||
syntax region texEnvArgs contained matchgroup=Delimiter
|
||||
\ start="\["rs=s+1 end="]"
|
||||
\ nextgroup=texEnvBgn,texEnvArgs skipwhite skipnl
|
||||
syntax cluster texEnvGroup add=texDefParm,texNewEnv,texComment
|
||||
|
||||
" Add support for \renewenvironment and \renewcommand
|
||||
syntax match texNewEnv "\\renewenvironment\>"
|
||||
\ nextgroup=texEnvName skipwhite skipnl
|
||||
syntax match texNewCmd "\\renewcommand\>"
|
||||
\ nextgroup=texCmdName skipwhite skipnl
|
||||
|
||||
" Match nested DefParms
|
||||
syntax match texDefParmNested contained "##\+\d\+"
|
||||
highlight def link texDefParmNested Identifier
|
||||
syntax cluster texEnvGroup add=texDefParmNested
|
||||
syntax cluster texCmdGroup add=texDefParmNested
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#syntax#load#packages() abort " {{{1
|
||||
if !exists('b:vimtex_syntax') | return | endif
|
||||
|
||||
try
|
||||
call vimtex#syntax#p#{b:vimtex.documentclass}#load()
|
||||
catch /E117:/
|
||||
endtry
|
||||
|
||||
for l:pkg in map(keys(b:vimtex.packages), "substitute(v:val, '-', '_', 'g')")
|
||||
try
|
||||
call vimtex#syntax#p#{l:pkg}#load()
|
||||
catch /E117:/
|
||||
endtry
|
||||
endfor
|
||||
|
||||
for l:pkg in g:vimtex_syntax_autoload_packages
|
||||
try
|
||||
call vimtex#syntax#p#{l:pkg}#load()
|
||||
catch /E117:/
|
||||
call vimtex#log#warning('Syntax package does not exist: ' . l:pkg,
|
||||
\ 'Please see :help g:vimtex_syntax_autoload_packages')
|
||||
endtry
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,92 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#misc#add_to_section_clusters(group) abort " {{{1
|
||||
for l:cluster in [
|
||||
\ 'texPartGroup',
|
||||
\ 'texChapterGroup',
|
||||
\ 'texSectionGroup',
|
||||
\ 'texSubSectionGroup',
|
||||
\ 'texSubSubSectionGroup',
|
||||
\ 'texParaGroup',
|
||||
\]
|
||||
execute printf('syntax cluster %s add=%s', l:cluster, a:group)
|
||||
endfor
|
||||
|
||||
execute printf('syntax cluster texVimtexGlobal add=%s', a:group)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#syntax#misc#include(name) abort " {{{1
|
||||
let l:inc_name = 'vimtex_nested_' . a:name
|
||||
|
||||
if !has_key(s:included, l:inc_name)
|
||||
let s:included[l:inc_name] = s:include(l:inc_name, a:name)
|
||||
endif
|
||||
|
||||
return s:included[l:inc_name] ? l:inc_name : ''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#syntax#misc#include_reset() abort " {{{1
|
||||
let s:included = {'vimtex_nested_tex': 0}
|
||||
endfunction
|
||||
|
||||
let s:included = {'vimtex_nested_tex': 0}
|
||||
|
||||
" }}}1
|
||||
function! vimtex#syntax#misc#new_math_zone(sfx, mathzone, starred) abort " {{{1
|
||||
" This function is based on Charles E. Campbell's amsmath.vba file 2018-06-29
|
||||
|
||||
if get(g:, 'tex_fast', 'M') !~# 'M' | return | endif
|
||||
|
||||
let foldcmd = get(g:, 'tex_fold_enabled') ? ' fold' : ''
|
||||
|
||||
let grp = 'texMathZone' . a:sfx
|
||||
execute 'syntax cluster texMathZones add=' . grp
|
||||
execute 'syntax region ' . grp
|
||||
\ . ' start=''\\begin\s*{\s*' . a:mathzone . '\s*}'''
|
||||
\ . ' end=''\\end\s*{\s*' . a:mathzone . '\s*}'''
|
||||
\ . foldcmd . ' keepend contains=@texMathZoneGroup'
|
||||
execute 'highlight def link '.grp.' texMath'
|
||||
|
||||
if a:starred
|
||||
let grp .= 'S'
|
||||
execute 'syntax cluster texMathZones add=' . grp
|
||||
execute 'syntax region ' . grp
|
||||
\ . ' start=''\\begin\s*{\s*' . a:mathzone . '\*\s*}'''
|
||||
\ . ' end=''\\end\s*{\s*' . a:mathzone . '\*\s*}'''
|
||||
\ . foldcmd . ' keepend contains=@texMathZoneGroup'
|
||||
execute 'highlight def link '.grp.' texMath'
|
||||
endif
|
||||
|
||||
execute 'syntax match texBadMath ''\\end\s*{\s*' . a:mathzone . '\*\=\s*}'''
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:include(cluster, name) abort " {{{1
|
||||
let l:name = get(g:vimtex_syntax_nested.aliases, a:name, a:name)
|
||||
let l:path = 'syntax/' . l:name . '.vim'
|
||||
|
||||
if empty(globpath(&runtimepath, l:path)) | return 0 | endif
|
||||
|
||||
unlet b:current_syntax
|
||||
execute 'syntax include @' . a:cluster l:path
|
||||
let b:current_syntax = 'tex'
|
||||
|
||||
for l:ignored_group in get(g:vimtex_syntax_nested.ignored, l:name, [])
|
||||
execute 'syntax cluster' a:cluster 'remove=' . l:ignored_group
|
||||
endfor
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,47 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
scriptencoding utf-8
|
||||
|
||||
function! vimtex#syntax#p#amsmath#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'amsmath') | return | endif
|
||||
let b:vimtex_syntax.amsmath = 1
|
||||
|
||||
" Allow subequations (fixes #1019)
|
||||
" - This should be temporary, as it seems subequations is erroneously part of
|
||||
" texBadMath from Charles Campbell's syntax plugin.
|
||||
syntax match texBeginEnd
|
||||
\ "\(\\begin\>\|\\end\>\)\ze{subequations}"
|
||||
\ nextgroup=texBeginEndName
|
||||
|
||||
call vimtex#syntax#misc#new_math_zone('AmsA', 'align', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsB', 'alignat', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsD', 'flalign', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsC', 'gather', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsD', 'multline', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsE', 'xalignat', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsF', 'xxalignat', 0)
|
||||
call vimtex#syntax#misc#new_math_zone('AmsG', 'mathpar', 1)
|
||||
|
||||
" Amsmath [lr][vV]ert (Holger Mitschke)
|
||||
if has('conceal') && &enc ==# 'utf-8' && get(g:, 'tex_conceal', 'd') =~# 'd'
|
||||
for l:texmath in [
|
||||
\ ['\\lvert', '|'] ,
|
||||
\ ['\\rvert', '|'] ,
|
||||
\ ['\\lVert', '‖'] ,
|
||||
\ ['\\rVert', '‖'] ,
|
||||
\ ]
|
||||
execute "syntax match texMathDelim '\\\\[bB]igg\\=[lr]\\="
|
||||
\ . l:texmath[0] . "' contained conceal cchar=" . l:texmath[1]
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,35 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#array#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'array') | return | endif
|
||||
let b:vimtex_syntax.array = 1
|
||||
|
||||
call vimtex#syntax#p#tabularx#load()
|
||||
if !get(g:, 'tex_fast', 'M') =~# 'M' | return | endif
|
||||
|
||||
"
|
||||
" The following code changes inline math so as to support the column
|
||||
" specifiers [0], e.g.
|
||||
"
|
||||
" \begin{tabular}{*{3}{>{$}c<{$}}}
|
||||
"
|
||||
" [0]: https://en.wikibooks.org/wiki/LaTeX/Tables#Column_specification_using_.3E.7B.5Ccmd.7D_and_.3C.7B.5Ccmd.7D
|
||||
"
|
||||
|
||||
syntax clear texMathZoneX
|
||||
if has('conceal') && &enc ==# 'utf-8' && get(g:, 'tex_conceal', 'd') =~# 'd'
|
||||
syntax region texMathZoneX matchgroup=Delimiter start="\([<>]{\)\@<!\$" skip="\%(\\\\\)*\\\$" matchgroup=Delimiter end="\$" end="%stopzone\>" concealends contains=@texMathZoneGroup
|
||||
else
|
||||
syntax region texMathZoneX matchgroup=Delimiter start="\([<>]{\)\@<!\$" skip="\%(\\\\\)*\\\$" matchgroup=Delimiter end="\$" end="%stopzone\>" contains=@texMathZoneGroup
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,34 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#asymptote#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'asymptote') | return | endif
|
||||
let b:vimtex_syntax.asymptote = 1
|
||||
|
||||
call vimtex#syntax#misc#add_to_section_clusters('texZoneAsymptote')
|
||||
|
||||
if !empty(vimtex#syntax#misc#include('asy'))
|
||||
syntax region texZoneAsymptote
|
||||
\ start='\\begin{asy\z(def\)\?}'rs=s
|
||||
\ end='\\end{asy\z1}'re=e
|
||||
\ keepend
|
||||
\ transparent
|
||||
\ contains=texBeginEnd,@vimtex_nested_asy
|
||||
else
|
||||
syntax region texZoneAsymptote
|
||||
\ start='\\begin{asy\z(def\)\?}'rs=s
|
||||
\ end='\\end{asy\z1}'re=e
|
||||
\ keepend
|
||||
\ contains=texBeginEnd
|
||||
highlight def link texZoneAsymptote texZone
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,32 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#beamer#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'beamer') | return | endif
|
||||
let b:vimtex_syntax.beamer = 1
|
||||
|
||||
syntax match texBeamerDelimiter '<\|>' contained
|
||||
syntax match texBeamerOpt '<[^>]*>' contained contains=texBeamerDelimiter
|
||||
|
||||
syntax match texStatementBeamer '\\only\(<[^>]*>\)\?' contains=texBeamerOpt
|
||||
syntax match texStatementBeamer '\\item<[^>]*>' contains=texBeamerOpt
|
||||
|
||||
syntax match texInputFile
|
||||
\ '\\includegraphics<[^>]*>\(\[.\{-}\]\)\=\s*{.\{-}}'
|
||||
\ contains=texStatement,texBeamerOpt,texInputCurlies,texInputFileOpt
|
||||
|
||||
call vimtex#syntax#misc#add_to_section_clusters('texStatementBeamer')
|
||||
|
||||
highlight link texStatementBeamer texStatement
|
||||
highlight link texBeamerOpt Identifier
|
||||
highlight link texBeamerDelimiter Delimiter
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,84 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#biblatex#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'biblatex') | return | endif
|
||||
let b:vimtex_syntax.biblatex = 1
|
||||
|
||||
if get(g:, 'tex_fast', 'r') !~# 'r' | return | endif
|
||||
|
||||
for l:pattern in [
|
||||
\ 'bibentry',
|
||||
\ 'cite[pt]?\*?',
|
||||
\ 'citeal[tp]\*?',
|
||||
\ 'cite(num|text|url)',
|
||||
\ '[Cc]ite%(title|author|year(par)?|date)\*?',
|
||||
\ '[Pp]arencite\*?',
|
||||
\ 'foot%(full)?cite%(text)?',
|
||||
\ 'fullcite',
|
||||
\ '[Tt]extcite',
|
||||
\ '[Ss]martcite',
|
||||
\ 'supercite',
|
||||
\ '[Aa]utocite\*?',
|
||||
\ '[Ppf]?[Nn]otecite',
|
||||
\ '%(text|block)cquote\*?',
|
||||
\]
|
||||
execute 'syntax match texStatement'
|
||||
\ '/\v\\' . l:pattern . '\ze\s*%(\[|\{)/'
|
||||
\ 'nextgroup=texRefOption,texCite'
|
||||
endfor
|
||||
|
||||
for l:pattern in [
|
||||
\ '[Cc]ites',
|
||||
\ '[Pp]arencites',
|
||||
\ 'footcite%(s|texts)',
|
||||
\ '[Tt]extcites',
|
||||
\ '[Ss]martcites',
|
||||
\ 'supercites',
|
||||
\ '[Aa]utocites',
|
||||
\ '[pPfFsStTaA]?[Vv]olcites?',
|
||||
\ 'cite%(field|list|name)',
|
||||
\]
|
||||
execute 'syntax match texStatement'
|
||||
\ '/\v\\' . l:pattern . '\ze\s*%(\[|\{)/'
|
||||
\ 'nextgroup=texRefOptions,texCites'
|
||||
endfor
|
||||
|
||||
for l:pattern in [
|
||||
\ '%(foreign|hyphen)textcquote\*?',
|
||||
\ '%(foreign|hyphen)blockcquote',
|
||||
\ 'hybridblockcquote',
|
||||
\]
|
||||
execute 'syntax match texStatement'
|
||||
\ '/\v\\' . l:pattern . '\ze\s*%(\[|\{)/'
|
||||
\ 'nextgroup=texQuoteLang'
|
||||
endfor
|
||||
|
||||
syntax region texRefOptions contained matchgroup=Delimiter
|
||||
\ start='\[' end=']'
|
||||
\ contains=@texRefGroup,texRefZone
|
||||
\ nextgroup=texRefOptions,texCites
|
||||
|
||||
syntax region texCites contained matchgroup=Delimiter
|
||||
\ start='{' end='}'
|
||||
\ contains=@texRefGroup,texRefZone,texCites
|
||||
\ nextgroup=texRefOptions,texCites
|
||||
|
||||
syntax region texQuoteLang contained matchgroup=Delimiter
|
||||
\ start='{' end='}'
|
||||
\ transparent
|
||||
\ contains=@texMatchGroup
|
||||
\ nextgroup=texRefOption,texCite
|
||||
|
||||
highlight def link texRefOptions texRefOption
|
||||
highlight def link texCites texCite
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,23 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
scriptencoding utf-8
|
||||
|
||||
function! vimtex#syntax#p#breqn#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'breqn') | return | endif
|
||||
let b:vimtex_syntax.breqn = 1
|
||||
|
||||
call vimtex#syntax#misc#new_math_zone('BreqnA', 'dmath', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('BreqnB', 'dseries', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('BreqnC', 'dgroup', 1)
|
||||
call vimtex#syntax#misc#new_math_zone('BreqnD', 'darray', 1)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,20 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
scriptencoding utf-8
|
||||
|
||||
function! vimtex#syntax#p#cases#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'cases') | return | endif
|
||||
let b:vimtex_syntax.cases = 1
|
||||
|
||||
call VimtexNewMathZone('E', '\(sub\)\?numcases', 0)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,44 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#cleveref#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'cleveref') | return | endif
|
||||
let b:vimtex_syntax.cleveref = 1
|
||||
if get(g:, 'tex_fast', 'r') !~# 'r' | return | endif
|
||||
|
||||
syntax match texStatement '\\\(\(label\)\?c\(page\)\?\|C\|auto\)ref\>'
|
||||
\ nextgroup=texCRefZone
|
||||
|
||||
" \crefrange, \cpagerefrange (these commands expect two arguments)
|
||||
syntax match texStatement '\\c\(page\)\?refrange\>'
|
||||
\ nextgroup=texCRefZoneRange skipwhite skipnl
|
||||
|
||||
" \label[xxx]{asd}
|
||||
syntax match texStatement '\\label\[.\{-}\]'
|
||||
\ nextgroup=texCRefZone skipwhite skipnl
|
||||
\ contains=texCRefLabelOpts
|
||||
|
||||
syntax region texCRefZone contained matchgroup=Delimiter
|
||||
\ start="{" end="}"
|
||||
\ contains=@texRefGroup,texRefZone
|
||||
syntax region texCRefZoneRange contained matchgroup=Delimiter
|
||||
\ start="{" end="}"
|
||||
\ contains=@texRefGroup,texRefZone
|
||||
\ nextgroup=texCRefZone skipwhite skipnl
|
||||
syntax region texCRefLabelOpts contained matchgroup=Delimiter
|
||||
\ start='\[' end=']'
|
||||
\ contains=@texRefGroup,texRefZone
|
||||
|
||||
highlight link texCRefZone texRefZone
|
||||
highlight link texCRefZoneRange texRefZone
|
||||
highlight link texCRefLabelOpts texCmdArgs
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
@@ -1,18 +0,0 @@
|
||||
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
|
||||
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#syntax#p#csquotes#load() abort " {{{1
|
||||
if has_key(b:vimtex_syntax, 'csquotes') | return | endif
|
||||
let b:vimtex_syntax.csquotes = 1
|
||||
|
||||
call vimtex#syntax#p#biblatex#load()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user