diff --git a/README.md b/README.md index a573a858..3976ed4c 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,35 @@ Install Supports python 3.7 or later. - pip3 install pynvim +- Installation option #1: install using uv (recommended): -You can install the package without being root by adding the `--user` flag. -Anytime you upgrade Neovim, make sure to upgrade pynvim as well: + - Install uv (https://docs.astral.sh/uv/). - pip3 install --upgrade pynvim + - Install pynvim (the `--upgrade` switch ensures installation of the latest + version): -Alternatively, you can install the development version by cloning this -repository and executing the following at the top level: + uv tool install --upgrade pynvim - pip3 install . + - Anytime you upgrade Neovim, make sure to upgrade pynvim as well by + re-running the above command. + +- Installation option #2: install using pipx: + + - Install pipx (https://pipx.pypa.io/stable/). + + - Install pynvim (the `--upgrade` switch ensures installation of the latest + version): + + pipx install --upgrade pynvim + + - Anytime you upgrade Neovim, make sure to upgrade pynvim as well by + re-running the above command. + +- Other installation options: + + - See [pynvim installation + documentation](https://pynvim.readthedocs.io/en/latest/installation.html) + for additional installation options and information. Python Plugin API ----------------- diff --git a/docs/installation.rst b/docs/installation.rst index 57883acb..9f2fc25e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -3,17 +3,63 @@ Installation The Neovim Python client supports Python 3.7 or later. -Using pip ---------- +Using uv or pipx +---------------- -You can install the package without being root by adding the ``--user`` flag:: +For automatic detection by Neovim, pynvim should be installed in a dedicated +Python virtual environment and the ``pynvim-python`` executable should be placed +on the ``PATH``. The recommended approach for this is to use a tool like uv +(https://docs.astral.sh/uv/) or pipx (https://pipx.pypa.io/stable/); the +``--upgrade`` switch ensures installation of the latest version: - pip3 install --user pynvim +- Install using uv (recommended):: -If you follow Neovim HEAD, make sure to upgrade ``pynvim`` when you upgrade -Neovim:: + uv tool install --upgrade pynvim - pip3 install --upgrade pynvim +- Install using pipx:: + + pipx install --upgrade pynvim + +**NOTE** For Neovim before v0.12.0, set the variable ``python3_host_prog`` in +``init.vim`` to point to ``pynvim-python``:: + + let g:python3_host_prog = 'pynvim-python' + +Using manually created Python virtual environment +------------------------------------------------- + +Alternatively, you may manually create a Python virtual environment +(https://docs.python.org/3.13/library/venv.html):: + + python3 -m venv pynvim-venv + +Then install pynvim into the virtual environment; the +``--upgrade`` switch ensures installation of the latest version:: + +- For Unix:: + + pynvim-venv/bin/python -m pip install --upgrade pynvim + +- For Windows:: + + pynvim-venv\Scripts\python -m pip install --upgrade pynvim + +Then copy the ``pynvim-python`` executable somewhere on the ``PATH``: + +- For Unix:: + + # Assuming `~/.local/bin` is on `PATH`: + cp pynvim-venv/bin/pynvim-python ~/.local/bin/pynvim-python + +- For Windows:: + + REM Assuming `C:\apps` is on `PATH`: + copy pynvim-venv\Scripts\pynvim-python.exe C:\apps\pynvim-python.exe + +**NOTE** For Neovim before v0.12.0, set the variable ``python3_host_prog`` in +``init.vim`` to point to ``pynvim-python``:: + + let g:python3_host_prog = 'pynvim-python' Install from source ------------------- @@ -23,6 +69,70 @@ Clone the repository somewhere on your disk and enter to the repository:: git clone https://github.com/neovim/pynvim.git cd pynvim -Now you can install it on your system:: +Now you can install it following the instructions above, using ``.`` instead of +``pynvim``; the ``--upgrade`` switch ensures installation of the latest version: + +- Install from source using uv:: + + uv tool install --upgrade . + +- Install from source using pipx:: + + pipx install --upgrade . + +- Install from source using manually created Python virtual environment: + + - Create ``pynvim-venv`` as above. + + - Install: + + - For Unix:: + + pynvim-venv/bin/python -m pip install --upgrade . + + - For Windows:: + + pynvim-venv\Scripts\python -m pip install --upgrade . + + - Copy ``pynvim-python`` executable as above. + +**NOTE** For Neovim before v0.12.0, set the variable ``python3_host_prog`` in +``init.vim`` to point to ``pynvim-python``:: + + let g:python3_host_prog = 'pynvim-python' + +Upgrade pynvim when upgrading Neovim +------------------------------------ + +Make sure to upgrade ``pynvim`` when you upgrade Neovim. Follow the previous +instructions; the ``--upgrade`` switch will ensure installation of the latest +version. + +Explicitly choosing pynvim virtual environment +---------------------------------------------- + +As an alternative to exposing ``pynvim-python`` on ``PATH``, you may configure +Neovim to use a specific Python interpreter that has pynvim installed; this may +be useful when working on pynvim itself. + +After installing into a virtual environment named ``pynvim-venv``, add the +following into Neovim's ``init.vim`` file: + +- For Unix:: + + let g:python3_host_prog = '/path/to/pynvim-venv/bin/python' + +- For Windows:: + + let g:python3_host_prog = 'c:\path\to\pynvim-venv\bin\python.exe' + +Installing outside of a virtual environment is deprecated +--------------------------------------------------------- + +Installing into the per-user Python site package area is a deprecated practice +with recent Python versions. For example, the following command fails on Ubuntu +24.04 with the error message ``error: externally-managed-environment``:: + + pip install --user pynvim - pip3 install . +Instead, always install into a virtual environment. diff --git a/pynvim/python.py b/pynvim/python.py new file mode 100644 index 00000000..7d3a3ac5 --- /dev/null +++ b/pynvim/python.py @@ -0,0 +1,28 @@ +"""Wrapper to expose the Python interpreter as `pynvim-python`. + +`setup.py` declares an entry point for the `main()` function below. When +`pynvim` is installed, an executable named `pynvim-python` will be generated +that will invoke `main()` below; that function then simply chains to the +underlying Python interpreter, passing along all command-line arguments. + +The intent is to have `pynvim-python` be on the `PATH` such that an invocation +such as: + + pynvim-python -c 'import pynvim' + +is equivalent to explicitly running the correct Python interpreter where +`pynvim` is installed: + + /path/to/python -c 'import pynvim' + +This allows Neovim to automatically detect the correct Python interpreter for +use with `pynvim`. +""" + +import subprocess +import sys + + +def main() -> None: + """Chain to Python interpreter, passing all command-line args.""" + subprocess.run([sys.executable] + sys.argv[1:]) diff --git a/setup.py b/setup.py index 55d6734e..fa0f12d9 100644 --- a/setup.py +++ b/setup.py @@ -58,4 +58,9 @@ setup_requires=setup_requires, tests_require=tests_require, extras_require=extras_require, + entry_points={ + 'console_scripts': [ + 'pynvim-python=pynvim.python:main', + ], + }, ) diff --git a/test/test_window.py b/test/test_window.py index 7a36d9e0..9267a14e 100644 --- a/test/test_window.py +++ b/test/test_window.py @@ -61,10 +61,11 @@ def test_vars(vim: Nvim) -> None: def test_options(vim: Nvim) -> None: vim.current.window.options['colorcolumn'] = '4,3' assert vim.current.window.options['colorcolumn'] == '4,3' + old_global_statusline = vim.options['statusline'] # global-local option vim.current.window.options['statusline'] = 'window-status' assert vim.current.window.options['statusline'] == 'window-status' - assert vim.options['statusline'] == '' + assert vim.options['statusline'] == old_global_statusline with pytest.raises(KeyError) as excinfo: vim.current.window.options['doesnotexist']