chibaqn /
Posts
2022-08-20 19:06:39

Neovim を Google Cloud Shell にインストールし、code-server で Vim の操作性を実現する

はじめに

個人開発の開発環境として、Google Cloud Shell を利用している。

項目
開発マシン Windows PC
開発サーバー Google Cloud Shell(Ubuntu)
エディタ code-server

エディタは Vim のキーバインドを使いたいので、VSCode Neovim という Extension を導入した。

今回は導入手順をまとめる。

Google Cloud Shell に Neovim をインストールする

インスタンスが terminate したとしても削除されないように永続ストレージ($HOME 配下)にインストールする。

手順

$HOME/.local 配下にインストールする。

$ ls ~/.local/lib/
code-server-4.5.2

Installing Neovim を参考にして、 Neovim をインストールする。

$ curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
...
$ chmod u+x nvim.appimage
$ ./nvim.appimage  # Neovim が起動する

$HOME/.local に配置する。

$ mv nvim.appimage ~/.local/lib/
$ ls ~/.local/lib/
code-server-4.5.2  nvim.appimage
$ ln -fs ~/.local/lib/nvim.appimage ~/.local/bin/nvim
$ ls ~/.local/bin/
code-server  nvim
$ which nvim
/home/XXX/.local/bin/nvim

Neovim が起動することを確認する。

$ nvim --version
NVIM v0.7.2
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-11 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -DNVIM_TS_HAS_SET_ALLOCATOR -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -Wimplicit-fallthrough -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=malloc -Wsuggest-attribute=cold -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include
Compiled by runner@fv-az395-591

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "
/home/runner/work/neovim/neovim/build/nvim.AppDir/usr/share/nvim"

Run :checkhealth for more info

code-server に VSCode Neovim を導入する

まずは、Extension を code-server にインストールする。

Neovim のパスを設定し、code-server を再起動すれば完了。

{
    ...
    "vscode-neovim.neovimExecutablePaths.linux": "/home/XXX/.local/bin/nvim",
}

おすすめ設定

Neovim の拡張機能を入れると Ctrl + c でのコピーが効かなくなる。マウスで選択して Ctrl + c もやりたい場合、下記を keybindings.json に追記する。

※ 設定から Ctrl + c の Neovim のショートカットを消すでもOK.

// Place your key bindings in this file to override the defaultsauto[]
[
  {
    "key": "ctrl+c",
    "command": "-vscode-neovim.escape",
    "when": "editorTextFocus && neovim.ctrlKeysInsert && neovim.init && neovim.mode != 'normal'"
  },
  {
    "key": "ctrl+c",
    "command": "-vscode-neovim.escape",
    "when": "editorTextFocus && neovim.ctrlKeysNormal && neovim.init && !dirtyDiffVisible && !inReferenceSearchEditor && !markersNavigationVisible && !notebookCellFocused && !parameterHintsVisible && !referenceSearchVisible && neovim.mode == 'normal'"
  }
]

yank した文字列をクリップボードにコピーする設定も ~/.config/nvim/init.vim に追加しておく。

set clipboard=unnamed

ESC キーを押したときに、入力モードを 英数 に切り替える

IME が ON の状態(日本語入力モード)のままコマンドを打ってしまうのがストレスフルなので、その対応。

※ Mac だと Karabiner-Elements で簡単にできるが、Windows は少し面倒くさい。

Google 日本語入力(1番手軽な手段)

Google 日本語入力の設定を変更する。

※ この方法だと、IME が ON の状態で INSERT モードを抜けるときに ESC キーを 2回 押さないといけない。

モード 入力キー コマンド
入力文字なし Escape IME を無効化

AutoHotkey(おすすめ)

AutoHotkey を用いて、ESC キーが押されたときの挙動を以下のようにを変更する。

  • ESC キーが押されたときに IME が ON の状態(日本語入力モード)であれば ESC キーを送信して IME を OFF にする。

IME制御用 関数群 を用いて実装する。

*Esc::
    getIMEMode := IME_GET()
    if (getIMEMode = 1) {
        Send {Esc}
        IME_SET(0)
    } else {
        Send {Esc}
    }
    return

;-----------------------------------------------------------
; IMEの状態の取得
;   WinTitle="A"    対象Window
;   戻り値          1:ON / 0:OFF
;-----------------------------------------------------------
IME_GET(WinTitle="A")  {
	ControlGet,hwnd,HWND,,,%WinTitle%
	if	(WinActive(WinTitle))	{
		ptrSize := !A_PtrSize ? 4 : A_PtrSize
	    VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
	    NumPut(cbSize, stGTI,  0, "UInt")   ;	DWORD   cbSize;
		hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
	             ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
	}

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283  ;Message : WM_IME_CONTROL
          ,  Int, 0x0005  ;wParam  : IMC_GETOPENSTATUS
          ,  Int, 0)      ;lParam  : 0
}

;-----------------------------------------------------------
; IMEの状態をセット
;   SetSts          1:ON / 0:OFF
;   WinTitle="A"    対象Window
;   戻り値          0:成功 / 0以外:失敗
;-----------------------------------------------------------
IME_SET(SetSts, WinTitle="A")    {
	ControlGet,hwnd,HWND,,,%WinTitle%
	if	(WinActive(WinTitle))	{
		ptrSize := !A_PtrSize ? 4 : A_PtrSize
	    VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
	    NumPut(cbSize, stGTI,  0, "UInt")   ;	DWORD   cbSize;
		hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
	             ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
	}

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283  ;Message : WM_IME_CONTROL
          ,  Int, 0x006   ;wParam  : IMC_SETOPENSTATUS
          ,  Int, SetSts) ;lParam  : 0 or 1
}

おわりに

僕のようなライトな Vimmer にとっては最高なエディタなのでは。

下記の点が嬉しい。

  • Neovim Vscode はあくまで拡張機能なので、エディタ自体は Vscode である。
  • Vim のキーバインドと普通のマウス操作が両立されている。
  • Vim のプラグインも VSCode のプラグインも動く。

ゴリゴリにカスタマイズする Vimmer じゃなくても、Neovim Vscode を利用すると幸せになると思う。