Skip to main content

a remote control interpreter for neovim

Project description

lvim

luavim - a remote control interpreter for neovim

lvim is a remote control for nvim, heavily inspired by neovim-remote (nvr) by mhinz: https://github.com/mhinz/neovim-remote

Install

The quickest way to start using lvim is with the uv package manager:

# See uv README for other installation options
curl -LsSf https://astral.sh/uv/install.sh | sh

The uvx tool can be used to quickly run Python programs in anonymous virtual environments:

alias lvim='uvx --from lvim lvim'

With this alias, lvim can be used to start the REPL:

$ lvim
Neovim v0.11.1+ga9a3981669 running LuaJIT 2.1.1741730670 [Lua 5.1]
PID: 599332 Connection: Socket /tmp/nvim.aemiller/o6ze3D/nvim.599332.0

Info:  %help                   -- or :h lua-guide
Usage: print(vim.fn.getcwd())  -- /home/aemiller/repos/lvim

aemiller@nvim://|⇒

Usage

When run without arguments lvim will "attach" to the nvim instance and provide a read-eval-print-loop for working with it. This is somewhat similar to IPython, and is using the same library to implement the prompt itself: https://github.com/prompt-toolkit/python-prompt-toolkit

-- By default, execute lua code in the attached nvim instance
aemiller@nvim:~/|⇒ vim.fn.getcwd()
/home/aemiller

-- Run shell commands via nvim with !
aemiller@nvim:~/|⇒ ! ls
bin
README.md
repos

-- Change the nvim working directory via the %cwd "magic" function
aemiller@nvim:~/|⇒ %cwd repos/lvim
/home/aemiller/repos/lvim

-- Change the lvim current directory via the %cd "magic" function
aemiller@nvim:~/|⇒ %cd repos/lvim
/home/aemiller/repos/lvim

See the directories section below for more info on navigation.

-- Run vim ex commands with :
aemiller@nvim:~/repos/lvim| :edit README.md

Completion

Pressing <Tab> in the prompt will provide auto-completion for the relevant command type via nvim RPC. Otherwise it functions similarly to the cmdline provided in nvim, with changes to the environment persisting between lines.

Discovery

Discovery of nvim is based on the environment variable $NVIM, set in either the shell environment, or the tmux environment (when $TMUX is also set). Using the tmux environment allows for nvim in another window to manage the state of this variable for all windows:

local connection = vim.fn.serverlist()[1]
vim.system({ "tmux", "set-environment", "NVIM", connection })

By default, if an existing nvim instance cannot be found, lvim will start one in a background thread using a socket in the local tmpdir:

$ tmux set-environment -u NVIM ; unset $NVIM ; lvim
auto starting nvim with: /bin/env nvim --headless --listen '/tmp/lvim.aemiller/tmpu853ocxs/nvim.231284.0'
Neovim v0.11.1+ga9a3981669 running LuaJIT 2.1.1741730670 [Lua 5.1]
PID: 231309 Connection: Listen /tmp/lvim.aemiller/tmpu853ocxs/nvim.231284.0

Info:  %help                   -- or :h lua-guide
Usage: print(vim.fn.getcwd())  -- /home/aemiller

-- Functions as an otherwise normal nvim instance managed by lvim
aemiller@nvim:~/|⇒ :ls
  1 %a   "[No Name]"                    line 1
aemiller@nvim:~/|⇒ exit
auto stopping nvim

lvim must have an instance of nvim to run against. If the auto listen server does not work, the --embed option can be provided to use nvim's built in stdin/stdout based headless instance. Because this only allows for one RPC client, notifications via the broker are not enabled.

An explicit nvim server connection can be provided with the --server option.

Running lvim with --clean will start nvim with --clean, skipping user data and state.

Directories

Since nvim and lvim are separate processes, they have separate working directories:

# Start nvim
~/repos/lvim $ nvim
# Start lvim
~/ $ lvim
aemiller@nvim://| %cwd
"/home/aemiller/repos/lvim"
aemiller@nvim://| %cd
"/home/aemiller/repos/lvim"

lvim also has a "pinned" directory, which defaults to the current working dir of the attached nvim instance. This directory and all paths relative to it will be formattted with a "//" prefix:

aemiller@nvim://| %cd! src
"/home/aemiller/repos/lvim/src"
aemiller@nvim://src| %cd src

The pinned directory can be updated with %pin:

aemiller@nvim://src| %pin!
aemiller@nvim://| %pin ..
aemiller@nvim://src|

To disable pinning, run lvim with the --no-pin flag.

By default, lvim will change it's working directory to match the one set in the attached nvim instance, but this can be disabled with the --no-cd flag:

~/ $ lvim --no-cd
aemiller@nvim:~/!| %cwd
"/home/aemiller/repos/lvim"
aemiller@nvim:~/!| %cd
"/home/aemiller"

The prompt will always show the lvim current directory (cd). If this is not the same as the nvim cwd, an ! is appended to the end of the path:

aemiller@nvim:~/!| %cd repos/lvim
"/home/aemiller/repos/lvim"
aemiller@nvim://|

To change both dirs at the same time, use the bang form:

aemiller@nvim://| %cd! src
"/home/aemiller/repos/lvim/src"
aemiller@nvim://src|

With no args, this will sync the cd and cwd:

aemiller@nvim://| %cd src
"/home/aemiller/repos/lvim/src"
aemiller@nvim://src!| %cd!
aemiller@nvim://src|

Config

lvim uses a configuration file format largely based on the one provided by ptpython. An example configuration with some sane defaults can be found in the repo at example/config.py

This file is read from the config home directory, set with --config or the LVIM_CONFIG_HOME environment variable. See the help text for this option for the default location on this machine.

Python REPL

If lvim is started with the --py or --ipy flags, it will instead start an instance of ptpython or ptipython with the various components of lvim available as globals:

  • vim - Connected pynvim API client
  • _session - NvimSession backing the vim client
  • broker - NvimBroker handling RPC notifications
  • repl - PyREPL instance for the running interpreter

This is useful for debugging and working with nvim's Python SDK. The config file is loaded from pyconfig.py in the LVIM_CONFIG_HOME. An example configuration can be found at example/pyconfig.py

ptpython is required for this mode, and can be installed via the py optional dependency set for lvim. ptipython also requires the IPython package to be installed, which is in the optional dependency set ipy:

alias pylvim='uvx --from "lvim[py]" lvim --py'
alias ipylvim='uvx --from "lvim[ipy]" lvim --ipy'

Development

All development on lvim can be handled through the uv tool:

uv sync --dev --all-extras
Resolved 43 packages in 0.54ms
Audited 41 packages in 0.06ms

Invocations of uv will read configuration from the pyproject.toml file and configure a virtual environment with lvim and it's dependencies under .venv in the repository.

nvim

When testing it is useful to run a separate nvim instance without user config:

lvim --clean --listen auto

Type Checking

Ensure no type errors are present with pyre:

uv run pyre check
ƛ No type errors found

Note: Pyre daemonizes itself on first run for faster subsequent executions. Be sure to shut it down with uv run pyre stop when finished.

Formatting

Format code with the ruff formatter:

uv run ruff format
15 files left unchanged

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lvim-0.0.2.tar.gz (430.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lvim-0.0.2-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

Details for the file lvim-0.0.2.tar.gz.

File metadata

  • Download URL: lvim-0.0.2.tar.gz
  • Upload date:
  • Size: 430.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for lvim-0.0.2.tar.gz
Algorithm Hash digest
SHA256 dcdcc0a40cd975c89a840e17f51032c3573c9b3c3f982500fa3612d62f4a29b5
MD5 637404aa913f4edf0b946ef2d0255ed8
BLAKE2b-256 7d8b969637a4958fa7ea8f1cb81d777b3dff8fdb733b259e4174b856e81ed765

See more details on using hashes here.

File details

Details for the file lvim-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: lvim-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 34.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for lvim-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 297fba92f254f2dd9efce661c8370905b3f2d28a7581d814c27512e8731781b2
MD5 8750cb6551e95336f705e457e48d1721
BLAKE2b-256 4db30574a7589c67feced3a5d709b3ac4d219d9b09cee1a39279dc6dff5ad175

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page