Class: Rufio::SyntaxHighlighter
- Inherits:
-
Object
- Object
- Rufio::SyntaxHighlighter
- Defined in:
- lib/rufio/syntax_highlighter.rb
Overview
bat コマンドを使ってファイルのシンタックスハイライトを行うクラス。bat が存在しない場合は available? が false を返し、highlight は [] を返す。mtime ベースのキャッシュを持ち、同じファイルの2回目以降は0msで返す。
Instance Method Summary collapse
-
#available? ⇒ Boolean
bat コマンドが利用可能かどうか.
-
#highlight(file_path, max_lines: 50) ⇒ Array<String>
ファイルをシンタックスハイライトして ANSI 付き行の配列を返す(同期版)。 bat が使えない場合、ファイルが存在しない場合は []。.
-
#highlight_async(file_path, max_lines: 50) {|lines| ... } ⇒ Object
ファイルをバックグラウンドスレッドでシンタックスハイライトする(非同期版)。 メインループをブロックせず、bat 完了時にコールバックを呼ぶ。 キャッシュヒット時はコールバックを即時(同期的に)呼ぶ。 同一ファイルへの重複呼び出しは無視する(ペンディングガード)。.
-
#initialize ⇒ SyntaxHighlighter
constructor
A new instance of SyntaxHighlighter.
Constructor Details
#initialize ⇒ SyntaxHighlighter
Returns a new instance of SyntaxHighlighter.
8 9 10 11 12 13 |
# File 'lib/rufio/syntax_highlighter.rb', line 8 def initialize @bat_available = bat_available? @cache = {} # file_path => { mtime: Time, lines: Array<String> } @pending = {} # file_path => true(非同期実行中フラグ) @mutex = Mutex.new end |
Instance Method Details
#available? ⇒ Boolean
bat コマンドが利用可能かどうか
18 19 20 |
# File 'lib/rufio/syntax_highlighter.rb', line 18 def available? @bat_available end |
#highlight(file_path, max_lines: 50) ⇒ Array<String>
ファイルをシンタックスハイライトして ANSI 付き行の配列を返す(同期版)。bat が使えない場合、ファイルが存在しない場合は []。
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/rufio/syntax_highlighter.rb', line 28 def highlight(file_path, max_lines: 50) return [] unless @bat_available return [] unless File.exist?(file_path) mtime = File.mtime(file_path) @mutex.synchronize do cache = @cache[file_path] return cache[:lines] if cache && cache[:mtime] == mtime end lines = run_bat(file_path, max_lines) @mutex.synchronize { @cache[file_path] = { mtime: mtime, lines: lines } } lines rescue => _e [] end |
#highlight_async(file_path, max_lines: 50) {|lines| ... } ⇒ Object
ファイルをバックグラウンドスレッドでシンタックスハイライトする(非同期版)。メインループをブロックせず、bat 完了時にコールバックを呼ぶ。キャッシュヒット時はコールバックを即時(同期的に)呼ぶ。同一ファイルへの重複呼び出しは無視する(ペンディングガード)。
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rufio/syntax_highlighter.rb', line 53 def highlight_async(file_path, max_lines: 50, &callback) return unless @bat_available return unless File.exist?(file_path) mtime = File.mtime(file_path) @mutex.synchronize do # キャッシュヒット → 即時コールバック cache = @cache[file_path] if cache && cache[:mtime] == mtime callback&.call(cache[:lines]) return end # 既にペンディング中 → 重複スレッドを立てない return if @pending[file_path] @pending[file_path] = true end Thread.new do begin lines = run_bat(file_path, max_lines) @mutex.synchronize do @cache[file_path] = { mtime: mtime, lines: lines } @pending.delete(file_path) end callback&.call(lines) rescue => _e @mutex.synchronize { @pending.delete(file_path) } callback&.call([]) end end nil end |