WindowsにてJuliaのREPLで改行する

Julia 言語の REPL にて関数定義のような複数行のコードを書いているとき、コードの途中に改行を挿入しようとして Enter キーを押すとコードが実行されてしまい、改行できない。このような場面では本来、標準のキーバインドとして用意されている meta-Enter を使えば改行を挿入できるのだけれど、Windows では上手くいかない。というのも、Windows のコマンドプロンプトでは Alt-Enter (一般的な Windows 用キーボードでは Alt キーが meta キーに相当)を入力すると「フルスクリーン表示のショートカット」として解釈されてしまうため、REPL に渡される前に「奪い取られて」しまう。そして、このコマンドプロンプトのショートカットキーは無効化できないようなので、改行を挿入するには別の方法が必要になる。

方法1:コピペ

一番簡単な方法は、テキストエディタなどで改行を含むファイルを開いておいて、そこから「コピー&ペーストで改行コードを貼り付ける」というもの。…ま、かなり面倒なのでオススメできないけれど、どんな Windows 環境でもすぐ使えるという意味で手軽。「最悪こういう手がある」と覚えておく価値はあると思う。

方法2:独自キーバインド定義

現実的な方法は、startup.jl を作って REPL のキーバインドをカスタマイズする方法。Julia 公式ドキュメントにはキーバインドカスタマイズ方法の説明があるので、これを読めば簡単に設定できる…と思いきや、これ、非常に簡単にしか書いておらず、しかもキーに関連付ける具体的なアクションに何があるのか等は「ソースを読め」というスパルタンな内容。おかげで、たった一つのキーバインドを追加するのに何時間もかかってしまった。

startup.jl でのキーバインド追加方法でのポイントを以下にまとめておく。

  1. %UserProfile%\.julia\config\startup.jl でキーバインドを定義するコードを書く
    • このファイルに書いた内容は REPL の起動直後に自動実行される
    • なお %UserProfile% は Windows では自動的に定義される環境変数
      • 典型的な環境では C:\Users\sgryjp などといったパスになる
  2. 書くべきコードは公式ドキュメントのコード例を参考にする
    • 下記のコードも公式ドキュメントをベースに少しカスタマイズしたもの
  3. キーバインドは、キーバインドを表す文字列がキーであり、そのキーバインド押下時に実行すべき処理が値となっている辞書で定義する
  4. 定義済みのアクションはドキュメント化されていないので、 LineEdit.jl の COMMAND_GROUPS 定数 に格納されているシンボル名(関数名)などを参考にトライ&エラーでお望みのものを探す
    • 複数のアクションを組み合わせたければ辞書の値として普通の関数を指定すれば良い

実装例

以下のキーバインド 2 つを定義する実装例を記す。

  • Alt+m ... 改行コードを挿入
  • Ctrl+o ... 改行コードを挿入、ただしカーソル位置を変えない
# %UserProfile%\.julia\config\startup.jl
import REPL
import REPL.LineEdit

let mykeys = Dict{Any,Any}(
    # Alt+m: Insert a newline
    "\\M-m" => (s,o...) -> LineEdit.edit_insert_newline(s),

    # Ctrl+o: Insert a newline without moving the cursor position
    "^o" => (s,o...) -> begin
        LineEdit.edit_insert_newline(s)
        LineEdit.edit_move_up(s)
        LineEdit.move_line_end(s)
        LineEdit.refresh_line(s)
    end,
)
    function customize_keys(repl)
        repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)
    end

    atreplinit(customize_keys)
end

なお、本当は(Julia の REPL が踏襲している)emacs のキーバインドに合わせて Ctrl+m で改行コードを挿入させたかったのだけれど、通常の Enter キー押下も Ctrl+m と認識されるようになり、今度はコード実行ができなくなってしまった。詳しくは調査していないけれど、このあたりの調査は泥臭くなる予感がするので詳しく調べず、安全なキーバインドを使った次第。