Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RubyLSPのマルチバイト文字対応
Search
Iori IKEDA
November 07, 2024
Programming
1
170
RubyLSPのマルチバイト文字対応
Omotesando.rb #103
での発表資料です。RubyLSP に行ったマルチバイト文字の対応について話しました。
Iori IKEDA
November 07, 2024
Tweet
Share
More Decks by Iori IKEDA
See All by Iori IKEDA
Passkeysのはなし
notfounds
0
85
Other Decks in Programming
See All in Programming
Honoとフロントエンドの 型安全性について
yodaka
7
1.2k
Immutable ActiveRecord
megane42
0
140
PHPのバージョンアップ時にも役立ったAST
matsuo_atsushi
0
110
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
560
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
250
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
170
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
150
楽しく向き合う例外対応
okutsu
0
110
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
560
Djangoアプリケーション 運用のリアル 〜問題発生から可視化、最適化への道〜 #pyconshizu
kashewnuts
1
250
SpringBoot3.4の構造化ログ #kanjava
irof
2
990
Featured
See All Featured
Optimizing for Happiness
mojombo
376
70k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Thoughts on Productivity
jonyablonski
69
4.5k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Visualization
eitanlees
146
15k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Building Your Own Lightsaber
phodgson
104
6.2k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
Into the Great Unknown - MozCon
thekraken
35
1.6k
Transcript
RubyLSPのマルチバイト文字対応 2024/11/07 - Omotesando.rb#103 Iori IKEDA @NotFounds8080
自己紹介 Iori IKEDA • 株式会社YAMAP • Webエンジニア • 壁と山を登るのが好きです •
Twitter: @NotFounds8080 • GitHub: @NotFounds
RubyLSPについて
RubyLSPとは • Rubyの言語サーバー • 2022年ごろからShopifyが開発 • 定義ジャンプやセマンティックハイライト、RobocopによるLintなど • プラグイン機構があり、RailsやRSpecの拡張 •
ブログ等で比較的よく紹介されている(気がする)
None
None
None
何かがおかしい...?
RubyLSPに潜む問題 • Definition jumps are not possible with files containing
Japanese characters. · Issue #1347 · Shopify/ruby-lsp · GitHub • 意訳: 日本語が含まれていると動かない • これじゃん!!! • どうやらメンテナも認識しているようだが未対応 • でもどうやって直せばいいんだ...
RubyLSPの問題
RubyLSPの問題 マルチバイト文字の位置計算をいい感じに する(意訳) Prismが位置計算を行うときにエン コーディングを考慮していないから どうにかする必要があるっぽい
RubyLSPの問題 いい感じのAPI生えたし 対応が進みそう!
RubyLSPの仕組み
None
None
class Hoge def fuga puts "Hello" end end Hoge.new.fuga
RubyLSPの仕組み 1. エディタ上で定義ジャンプ { "method": "textDocument/definition", "params": { "textDocument": { "uri": "file://a.rb" }, "position": { "line": 6, "character": 9 } } }
2. positionを先頭から何文字目かに変換 元のファイルでは 6行 9文字目 'class Hoge\ndef fuga\nputs "Hello"\nend\nend\n\nHoge.new.fuga\n'
class Hoge def fuga puts "Hello" end end Hoge.new.fuga RubyLSPの仕組み 53文字目
3. 先頭からの何文字数からノードを取得 抽象構文木(AST)を辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 0~42文字目
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 13~38文字目
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 22~34文字目
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 44~57文字目
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 44~48文字目
3. 先頭からの何文字数からノードを取得 ASTを辿り、53文字目のノードを探す class Hoge def fuga puts "Hello" end
end Hoge.new.fuga RubyLSPの仕組み 53~57文字目
class Hoge def fuga puts "Hello" end end Hoge.new.fuga
RubyLSPの仕組み 4. 事前に作成したコードのIndex(辞書)から対象のノードを探す ノードが見つかったらLSPに結果を返す { "uri": "file://a.rb", "range": { "start": { "line": 1, "character": 2 }, "end": { "line": 3, "character": 5 } } }
RubyLSPの問題(再掲) マルチバイト文字の位置計算をいい感じに する(意訳) Prismが位置計算を行うときにエン コーディングを考慮していないから どうにかする必要があるっぽい
RubyLSPの問題 位置の計算をしているところが問題 • インデックス作成 • 対象ノードを取得 インデックスの位置計算が不正確 ⇒ノードの正しい場所を返せない 対象ノードの取得が不正確 ⇒関係ないノードの場所を返す
RubyLSPの修正
RubyLSPの修正 • 主な修正内容 ◦ LSPを初期化時にエディタから受け取ったencodingを設定 ◦ 位置計算を行っている箇所でPrismの新しいAPIを利用
None
無事動くようになった🎉🎉🎉 Ruby LSP v0.19.2~ 🚀 latest: v0.21.3
まとめ • RubyLSPはRubyの言語サーバー • RubyLSPの仕組みザックリ解説 • 学び ◦ ファイルや文字列を扱うときはエンコーディングに注意 ぜひRubyLSPを試してみてください!
参考文献・資料 • Code indexing: How language servers understand our code
• Language Server Protocol の仕様 及び実装方法 • Ruby LSP | An opinionated language server for Ruby. Batteries included! • https://github.com/Shopify/ruby-lsp/pull/2619 • https://github.com/Shopify/ruby-lsp/pull/2669