惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
月光博客
月光博客
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
Stack Overflow Blog
Stack Overflow Blog
Engineering at Meta
Engineering at Meta
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
宝玉的分享
宝玉的分享
A
About on SuperTechFans
Vercel News
Vercel News
P
Proofpoint News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
Jina AI
Jina AI
Y
Y Combinator Blog
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
How to Use Python Inside Vim Script with Neovim
2019-04-22 · via jdhao's digital space

Introduction#

I have been using Vim-airline for a while to customize my statusline. We can change the theme used for statusline with the many themes available in vim-airline-themes. Not all these themes looks good since it depends on the background color you use for Neovim and certainly your aesthetics.

I only use a handful of themes myself and I change my themes when I feel bored with one theme. It occurs to me that I can write a simple script to randomly pick a theme from my favorite list1. It turns out writing such a script is not easy for Neovim newbies like me.

In this post, I would like to share how I end up achieving what I want by mixing Vim script and Python script.

Prerequisite#

This post is specifically targeted at Neovim users so that some of the settings may not apply if you use Vim.

First, you need to install Python and Python 3 is preferable since Python 2 support will stop in 2020. Make sure that you can call python from the command line. When you start Neovim and :echo has('python3') will print 1 in the command line.

You should also install pynvim, which is the Python client and plugin host for Neovim. You can install it with pip:

Finally, you should set the variable g:python3_host_prog to the location of Python executable. If your Python executable path is ~/anaconda3/bin/python, you should add the following setting in your init.vim:

let g:python3_host_prog=expand('~/anaconda3/bin/python')

After that, open Neovim and run :checkhealth provider and make sure there is no error in the part about Python 3. A sample output is shown below:

## Python 3 provider (optional)
  - INFO: Using: g:python3_host_prog = "D:/Anaconda/python"
  - INFO: Executable: D:\Anaconda\python
  - INFO: Python version: 3.6.5
  - INFO: pynvim version: 0.3.2
  - OK: Latest pynvim is installed.

Pick a random airline theme#

Generate a random number in the given range#

To pick a random theme from my favorite themes, I need to create a function which return a random index of the theme given the lowest and highest index. First, I will show my final function and then I will explain it bit by bit.

Click to see the function.
" generate a random integer from range [Low, High] using Python
function! RandInt(Low, High) abort
" if you use Python 3, the python block should start with `python3` instead of
" `python`, see https://github.com/neovim/neovim/issues/9927
python3 << EOF
import vim
import random

# using vim.eval to import variable outside Python script to python
idx = random.randint(int(vim.eval('a:Low')), int(vim.eval('a:High')))

# using vim.command to export variable inside Python script to vim script so
# we can return its value in vim script
vim.command("let index = {}".format(idx))
EOF

return index
endfunction

In the above function RandInt(), we define a function which accept two parameter Low and High. We generate a random integer between in the range $[Low, High]$ using the Python package random and return the index.

The format for Python script is as follows:

python[3] << MARKER
# python code here
MARKER

If you use Python 2, you should use python keyword, otherwise use python3, which is explained here. To manipulate Neovim inside Python script, we need to import package vim.

To get the value of Vim variable Low and High inside Python script, we need to import them. vim.eval()2 is used to get their value, which is used to evaluate the expression using built-in expression evaluator. According to documentation, the return value is:

  • a string if the Vim expression evaluates to a string or number

So we need to use int() to convert the return value to integer.

After we get the value of idx, how do we use it outside the Python script? We can use vim.command() to achieve that:

vim.command("let index = {}".format(idx))

vim.command(str) will execute str as Vim command, thus assigning the value of idx to Vim variable index.

Pick a airline theme#

Now we can define a list of themes to pick and generate a random index and set the airline theme using the theme at the index. An example code is shown below:

let s:candidate_airlinetheme = ['alduin', 'ayu_mirage', 'base16_flat',
    \ 'monochrome', 'base16_grayscale', 'lucius', 'base16_tomorrow',
    \ 'base16color', 'biogoo', 'distinguished', 'gruvbox', 'jellybeans',
    \ 'luna', 'raven', 'seagull', 'solarized_flood', 'term', 'vice', 'zenburn']

let s:idx = RandInt(0, len(s:candidate_airlinetheme)-1)
let s:theme = s:candidate_airlinetheme[s:idx]
let g:airline_theme=s:theme

In the above script, len() is used to get the length of a list.

Conclusion#

In this post, I introduced how to mix Python script with Vim script. Specifically, I write a simple function to generate a random index and then pick a airline theme based on the index. I have just scratched the surface of the powerful ability of Python programming inside Vim. For more information, see :h python.

References#