1
0
mirror of https://github.com/Morantron/tmux-fingers.git synced 2024-06-28 07:40:57 +02:00
tmux-fingers/lib/fingers/hinter.rb

137 lines
2.7 KiB
Ruby
Raw Permalink Normal View History

2020-05-02 11:45:56 +02:00
class ::Fingers::Hinter
def initialize(
input:,
width:,
state:,
2022-07-06 16:46:12 +02:00
output:, patterns: Fingers.config.patterns,
2020-05-02 11:45:56 +02:00
alphabet: Fingers.config.alphabet,
huffman: Huffman.new,
formatter: ::Fingers::MatchFormatter.new
2020-05-02 11:45:56 +02:00
)
@input = input
@width = width
@hints_by_text = {}
@state = state
@output = output
@formatter = formatter
@huffman = huffman
2020-05-02 11:45:56 +02:00
@patterns = patterns
@alphabet = alphabet
end
def run
lines[0..-2].each { |line| process_line(line, "\n") }
2022-07-06 16:46:12 +02:00
process_line(lines[-1], "")
2020-05-02 11:45:56 +02:00
STDOUT.flush
2022-05-18 15:11:54 +02:00
output.flush
2020-05-02 11:45:56 +02:00
build_lookup_table!
end
def lookup(hint)
lookup_table[hint]
end
2022-04-24 16:45:06 +02:00
def matches
@matches ||= @hints_by_text.keys.uniq.flatten
end
2020-05-02 11:45:56 +02:00
private
attr_reader :hints,
2022-07-06 16:46:12 +02:00
:hints_by_text,
:input,
:lookup_table,
:width,
:state,
:formatter,
:huffman,
:output,
:patterns,
:alphabet
2020-05-02 11:45:56 +02:00
def build_lookup_table!
@lookup_table = hints_by_text.invert
end
def process_line(line, ending)
2023-03-27 09:23:45 +02:00
Fingers.logger.info("processing line")
2020-05-02 11:45:56 +02:00
result = line.gsub(pattern) { |_m| replace($~) }
output.print(result + ending)
end
def pattern
2022-07-06 16:46:12 +02:00
@pattern ||= Regexp.compile("(#{patterns.join("|")})")
2020-05-02 11:45:56 +02:00
end
def hints
return @hints if @hints
@hints = huffman.generate_hints(alphabet: alphabet, n: n_matches)
2020-05-02 11:45:56 +02:00
end
def replace(match)
text = match[0]
2023-03-27 09:23:45 +02:00
#captured_text = match && match.named_captures["capture"] || text
captured_text = match && match || text
2020-05-02 11:45:56 +02:00
2023-03-27 09:23:45 +02:00
#if match.named_captures["capture"]
#match_start, match_end = match.offset(0)
#capture_start, capture_end = match.offset(:capture)
2020-05-02 11:45:56 +02:00
2023-03-27 09:23:45 +02:00
#capture_offset = [capture_start - match_start, capture_end - capture_start]
#else
2020-05-02 11:45:56 +02:00
capture_offset = nil
2023-03-27 09:23:45 +02:00
#end
2023-05-23 14:46:14 +02:00
# Converting match data to string
captured_text = captured_text.to_s
2020-05-02 11:45:56 +02:00
if hints_by_text.has_key?(captured_text)
hint = hints_by_text[captured_text]
else
hint = hints.pop
hints_by_text[captured_text] = hint
end
2023-03-27 09:23:45 +02:00
2020-05-02 11:45:56 +02:00
# TODO: this should be output hint without ansi escape sequences
formatter.format(
hint: hint,
highlight: text,
selected: state.selected_hints.include?(hint),
offset: capture_offset
)
2023-03-27 09:23:45 +02:00
2020-05-02 11:45:56 +02:00
end
def lines
2023-03-27 09:23:45 +02:00
@lines ||= input.split("\n")
2020-05-02 11:45:56 +02:00
end
def n_matches
return @n_matches if @n_matches
match_set = ::Set.new
2020-05-02 11:45:56 +02:00
2022-07-06 16:46:12 +02:00
Fingers.benchmark_stamp("counting-matches:start")
2020-05-02 11:45:56 +02:00
lines.each do |line|
2023-03-27 09:23:45 +02:00
Fingers.logger.info("line: #{line}")
Fingers.logger.info("pattern: #{pattern}")
Fingers.logger.info("----")
2021-08-08 20:43:01 +02:00
line.scan(pattern) do |match|
match_set.add($&)
end
end
2020-05-02 11:45:56 +02:00
2022-07-06 16:46:12 +02:00
Fingers.benchmark_stamp("counting-matches:end")
2020-05-02 11:45:56 +02:00
@n_matches = match_set.length
2020-05-02 11:45:56 +02:00
@n_matches
2020-05-02 11:45:56 +02:00
end
end