最近ようやく知ったのだがREPLの機能を拡張するモジュールとして OhMyREPL.jlというものがあるらしい。
- 括弧の入力補助
- コードのハイライト機能
等色々な機能があるのだが,メインで使っているEmacsのjulia-replはeterm-256color上で使っているため, 256色しか対応しない。

デフォルトのスキームは256色対応だが,背景が明るい端末では少し見づらい。
そこで,サブの色々な環境で切り替えられるような感じのものを試しに作ってみた。
方針
実行環境は
の4種類。 ベースはEmacs上のソースの色使いで,この記事ではEmacs上のREPL対応までのコードとする。
OhMyREPLの色の指定方法とか
基本的にCrayons.jlで指定する。
OhMyREPL.Passes.SyntaxHighlighterの以下の関数で,
カラースキームを変更することで色等が変えられるようだ。
symbol!(scheme, Crayon型)comment!(scheme, Crayon型)string!(scheme, Crayon型)call!(scheme, Crayon型)op!(scheme, Crayon型)keyword!(scheme, Crayon型)function_def!(scheme, Crayon型)error!(scheme, Crayon型)argdef!(scheme, Crayon型)macro!(scheme, Crayon型)number!(scheme, Crayon型)text!(scheme, Crayon型)
またCrayon型を簡易に設定するcrayon"文字列"のマクロが用意されている。
- 基本の16色(文字色)は
crayon"blue",crayon"light_red"とかの感じで指定可能 - 256色(文字色)は
crayon"127"のように0~255の10進で指定可能 - 24bit色(文字色)は
crayon"0xffffff"のような感じで指定可能 - 文字,背景色, 太字等の指定も可能で,
crayon"fg:red bg:white bold"のような感じ
とりあえずCrayons.test_256_color()で色を確認しながら色を設定していく。

実装例
using OhMyREPL, Crayons function myset_schemes!(scheme; colors_pr=[]) _r = OhMyREPL.Passes.SyntaxHighlighter funcs = Dict( :symbol => _r.symbol!, :comment => _r.comment!, :string => _r.string!, :call => _r.call!, :op => _r.op!, :keyword => _r.keyword!, :function_def => _r.function_def!, :error => _r.error!, :argdef => _r.argdef!, :macro => _r.macro!, :number => _r.number!, :text => _r.text!) for (k, v) in colors_pr funcs[k](scheme, v) end end function myadd_schemes() emacs_cfg = (name="emacs", scheme=[ :symbol => crayon"bold cyan", :comment=>crayon"red", :string => crayon"red", :call => crayon"21", :op => crayon"bold 90", :keyword => crayon"bold 164", :function_def => crayon"bold 21", :error=> crayon"bg:196", :argdef=>crayon"196", :macro=>crayon"196", :number=> crayon"cyan", :text=>crayon"0"]) vscode_cfg = (name="vscode", scheme= [ :symbol => crayon"bold cyan", :comment=>crayon"28", :string => crayon"red", :call => crayon"yellow", :op => crayon"bold 90", :keyword => crayon"bold 164", :function_def => crayon"bold 21", :error=> crayon"bg:196", :argdef=>crayon"196", :macro=>crayon"196", :number=> crayon"cyan", :text=>crayon"0"]) gnome_cfg = (name="gnome", scheme= [ :symbol => crayon"bold cyan", :comment=>crayon"red", :string => crayon"red", :call => crayon"21", :op => crayon"bold 90", :keyword => crayon"bold 164", :function_def => crayon"bold 21", :error=> crayon"bg:196", :argdef=>crayon"196", :macro=>crayon"196", :number=> crayon"cyan", :text=>crayon"0"]) for cfg in [emacs_cfg, vscode_cfg, gnome_cfg] scheme = OhMyREPL.Passes.SyntaxHighlighter.ColorScheme() myset_schemes!(scheme; colors_pr=cfg.scheme) OhMyREPL.Passes.SyntaxHighlighter.add!(cfg.name, scheme) end end myadd_schemes() if "TERM" in keys(ENV) && ENV["TERM"] == "eterm-256color" colorscheme!("emacs") elseif any(occursin.(r"^VSCODE", keys(ENV))) # isdefined(Main, :VSCodeServer) colorscheme!("vscode") elseif "GNOME_TERMINAL_SERVICE" in keys(ENV) colorscheme!("gnome") end

- 色指定に関しては
macroがバグッって表示されない。argdefもうまく動いているかどうか不明。macroに関しては,名前付タプルに指定できない等の制限があるので,それが原因ではと推測。 - 面倒なので,pair型の配列を引数としてschemeを変更できる関数を作ってそれぞれの環境の パラメータを変えている。
- emacsは環境変数の
TERMがeterm-256colorかどうかで判定 - VSCodeのREPLは最初に
VSCodeServerが走るので,モジュールがあるかどうかで判定 - Gnome端末は
GNOME_TERMINAL_SERVICEがあるかどうかで判定しているが,これでいいのかは分からない - Guakeは背景が暗いので(今のところは)何もしない。
本来は~/.julia/config/startup.jlに書くところであるが,常用するかどうかは決まってないので,
使いたい時に適宜includeすることで使っていく予定。
後日ソース修正
~/.julia/config/startup.jlはVSCodeServerを読み込む前に実行されるので,以前のコードではうまく判定しない。
(REPLが立ち上がった後に読む込む場合はOK)
環境変数の中に「VSCODE」で始まるものが何か存在する時と条件を修正。