Compare commits

...

84 Commits

Author SHA1 Message Date
Adam Stankiewicz
7972e8eea1 Build 2020-08-27 15:02:54 +02:00
Adam Stankiewicz
6ed481e463 Make sure all extensions are covered 2020-08-27 15:01:44 +02:00
Adam Stankiewicz
c1e1870a3d Fix ocaml and dune ftdetect 2020-08-27 09:30:50 +02:00
Adam Stankiewicz
f0d6ecff07 Build 2020-08-25 23:09:24 +02:00
Tim Bedard
15e5df246e Add missing newlines (#527) 2020-08-25 23:08:33 +02:00
Adam Stankiewicz
94ababe91f Fix ansible ftdetect 2020-08-25 14:28:44 +02:00
Adam Stankiewicz
080b8cdc60 Fix ansible ftdetect 2020-08-25 14:26:38 +02:00
Adam Stankiewicz
e47af23f64 Cleanup ftdetect 2020-08-25 14:03:03 +02:00
Adam Stankiewicz
8f5134aef8 Include docs of plugins 2020-08-24 12:37:31 +02:00
Adam Stankiewicz
be8d039e02 Remove vifm and test all filetypes 2020-08-24 12:34:24 +02:00
Adam Stankiewicz
38ce8e9cb6 Use make in CI 2020-08-24 11:53:03 +02:00
Adam Stankiewicz
55ad5a982a Migrate to makefile 2020-08-24 11:52:33 +02:00
Adam Stankiewicz
b2055afaa7 Migrate only after dirs 2020-08-24 11:48:35 +02:00
Adam Stankiewicz
63a175357a Remove some custom dirs config 2020-08-24 10:56:09 +02:00
Adam Stankiewicz
25db54573a Mention vim-polyglot is more secure than using individual packs 2020-08-24 10:32:03 +02:00
Adam Stankiewicz
d1bfe50419 Ignore compiler for javascript, fixes #521 2020-08-24 10:29:39 +02:00
Adam Stankiewicz
22e8e01c1e Use setf for ambiguous extensions 2020-08-24 09:52:25 +02:00
Adam Stankiewicz
30bef582ba Fix blade ftdetect 2020-08-24 09:31:34 +02:00
Adam Stankiewicz
74d940cda3 Remove travis 2020-08-24 00:21:35 +02:00
Adam Stankiewicz
54d2386262 Update readme 2020-08-24 00:05:31 +02:00
Adam Stankiewicz
a47c315b01 Update readme 2020-08-24 00:04:36 +02:00
Adam Stankiewicz
ff0ada0dc3 Fix CI 2020-08-24 00:01:53 +02:00
Adam Stankiewicz
e194de5875 Debug CI 2020-08-23 23:59:02 +02:00
Adam Stankiewicz
012cf89210 Fix CI 2020-08-23 23:54:23 +02:00
Adam Stankiewicz
ac71777dc2 Fix CI 2020-08-23 23:40:50 +02:00
Adam Stankiewicz
23defeb610 fix: Migrate build script to ruby 2020-08-23 23:35:05 +02:00
Adam Stankiewicz
114a93bb7c Migrate ftdetect generation to ruby 2020-08-23 23:25:06 +02:00
Adam Stankiewicz
f3ab28a287 Move packages to yaml file 2020-08-23 19:39:42 +02:00
Adam Stankiewicz
bc3b36088e Update 2020-08-23 17:26:30 +02:00
Adam Stankiewicz
5d0150e326 Migrate build script to ruby 2020-08-21 19:49:36 +02:00
Adam Stankiewicz
cf8e31ff7f Update 2020-08-21 14:51:19 +02:00
Adam Stankiewicz
0df1bfa0c5 Add requirements.txt support, closes #507 2020-08-18 23:31:31 +02:00
Adam Stankiewicz
f7302d9262 Add jq syntax, closes #502 2020-08-18 23:25:22 +02:00
Adam Stankiewicz
7e38f4288a Add improved sql syntax, closes #505 2020-08-18 23:22:09 +02:00
Adam Stankiewicz
e521ba3ae2 Add fennel support, closes #514 2020-08-18 23:09:35 +02:00
Adam Stankiewicz
ee4f51587d Add ftdetect for jsonnet 2020-08-18 23:06:10 +02:00
Adam Stankiewicz
20a388cbc8 Add jsonnet support, closes #515 2020-08-18 23:04:38 +02:00
Adam Stankiewicz
81e61a3c5d Ignore auto-generated tags file 2020-08-18 23:00:07 +02:00
Adam Stankiewicz
5670985b3a Add docs, fixes #501 2020-08-18 22:45:46 +02:00
Adam Stankiewicz
69eae22ea6 Let fsharp have priority over fs files, fixes #523 2020-08-18 21:30:22 +02:00
Adam Stankiewicz
f8cee0172b Allow to set let g:python_highlight_all = 0, closes #474 2020-08-18 20:52:00 +02:00
Adam Stankiewicz
c6936aeeb1 Fix dhall plugin, closes #519 2020-08-18 20:08:26 +02:00
Adam Stankiewicz
6bb111eaba Embed plugin guards 2020-08-18 20:01:12 +02:00
Adam Stankiewicz
dfecb63078 Report download errors 2020-08-18 18:49:24 +02:00
Adam Stankiewicz
00015bd105 Migrate all ftdetect to linguist 2020-08-18 15:53:18 +02:00
Adam Stankiewicz
d821de3142 Migrate more filetypes 2020-08-18 11:54:28 +02:00
Adam Stankiewicz
a3bdbcdb3c Fix svelte branch name, closes #522 2020-08-14 19:15:07 +02:00
Adam Stankiewicz
34e01b8b62 Start github-linguist rewrite 2020-08-06 13:42:56 +02:00
Adam Stankiewicz
1e533e5982 Update 2020-08-06 13:22:17 +02:00
Adam Stankiewicz
56121b4e27 Update 2020-07-26 10:20:08 +02:00
Adam Stankiewicz
9c3c0bc082 Fix rspect ftdetect, #503 2020-07-06 19:14:22 +02:00
Adam Stankiewicz
8500ae8bb9 Update 2020-07-06 19:13:39 +02:00
Adam Stankiewicz
d09a56a494 Add unison language support 2020-06-25 13:40:40 +02:00
Adam Stankiewicz
abca7c2014 Update 2020-06-25 13:38:15 +02:00
TravonteD
8b6c06e723 Add detection for rspec files (#503)
Standard convention for rspec files is "*_spec.rb". This is also what
rspec.vim (the syntax plugin that is pulled in) uses.
2020-06-19 14:47:03 +02:00
Adam Stankiewicz
a86c0179eb Update 2020-06-13 11:36:03 +02:00
Adam Stankiewicz
22095febb7 Update 2020-06-10 11:46:12 +02:00
Adam Stankiewicz
ff066ee9f0 Update 2020-06-07 17:37:15 +02:00
Adam Stankiewicz
5b38663027 Update README.md 2020-06-01 22:01:48 +02:00
Adam Stankiewicz
f0b38f2c1d Install vim 8 for tests 2020-05-31 23:53:41 +02:00
Adam Stankiewicz
6676d61f61 Fix 2020-05-31 23:51:46 +02:00
Adam Stankiewicz
f0da1a9f4d Update vim version 2020-05-31 23:48:07 +02:00
Adam Stankiewicz
298d6b6356 Fix tests 2020-05-31 23:44:10 +02:00
Adam Stankiewicz
62f004c3da Update travis script 2020-05-31 23:42:04 +02:00
Adam Stankiewicz
c73ea49ecb Improve bash and zsh highlighting 2020-05-31 20:57:37 +02:00
Adam Stankiewicz
b2be47befc Update 2020-05-31 20:52:04 +02:00
Adam Kwiatek
de38ccabbd Enable TypeScript in ftdetect (#496) 2020-05-29 21:10:18 +02:00
Adam Stankiewicz
f0f49cf0fa Add support for ics, closes #492 2020-05-28 11:12:25 +02:00
Adam Stankiewicz
224a6348f9 Update 2020-05-28 11:09:19 +02:00
Emerson MX
00c3f02945 Remove gdscript ftplugin (#494) 2020-05-28 11:05:53 +02:00
Adam Stankiewicz
df34b4b4fa Update 2020-05-21 22:45:59 +02:00
Adam Stankiewicz
f3804b0892 Restore support for polyglot_disabled for ftdetect, closes #491 2020-05-21 22:45:04 +02:00
Adam Stankiewicz
685aeaaeb1 Add ledger support, closes #488 2020-05-20 20:24:48 +02:00
Adam Stankiewicz
a9cc6fd218 Remove latex, fixes #484 2020-05-20 20:19:03 +02:00
Adam Stankiewicz
3c47f192b5 Fix jinja.html detection 2020-05-20 19:44:40 +02:00
Adam Stankiewicz
c8b350432c Remove generation of ftdetect from build 2020-05-20 19:35:10 +02:00
Adam Stankiewicz
cdb8e233c2 Manually fix ftdetect 2020-05-20 19:32:07 +02:00
Adam Stankiewicz
ff282f610f Remove extra files 2020-05-20 17:29:46 +02:00
Adam Stankiewicz
74cb75bedd Add vim-raku, closes #490 2020-05-20 17:06:38 +02:00
Adam Stankiewicz
42529540df Remove non-working ftplugin line, closes #485 2020-05-20 17:04:22 +02:00
Adam Stankiewicz
a688c66a04 Update 2020-05-20 16:59:09 +02:00
Adam Stankiewicz
0a7c62b3b2 Remove rego syntax, fixes #486 2020-04-30 16:49:01 +02:00
Adam Stankiewicz
c7b5826d53 Update 2020-04-28 01:09:08 +02:00
Adam Stankiewicz
1d348d0c2d Update badge 2020-04-25 23:23:00 +02:00
301 changed files with 25921 additions and 28519 deletions

7
.gitattributes vendored
View File

@@ -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
View 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
View File

@@ -1,2 +1,3 @@
/tmp
!*ctags*
tags

View File

@@ -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

View File

@@ -1,4 +0,0 @@
source 'https://rubygems.org'
gem 'vimrunner'
gem 'rspec'

View File

@@ -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

7
Makefile Normal file
View File

@@ -0,0 +1,7 @@
.PHONY: all
all:
@ scripts/build
test:
@ scripts/test

116
README.md
View File

@@ -1,22 +1,20 @@
![vim-polyglot](https://i.imgur.com/9RxQK6k.png)
[![Build Status][travis-img-url]][travis-url] [![Maintenance](https://img.shields.io/maintenance/yes/2019.svg?maxAge=2592000)]()
[travis-img-url]: https://travis-ci.org/sheerun/vim-polyglot.svg
[travis-url]: https://travis-ci.org/sheerun/vim-polyglot
![build](https://github.com/sheerun/vim-polyglot/workflows/Vim%20Polyglot%20CI/badge.svg) [![Maintenance](https://img.shields.io/maintenance/yes/2020.svg?maxAge=2592000)]()
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-->155<!--/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,7 +36,7 @@ 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.
@@ -59,110 +57,117 @@ If you need full functionality of any plugin, please use it directly with your p
- [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)
- [clojure](https://github.com/guns/vim-clojure-static) (syntax, indent, doc, 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)
- [coffee-script](https://github.com/kchmck/vim-coffee-script) (syntax, indent, doc, compiler, autoload, ftplugin)
- [cql](https://github.com/elubow/cql-vim) (syntax)
- [cryptol](https://github.com/victoredwardocallaghan/cryptol.vim) (syntax, compiler, ftplugin)
- [cryptol](https://github.com/victoredwardocallaghan/cryptol.vim) (syntax, doc, compiler, ftplugin)
- [crystal](https://github.com/rhysd/vim-crystal) (syntax, indent, autoload, ftplugin)
- [csv](https://github.com/chrisbra/csv.vim) (syntax, autoload, ftplugin)
- [csv](https://github.com/chrisbra/csv.vim) (syntax, doc, 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)
- [dart](https://github.com/dart-lang/dart-vim-plugin) (syntax, indent, doc, autoload, ftplugin)
- [dhall](https://github.com/vmchale/dhall-vim) (syntax, doc, 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)
- [elixir](https://github.com/elixir-lang/vim-elixir) (syntax, indent, doc, 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)
- [fennel](https://github.com/bakpakin/fennel.vim) (syntax, indent, ftplugin)
- [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)
- [fsharp](https://github.com/ionide/Ionide-vim) (syntax, indent, doc, autoload)
- [gdscript](https://github.com/calviken/vim-gdscript3) (syntax, indent)
- [git](https://github.com/tpope/vim-git) (syntax, indent, doc, 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)
- [go](https://github.com/fatih/vim-go) (syntax, indent, doc, compiler)
- [gradle](https://github.com/tfnico/vim-gradle) (compiler)
- [graphql](https://github.com/jparise/vim-graphql) (syntax, indent, autoload, ftplugin, after)
- [graphql](https://github.com/jparise/vim-graphql) (syntax, indent, autoload, ftplugin, after, doc)
- [haml](https://github.com/sheerun/vim-haml) (syntax, indent, compiler, ftplugin)
- [handlebars](https://github.com/mustache/vim-mustache-handlebars) (syntax, indent, ftplugin)
- [handlebars](https://github.com/sheerun/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)
- [haskell](https://github.com/neovimhaskell/haskell-vim) (syntax, indent, doc, 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)
- [icalendar](https://github.com/chutzpah/icalendar.vim) (syntax)
- [idris](https://github.com/idris-hackers/idris-vim) (syntax, indent, doc, ftplugin)
- [ion](https://github.com/vmchale/ion-vim) (syntax, ftplugin)
- [javascript](https://github.com/pangloss/vim-javascript) (syntax, indent, compiler, ftplugin, extras)
- [javascript](https://github.com/pangloss/vim-javascript) (syntax, indent, ftplugin, extras)
- [jenkins](https://github.com/martinda/Jenkinsfile-vim-syntax) (syntax, indent)
- [jinja](https://github.com/lepture/vim-jinja) (syntax, indent)
- [jq](https://github.com/vito-c/jq.vim) (syntax, ftplugin)
- [json5](https://github.com/GutenYe/json5.vim) (syntax)
- [json](https://github.com/elzr/vim-json) (syntax, indent, ftplugin)
- [jsonnet](https://github.com/google/vim-jsonnet) (syntax, doc, autoload, 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)
- [jsx](https://github.com/MaxMEllon/vim-jsx-pretty) (autoload, after, doc)
- [julia](https://github.com/JuliaEditorSupport/julia-vim) (syntax, indent, doc, autoload, ftplugin)
- [kotlin](https://github.com/udalov/kotlin-vim) (syntax, indent, ftplugin)
- [latex](https://github.com/lervag/vimtex) (indent, compiler, autoload, ftplugin, syntax)
- [ledger](https://github.com/ledger/vim-ledger) (syntax, indent, doc, compiler, autoload)
- [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)
- [log](https://github.com/MTDL9/vim-log-highlighting) (syntax, doc)
- [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)
- [markdown](https://github.com/plasticboy/vim-markdown) (syntax, indent, doc, 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)
- [nim](https://github.com/zah/nim.vim) (syntax, indent, compiler, autoload)
- [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)
- [ocaml](https://github.com/rgrinberg/vim-ocaml) (syntax, indent, doc, 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)
- [pgsql](https://github.com/lifepillar/pgsql.vim) (syntax, indent, doc)
- [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)
- [powershell](https://github.com/PProvost/vim-ps1) (syntax, indent, doc, 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)
- [python](https://github.com/vim-python/python-syntax) (syntax, doc)
- [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)
- [raml](https://github.com/IN3D/vim-raml) (syntax, ftplugin)
- [raku](https://github.com/Raku/vim-raku) (syntax, indent, ftplugin)
- [raml](https://github.com/IN3D/vim-raml) (syntax, doc, ftplugin)
- [razor](https://github.com/adamclerk/vim-razor) (syntax, indent, ftplugin)
- [reason](https://github.com/reasonml-editor/vim-reason-plus) (syntax, indent)
- [rego](https://github.com/tsandall/vim-rego) (syntax)
- [reason](https://github.com/reasonml-editor/vim-reason-plus) (syntax, indent, doc)
- [requirements](https://github.com/raimon49/requirements.txt.vim) (syntax, autoload)
- [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)
- [ruby](https://github.com/vim-ruby/vim-ruby) (syntax, indent, doc, compiler, autoload, ftplugin)
- [rust](https://github.com/rust-lang/rust.vim) (syntax, indent, doc, compiler, autoload, ftplugin, ctags)
- [sbt](https://github.com/derekwyatt/vim-sbt) (syntax)
- [scala](https://github.com/derekwyatt/vim-scala) (syntax, indent, compiler, ftplugin, ctags)
- [scala](https://github.com/derekwyatt/vim-scala) (syntax, indent, doc, compiler, ftplugin, ctags)
- [scss](https://github.com/cakebaker/scss-syntax.vim) (syntax, indent, ftplugin)
- [sh](https://github.com/arzg/vim-sh) (syntax)
- [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)
- [sql](https://github.com/shmup/vim-sql-syntax) (syntax)
- [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)
@@ -170,60 +175,55 @@ If you need full functionality of any plugin, please use it directly with your p
- [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)
- [terraform](https://github.com/hashivim/vim-terraform) (syntax, indent, doc, autoload, ftplugin)
- [textile](https://github.com/timcharper/textile.vim) (syntax, doc, 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)
- [unison](https://github.com/unisonweb/unison) (syntax)
- [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)
- [velocity](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)
- [xsl](https://github.com/vim-scripts/XSLT-syntax) (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)
- [zig](https://github.com/ziglang/zig.vim) (syntax, indent, autoload, ftplugin)
- [zinit](https://github.com/zinit-zsh/zplugin-vim-syntax) (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.

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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)
@@ -762,6 +762,10 @@ fu! csv#CalculateColumnWidth(row, silent) "{{{3
" does not work with fixed width columns
" row for the row for which to calculate the width
let b:col_width=[]
if has( 'vartabs' ) && b:delimiter == "\t"
let vts_save=&vts
set vts=
endif
try
if exists("b:csv_headerline")
if line('.') < b:csv_headerline
@@ -780,6 +784,9 @@ fu! csv#CalculateColumnWidth(row, silent) "{{{3
" delete buffer content in variable b:csv_list,
" this was only necessary for calculating the max width
unlet! b:csv_list s:columnize_count s:decimal_column
if has( 'vartabs' ) && b:delimiter == "\t"
let &vts=vts_save
endif
endfu
fu! csv#Columnize(field) "{{{3
" Internal function, not called from external,
@@ -1500,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
@@ -1536,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)
@@ -1949,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
@@ -1978,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
@@ -2256,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>)',
@@ -2304,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()', '')
@@ -2339,7 +2350,7 @@ fu! csv#ColumnWidth()
endfu
fu! csv#Map(map, name, definition, ...) "{{{3
let keyname = substitute(a:name, '[<>]', '', 'g')
let keyname = substitute(substitute(a:name, '[<>]', '', 'g'), '-', '_', 'g')
let expr = (exists("a:1") && a:1 == 'expr' ? '<expr>' : '')
if !get(g:, "csv_nomap_". tolower(keyname), 0)
" All mappings are buffer local

View File

@@ -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'

View File

@@ -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
View 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

View File

@@ -170,8 +170,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 +266,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 +371,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 +496,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 +557,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

View File

@@ -1,164 +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!')
let l:polyglot = !empty(filter(copy(l:scriptnames), "v:val =~# 'polyglot'"))
if l:polyglot
call health#report_info('LaTeX-Box is included with vim-polyglot and may be disabled with:')
call health#report_info('let g:polyglot_disabled = [''latex'']')
endif
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
View 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
View 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
View 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

36
autoload/requirements.vim Normal file
View 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

View File

@@ -55,6 +55,8 @@ function! terraform#commands(ArgLead, CmdLine, CursorPos) abort
\ 'graph',
\ 'import',
\ 'init',
\ 'login',
\ 'logout',
\ 'output',
\ 'plan',
\ 'providers',

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,707 +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_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_keywords', ['TODO', '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', '')
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
let l:polyglot = !empty(filter(copy(l:scriptnames), "v:val =~# 'polyglot'"))
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!',
\])
if l:polyglot
call vimtex#log#warning([
\ 'LaTeX-Box is included with vim-polyglot and may be disabled with:',
\ 'let g:polyglot_disabled = [''latex'']',
\])
endif
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

View File

@@ -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

View File

@@ -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 v:true
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 v:true
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 v:true
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 v:true
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,192 +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
"
" 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('s:created_maps')
call s:create_map(a:map)
endif
endfunction
" }}}1
function! vimtex#imaps#list() abort " {{{1
silent new vimtex\ imaps
for l:map in s:created_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(s:created_maps, a:map) >= 0 | return | endif
let l:leader = get(a: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 . a:map.lhs
let l:wrapper = get(a: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(a:map, 'context')
execute 'let l:key = "' . escape(l:lhs, '<') . '"'
let l:key .= a:map.rhs
if !exists('b:vimtex_context')
let b:vimtex_context = {}
endif
let b:vimtex_context[l:key] = a:map.context
endif
" The rhs may be evaluated before being passed to wrapper, unless expr is
" disabled (which it is by default)
if !get(a:map, 'expr')
let a:map.rhs = string(a:map.rhs)
endif
silent execute 'inoremap <expr><silent><nowait><buffer>' l:lhs
\ l:wrapper . '("' . escape(l:lhs, '\') . '", ' . a:map.rhs . ')'
let s:created_maps += [a: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
" {{{1 Initialize module
let s:created_maps = []
" }}}1
endif

View File

@@ -1,147 +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)
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 . '/**/' . 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,778 +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(g:vimtex_toc_todo_keywords, '|') . ')'
\ . '|\%\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(g:vimtex_toc_todo_keywords, '|') . ')[ :]+\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]
return {
\ 'title' : toupper(l:type) . ': ' . 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
return {
\ 'title' : 'TODO: ' . 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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*%(' . 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,82 +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
" 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
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
endfunction
" }}}1
endif

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,25 +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#dot2texi#load() abort " {{{1
if has_key(b:vimtex_syntax, 'dot2texi') | return | endif
let b:vimtex_syntax.dot2texi = 1
call vimtex#syntax#misc#include('dot')
call vimtex#syntax#misc#add_to_section_clusters('texZoneDot')
syntax region texZoneDot
\ start="\\begin{dot2tex}"rs=s
\ end="\\end{dot2tex}"re=e
\ keepend
\ transparent
\ contains=texBeginEnd,@vimtex_nested_dot
endfunction
" }}}1
endif

View File

@@ -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#glossaries#load() abort " {{{1
if has_key(b:vimtex_syntax, 'glossaries') | return | endif
let b:vimtex_syntax.glossaries = 1
" Currently nothing here
endfunction
" }}}1
endif

View File

@@ -1,21 +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#glossaries_extra#load() abort " {{{1
if has_key(b:vimtex_syntax, 'glossaries_extra') | return | endif
let b:vimtex_syntax.glossaries_extra = 1
" Load amsmath
call vimtex#syntax#p#glossaries#load()
endfunction
" }}}1
endif

View File

@@ -1,25 +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#gnuplottex#load() abort " {{{1
if has_key(b:vimtex_syntax, 'gnuplottex') | return | endif
let b:vimtex_syntax.gnuplottex = 1
call vimtex#syntax#misc#include('gnuplot')
call vimtex#syntax#misc#add_to_section_clusters('texZoneGnuplot')
syntax region texZoneGnuplot
\ start='\\begin{gnuplot}\(\_s*\[\_[\]]\{-}\]\)\?'rs=s
\ end='\\end{gnuplot}'re=e
\ keepend
\ transparent
\ contains=texBeginEnd,texBeginEndModifier,@vimtex_nested_gnuplot
endfunction
" }}}1
endif

View File

@@ -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#hyperref#load() abort " {{{1
if has_key(b:vimtex_syntax, 'hyperref') | return | endif
let b:vimtex_syntax.hyperref = 1
syntax match texStatement '\\url\ze[^\ta-zA-Z]' nextgroup=texUrlVerb
syntax region texUrlVerb matchgroup=Delimiter
\ start='\z([^\ta-zA-Z]\)' end='\z1' contained
syntax match texStatement '\\url\ze\s*{' nextgroup=texUrl
syntax region texUrl matchgroup=Delimiter start='{' end='}' contained
syntax match texStatement '\\href' nextgroup=texHref
syntax region texHref matchgroup=Delimiter start='{' end='}' contained
\ nextgroup=texMatcher
syntax match texStatement '\\hyperref' nextgroup=texHyperref
syntax region texHyperref matchgroup=Delimiter start='\[' end='\]' contained
highlight link texUrl Function
highlight link texUrlVerb texUrl
highlight link texHref texUrl
highlight link texHyperref texRefZone
endfunction
" }}}1
endif

View File

@@ -1,75 +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#listings#load() abort " {{{1
if has_key(b:vimtex_syntax, 'listings') | return | endif
let b:vimtex_syntax.listings = s:get_nested_languages()
" First some general support
syntax match texInputFile
\ "\\lstinputlisting\s*\(\[.\{-}\]\)\={.\{-}}"
\ contains=texStatement,texInputCurlies,texInputFileOpt
syntax match texZone "\\lstinline\s*\(\[.\{-}\]\)\={.\{-}}"
" Set all listings environments to listings
syntax cluster texFoldGroup add=texZoneListings
syntax region texZoneListings
\ start="\\begin{lstlisting}\(\_s*\[\_[^\]]\{-}\]\)\?"rs=s
\ end="\\end{lstlisting}\|%stopzone\>"re=e
\ keepend
\ contains=texBeginEnd
" Next add nested syntax support for desired languages
for l:nested in b:vimtex_syntax.listings
let l:cluster = vimtex#syntax#misc#include(l:nested)
if empty(l:cluster) | continue | endif
let l:group_main = 'texZoneListings' . toupper(l:nested[0]) . l:nested[1:]
let l:group_lstset = l:group_main . 'Lstset'
let l:group_contained = l:group_main . 'Contained'
execute 'syntax cluster texFoldGroup add=' . l:group_main
execute 'syntax cluster texFoldGroup add=' . l:group_lstset
execute 'syntax region' l:group_main
\ 'start="\c\\begin{lstlisting}\s*'
\ . '\[\_[^\]]\{-}language=' . l:nested . '\%(\s*,\_[^\]]\{-}\)\?\]"rs=s'
\ 'end="\\end{lstlisting}"re=e'
\ 'keepend'
\ 'transparent'
\ 'contains=texBeginEnd,@' . l:cluster
execute 'syntax match' l:group_lstset
\ '"\c\\lstset{.*language=' . l:nested . '\%(\s*,\|}\)"'
\ 'transparent'
\ 'contains=texStatement,texMatcher'
\ 'skipwhite skipempty'
\ 'nextgroup=' . l:group_contained
execute 'syntax region' l:group_contained
\ 'start="\\begin{lstlisting}"rs=s'
\ 'end="\\end{lstlisting}"re=e'
\ 'keepend'
\ 'transparent'
\ 'containedin=' . l:group_lstset
\ 'contains=texStatement,texBeginEnd,@' . l:cluster
endfor
highlight link texZoneListings texZone
endfunction
" }}}1
function! s:get_nested_languages() abort " {{{1
return map(
\ filter(getline(1, '$'), "v:val =~# 'language='"),
\ 'matchstr(v:val, ''language=\zs\w\+'')')
endfunction
" }}}1
endif

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