Umi Uyuraのブログ

プログラミング関連の作業ログ

Emacsのlsp-modeをPythonのvenv環境で使う

EmacsPythonコードをいじるとき用にlsp-modeを使ってみることにしましたが、venv環境で使うときに少し手間取ったので、やったことをメモ。

LSP Mode - Language Server Protocol support for Emacs

環境情報

項目 情報
OS Windows 11 Home 22H2 (OSビルド 22621.1413)
WSL Ubuntu 22.04.2 (Kernel: 5.15.90.1-microsoft-standard-WSL2)
Emacs GNU Emacs 28.1
Python 3.11.3

WSLのEmacsを使い、WSL内にPython開発環境を用意しています。

インストール

lsp-mode関連

公式サイトの Installation - LSP Mode - LSP support for Emacs 「Manually via MELPA」と「Vanilla Emacs」のあたりを参考に、以下のパッケージをpackage.elの list-package からインストール。

  • lsp-mode
  • lsp-ui
  • flycheck ※もともとインストール済
  • company-mode

lsp-modeインストール後は、 Performance - LSP Mode - LSP support for Emacs にあるとおり、 lsp-doctor を実行しつつ推奨設定をおこなっておきます。

Python用language-server

次にPython用のlanguage-serverをインストールしますが、 Languages - LSP Mode - LSP support for Emacs を見ると複数種類あって迷うところ。

deprecatedと書かれているPalantirと、リポジトリアーカイブされていたMicrosoftのもの除いても以下の4種類あります。

この中から、この時点でStarが一番多かった Pylsp (python-lsp/python-lsp-server) を使ってみることにしました。

プロジェクト用のフォルダを作成してから、venv環境を作成、パッケージをインストールします。

$ mkdir testproj && cd testproj
$ python -m venv .venv
$ . .venv/bin/activate
(.venv) $ python -m pip install 'python-lsp-server[all]'

lsp-mode実行

pylspが見えない

この状態でEmacs内でPythonソースコードを開いて M-x lsp を実行したところ、以下のようなメッセージが出力されました。

LSP :: The following servers support current file but do not have automatic installation: pyls pylsp ruff-lsp
You may find the installation instructions at https://emacs-lsp.github.io/lsp-mode/page/languages.
(If you have already installed the server check *lsp-log*).

*lsp-log* バッファを見ると、language-serverが見つからないというメッセージが。

Command "pyls" is not present on the path.
Command "pylsp" is not present on the path.
Command "ruff-lsp" is not present on the path.

この中の pylsp が今回入れたpython-lsp-serverなのですが、venv環境に入れたものが見えていないようです。

venv環境のlanguage-serverを参照する

lsp-modeがvenv環境にあるコマンドを参照してくれるように、プロジェクトローカルに設定を用意します。

まず、venv環境にある pylsp コマンドのパスを確認。

(.venv) $ which pylsp
path/to/.venv/bin/pylsp

Emacs上でPythonソースコードを開いた状態で M-x add-dir-local-variable を実行して、 python-mode に変数 lsp-pylsp-server-command と上記のパスを設定します。

Mode or subdirectory (default python-mode): python-mode
Add directory-local variable: lsp-pylsp-server-command
Add lsp-pylsp-server-command with value: "path/to/.venv/bin/pylsp"

パスは文字列として設定するので、ダブルクォーテーションで括ります。

実行すると、以下のように .dir-locals.el バッファが生成されるので、保存しておきます。

;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

((python-mode . ((lsp-pylsp-server-command . "path/to/.venv/bin/pylsp"))))

あらためてPythonソースコードを開き直すと、以下のようにローカル変数を読み込むかどうかの確認が表示されるので、読み込むために y を選択。

The local variables list in <path/to/project>
contains variables that are risky (**).

DO you want to apply it? You can type
y -- to apply the local variables list.
n -- to ignore the local variables list.

 ** lsp-pylsp-server-command : "path/to/.venv/bin/pylsp"

ソースコードを開いて M-x lsp を実行すると、以下のようにプロジェクトのルートを聞かれるので、表示されているもので問題なければ i を選択。

i ==> Import project root <path/to/project>
I ==> Import project by selecting root directory interactively
. ==> Import project at current directory <path/to/project>
d ==> Do not ask again for the current project by adding <path/to/project> to lsp-session-folders-blacklist
D ==> Do not ask again for the current project by selecting ignore path interactively
n ==> Do nothing: ask again when opening other files from the current project

Select action: i

メッセージに以下のように表示されれば、language-serverに接続できています。

LSP :: Connected to [pylsp:20879/starting path/to/project].

lsp-modeによるコード補完が動くようになりました。

lsp-modeによるコード補完