-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
completer.rb
100 lines (85 loc) · 2.43 KB
/
completer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
89
90
91
92
93
94
95
96
97
98
99
100
# frozen_string_literal: true
require_relative "completions"
module TTY
class Reader
# Responsible for word completion
#
# @api private
class Completer
# The completion suggestions
attr_reader :completions
# The handler for finding word completion suggestions
attr_reader :handler
# The word to complete
attr_reader :word
# Create a Completer instance
#
# @api private
def initialize(handler: nil)
@handler = handler
@completions = Completions.new
@show_initial = false
@word = ""
end
# Find a suggestion to complete a word
#
# @param [Line] line
# the line to complete a word in
#
# @return [Boolean, String]
# the completed word or false when no suggestion is found
#
# @api public
def complete(line, initial: false)
initial ? complete_initial(line) : complete_next(line)
end
# Find suggestions and complete the initial word
#
# @param [Line] line
# the line to complete a word in
#
# @return [Boolean, String]
# the completed word or false when no suggestion is found
#
# @api public
def complete_initial(line)
@word = line.word_to_complete
suggestions = handler.(word)
completions.clear
return false if suggestions.empty?
completions.concat(suggestions)
completed_word = completions.get
line.remove(word.length)
line.insert(completed_word)
completed_word
end
# Complete a word with the next suggestion from completions
#
# @param [Line] line
# the line to complete a word in
#
# @return [Boolean, String]
# the completed word or false when no suggestion is found
#
# @api public
def complete_next(line)
return false if completions.empty?
previous_suggestion = completions.get
if completions.last? && !@show_initial
@show_initial = true
completed_word = word
else
if @show_initial
@show_initial = false
previous_suggestion = word
end
completions.next
completed_word = completions.get
end
line.remove(previous_suggestion.length)
line.insert(completed_word)
completed_word
end
end # Completer
end # Reader
end # TTY