DAP(Debug Adapter Protocol)を試す

DAP(Debug Adapter Protocol)を試す。

github.com

Official page for Debug Adapter Protocolを見ながら、色々と試してみる。

LSPと同じようなものだと思われるので、とっつきは良かったのだが、 gdbとかlldbとか通常のデバッガのコマンドの対応が良くわからず苦労した。

Overview にあるシーケンス図に惑わされた感じ。

いくつかadapterを動かした感じだと、

1.adapter起動し、initializeを投げる

2.launch(やattach)コマンドで、実行ファイルを指定

3.breakpointの設定(setBreakpointsやserFunctionBreakpoints)

4.configurationDoneを投げると、実行ファイルが起動される(gdbのrunコマンド?)

5.breakpointとかで止まる(stoppedイベント)

公式ドキュメントの図だと、configurationDoneのあとで、launchしているように見えたので、 しばらく悩んでしまった。

stoppedイベントだと、止まった要因(breakpoint,step,exception,・・・)は分かるが、 具体的に止まった場所(どのファイルの何行目)は分からない。

stackTraceの応答を見れば良さそうなのだが、ちょっと面倒かも。

initializedイベントが送られるタイミングも最初、分からなかった。 initializeの後すぐに来るのかと思ったら、launchの後に来る。

initialized後がconfigurationの期間で、それが終わったらクライアントからconfigurationDoneを送れということか。

scintillaのtermbox実装

テキストエディタ作成用のライブラリScintillacurses向け実装であるScintermを使っている。 とても良くできていて、問題なく使えているが、色の指定については制約が強い。 16色しか使えないのは良いとして、色の設定が面倒だった。

masahino123.hatenablog.com

そうこうしているうちに、Scintillaのバージョンが上り、Scintermが本家の配布物に含まれなくなったりといったことも起こっていた。

色の設定についてScintermを改造することを考えていたが、 思いきって、別の実装をやってみることにした。 せっかくならcurses以外でということで、termboxを選択。 実際にはtermboxからforkしているtermbox_nextを使うことにした。

GitHub - nullgemm/termbox_next: Library for writing text-based user interfaces

本家のtermboxはメンテ終了しちゃっているので、今さら感もあるが、以前termboxのmrubyバインディングを作ったこともあり、 使い方は把握できている。 また、termbox_nextはtruecolorにも対応している。

作ったのがこれ。

GitHub - masahino/scintilla-termbox

Scintermでcursesの関数を使っているところをtermbox用に変えていく作業が中心。 やってみての感想は、Scintilla良くできているなぁ、というところ。

Scintermとの違いは以下。

  • 色の設定に対応できるように
  • Listbox(自動補完とかで使う)、Calltip、スクロールバー、マーカーの形状を変更

この実装を使って作ったテキストエディタはこれ。

GitHub - masahino/mruby-bin-mrbmacs-termbox: Scintilla base text editor written in mruby

もともと作っていたcurses版のtermbox版。 ほぼほぼ同じ感じ。

サンプル画像がこれ。

https://user-images.githubusercontent.com/381912/141677899-5cb7041d-0b92-44ab-a727-fddee4565c70.png

初期のcurses版の画像がこんな感じだったので、そこそこ見た目が改善されてきているのではないかと思っている。

https://user-images.githubusercontent.com/381912/59429288-6a95b200-8e1a-11e9-9aa7-967dfb05d170.png

LSP(Language Server Protocol)のsignatureHelpと閉括弧の自動補完

LSP(Language Server Protocol)にsignatureHelpというのがありまして、メソッドの引数情報なんかを表示するのなんかに使えそうなもの。

rubyのLSPサーバであるsolargraph(バージョン0.39.8)を使ってみたら、 例えば、

puts(

と"("が入力された段階で、サーバにリクエスト出しても返ってこない。

puts()

となっているとこで"("の位置を指定して、リクエストすると、

{
  "signatures"=>[
  {
    "label"=>"puts(*args)",
    "documentation"=>"Invoke method +puts+ on STDOUT and passing +_args_+\n\nISO 15.3.1.2.11\n\n\n\nVisibility: public"
  },
  {
    "label"=>"puts(obj, ...)",
    "documentation"=>"Returns:\n* [nil] \n\nVisibility: public"
  },
  {
    "label"=>"puts(*)",
    "documentation"=>"Equivalent to\n\n    $stdout.puts(obj, ...)\n\n\n\nReturns:\n* [nil] \n\nVisibility: public"
  },
  {"label"=>"puts(*args)", "documentation"=>"Visibility: public"
  }]
}

という応答が返ってきた。素晴しい。

これって、文法エラーになるような不完全な状況だとsignatureHelpが使えないということでは? 入力途中に使えないと意味ないじゃん、と思って、Visual Stdio Codeでも試してみたら、 なんのことは無い、デフォルトで閉括弧が勝手に入力されるので、何の問題もない。

ふむ。 まずは、閉括弧の自動補完機能を作ってみるか・・・

自作テキストエディタをwindows環境でなんとかしようと挑戦する話

テキストエディタ用のフレームワークであるScintilla(https://www.scintilla.org/)と mruby( https://github.com/mruby/mruby)を使ってEmacsテキストエディタを作るという取り組みを、 この数年、ちまちまとやっている。

普段使っているMacOS上では、それなりに動いていていると思う。 何が動いて、何が出来ないかを自分では把握できているから、ヤバい操作は回避しているだけで、 普通のレベルで常用するには、まだまだ不足だろうとは思う。

何故かときどき、Mac以外の環境でも動くようにしたいなぁ、 という思いが湧き上がり(ほかにすることが無いからか?)、 ビルド環境の整備をしばらく頑張っては諦めるというパターンを何度も何度も繰り返している。 Linuxでは、まあなんとななるのだが、Windows環境が自分には難しい。

自作エディタは、cursesを使ったTUIアプリで、 scintillacurses実装を使っている。 キー入力の部分にはlibtermkey というものを使っているので、このあたりが複雑。 libtermkeyは、最初は便利だから良かったんだけど、windows上で使うのには向いてなかったようだ。 libtermkeyを使わないようにするという作業にも何度か着手したが、そのうち面倒になって放置するということを定期的に繰り返している。

mruby側ではmrbgem(mruby-cursesだったり)の関係でビルドエラーが出易い。

複数環境で使えるよう、mruby-cliを使ったビルド環境も整えようとして、さらに混乱に拍車がかかる。

windows上でもcygwin環境であれば、ある程度簡単にビルドできる。 今回、何度目かのチャレンジになるがmingwでもビルドできるようにしたい。

いろいろと試した結果、mingwではPDCursesを使うことにした。 また、libtermkeyはcursesかunibilium(https://github.com/mauke/unibilium)を使うのだが、 mingwではunibiliumを使うようにした。 単にコンパイルエラーを無理矢理回避する作業を、トライ&エラーで試し続けた結果である。

これで、ビルドが通る確率は高まったハズ。 ただ実際は、mruby-termkeyのビルド時には、unset PKG_CONFIG_PATHしてrakeという謎の手順が必要な状態。

さて、ビルドが通ったのでいざ起動してみると、 PDCursesのinitscrで一個新しいウィンドウが開いたので驚いた。 そしてそのウィンドウには最初から「Font」と「Paste」というメニューが用意されている。 Fontは良いが、PasteメニューではCtrl-vが勝手にペーストに使われるので、困る。 自作エディタはEmacs風なので、Ctrl-vは別用途に使いたい。 幸い回避策は用意されていて、たとえば次のようにすれば、PDCursesのメニューでのCtrl-vは無効にできる。

  PDC_set_function_key(FUNCTION_KEY_PASTE, 0);

メニューを表示しない方法もあるようだ。

他にも、カーソルキーが効かなかったり、日本語入力と表示が残念な状態だったり、 問題は山積みなのだが、いかんせん、自分が普段使っている環境ではないので、 ビルドエラーが取れたぐらいで、なんとなく満足してしまって、あきらめモードに入ってしまう。 そして、そのうち気づいたらビルドもエラーになるということの繰り返し・・・

一応、いまのところ、下のキャプチャぐらいの形にはなっている。

f:id:masahino123:20200516163410p:plain
mrbmacs-curses(mingw64)

まあ、一旦こんなところで。

scintillaの新しいバージョン3.20.0がリリースされていたので、次はその対応をやってみよう。 試しにバージョンアップしてみたら、ビルドエラーが発生している。 ビルド関係の修復ばかりで、エディタそのものの機能向上やバグフィックスはちっとも進まない。

MinecraftのAdd-onを試してみる

連休中は、子ども達と一緒にMinecraftで遊ぶ時間が長かった。 子どもとは、switch版で複数のコントローラでTVの画面分割でやっている。 2分割より4分割のほうが見易いようだ。 そのため、私が遊ぶ時間が無いとき(在宅勤務中とか)も、 勝手に3人目のプレイヤーとして参加しているようだ。 みんなでMinecraftしていても、私は一人で、黙々と作業していることが多い。

一人でやるこもある。 通勤電車でiPhone版をやったり、タブレットでやったり。 家では、FireTVでやったり。

やってることは、みんなでやっているときと、さほど変わらないのだけど、 ワールドに他の人がいるほうが、楽しいように思える。

色々な遊びかたを探るため、 少し前に、serverを立てるのを試してみた。 どんなのが良いか、色々探したが公式のbedrockサーバをubuntuで動かして、 満足してしまった。 https://www.minecraft.net/ja-jp/download/server/bedrock/

サーバの良い活用方法は考え中。 端末を変えても、同じワールドでプレイできるのは良い。 ただ、通勤電車のなかでは、通信切れまくりで、あまり良くない。

サーバの次は、Add-onかな、と次の遊び方を模索中。

検索しても、情報があるようで、そんなに無い気がする。探し方の問題か?

このサイトのTutorialを試すことで、Resource PackとBehavior Pack については、弄り方が掴めた。 minecraft.gamepedia.com

日本語版もあるが、ファイルのフォーマットが少し古い。 Add-on - Minecraft Wiki

次は、scriptに挑戦する。

Resource PackとBehavior Packの設定ファイルはJSON形式、 scriptは、JavaScriptなので、そのためのテキストエディタ環境整備も平行して行うのである。

Scintilla cursesでの色指定

Scintillacurses向け実装の色についてのメモ。 何度も調べては忘れるを繰り返すので、いい加減書いておく。

www.scintilla.org

Scintillaテキストエディタ用のライブラリで、gtkwindows向けのライブラリがある。 ncurses用は、以前は別に開発されていたようだが、その後本体に取り込まれた。 が、最新版(4.x)には含まれておらず、LongTerm3ブランチというバージョン3系統で提供されている。 最新版は、C++の新しい機能を使っており、対応できない環境があるためLongTerm3ブランチが用意されたものと、理解している。 機能的には、後追いで追随されている模様。

以上が前置きで、ここからが本題。

テキストエディタの機能として、カラーマップを好みに変えたいが、 残念ながらScintilla cursesは最大16色までしかサポートしていない。 端末がどれだけサポートしてても関係ない。

使える色も決まっていて、次の16色。色の指定は0xBBGGRRの書式。RGBでは無い。 REAMDE.mdだとこのBBGGRRで説明があるのだけれども、ソースだとRGBが使われていて、ややこしい。

  1. black (0x000000) 0
  2. red (0x000080) 1
  3. green (0x008000) 2
  4. yellow (0x008080) 3
  5. blue (0x800000) 4
  6. magenta (0x800080) 5
  7. cyan (0x808000) 6
  8. white (0xC0C0C0) 7
  9. light black (0x404040) 8
  10. light red (0x0000FF) 9
  11. light green (0x00FF00) 10
  12. light yellow (0x00FFFF) 11
  13. light blue (0xFF0000) 12
  14. light magenta (0xFF00FF) 13
  15. light cyan (0xFFFF00) 14
  16. light white (0xFFFFFF) 15

Scintillaの色の設定はRGBでそれぞれ0から255の範囲で行う。 cursesでは、上記16色以外が設定されると、白(0xC0C0C0)になる。

さすがに16色では寂しい。

どうするか?

ターミナルエミュレータで、お気に入りの配色を設定してしまえば、Scintilla cursesでは、色の対応だけ気にしておけばよい。

ただ・・・ターミナルの配色と、エディタの配色は変えたいという気分になるときもあるので、 独立して設定できる方法も欲しい。

  • [案2]デフォルトのカラーマップを変更

色番号0-15番をcursesのinit_colorを使って変更する。 色番号とR,G,Bの値を指定するのだが、RGBの範囲は0から1000の範囲なので、値の変換が必要。約4倍だ。

で、やってみたらinit_colorがエラーになった。 どこに問題があるのか探ってみたら、tmux上では上手くいかないことがあった。 色々設定を変えて、トライしていたら、そのうち動くようになった。

なにかのタイミングで、tmuxが8色しか使えない状態になっていたようだが、よく分からない。

この過程で、tmux -2 で起動すると、強制的に256色モードで起動するという知見を得た。

ということで、16色の範囲であれば、256色ぐらいは使えるようになったかな。

LSPの実装について

やっぱりサーバによって挙動が異なるので、気づいた点をメモっておく。

initializeの応答

最初にclientからinitializeリクエストを送ると、サーバからレスポンスが返ってくるのだが、 応答に時間がかかるサーバと、すぐに返してくるサーバがある。

solargraphなんかは、結構時間がかかる。 場合によっては10秒とかかかるので、initialize投げておいて、 別の処理に移っておく必要がある。

一方で、cqueryはすぐに返ってくる。 ただし、裏でファイルのindex化の処理などをやっているようで、 しばらく、"$cquery/progess"というnotificationを送ってくる。 本当に、初期化が終了したタイミングを掴みづらい。

formatting

‘textDocument/formatting’ というメソッドがあり、文字通り整形してくれる。 formattingはファイル全体を対象にしている。部分指定では、'rangeFormatting'というのがある。

solargraphで試すと、ファイル全体を差し替えるようなtextEdit[]が返ってくるので、 そのまま入れ替えれば良い。

cqueryだと、変更箇所だけを指定したtextEdit配列が返ってくるので、 個々に処理しないといけない。

クライアント側を実装するのに、どんなresponseが返ってくるのかは、実物を見るほうが判りやすいのだが、 幾つかのサーバを試さないと、予期せぬ動作に悩まされることが多い印象。