Compare commits
No commits in common. "d9e2205553cddf4a8afac87416b72c0ccab2cce5" and "f6cd13b58709cfdd3304d5f2e28b86b6f1eaa872" have entirely different histories.
d9e2205553
...
f6cd13b587
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
@ -1,579 +0,0 @@
|
|||||||
---
|
|
||||||
Title: Neovim as a LaTex Development Environment
|
|
||||||
Date: 2023-10-14 12:00:00+0200
|
|
||||||
Date: 2023-10-14 17:00:00+0200
|
|
||||||
Lang: en
|
|
||||||
Author: Fabrice
|
|
||||||
Category: software
|
|
||||||
Tags: vim, neovim, latex, zathura
|
|
||||||
Slug: nvim-latex
|
|
||||||
table-of-contents: true
|
|
||||||
Header_Cover: ../images/covers/fern-forest.jpg
|
|
||||||
Summary: How to turn Neovim into a full-fledged latex development environment
|
|
||||||
---
|
|
||||||
|
|
||||||
# Introduction
|
|
||||||
|
|
||||||
[LaTeX](https://en.wikipedia.org/wiki/LaTeX) is a typesetting software for
|
|
||||||
producing typographically sound printable documents that is mostly used by the
|
|
||||||
scientific community (but [not
|
|
||||||
only](https://www.ctan.org/pkg/latex-sciences-humaines)) as it allows writing
|
|
||||||
mathematics formulae in a somewhat *not-that-much painful* way, is shipped with
|
|
||||||
[bibliography engines](https://www.ctan.org/pkg/biblatex), enables easy
|
|
||||||
cross-referencing and automatically generates table of contents.
|
|
||||||
|
|
||||||
It is based on a markup language that allows writers to focus on the content of
|
|
||||||
the document and leaves the typesetting to the software (at least most of the
|
|
||||||
time).
|
|
||||||
It moreover enjoys [many](https://ctan.org/) libraries that span from enabling
|
|
||||||
[new features](https://ctan.org/pkg/algorithm2e) to [simpler
|
|
||||||
version](https://www.ctan.org/pkg/a4wide) of more [complete
|
|
||||||
tools](https://ctan.org/pkg/geometry).
|
|
||||||
|
|
||||||
In this blog post we will see how to setup [Neovim](https://neovim.io/) to
|
|
||||||
manipulate LaTeX document while enabling modern features such as
|
|
||||||
[language server
|
|
||||||
protocol](https://en.wikipedia.org/wiki/Language_Server_Protocol) and what you
|
|
||||||
want from any LaTeX IDEs: forward and backward
|
|
||||||
searches (respectively going from the source code to the resulting document and
|
|
||||||
vice-versa, thanks to
|
|
||||||
[synctex](https://tug.org/tugboat/tb29-3/tb93laurens.pdf)).
|
|
||||||
|
|
||||||
As a PDF reader, we will use [zathura](https://pwmt.org/projects/zathura/) to
|
|
||||||
show how to setup backward search (search from the document toward the source).
|
|
||||||
It is a highly configurable, lightweight document viewer which natively enjoys
|
|
||||||
vim-like shortcuts.
|
|
||||||
|
|
||||||
# Ingredients
|
|
||||||
|
|
||||||
Before starting we will need several components to achieve this lofty goal of
|
|
||||||
painlessly writing LaTeX documents with the best text editor. Let us start by
|
|
||||||
listing them; we will shortly see the installation and configuration procedure:
|
|
||||||
|
|
||||||
* A configurable text editor to be able to write the document:
|
|
||||||
[Neovim](https://neovim.io). For that we will also need some plugins to
|
|
||||||
unleash its full capability:
|
|
||||||
* [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig): a plugin to
|
|
||||||
facilitate the configuration
|
|
||||||
[LSP](https://en.wikipedia.org/wiki/Language_Server_Protocol) for `Neovim`.
|
|
||||||
* [nvim-cmp](https://github.com/hrsh7th/nvim-cmp): a completion engine for
|
|
||||||
`Neovim`.
|
|
||||||
* [vimtex](https://github.com/lervag/vimtex): a language specific plugin for
|
|
||||||
LaTeX files that supports many features such as accurate syntactic
|
|
||||||
coloration, support of multi-files, add LaTeX-specific [text
|
|
||||||
objects](https://vimhelp.org/motion.txt.html#text-objects), improved
|
|
||||||
foldings and so on.
|
|
||||||
* [texlab](https://github.com/latex-lsp/texlab): to enable LSP features, you
|
|
||||||
also a LSP server for vim to communicate with, which is exactly what
|
|
||||||
`texlab` is.
|
|
||||||
* [zathura](https://pwmt.org/projects/zathura/): finally a PDF viewer, we will
|
|
||||||
use `zathura` here, but `vimtex` supports many others with predefined setups.
|
|
||||||
However you will have to look for the specific documentation of your pdf
|
|
||||||
reader to enable reverse search if it is possible.
|
|
||||||
|
|
||||||
# Setting Neovim up
|
|
||||||
|
|
||||||
Now that we have prepared everything, we need to setup `Neovim`.
|
|
||||||
We will assume a blank configuration and start from scratch.
|
|
||||||
I got inspired by a [blogpost about snippets in
|
|
||||||
Neovim](https://pcoves.gitlab.io/en/blog/nvim-snippets/#installation) and used
|
|
||||||
`NVIM_APPNAME` environment variables for testing this configuration. Please let
|
|
||||||
me know if anything is not working as intended.
|
|
||||||
|
|
||||||
## Being Lazy
|
|
||||||
|
|
||||||
Anyhow, we first need to install the different plugins that we need. For this
|
|
||||||
purpose, I used the [lazy](https://github.com/folke/lazy.nvim) plugin manager,
|
|
||||||
but you can use whichever you see fit for the task.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Lazy Package Manager
|
|
||||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
|
||||||
if not vim.loop.fs_stat(lazypath) then
|
|
||||||
vim.fn.system({
|
|
||||||
"git",
|
|
||||||
"clone",
|
|
||||||
"--filter=blob:none",
|
|
||||||
"https://github.com/folke/lazy.nvim.git",
|
|
||||||
"--branch=stable", -- latest stable release
|
|
||||||
lazypath,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
vim.opt.rtp:prepend(lazypath)
|
|
||||||
|
|
||||||
-- Packages
|
|
||||||
require("lazy").setup({
|
|
||||||
"lervag/vimtex",
|
|
||||||
"neovim/nvim-lspconfig",
|
|
||||||
"hrsh7th/cmp-nvim-lsp",
|
|
||||||
"hrsh7th/nvim-cmp",
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
In the code block above —in `$NVIM_CONFIG/init.lua`— the first part is to bootstrap lazy (so it can install
|
|
||||||
itself if not already there) and the last block describe the installation of the
|
|
||||||
following plugins : `vimtex`, `nvim-lspconfig`, `nvim-cmp` and finally
|
|
||||||
`cmp-nvim-lsp` to glue the completion engine and `lspconfig`.
|
|
||||||
|
|
||||||
Now it is all good and done, but nothing is configured yet, and if you open a
|
|
||||||
LaTeX file in this state, you will only enjoy the benefits of an unconfigured
|
|
||||||
`vimtex`, which is already nice as is it, but not enough to achieve our goal.
|
|
||||||
And it's a bit sad to have installed three other plugins for nothing.
|
|
||||||
|
|
||||||
# vimtex
|
|
||||||
|
|
||||||
It will be a bit anti-climatic after the previous teasing, but we will use
|
|
||||||
`vimtex` as vanilla as possible…
|
|
||||||
We still need to tell it to use `zathura` as a pdf viewer:
|
|
||||||
```lua
|
|
||||||
vim.g.vimtex_view_method = "zathura"
|
|
||||||
```
|
|
||||||
|
|
||||||
This will allow `vimtex` to automatically open `zathura` upon compilation,
|
|
||||||
which is bound to `<LocalLeader>ll` by default. Meaning that we have to define
|
|
||||||
[`<LocalLeader>`](https://neovim.io/doc/user/map.html#%3CLocalLeader%3E), which
|
|
||||||
I usually set to be a comma: “`,`”:
|
|
||||||
```lua
|
|
||||||
vim.g.maplocalleader = ","
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, you can use `,lv` to view the current line in `zathura`, and `,ll` to
|
|
||||||
compile your document. Yay!
|
|
||||||
|
|
||||||
More can be then done, such as using vimtex folds, which are disabled by
|
|
||||||
default (contrary to what [vim-latex](https://github.com/vim-latex/vim-latex)
|
|
||||||
was doing, which is the former plugin I used):
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- From: https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L4671-L4713
|
|
||||||
vim.o.foldmethod = "expr"
|
|
||||||
vim.o.foldexpr="vimtex#fold#level(v:lnum)"
|
|
||||||
vim.o.foldtext="vimtex#fold#text()"
|
|
||||||
-- I like to see at least the content of the sections upon opening
|
|
||||||
vim.o.foldlevel=2
|
|
||||||
```
|
|
||||||
|
|
||||||
Now the sky is your limit, but to start with, here follows a quick list of what
|
|
||||||
is possible now:
|
|
||||||
|
|
||||||
- Compile the document: `,ll`
|
|
||||||
- This also automatically generates a [quickfix
|
|
||||||
buffer](https://vimhelp.org/quickfix.txt.html) which is quite complete… even
|
|
||||||
a tad bit too much sometimes.
|
|
||||||
I used it as is to hunt for over/underfull hboxes, but you can filter them
|
|
||||||
out by setting the
|
|
||||||
[`vim.g.vimtex_quickfix_ignore_filters`](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L2365-L2378)
|
|
||||||
variable.
|
|
||||||
- View the current location in the document: `,lv`.
|
|
||||||
- Show table of content navigation: `,lt`.
|
|
||||||
* Using latex-specific text objects such as `$` for math or `e` for environment
|
|
||||||
(defined by `\begin{…}` and `\end{…}`).
|
|
||||||
- Insert command/environment : `<F6>/<F7>` (in normal and visual mode; these are
|
|
||||||
not very accessible, but can be remapped).
|
|
||||||
- Support for [TeX
|
|
||||||
directives](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L481-L504)
|
|
||||||
(which are common with others LaTeX' IDEs), such as
|
|
||||||
`%! TeX program = xelatex` to specify a latex compiler.
|
|
||||||
* For machine-aided proofreading, you can also enable [grammar checking
|
|
||||||
tools](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L5577-L5610),
|
|
||||||
such as [languagetool](https://languagetool.org/). I didn't check for
|
|
||||||
[grammalecte](https://grammalecte.net/) support for French yet, but it may
|
|
||||||
prove to be an [interesting
|
|
||||||
endeavour](https://upload.wikimedia.org/wikipedia/commons/9/9f/Rabbit_Hole.jpg).
|
|
||||||
|
|
||||||
**Remark.** vimtex
|
|
||||||
[claims](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L6549-L6624)
|
|
||||||
that their coloration is more accurate than what
|
|
||||||
[tree-sitter](https://tree-sitter.github.io/tree-sitter/), then if you are using
|
|
||||||
[nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter), you may
|
|
||||||
want to disable it for vimtex (it raises a warning otherwise):
|
|
||||||
|
|
||||||
```lua
|
|
||||||
require("nvim-treesitter.configs").setup({
|
|
||||||
highlight = {
|
|
||||||
enable = true,
|
|
||||||
disable = { "latex", },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Okay, that's all and good, but to quote [wikipedia](https://en.wikipedia.org):
|
|
||||||
|
|
||||||
> The goal of the [language server] protocol is to allow programming language
|
|
||||||
> support to be implemented and distributed independently of any given editor or
|
|
||||||
> IDE. In the early 2020s LSP quickly became a "norm" for language intelligence
|
|
||||||
> tools providers.
|
|
||||||
|
|
||||||
Source: <https://en.wikipedia.org/wiki/Language_Server_Protocol>
|
|
||||||
|
|
||||||
We are not early 2020s-ready for LaTeX yet, and even if we can send our current
|
|
||||||
location to `zathura`, the contrary is not possible yet.
|
|
||||||
Let us now address these two issues.
|
|
||||||
|
|
||||||
# Language Server Protocol
|
|
||||||
|
|
||||||
Setting up language server protocol with Vim is a big morsel, and have been the
|
|
||||||
topic of [some tuppervim's
|
|
||||||
sessions](https://tuppervim.org/archives/pads/grenoble-2212.txt) at some point.
|
|
||||||
|
|
||||||
Here follows a minimal configuration that should work with `texlab`:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Minimal lsp config
|
|
||||||
local lspconfig = require("lspconfig")
|
|
||||||
lspconfig.texlab.setup {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Easy, innit? Well, that's well and good, we can now see errors and warnings
|
|
||||||
decorating the file like a Christmas tree, but we can not use any of the LSP
|
|
||||||
tools such as obtaining information on a bibliography key, or rename a macro.
|
|
||||||
|
|
||||||
However, let us just remark that texlab is a pretty minimal LSP server, and
|
|
||||||
does not implement the myriads of possible functionalities.
|
|
||||||
Henceforth, I simply copy-pasted the default example from the [nvim-lspconfig
|
|
||||||
Readme](https://github.com/neovim/nvim-lspconfig), tried the shortcuts one by
|
|
||||||
one, and removed those which raised an error for “not implemented
|
|
||||||
functionality” 🤡:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Use LspAttach autocommand to only map the following keys
|
|
||||||
-- after the language server attaches to the current buffer
|
|
||||||
vim.api.nvim_create_autocmd("LspAttach", {
|
|
||||||
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
|
|
||||||
callback = function(ev)
|
|
||||||
-- Enable completion triggered by <c-x><c-o>
|
|
||||||
vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc"
|
|
||||||
|
|
||||||
-- Buffer local mappings.
|
|
||||||
-- See `:help vim.lsp.*` for documentation on any of the below functions
|
|
||||||
local opts = { buffer = ev.buf }
|
|
||||||
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
|
|
||||||
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
|
|
||||||
vim.keymap.set("n", "gR", vim.lsp.buf.rename, opts)
|
|
||||||
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Which thus enables:
|
|
||||||
|
|
||||||
* Omnicompletion using LSP (I won't elaborate on this point, either you use it
|
|
||||||
or not, but if you're using it, it may be useful to leave. I personally
|
|
||||||
don't).
|
|
||||||
* Go to a definition, with `gd`, which can be a macro, a reference, or even a
|
|
||||||
bibliography reference.
|
|
||||||
* Show the information about the element under the cursor using `K`, it can be
|
|
||||||
useful to quickly check a reference. Note that pressing `K` twice jumps into
|
|
||||||
the floating window. That can prove useful to copy an article title to search
|
|
||||||
for it somewhere else for instance.
|
|
||||||
* Rename a macro/variable among **all** files in the current working document
|
|
||||||
using `gR`.
|
|
||||||
It's a lifesaver when renaming macros as it avoids writing [regular
|
|
||||||
expressions](https://xkcd.com/1171/).
|
|
||||||
* Show each place where a reference appears with `gr` in a
|
|
||||||
[quickfix](https://vimhelp.org/quickfix.txt.html) window.
|
|
||||||
It allows checking where a formula is referenced or verifying if you cited
|
|
||||||
yourself enough.
|
|
||||||
I personally use
|
|
||||||
[telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) for that
|
|
||||||
purpose as it is more readable, but it goes beyond the scope of this blogpost.
|
|
||||||
|
|
||||||
And that is about it.
|
|
||||||
We now follow the same steps as before: enable the completion engine by fetching
|
|
||||||
the configuration from the [nvim-cmp](https://github.com/hrsh7th/nvim-cmp)
|
|
||||||
readme file and the [vimtex
|
|
||||||
documentation](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L4586-L4625),
|
|
||||||
then prune it.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- nvim-cmp
|
|
||||||
local cmp = require("cmp")
|
|
||||||
cmp.setup({
|
|
||||||
sources = cmp.config.sources({
|
|
||||||
{ name = "nvim_lsp" },
|
|
||||||
{ name = "buffer" },
|
|
||||||
}),
|
|
||||||
mapping = cmp.mapping.preset.insert({
|
|
||||||
["<C-Space>"] = cmp.mapping.complete(),
|
|
||||||
["<C-u>"] = cmp.mapping.scroll_docs(-4),
|
|
||||||
["<C-d>"] = cmp.mapping.scroll_docs(4),
|
|
||||||
["<C-l>"] = cmp.mapping.confirm({ select = true }),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
And we're all good from Neovim's side. You can of course start fine-tuning it
|
|
||||||
but it's not the purpose of this blogpost.
|
|
||||||
|
|
||||||
# Plug it into zathura
|
|
||||||
|
|
||||||
Now that you tweaked your Neovim configuration so much that it now consumes 10GB
|
|
||||||
of memory and takes 12s to launch using all your 24 CPU cores, we can move onto
|
|
||||||
configuring zathura.
|
|
||||||
|
|
||||||
One of the reasons I moved from
|
|
||||||
[vim-latex](https://github.com/vim-latex/vim-latex) to
|
|
||||||
[vimtex](https://github.com/lervag/vimtex) is reverse search: to enable it with
|
|
||||||
`vim-latex`, I was using [nvim-remote](https://github.com/mhinz/neovim-remote)
|
|
||||||
which is a wrapper for `nvim --listen` with a lot of constraints, while the most
|
|
||||||
annoying one is that if I used reverse search from a detached[^1] zathura window
|
|
||||||
without starting `nvr` first… then it spawns the process which I cannot recover.
|
|
||||||
Which usually happens when I'm in a rush to fix something quickly.
|
|
||||||
|
|
||||||
Fortunately, this is a thing of the past as it is possible to directly send a
|
|
||||||
directive to `vimtex` upon which it will look for the corresponding buffer and
|
|
||||||
open the file at the corresponding location while following its state
|
|
||||||
(which can be viewed with `,li`).
|
|
||||||
To do so, the
|
|
||||||
[documentation](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L5985-L6033)
|
|
||||||
states that you have to launch the following command, where `%l` is the line in
|
|
||||||
the file and `%f` is the name of the file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nvim --headless -c "VimtexInverseSearch %l '%f'"
|
|
||||||
```
|
|
||||||
|
|
||||||
That's all and good, we just have to tell Zathura which command to launch when
|
|
||||||
doing backward search, which by default is done with `Ctrl` + `left mouse
|
|
||||||
button` on the portion of the text you want to view in the code.
|
|
||||||
To do that, the following configuration that you can put in
|
|
||||||
`$HOME/.config/zathura/zathurarc` should do the trick:
|
|
||||||
|
|
||||||
```
|
|
||||||
set synctex true
|
|
||||||
set synctex-editor-command "nvim --headless -c \"VimtexInverseSearch %{line} '%{input}'\""
|
|
||||||
```
|
|
||||||
|
|
||||||
And… that's it! You can now go to the location you want in your source file,
|
|
||||||
compile it on the fly and scrutinise the warnings to look for overfull hboxes!
|
|
||||||
|
|
||||||
[^1]: Meaning that it is not owned by any terminal I have opened, I
|
|
||||||
can otherwise still recover it somehow.
|
|
||||||
|
|
||||||
# Conclusion
|
|
||||||
|
|
||||||
In this blogpost, we saw how to minimally set up Neovim to work with latex using
|
|
||||||
modern toolchains. You can use it as a base to then improve your workflow and
|
|
||||||
write your documents in a breeze with neovim.
|
|
||||||
|
|
||||||
To summarise the configuration we used, it can be done in an `init.lua` file in
|
|
||||||
your vim configuration directory:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Lazy Package Manager
|
|
||||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
|
||||||
if not vim.loop.fs_stat(lazypath) then
|
|
||||||
vim.fn.system({
|
|
||||||
"git",
|
|
||||||
"clone",
|
|
||||||
"--filter=blob:none",
|
|
||||||
"https://github.com/folke/lazy.nvim.git",
|
|
||||||
"--branch=stable", -- latest stable release
|
|
||||||
lazypath,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
vim.opt.rtp:prepend(lazypath)
|
|
||||||
|
|
||||||
require("lazy").setup({
|
|
||||||
"lervag/vimtex",
|
|
||||||
"neovim/nvim-lspconfig",
|
|
||||||
"hrsh7th/cmp-nvim-lsp",
|
|
||||||
"hrsh7th/nvim-cmp",
|
|
||||||
})
|
|
||||||
|
|
||||||
-- vimtex
|
|
||||||
vim.g.vimtex_view_method = "zathura"
|
|
||||||
vim.g.maplocalleader = ","
|
|
||||||
|
|
||||||
vim.o.foldmethod = "expr"
|
|
||||||
vim.o.foldexpr="vimtex#fold#level(v:lnum)"
|
|
||||||
vim.o.foldtext="vimtex#fold#text()"
|
|
||||||
vim.o.foldlevel=2
|
|
||||||
|
|
||||||
-- Minimal lsp config
|
|
||||||
local lspconfig = require("lspconfig")
|
|
||||||
lspconfig.texlab.setup {}
|
|
||||||
|
|
||||||
-- Use LspAttach autocommand to only map the following keys
|
|
||||||
-- after the language server attaches to the current buffer
|
|
||||||
vim.api.nvim_create_autocmd("LspAttach", {
|
|
||||||
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
|
|
||||||
callback = function(ev)
|
|
||||||
-- Enable completion triggered by <c-x><c-o>
|
|
||||||
vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc"
|
|
||||||
|
|
||||||
-- Buffer local mappings.
|
|
||||||
-- See `:help vim.lsp.*` for documentation on any of the below functions
|
|
||||||
local opts = { buffer = ev.buf }
|
|
||||||
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
|
|
||||||
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
|
|
||||||
vim.keymap.set("n", "gR", vim.lsp.buf.rename, opts)
|
|
||||||
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- nvim-cmp
|
|
||||||
local cmp = require("cmp")
|
|
||||||
cmp.setup({
|
|
||||||
sources = cmp.config.sources({
|
|
||||||
{ name = "buffer" },
|
|
||||||
{ name = "nvim_lsp" },
|
|
||||||
}),
|
|
||||||
mapping = cmp.mapping.preset.insert({
|
|
||||||
["<C-Space>"] = cmp.mapping.complete(),
|
|
||||||
["<C-u>"] = cmp.mapping.scroll_docs(-4),
|
|
||||||
["<C-d>"] = cmp.mapping.scroll_docs(4),
|
|
||||||
["<C-l>"] = cmp.mapping.confirm({ select = true }),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
and the following in your `zathurarc` file:
|
|
||||||
|
|
||||||
```
|
|
||||||
set synctex true
|
|
||||||
set synctex-editor-command "nvim --headless -c \"VimtexInverseSearch %{line} '%{input}'\""
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that due to some technical limitations, it's not fully perfect.
|
|
||||||
For instance, synctex is not fully accurate with beamer slides, and just select
|
|
||||||
the whole slide instead of the selected text. It is still better than nothing
|
|
||||||
in my opinion, and it's a drawback that every LaTeX IDE is subject to.
|
|
||||||
|
|
||||||
Now that everything is set up, you can skim the [vimtex
|
|
||||||
documentation](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt) to
|
|
||||||
look for things you want to activate and learn more about its features.
|
|
||||||
Keep in mind though that you should not be too greedy, just pick some habits one
|
|
||||||
at a time in order to ingrain them into your workflow.
|
|
||||||
You can also expand directly `Neovim` with
|
|
||||||
[snippets](https://github.com/L3MON4D3/LuaSnip) support for instance to automate
|
|
||||||
some tasks as LaTeX can be quite verbose from time to time.
|
|
||||||
I leave you now with some further reading about the topic.
|
|
||||||
|
|
||||||
## See Also
|
|
||||||
|
|
||||||
* jdhao. [A Complete Guide on Writing LaTeX with Vimtex in
|
|
||||||
Neovim](https://jdhao.github.io/2019/03/26/nvim_latex_write_preview/). June 2019.
|
|
||||||
A blogpost that serves the same purpose as this one, eventhough it's not fully
|
|
||||||
up to date, for instance regarding backward search.
|
|
||||||
* Gilles Castel. [How I'm able to take notes in mathematics lectures using LaTeX
|
|
||||||
and Vim](https://castel.dev/post/lecture-notes-1/).
|
|
||||||
An example of how to streamline writing maths with Neovim, vimtex and
|
|
||||||
snippets. The goal may not be for everyone (as writing new maths and following
|
|
||||||
a lecture are not one and the same), but it's still an interesting read. For
|
|
||||||
instance it presents the `concealment` feature of [vim](https://www.vim.org/)
|
|
||||||
that makes previewing the result easier.
|
|
||||||
I also recommend the rest of the blog, as it contains information about
|
|
||||||
[inkscape](https://inkscape.org/) and how to integrate it with LaTeX.
|
|
||||||
|
|
||||||
# Bonus: Key bindings for bépo users
|
|
||||||
|
|
||||||
As a [bépo](https://fr.wikipedia.org/wiki/B%C3%A9po) user, I have some remapping
|
|
||||||
done in Neovim, and especially [direction
|
|
||||||
keys](https://vimhelp.org/usr_02.txt.html#02.3):
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Some shortcuts
|
|
||||||
local keymap = vim.keymap.set
|
|
||||||
local opts = {noremap = true, silent = true}
|
|
||||||
|
|
||||||
-- [HJKL] <-> {CTSR}
|
|
||||||
local map_list = {
|
|
||||||
['c'] = 'h', ['r'] = 'l', ['t'] = 'j', ['s'] = 'k', ['C'] = 'H', ['R'] = 'L', ['T'] = 'J', ['S'] = 'K', -- [HJKL] -> [CTSR]
|
|
||||||
['j'] = 't', ['J'] = 'T', ['l'] = 'c', ['L'] = 'C', ['h'] = 'r', ['H'] = 'R', ['k'] = 's', ['K'] = 'S', -- [CTSR] -> [HJKL]: J = until, L = change, h = replace, k = substitute
|
|
||||||
}
|
|
||||||
for key, binding in pairs(map_list) do
|
|
||||||
keymap({'n', 'x'}, key, binding, opts)
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
That's nice and all but… it conflicts with the [vimtex default
|
|
||||||
mappings](https://github.com/lervag/vimtex/blob/master/doc/vimtex.txt#L800-L912)
|
|
||||||
such as `cse` to rename an environment which can be useful to replace an `align`
|
|
||||||
with `align*` for instance. Meaning that going back one character would trigger
|
|
||||||
vim to wait for the next key input, which is kind of annoying.
|
|
||||||
|
|
||||||
Hence the need to remap the vimtex default shortcuts starting with `c`, `t`, `s`
|
|
||||||
or `r`.
|
|
||||||
Fortunately, it's only the case for `c` and `t`. I first just add the remapping
|
|
||||||
to `$NVIMDIR/after/ftplugin/tex.lua`, however I soon noticed that it's not
|
|
||||||
sufficient as vimtex is also used for `.tikz`, `.cls` and `.bib` files,[^2] thus we
|
|
||||||
will use
|
|
||||||
[autocommand](https://neovim.io/doc/user/lua-guide.html#lua-guide-autocommands)
|
|
||||||
for that:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
-- Some BÉPO mappings for vimtex
|
|
||||||
vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
|
|
||||||
pattern = {"*.tex", "*.bib", "*.cls", "*.tikz",},
|
|
||||||
group = vim.api.nvim_create_augroup("latex", { clear = true }),
|
|
||||||
callback = function()
|
|
||||||
local vimtex_remaps = {
|
|
||||||
-- c <-> t
|
|
||||||
{ mode = "n", source = "csd", target = "tsd", command = "<Plug>(vimtex-delim-change-math)"},
|
|
||||||
{ mode = "n", source = "csc", target = "lsc", command = "<Plug>(vimtex-cmd-change)"},
|
|
||||||
{ mode = "n", source = "cse", target = "lse", command = "<Plug>(vimtex-env-change)"},
|
|
||||||
{ mode = "n", source = "cs$", target = "ls$", command = "<Plug>(vimtex-env-change-math))"},
|
|
||||||
-- t <-> j
|
|
||||||
{ mode = {"x", "n"}, source = "tsD", target = "jsD", command = "<Plug>(vimtex-delim-toggle-modifier-reverse)"},
|
|
||||||
{ mode = {"x", "n"}, source = "tsd", target = "jsd", command = "<Plug>(vimtex-delim-toggle-modifier)"},
|
|
||||||
{ mode = {"x", "n"}, source = "tsf", target = "jsf", command = "<Plug>(vimtex-cmd-toggle-frac)"},
|
|
||||||
{ mode = "n", source = "tsc", target = "jsc", command = "<Plug>(vimtex-cmd-toggle-star)"},
|
|
||||||
{ mode = "n", source = "ts$", target = "js$", command = "<Plug>(vimtex-env-toggle-math)"},
|
|
||||||
{ mode = "n", source = "tse", target = "jse", command = "<Plug>(vimtex-env-toggle-star)"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _,remap in pairs(vimtex_remaps) do
|
|
||||||
if vim.fn.maparg(remap.source) ~= "" then
|
|
||||||
vim.keymap.del(remap.mode, remap.source, { buffer = true })
|
|
||||||
vim.keymap.set(remap.mode, remap.target, remap.command, { silent = true, noremap = true, buffer = true})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The sanity check with
|
|
||||||
[`maparg(·)`](https://vimhelp.org/builtin.txt.html#maparg%28%29) is done to
|
|
||||||
avoid unmapping a mapping that already doesn't exist, which will raise an error
|
|
||||||
(as I have the (bad?) habit to type `:e` to reload the current file when
|
|
||||||
thinking, that what triggered this behaviour in my case).
|
|
||||||
|
|
||||||
**Remark.** Please also note that it is not fully remapped yet, for instance in the table of
|
|
||||||
content navigation there are still collisions, as `t` for instance toggles
|
|
||||||
showing TODOs or `s` toggles the section numbering.
|
|
||||||
|
|
||||||
To finish and for the sake of completeness, here follows the bépo-bindings for
|
|
||||||
zathura, to put in your `zathurarc` file:
|
|
||||||
|
|
||||||
```text
|
|
||||||
## BEPO
|
|
||||||
# hjkl → ctsr
|
|
||||||
map t scroll down
|
|
||||||
map s scroll up
|
|
||||||
map c scroll left
|
|
||||||
map r scroll right
|
|
||||||
|
|
||||||
# JK → TS
|
|
||||||
map T navigate next
|
|
||||||
map S navigate previous
|
|
||||||
|
|
||||||
# r → p
|
|
||||||
map p rotate rotate-cw
|
|
||||||
|
|
||||||
# R → u
|
|
||||||
map u reload
|
|
||||||
|
|
||||||
# Mode Index
|
|
||||||
map [index] t navigate_index down
|
|
||||||
map [index] s navigate_index up
|
|
||||||
map [index] r navigate_index expand
|
|
||||||
map [index] c navigate_index collapse
|
|
||||||
|
|
||||||
map [index] R navigate_index expand-all
|
|
||||||
map [index] C navigate_index collapse-all
|
|
||||||
```
|
|
||||||
|
|
||||||
[^2]: Actually `.cls` and `.tikz` are detected as tex files, so the `ftplugin`
|
|
||||||
approach works but `.bib` is detected as a bibtex file and enjoys its own
|
|
||||||
filetype.
|
|
@ -1,7 +1,6 @@
|
|||||||
---
|
---
|
||||||
Title: Use termtosvg to screencast your terminal
|
Title: Use termtosvg to screencast your terminal
|
||||||
Date: 2019-04-24 17:01+5:30
|
Date: 2019-04-24 17:01+5:30
|
||||||
Modified: 2023-07-10 12:00
|
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: software
|
Category: software
|
||||||
Tags: termtosvg
|
Tags: termtosvg
|
||||||
@ -16,7 +15,7 @@ Therefore, it is common to just paste those term information when it comes to sh
|
|||||||
|
|
||||||
However, once the Pandora box of terminals is opened, yet another world reveals itself: [ncurse](https://www.gnu.org/software/ncurses/).
|
However, once the Pandora box of terminals is opened, yet another world reveals itself: [ncurse](https://www.gnu.org/software/ncurses/).
|
||||||
It is common to represent static elements with it using a screenshot, however as I already complained about it in [another post]({filename}/tips/latex-adblock.md).
|
It is common to represent static elements with it using a screenshot, however as I already complained about it in [another post]({filename}/tips/latex-adblock.md).
|
||||||
It is not a fully satisfactory solution as we also loose all the text information, and it is thus impossible to copy a part of the screen content without typing it again (or [OCR](https://en.wikipedia.org/wiki/Optical_character_recognition)ise the screenshot?).
|
It is not a fully satisfactory solution as we also loose all the text information, and it is thus impossible to copy a part of the screen content without typing it again (or [OCR](https://www.gnu.org/software/ncurses/)ise the screenshot?).
|
||||||
|
|
||||||
[Nicolas Bedos](https://github.com/nbedos) comes with a solution for this named [termtosvg](https://nbedos.github.io/termtosvg/).
|
[Nicolas Bedos](https://github.com/nbedos) comes with a solution for this named [termtosvg](https://nbedos.github.io/termtosvg/).
|
||||||
This small python program is available on `pip` as well as [github](https://nbedos.github.io/termtosvg/).
|
This small python program is available on `pip` as well as [github](https://nbedos.github.io/termtosvg/).
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
Title: Écrire son courriel en markdown avec vim
|
Title: Écrire son courriel en markdown avec vim
|
||||||
Date: 2019-04-22 19:00
|
Date: 2019-04-22 19:00
|
||||||
Modified: 2023-10-14 19:00
|
Modified: 2019-04-24 09:35
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: astuces
|
Category: astuces
|
||||||
Tags: emails, pandoc, Vim
|
Tags: emails, pandoc, Vim
|
||||||
@ -24,11 +24,7 @@ pandoc -t html5 -s <fichier> | xclip -selection clipboard
|
|||||||
|
|
||||||
Ainsi, en ajoutant ce raccourci dans votre fichier de configuration pour les markdown dans vim (pour ma part il est dans `ftplugin/pandoc.vim`):
|
Ainsi, en ajoutant ce raccourci dans votre fichier de configuration pour les markdown dans vim (pour ma part il est dans `ftplugin/pandoc.vim`):
|
||||||
```vim
|
```vim
|
||||||
map <raccourci> :w !pandoc -t html5 -s \| xclip -selection clipboard<cr>
|
map <raccourcis> :w !pandoc -t html5 -s \| xclip -selection clipboard<cr>
|
||||||
```
|
|
||||||
ou en version plus moderne (lua + wayland):
|
|
||||||
```lua
|
|
||||||
vim.keymap.set('n', <raccourci>, ':w !pandoc -t html5 -s | wl-copy<CR><CR>', { noremap = true, silent = true })
|
|
||||||
```
|
```
|
||||||
on peut alors directement coller le contenu du *buffer* courant formatée par [pandoc](https://pandoc.org/) dans thunderbird.
|
on peut alors directement coller le contenu du *buffer* courant formatée par [pandoc](https://pandoc.org/) dans thunderbird.
|
||||||
Bien entendu, vous pouvez décorer cette commande à l’aide de vos options favorites.
|
Bien entendu, vous pouvez décorer cette commande à l’aide de vos options favorites.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
Title: Write your emails in markdown with vim
|
Title: Write your emails in markdown with vim
|
||||||
Date: 2019-04-22 19:00
|
Date: 2019-04-22 19:00
|
||||||
Modified: 2023-10-14 19:00
|
Modified: 2019-04-24 09:35
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: tips
|
Category: tips
|
||||||
Tags: emails, pandoc, Vim
|
Tags: emails, pandoc, Vim
|
||||||
@ -26,10 +26,6 @@ Therefore, adding:
|
|||||||
```vim
|
```vim
|
||||||
map <your map> :w !pandoc -t html5 -s \| xclip -selection clipboard<cr>
|
map <your map> :w !pandoc -t html5 -s \| xclip -selection clipboard<cr>
|
||||||
```
|
```
|
||||||
or a more modern version using `lua` and `wayland`:
|
|
||||||
```lua
|
|
||||||
vim.keymap.set('n', <your map>, ':w !pandoc -t html5 -s | wl-copy<CR><CR>', { noremap = true, silent = true })
|
|
||||||
```
|
|
||||||
in your vim `ftplugin/pandoc.vim` configuration file allows you to copy directly the output of [pandoc](https://pandoc.org/) on you opened buffer into your clipboard and thus past it directly into thunderbird.
|
in your vim `ftplugin/pandoc.vim` configuration file allows you to copy directly the output of [pandoc](https://pandoc.org/) on you opened buffer into your clipboard and thus past it directly into thunderbird.
|
||||||
Of course, you can customize this command line as you want. For instance my base-header-level is 4, as I think that first-level titles are a bit too much for emails.
|
Of course, you can customize this command line as you want. For instance my base-header-level is 4, as I think that first-level titles are a bit too much for emails.
|
||||||
You can even use some simple [css rules](https://perfectmotherfuckingwebsite.com/) in a separated style sheet along with the `--self-contained` option of pandoc to be able to do basic general formating (for a newsletter for instance).
|
You can even use some simple [css rules](https://perfectmotherfuckingwebsite.com/) in a separated style sheet along with the `--self-contained` option of pandoc to be able to do basic general formating (for a newsletter for instance).
|
||||||
|
@ -45,16 +45,10 @@ Tessen interprète ensuite la réponse de ces outils pour les intégrer avec
|
|||||||
Après avoir essayé _fuzzel_, je me suis rendu compte que leur algorithme de
|
Après avoir essayé _fuzzel_, je me suis rendu compte que leur algorithme de
|
||||||
recherche approximative ne me convenait pas, n'étant pas
|
recherche approximative ne me convenait pas, n'étant pas
|
||||||
[fzf](https://github.com/junegunn/fzf) qui est intégré dans pas mal de mes
|
[fzf](https://github.com/junegunn/fzf) qui est intégré dans pas mal de mes
|
||||||
programmes et dont j'ai pris mes habitudes quant à la recherche (par exemple
|
programmes et dont j'ai pris mes habitudes quant à la recherche.
|
||||||
pour la complétion dans mon `shell`), ainsi que certains raccourcis assez
|
|
||||||
universels comme `Ctrl-u` pour effacer la ligne en cours.
|
|
||||||
|
|
||||||
J'ai donc décidé d'utiliser `rofi` qui avait l'air de bien fonctionner bien
|
J'ai donc décidé d'utiliser `rofi` qui avait l'air de bien fonctionner… mis à
|
||||||
qu'il ne se lance via `xwayland` qui n'est pas considéré comme assez pur par
|
part les raccourcis claviers. Mais un aperçu de la page de manuel indique que cela est possible:
|
||||||
certaines personnes.
|
|
||||||
Sauf que les raccourcis claviers spécifiques à `rofi-pass` ne fonctionnent pas
|
|
||||||
par défaut.
|
|
||||||
Cependant un aperçu de la page de manuel indique que cela est possible:
|
|
||||||
|
|
||||||
> If the dmenu program of your choice supports custom keybindings with exit
|
> If the dmenu program of your choice supports custom keybindings with exit
|
||||||
> codes greater than or equal to 10, tessen can execute custom operations on a
|
> codes greater than or equal to 10, tessen can execute custom operations on a
|
||||||
@ -71,7 +65,7 @@ tombe bien, dans la configuration de rofi, il y a les options
|
|||||||
[`kb-custom-<n>`](https://github.com/davatorium/rofi/blob/next/doc/rofi-keys.5.markdown#kb-custom-1)
|
[`kb-custom-<n>`](https://github.com/davatorium/rofi/blob/next/doc/rofi-keys.5.markdown#kb-custom-1)
|
||||||
qui permettent d’associer la touche ou combinaison de touches à un code d’erreur
|
qui permettent d’associer la touche ou combinaison de touches à un code d’erreur
|
||||||
valant “_9+n_”, `kb-custom-1` correspondant donc à 10 et `kb-custom-9`
|
valant “_9+n_”, `kb-custom-1` correspondant donc à 10 et `kb-custom-9`
|
||||||
correspondant à 20. Je précise parce qu'au début j'avais associé un raccourcis à
|
correspondant à 20 (je précise parce qu'au début j'avais associé un raccourcis à
|
||||||
`kb-custom-10` en me disant que ça serait associé au code de sortie 10, et donc
|
`kb-custom-10` en me disant que ça serait associé au code de sortie 10, et donc
|
||||||
interprété par tessen comme `auto type username and password ` d'après le
|
interprété par tessen comme `auto type username and password ` d'après le
|
||||||
manuel… or il n'en était rien. Heureusement que je suis tombé sur un [message sur
|
manuel… or il n'en était rien. Heureusement que je suis tombé sur un [message sur
|
||||||
@ -99,9 +93,7 @@ J'ai d'abord essayé de le rajouter dans la configuration par défaut
|
|||||||
avec [rofimoji](https://github.com/fdw/rofimoji) qui ne s'est pas gêné pour me
|
avec [rofimoji](https://github.com/fdw/rofimoji) qui ne s'est pas gêné pour me
|
||||||
le dire.
|
le dire.
|
||||||
|
|
||||||
Maintenant il ne reste plus qu'à l'intégrer à tessen, ce qui est possible à
|
Maintenant il ne reste plus qu'à l'intégrer à tessen, ce qui est possible à l'aide du fichier de configuration `$HOME/.config/tessen/config` à l'aide des lignes :
|
||||||
l'aide du fichier de configuration `$HOME/.config/tessen/config` à l'aide des
|
|
||||||
lignes :
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
dmenu_backend="rofi"
|
dmenu_backend="rofi"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
Title: Rofi's keyboard shortcut for passwordstore on Wayland
|
Title: Rofi's keyboard shortcut for passwordstore on Wayland
|
||||||
Date: 2023-07-10 12:00
|
Date: 2023-07-09 15:00
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: Tips
|
Category: Tips
|
||||||
Tags: pass, rofi, tessen
|
Tags: pass, rofi, tessen
|
||||||
|
Loading…
Reference in New Issue
Block a user