[Obsidian] で kill line と yank したい
"Obsidian" で、Ctrl+K & Ctrl+Y が機能してくれなかったので、プラグインを入れて、更に自分向けに改変してみました。
Ctrl+K? Ctrl+Y ? なんぞや?って人は、この界隈に存在しないでしょうが、GNU Emacs における、私にとってなくてはならない機能です。
Ctrl+K : kill line … カーソル位置から行尾まで全てを削除
Ctrl+Y : yank … いわゆる貼り付け
いやってほど、これらを多用する私ですが、"Obsidian" では Ctrl+k は機能するものの、それはクリップボードには入らずにペーストできません。Ctrl+Y はそもそも機能がありません。いても立ってもいられなかったのですが、同じような人はいました。ありがたい。
kill と yank できるプラグインを発見するの巻
まんまの機能をプラグインとして提供してくれています。ついでに Ctrl+SPC での set mark や、Ctrl+W での kill-range なんかもついてます。ありがたい。
hotkey は勿論変更ができます。わたしは set mark を Ctrl+Shift+2 (JISキーボードでいう Ctrl+@) にしています。Ctrl+SPC は、漢字変換のショートカットなので。
しかし、私の環境では満足に動きませんでした。機能としては動きました。動くんです。しかし、私の日本語入力(IME)のキーカスタマイズがちょっと尋常ではないことが起因して、正常に動作しません。それは、私の設定している漢字変換後の決定が Ctrl+K なのです。変なのは理解してます。Ctrl+M や Enter でも確定できるようにしてありますが、使いません。私には確定に Ctrl+K が人生として必要なのです。これだと何が起こるのか? 2文節以上の日本語を確定すると、1文節目が繰り返されて決定されるという、謎の動きになりました。単漢字変換を使っているわけじゃないんだから、これは想定外です。
kill-line と kill-range の機能を改変してみた
ということで、このプラグインは、私の使っている漢字変換確定時の Ctrl+K とめっちゃ相性が悪い。そこで、IME が on になっているときは、Ctrl+K の挙動を制御するように修正しました。
さらに、Ctrl+Shift+2(set mark) してからの Ctrl+W(kill range) での範囲選択方法が、めんどうなのです。set mark を 2回おして、範囲選択状態を確定する必要があります。set mark して、cut したい範囲までカーソルを移動してから Ctrl+W したら削除してほしい。ということで、更にそのように改変しました。どこで mark されたか分からない、なんてことにはならないので、私にはこれで十分です。なるほど、marker 表示するっていう改変もできそうですねぇ…?
結果、そんな私のコードはこちらです。元から fork して修正したものを、このリポジトリに突っ込んでいます。
はい、誰もこんな機能も改変も必要ではないと思いますが、たまには TypeScript もいじるのもいいかなという、そんな1日でした。
参考リンク
以下のサイトにお世話になりました。これらがなかったら、何もできませんでした。時系列で並べてあります。私の調べ学習の流れや気づきにもなるでしょう。
JavaScript で IME の状況を判定するには、でこちらを参考に。今回のコードに直接影響はしませんでしたが、JavaScript で引っかけられることは分かりました。あと、ここにある 'isComposing' がヒントにもなりました。
Obsidian は、Code Mirror をベースにしたエディタです。どうも 'cm.display.input.composing' というチェック方法を見る限り、Code Mirror が所持するキーのステータスを見ればどうにかなると判断しました。
ここまでの情報をヒントに更に Obsidian API を眺めたり、'Editor' や 'MarkdownView' などの Class 情報を見たりとかイロイロしました。結果、Code Mirror 側のライブラリを直接見るしかなさそうです。それがこちら。ちょっと古い情報ではありましたが、Obsidian で 'composing' を見れば行けそう。
そしてついに、Obsidian API でまさにそれに巡り合います。
Code Mirror の 'EditorView' で Code Mirror 固有の state などを拾えます。
結果、次のようなコードを書けば良いというところまで行き着いたのです。
import { EditorView } from '@codemirror/view'
// @ts-expect-error
const editorView = view.editor.cm as EditorView
if (!editorView.composing) {
:
(IME offの時の処理...)
:
}
多くのエンジニアに多謝。
#obsidian