### Install pynvim from source into a virtual environment (Windows) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim from source into a manually created virtual environment on Windows. ```bash pynvim-venv\Scripts\python -m pip install --upgrade . ``` -------------------------------- ### Install pynvim into a virtual environment (Windows) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim into a manually created virtual environment on Windows. ```bash pynvim-venv\Scripts\python -m pip install --upgrade pynvim ``` -------------------------------- ### Install pynvim from source using uv Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim from source using uv. The --upgrade switch ensures the latest version. ```bash uv tool install --upgrade . ``` -------------------------------- ### Install pynvim into a virtual environment (Unix) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim into a manually created virtual environment on Unix-like systems. ```bash pynvim-venv/bin/python -m pip install –upgrade pynvim ``` -------------------------------- ### Install pynvim from source into a virtual environment (Unix) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim from source into a manually created virtual environment on Unix-like systems. ```bash pynvim-venv/bin/python -m pip install --upgrade . ``` -------------------------------- ### Install pynvim for development Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Install the package in editable mode to apply local code changes. ```bash pip3 install . ``` -------------------------------- ### Development: Install local virtualenv Source: https://github.com/neovim/pynvim/blob/master/README.md Steps to set up and activate a local virtual environment for development. ```bash python3 -m virtualenv venv source venv/bin/activate ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/neovim/pynvim/blob/master/README.md Installs the development dependencies for the project, including tools like bump-my-version. ```bash pip install .[dev] ``` -------------------------------- ### Install pynvim from source using pipx Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Install pynvim from source using pipx. The --upgrade switch ensures the latest version. ```bash pipx install --upgrade . ``` -------------------------------- ### Deprecated installation method Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Installing pynvim into the per-user Python site package area is deprecated and may fail with errors like 'externally-managed-environment'. Always install into a virtual environment. ```bash pip install --user pynvim ``` -------------------------------- ### Install pynvim using uv Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Use uv for automatic detection by Neovim. Ensure the pynvim-python executable is on your PATH. The --upgrade switch installs the latest version. ```bash uv tool install --upgrade pynvim ``` -------------------------------- ### Install pynvim using pipx Source: https://github.com/neovim/pynvim/blob/master/README.md Install pynvim using pipx. Re-run the upgrade command to update pynvim when Neovim is upgraded. ```bash pipx install pynvim ``` ```bash pipx upgrade pynvim ``` -------------------------------- ### Interact with Neovim Buffer and Windows Source: https://github.com/neovim/pynvim/blob/master/README.md Demonstrates how to get the current buffer, modify its lines, split the window, and set window width. Also shows how to set and retrieve global variables. ```python >>> buffer = nvim.current.buffer >>> buffer[0] = 'replace first line' >>> buffer[:] = ['replace whole buffer'] >>> nvim.command('vsplit') >>> nvim.windows[1].width = 10 >>> nvim.vars['global_var'] = [1, 2, 3] >>> nvim.eval('g:global_var') [1, 2, 3] ``` -------------------------------- ### Install pynvim using pipx Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Use pipx for automatic detection by Neovim. Ensure the pynvim-python executable is on your PATH. The --upgrade switch installs the latest version. ```bash pipx install --upgrade pynvim ``` -------------------------------- ### Start Nvim with socket listener Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Launch Nvim with a specific socket address for external connections. ```bash nvim --listen /tmp/nvim.sock ``` -------------------------------- ### Run Nvim with local pynvim Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Use PYTHONPATH to point Nvim to a local pynvim installation. ```bash PYTHONPATH=/path/to/pynvim nvim ``` -------------------------------- ### Embed Nvim in Python application Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Start an Nvim instance as a child process directly from Python. ```python >>> from pynvim import attach >>> nvim = attach('child', argv=["/bin/env", "nvim", "--embed", "--headless"]) ``` -------------------------------- ### Python Plugin API Example: Modifying Vim Variables Source: https://github.com/neovim/pynvim/blob/master/README.md Demonstrates the correct way to modify a Vim dictionary variable from Python. Direct modification of dictionary fields does not work; the entire dictionary must be reassigned. ```python vim.vars['my_dict']['field1'] = 'value' # Does not work my_dict = vim.vars['my_dict'] # my_dict['field1'] = 'value' # Instead do vim.vars['my_dict'] = my_dict # ``` -------------------------------- ### Attach UI for Custom Frontends Source: https://context7.com/neovim/pynvim/llms.txt Initialize a remote UI connection to Neovim. ```python import pynvim ``` -------------------------------- ### Inspect Loaded Plugins and Runtime Path Source: https://github.com/neovim/pynvim/blob/master/docs/usage/remote-plugins.md Use Neovim commands to verify that plugins are loaded and check the current runtime path configuration. ```vim :scriptnames 1: ~/path/to/your/plugin-git-repo/vimrc 2: /usr/share/nvim/runtime/filetype.vim ... 25: /usr/share/nvim/runtime/plugin/zipPlugin.vim 26: ~/path/to/your/plugin-git-repo/plugin/lucid.vim ``` ```vim :set runtimepath runtimepath=~/.config/nvim,/etc/xdg/nvim,~/.local/share/nvim/site,..., ,~/g/path/to/your/plugin-git-repo " Or alternatively :echo &rtp ``` -------------------------------- ### Run tests with custom Nvim binary Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Specify a custom Nvim executable for the test suite. ```bash NVIM_CHILD_ARGV='["/path/to/nvim", "--clean", "--embed", "--headless"]' pytest ``` -------------------------------- ### Run tests with visible Nvim instance Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Launch an Nvim instance in a terminal emulator to observe state during testing. ```bash export NVIM=/tmp/nvimtest xterm -e "nvim --listen $NVIM -u NONE" & python -m pytest ``` -------------------------------- ### Development: Run tests and linting with uvx Source: https://github.com/neovim/pynvim/blob/master/README.md Utilize uvx to run tests and linting without managing a virtual environment. Includes commands for pytest and flake8. ```bash uvx --with pynvim --with pytest --with pytest-timeout pytest ``` ```bash uvx --with pynvim --with flake8-import-order --with flake8-docstrings --with pep8-naming flake8 pynvim test ``` ```bash uvx --with pynvim --with msgpack-types mypy --show-error-codes pynvim test ``` -------------------------------- ### Configure python3_host_prog for older Neovim versions Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md For Neovim before v0.12.0, set the python3_host_prog variable in init.vim to point to pynvim-python. ```vim let g:python3_host_prog = 'pynvim-python' ``` -------------------------------- ### Copy pynvim-python executable to PATH (Windows) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Copy the pynvim-python executable to a directory on your PATH on Windows. ```batch REM Assuming `C:\apps` is on `PATH`: copy pynvim-venv\Scripts\pynvim-python.exe C:\apps\pynvim-python.exe ``` -------------------------------- ### Create a Python virtual environment Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Manually create a Python virtual environment using the venv module. ```bash python3 -m venv pynvim-venv ``` -------------------------------- ### Connect to Nvim via Python REPL Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Attach to a running Nvim instance using a socket connection. ```python >>> from pynvim import attach # Create a session attached to Nvim's address (`v:servername`). >>> nvim = attach('socket', path='/tmp/nvim.sock') # Now do some work. >>> buffer = nvim.current.buffer # Get the current buffer >>> buffer[0] = 'replace first line' >>> buffer[:] = ['replace whole buffer'] >>> nvim.command('vsplit') >>> nvim.windows[1].width = 10 >>> nvim.vars['global_var'] = [1, 2, 3] >>> nvim.eval('g:global_var') [1, 2, 3] ``` -------------------------------- ### Copy pynvim-python executable to PATH (Unix) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Copy the pynvim-python executable to a directory on your PATH on Unix-like systems. ```bash # Assuming `~/.local/bin` is on `PATH`: cp pynvim-venv/bin/pynvim-python ~/.local/bin/pynvim-python ``` -------------------------------- ### Clone pynvim repository Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Clone the pynvim repository from GitHub and navigate into the directory. ```bash git clone https://github.com/neovim/pynvim.git cd pynvim ``` -------------------------------- ### Connect to Neovim with pynvim.attach() Source: https://context7.com/neovim/pynvim/llms.txt Use attach() to connect to a running Neovim instance or spawn a new embedded process. Supports socket, TCP, stdio, and child process transports. Can be used as a context manager for automatic cleanup. ```python import pynvim # Connect to a running Neovim via Unix socket # First start Neovim with: nvim --listen /tmp/nvim.sock vim = pynvim.attach('socket', path='/tmp/nvim.sock') # Connect via TCP vim = pynvim.attach('tcp', address='127.0.0.1', port=7450) # Embed Neovim as a child process (headless mode) vim = pynvim.attach('child', argv=['/usr/bin/env', 'nvim', '--embed', '--headless']) # Use as context manager for automatic cleanup with pynvim.attach('socket', path='/tmp/nvim.sock') as nvim: print(nvim.funcs.getpid()) print(nvim.current.line) # Close the session when done vim.close() ``` -------------------------------- ### Enable logging for the plugin host Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Set environment variables to enable debug logging for the Python host. ```bash NVIM_PYTHON_LOG_FILE=logfile NVIM_PYTHON_LOG_LEVEL=DEBUG nvim ``` -------------------------------- ### Configure Local Plugin Development Source: https://github.com/neovim/pynvim/blob/master/docs/usage/remote-plugins.md Create a custom vimrc to append the current directory to the runtime path for local testing. ```console cat vimrc let &runtimepath.=','.escape(expand(':p:h'), '\,') ``` ```console nvim -u ./vimrc ``` -------------------------------- ### Execute pynvim tests Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Run the test suite using pytest. ```bash python -m pytest ``` -------------------------------- ### Manage Buffer Highlighting Source: https://context7.com/neovim/pynvim/llms.txt Programmatically add, clear, and batch update syntax highlights in Neovim buffers using highlight source IDs. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') buf = nvim.current.buffer buf[:] = ['line one', 'line two', 'line three'] # Allocate a highlight source ID for your plugin src_id = nvim.new_highlight_source() # Add individual highlights # add_highlight(hl_group, line, col_start, col_end, src_id) buf.add_highlight('Error', 0, 0, 4, src_id) # Highlight "line" on line 1 buf.add_highlight('String', 1, 5, -1, src_id) # Highlight from col 5 to end buf.add_highlight('Comment', 2, 0, -1, src_id) # Highlight entire line # Async highlight (fire and forget) buf.add_highlight('Warning', 0, 0, -1, src_id, async_=True) # Clear highlights buf.clear_highlight(src_id) # Clear all from src_id buf.clear_highlight(src_id, 0, 2) # Clear lines 0-2 only # Batch update highlights (efficient for many changes) highlights = [ ('Error', 0, 0, 4), # (group, line, col_start, col_end) ('String', 1), # Entire line ('Comment', 2, 0, 10), ] buf.update_highlights(src_id, highlights, clear=True, async_=False) # Update with partial clear (clear lines 0-5, then add new highlights) buf.update_highlights(src_id, highlights, clear_start=0, clear_end=5) ``` -------------------------------- ### Working with Tabpages in pynvim Source: https://context7.com/neovim/pynvim/llms.txt Tabpages are collections of windows. This snippet shows how to connect to Neovim, which is a prerequisite for interacting with tabpages. ```python import pynvim vim = pynvim.attach('socket', path='/tmp/nvim.sock') ``` -------------------------------- ### Develop Remote Plugins with Decorators Source: https://context7.com/neovim/pynvim/llms.txt Define Neovim plugins, commands, functions, and autocmds using pynvim decorators in the rplugin/python3/ directory. ```python import pynvim @pynvim.plugin class MyPlugin: def __init__(self, nvim): self.nvim = nvim @pynvim.function('MyAdd', sync=True) def add_numbers(self, args): """Define a Vimscript function :call MyAdd(1, 2)""" return args[0] + args[1] @pynvim.command('MyCommand', nargs='*', range='', bang=True) def my_command(self, args, range, bang): """Define a Vim command :MyCommand arg1 arg2""" self.nvim.current.line = f'Args: {args}, Range: {range}, Bang: {bang}' @pynvim.command('MyWrite', nargs=1, complete='file') def my_write(self, args): """Command with file completion""" filename = args[0] self.nvim.command(f'write {filename}') @pynvim.autocmd('BufEnter', pattern='*.py', eval='expand("")', sync=True) def on_buf_enter(self, filename): """Handle BufEnter events for Python files""" self.nvim.api.echo([[f'Entered: {filename}']], True, {}) @pynvim.autocmd('BufWritePre', pattern='*') def on_buf_write_pre(self): """Async autocmd handler (default)""" self.nvim.command('echom "Saving..."', async_=True) @pynvim.function('AsyncProcess', sync=False, allow_nested=True) def async_process(self, args): """Async function that can run during other handlers""" # Must use async_=True for Neovim calls self.nvim.command('echom "Processing..."', async_=True) @pynvim.shutdown_hook def on_shutdown(self): """Called when the plugin host shuts down""" pass ``` -------------------------------- ### Development: Reinstall pynvim Source: https://github.com/neovim/pynvim/blob/master/README.md Reinstall pynvim after code changes for modifications to take effect. ```bash pip install . ``` -------------------------------- ### Attach and Manage Neovim UI Source: https://context7.com/neovim/pynvim/llms.txt Connect to a child Neovim process, attach as a UI, and handle redraw notifications. ```python nvim = pynvim.attach('child', argv=['nvim', '--embed']) # Attach as a UI nvim.ui_attach(80, 24, rgb=True) # Handle redraw notifications def on_notification(name, args): if name == 'redraw': for update in args: event_name = update[0] event_args = update[1:] handle_redraw_event(event_name, event_args) def on_request(name, args): return None def handle_redraw_event(name, args): print(f"Redraw event: {name}") # Run the event loop nvim.run_loop(on_request, on_notification) # Resize UI nvim.ui_try_resize(120, 40) # Detach UI nvim.ui_detach() ``` -------------------------------- ### Define and invoke Lua code Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Use vim.exec_lua to define Lua modules and vim.lua to access them from Python. ```python vim.exec_lua(""" local a = vim.api local function add(a,b) return a+b end local function buffer_ticks() local ticks = {} for _, buf in ipairs(a.nvim_list_bufs()) do ticks[#ticks+1] = a.nvim_buf_get_changedtick(buf) end return ticks end _testplugin = {add=add, buffer_ticks=buffer_ticks} """) ``` ```python mod = vim.lua._testplugin mod.add(2,3) # => 5 mod.buffer_ticks() # => list of ticks ``` -------------------------------- ### Embed Neovim in a Python Application Source: https://github.com/neovim/pynvim/blob/master/README.md Shows how to attach to a Neovim instance as a child process, useful for embedding Neovim within a Python application. The `--headless` argument prevents Neovim from waiting for a UI. ```python >>> import pynvim >>> nvim = pynvim.attach('child', argv=["/usr/bin/env", "nvim", "--embed", "--headless"]) ``` -------------------------------- ### Execute Vim Commands Source: https://context7.com/neovim/pynvim/llms.txt Run Ex commands, evaluate Vimscript expressions, and manage global variables and options. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Execute Ex commands nvim.command('echo "Hello"') nvim.command('set number') nvim.command('normal gg') nvim.command('w /tmp/file.txt') # Get command output output = nvim.command_output('echo "test"') print(output) # "test" # Evaluate Vimscript expressions result = nvim.eval('2 + 2') # Returns 4 cwd = nvim.eval('getcwd()') exists = nvim.eval('exists("g:myvar")') # Global variables nvim.vars['python'] = [1, 2, {'key': 'value'}] print(nvim.vars['python']) # [1, 2, {'key': 'value'}] del nvim.vars['python'] # Delete variable # Vim special variables (read-only) print(nvim.vvars['version']) # Vim version # Global options nvim.options['background'] = 'light' print(nvim.options['background']) # Change directory nvim.chdir('/tmp') # Get string display width width = nvim.strwidth('hello') # Returns 5 # Feed keys to Neovim nvim.feedkeys('ihello') nvim.input('itext') # Replace terminal codes esc = nvim.replace_termcodes('') cr = nvim.replace_termcodes('') nvim.feedkeys(esc) ``` -------------------------------- ### Run linters and tests via tox Source: https://github.com/neovim/pynvim/blob/master/docs/development.md Use tox to execute tests and linters across multiple Python environments. ```bash tox run # run on all available python environments tox run -e py311,checkqa # run on python3.11, and linters tox run –parallell # run everything in parallel ``` -------------------------------- ### Nvim API Methods (vim.api) Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Exposes Neovim API methods directly. The 'nvim_' prefix is omitted when calling methods via the vim.api namespace. ```APIDOC ## vim.api ### Description Exposes Neovim API methods. The initial 'nvim_' prefix is omitted. Object-specific methods can be called directly on the object (e.g., buf.api.line_count()). ### Parameters - **async_** (bool) - Optional - If True, sends a msgpack notification instead of a request, making the return value unavailable. ### Request Example ```python # Call nvim_strwidth result = vim.api.strwidth("some text") # Call nvim_buf_line_count buf = vim.current.buffer length = buf.api.line_count() ``` ``` -------------------------------- ### Working with Windows in pynvim Source: https://context7.com/neovim/pynvim/llms.txt Windows represent viewports into buffers. Access window properties like buffer, cursor position, dimensions, and tabpage. You can also switch the current window and manage window-local options. ```python import pynvim vim = pynvim.attach('socket', path='/tmp/nvim.sock') # Get current window window = nvim.current.window # Get all windows windows = nvim.windows print(len(windows)) # Number of windows # Access windows by index first_window = nvim.windows[0] # Window properties print(window.buffer) # Buffer displayed in window print(window.cursor) # (row, col) cursor position window.cursor = (5, 10) # Set cursor to row 5, col 10 print(window.height) # Window height in rows window.height = 20 # Set height print(window.width) # Window width in columns window.width = 80 # Set width print(window.row) # Window position (row) print(window.col) # Window position (col) print(window.tabpage) # Tabpage containing window print(window.number) # Window number print(window.valid) # True if window exists # Switch current window vim.current.window = nvim.windows[1] # Window-local options window.options['foldmethod'] = 'syntax' print(window.options['foldmethod']) # Create and manage windows vim.command('vsplit') # Vertical split vim.command('split') # Horizontal split vim.command('new') # New window with empty buffer ``` -------------------------------- ### Use Neovim API Source: https://context7.com/neovim/pynvim/llms.txt Interact with native Neovim API methods directly via the api namespace or low-level request method. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Call API methods (nvim_* functions without the prefix) width = nvim.api.strwidth('text') # nvim_strwidth nvim.api.command('echo "hi"') # nvim_command result = nvim.api.eval('2+2') # nvim_eval # Display messages nvim.api.echo([['Hello ', 'Normal'], ['World', 'ErrorMsg']], True, {}) # Buffer API methods via buffer.api buf = nvim.current.buffer line_count = buf.api.line_count() # nvim_buf_line_count buf.api.set_lines(0, -1, True, ['new', 'content']) lines = buf.api.get_lines(0, -1, True) buf.api.set_var('myvar', 'value') # b:myvar value = buf.api.get_var('myvar') # Window API methods via window.api win = nvim.current.window win.api.set_cursor([1, 0]) # nvim_win_set_cursor pos = win.api.get_cursor() # Low-level request method result = nvim.request('nvim_strwidth', 'text') nvim.request('nvim_buf_set_lines', buf, 0, -1, True, ['line1']) # Async API calls (notifications) nvim.api.command('echo "async"', async_=True) nvim.request('nvim_command', 'redraw', async_=True) ``` -------------------------------- ### Lua Integration (vim.lua) Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Allows Python plugins to define and invoke Lua code within Neovim's in-process Lua interpreter. ```APIDOC ## vim.exec_lua / vim.lua ### Description Defines and invokes Lua code. Use vim.exec_lua to define modules or functions, and access them via the vim.lua namespace. ### Parameters - **code** (string) - Required - The Lua code to execute. - **args** (list) - Optional - Arguments passed to the Lua code block, available as '...' in Lua. - **async_** (bool) - Optional - If True, executes asynchronously. ### Request Example ```python # Define a module vim.exec_lua(""" _testplugin = {add = function(a,b) return a+b end} """) # Access the module mod = vim.lua._testplugin mod.add(2, 3) # Returns 5 ``` ``` -------------------------------- ### Configure Neovim to use a specific Python interpreter (Unix) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Configure Neovim to use a specific Python interpreter from a virtual environment on Unix-like systems by setting g:python3_host_prog. ```vim let g:python3_host_prog = '/path/to/pynvim-venv/bin/python' ``` -------------------------------- ### Manage Neovim Tabpages Source: https://context7.com/neovim/pynvim/llms.txt Access and manipulate tabpages, windows, and their properties within a Neovim instance. ```python # Get current tabpage tabpage = nvim.current.tabpage # Get all tabpages tabpages = nvim.tabpages print(len(tabpages)) # Number of tabpages # Tabpage properties print(tabpage.window) # Current window in tabpage print(tabpage.windows) # List of windows in tabpage print(tabpage.number) # Tabpage number print(tabpage.valid) # True if tabpage exists # Switch tabpages nvim.command('tabnew') # Create new tabpage nvim.current.tabpage = nvim.tabpages[0] # Switch to first tabpage # Iterate over tabpages for tp in nvim.tabpages: print(f"Tabpage {tp.number} has {len(tp.windows)} windows") ``` -------------------------------- ### Usage: Attach Python REPL to Nvim socket Source: https://github.com/neovim/pynvim/blob/master/README.md Connect a Python REPL to a running Neovim instance via its socket address using the pynvim library. ```python import pynvim # Create a session attached to Nvim's address (`v:servername`). vim = pynvim.attach('socket', path='/tmp/nvim.sock') ``` -------------------------------- ### Asynchronous Execution (vim.async_call) Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Schedules code to be executed on the main thread from a spawned thread. ```APIDOC ## vim.async_call ### Description Allows a spawned thread to schedule code to be executed on the main thread. Useful for deferring execution that should not block Neovim. ### Parameters - **func** (callable) - Required - The function to execute. - **args** (list) - Optional - Arguments to pass to the function. ### Request Example ```python # Schedule a function call vim.async_call(myfunc, args...) ``` ``` -------------------------------- ### Integrate Lua with Neovim Source: https://context7.com/neovim/pynvim/llms.txt Execute Lua code and define Lua modules within Neovim from Python. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Execute Lua code with arguments result = nvim.exec_lua('return 2 + 2') # Returns 4 # Pass arguments to Lua (available as ...) result = nvim.exec_lua('local x, y = ...; return x + y', 10, 20) print(result) # 30 # Define a Lua module nvim.exec_lua(""" local a = vim.api local function add(x, y) return x + y end local function set_buffer_lines(buf, lines) a.nvim_buf_set_lines(buf, 0, -1, true, lines) end local function get_buffer_count(buf) return a.nvim_buf_line_count(buf) end _myplugin = { add = add, set_buffer_lines = set_buffer_lines, get_buffer_count = get_buffer_count } """) ``` -------------------------------- ### Configure Neovim to use a specific Python interpreter (Windows) Source: https://github.com/neovim/pynvim/blob/master/docs/installation.md Configure Neovim to use a specific Python interpreter from a virtual environment on Windows by setting g:python3_host_prog. ```vim let g:python3_host_prog = 'c:\path\to\pynvim-venv\bin\python.exe' ``` -------------------------------- ### Invoke msgpack requests directly Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Use vim.request to call API methods by their full name as a string. ```python result = vim.request("nvim_strwidth", "some text") length = vim.request("nvim_buf_line_count", buf) ``` -------------------------------- ### Interact with Lua via nvim.lua Source: https://context7.com/neovim/pynvim/llms.txt Execute Lua functions and pass Neovim objects to Lua from Python. ```python mod = nvim.lua._myplugin result = mod.add(5, 3) # Returns 8 # Pass Neovim objects to Lua functions buf = nvim.current.buffer mod.set_buffer_lines(buf, ['line1', 'line2', 'line3'], async_=True) count = mod.get_buffer_count(buf) # Call global Lua functions nvim.exec_lua("function global_func(x) return x * 2 end") result = nvim.lua.global_func(21) # Returns 42 # Async Lua calls nvim.lua._myplugin.set_buffer_lines(buf, ['async'], async_=True) ``` -------------------------------- ### Call Neovim API methods Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Use vim.api to invoke Neovim API methods. The 'nvim_' prefix is omitted from method names. ```python result = vim.api.strwidth("some text") ``` ```python buf = vim.current.buffer length = buf.api.line_count() ``` -------------------------------- ### Schedule asynchronous execution Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Use vim.async_call to schedule code execution on the main thread from a spawned thread. ```vim :python vim.async_call(myfunc, args...) ``` -------------------------------- ### Define a Remote Plugin in Python Source: https://github.com/neovim/pynvim/blob/master/docs/usage/remote-plugins.md Use the @pynvim.plugin decorator to define a class-based plugin. Handlers can be registered for functions, commands, and autocommands. ```python import pynvim @pynvim.plugin class TestPlugin(object): def __init__(self, nvim): self.nvim = nvim @pynvim.function('TestFunction', sync=True) def testfunction(self, args): return 3 @pynvim.command('TestCommand', nargs='*', range='') def testcommand(self, args, range): self.nvim.current.line = ('Command with args: {}, range: {}' .format(args, range)) @pynvim.autocmd('BufEnter', pattern='*.py', eval='expand("")', sync=True) def on_bufenter(self, filename): self.nvim.api.echo([['testplugin is in ' + filename]], True, {}) ``` -------------------------------- ### Bump Version with bump-my-version (Patch) Source: https://github.com/neovim/pynvim/blob/master/README.md Increments the patch version of the project using bump-my-version. This updates version strings in pyproject.toml and pynvim/_version.py, creates a git commit, and tags the release. ```bash bump-my-version bump patch ``` -------------------------------- ### Run Event Loop and Message Handling Source: https://context7.com/neovim/pynvim/llms.txt Manage synchronous requests and asynchronous notifications using a message loop, with options for blocking or manual message processing. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Subscribe to Neovim events nvim.subscribe('my_custom_event') def handle_request(name, args): """Handle synchronous requests from Neovim""" if name == 'my_request': return process_request(args) return None def handle_notification(name, args): """Handle async notifications from Neovim""" if name == 'my_custom_event': handle_custom_event(args) elif name == 'nvim_buf_lines_event': handle_buffer_change(args) def error_handler(msg): """Handle errors during event processing""" print(f"Error: {msg}") # Run the event loop (blocks until stopped) nvim.run_loop( request_cb=handle_request, notification_cb=handle_notification, err_cb=error_handler ) # Or process messages one at a time while True: msg = nvim.next_message() if msg: process_message(msg) # Stop the event loop from another thread nvim.stop_loop() # Unsubscribe from events nvim.unsubscribe('my_custom_event') # Quit Neovim nvim.quit() # Sends 'qa!' by default nvim.quit('wqa') # Save and quit ``` -------------------------------- ### Bump Version with bump-my-version (Minor) Source: https://github.com/neovim/pynvim/blob/master/README.md Increments the minor version of the project using bump-my-version. This updates version strings in pyproject.toml and pynvim/_version.py, creates a git commit, and tags the release. ```bash bump-my-version bump minor ``` -------------------------------- ### Vimscript Functions (vim.funcs) Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Exposes Vimscript functions (builtin and user-defined) as a Python namespace. ```APIDOC ## vim.funcs ### Description Exposes Vimscript functions as a Python namespace. These functions can also accept the async_ keyword argument. ### Parameters - **async_** (bool) - Optional - If True, executes as a notification without waiting for a return value. ### Request Example ```python # Set the value of a register vim.funcs.setreg('0', ["some", "text"], 'l') ``` ``` -------------------------------- ### Push Git Changes and Tags Source: https://github.com/neovim/pynvim/blob/master/README.md Command to push local commits and tags to the remote repository, typically used after version bumping. ```bash git push --follow-tags ``` -------------------------------- ### Execute Vimscript functions Source: https://github.com/neovim/pynvim/blob/master/docs/usage/python-plugin-api.md Access builtin and user-defined Vimscript functions via the vim.funcs namespace. ```python vim.funcs.setreg('0', ["some", "text"], 'l') ``` -------------------------------- ### Bump Version with bump-my-version (Major) Source: https://github.com/neovim/pynvim/blob/master/README.md Increments the major version of the project using bump-my-version. This updates version strings in pyproject.toml and pynvim/_version.py, creates a git commit, and tags the release. ```bash bump-my-version bump major ``` -------------------------------- ### Call Vimscript Functions Source: https://context7.com/neovim/pynvim/llms.txt Access built-in and user-defined Vimscript functions through the funcs namespace. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Call built-in Vimscript functions result = nvim.funcs.join(['first', 'last'], ', ') print(result) # "first, last" nvim.funcs.setreg('0', ['some', 'text'], 'l') # Set register line_count = nvim.funcs.line('$') # Get last line number file_exists = nvim.funcs.filereadable('/tmp/file.txt') # Get buffer info bufname = nvim.funcs.bufname('%') bufnr = nvim.funcs.bufnr('%') # String manipulation upper = nvim.funcs.toupper('hello') # "HELLO" trimmed = nvim.funcs.trim(' text ') # List operations sorted_list = nvim.funcs.sort([3, 1, 2]) length = nvim.funcs.len([1, 2, 3]) # Async function calls (fire and forget) nvim.funcs.setline(1, 'async text', async_=True) ``` -------------------------------- ### Push to Master Branch Source: https://github.com/neovim/pynvim/blob/master/README.md Pushes the current branch to the remote 'master' repository. This is a step in the release process. ```bash git push ``` -------------------------------- ### Working with Buffers in pynvim Source: https://context7.com/neovim/pynvim/llms.txt Buffers represent file contents and support Python list-like indexing and slicing for reading and modifying lines. You can also access buffer properties, variables, options, marks, and ranges. ```python import pynvim vim = pynvim.attach('socket', path='/tmp/nvim.sock') # Get the current buffer buffer = nvim.current.buffer # Read buffer contents first_line = buffer[0] # Get first line all_lines = buffer[:] # Get all lines as list slice_lines = buffer[1:5] # Get lines 2-5 (0-indexed) last_line = buffer[-1] # Get last line # Modify buffer contents buffer[0] = 'New first line' # Replace first line buffer[:] = ['line1', 'line2'] # Replace entire buffer buffer[1:3] = ['a', 'b', 'c'] # Replace slice with new lines # Append lines buffer.append('new line') # Append at end buffer.append(['line1', 'line2'], 0) # Insert at beginning # Delete lines del buffer[0] # Delete first line del buffer[1:3] # Delete a range buffer[-1] = None # Delete last line # Buffer properties print(len(buffer)) # Number of lines print(buffer.name) # Buffer file name buffer.name = '/tmp/newname.txt' # Set buffer name print(buffer.number) # Buffer number print(buffer.valid) # True if buffer exists print(buffer.loaded) # True if buffer is loaded # Buffer-local variables buffer.vars['myvar'] = 'value' print(buffer.vars['myvar']) # Buffer-local options buffer.options['shiftwidth'] = 4 print(buffer.options['shiftwidth']) # Buffer marks vim.command('mark V') row, col = buffer.mark('V') # Returns (row, col) tuple # Buffer ranges range_obj = buffer.range(1, 10) # Lines 1-10 print(range_obj[:]) ``` -------------------------------- ### Perform Thread-Safe Async Operations Source: https://context7.com/neovim/pynvim/llms.txt Use async_call to schedule tasks on the main thread from background threads and utilize async_=True for fire-and-forget calls. ```python import pynvim import threading import time nvim = pynvim.attach('socket', path='/tmp/nvim.sock') def background_task(): """Long-running background operation""" time.sleep(2) result = "Background task completed" # Schedule callback on main thread nvim.async_call(update_buffer, result) def update_buffer(text): """Runs on main thread, can safely use nvim API""" nvim.current.buffer.append(text) nvim.command('redraw') # Start background thread thread = threading.Thread(target=background_task) thread.start() # Async keyword argument for fire-and-forget calls nvim.command('echo "Starting..."', async_=True) nvim.funcs.setline(1, 'Async write', async_=True) nvim.api.echo([['Message']], True, {}, async_=True) nvim.lua.some_func(arg, async_=True) # For plugins, defer execution to not block Neovim @pynvim.command('LongTask') def long_task(self): def do_work(): # Expensive computation here result = compute_something() self.nvim.async_call(self.show_result, result) thread = threading.Thread(target=do_work) thread.start() ``` -------------------------------- ### Access and Modify Vim Variables Source: https://context7.com/neovim/pynvim/llms.txt Interact with global, buffer, window, and tabpage variables. Note that nested dictionary modifications require re-assignment to take effect. ```python import pynvim nvim = pynvim.attach('socket', path='/tmp/nvim.sock') # Global variables (g:) nvim.vars['my_global'] = 'value' nvim.vars['my_list'] = [1, 2, 3] nvim.vars['my_dict'] = {'key': 'value'} print(nvim.vars['my_global']) print(nvim.vars.get('missing', 'default')) del nvim.vars['my_global'] # IMPORTANT: Dictionary modification caveat # This does NOT work due to Neovim limitations: nvim.vars['my_dict']['field'] = 'new' # No effect! # Instead, modify and reassign: my_dict = nvim.vars['my_dict'] my_dict['field'] = 'new_value' nvim.vars['my_dict'] = my_dict # Vim special variables (v:, read-only) print(nvim.vvars['version']) print(nvim.vvars['progname']) # Buffer-local variables (b:) buf = nvim.current.buffer buf.vars['buffer_var'] = [1, 2, 3] print(buf.vars['buffer_var']) # Window-local variables (w:) win = nvim.current.window win.vars['window_var'] = 'value' # Tabpage-local variables (t:) tab = nvim.current.tabpage tab.vars['tabpage_var'] = 'value' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.