search_ui 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc66d5f87d1370805a30dad557a8831bc5a6e92d58f7a66cfbd1d595894a8643
4
- data.tar.gz: 49a905c0c598310528f07e4bf7edf5cee63da6f522329c6417ca3b5b19834d5c
3
+ metadata.gz: e7d5feb21158fa490f48360724a1e4bd0110a1dd64d89c6bbb79be5bf8de3019
4
+ data.tar.gz: e162cee1ef6035b7ea1305360c88d260b5ebb0b5ecf91fe573a2d0be5c50eaca
5
5
  SHA512:
6
- metadata.gz: 36333f847712de6afc618fd6f8671b8ad693c9d929056863a959920bbed0d23cc888d4043ddddfe122a6f284128bfee8983cf0a2d45bf13cdcf0ff80c15c795c
7
- data.tar.gz: 39b38086ac623ab6b918e56a3828396439dd383dec601c71c99ecb6124f327f00a47ce0b045935ef7fab84c7d0f349ea111650c3cfd1b1f5f1bc1757b63913a5
6
+ metadata.gz: 66b6d79977ab604dc5cb1fec8bb6c5e9467ac80af1a7ad4e95dab2466aa6c5d48f98e5b4e3fd820a1522f16dfcd88e02690759a09ef8d906f21a3d8e6d32a079
7
+ data.tar.gz: eebad124b4790a0059b7ce0fd7b337cbb55d439035a04e869ca6d040130a333b3d63531ed21d40b0745200493831cc653513ff3c4b7d2324a94172ac67d8fa38
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -18,35 +18,54 @@ class SearchUI::Search
18
18
  include Term::ANSIColor
19
19
  extend Term::ANSIColor
20
20
 
21
- # Initializes a new SearchUI::Search instance with the specified parameters.
21
+ # Represents the current state of the search interface.
22
22
  #
23
- # @param match [ Proc ] a procedure that takes a string and returns an array
24
- # of matching objects
25
- # @param query [ Proc ] a procedure that takes the current answer, matches,
26
- # and selector index to generate a query result
27
- # @param found [ Proc ] a procedure that takes the current answer, matches,
28
- # jand selector index to determine if a selection has been made
29
- # @param output [ IO ] the output stream to display the search interface
30
- # (defaults to STDOUT)
31
- # @param prompt [ String ] the prompt template to display during searching
32
- # (defaults to 'Search? %s')
23
+ # @attr answer [ String ] the current input string entered by the user
24
+ # @attr selector [ Integer ] the index of the currently selected match
25
+ State = Struct.new(:answer, :selector)
26
+
27
+ # Initializes a new SearchUI::Search instance to manage an interactive
28
+ # console search interface. This method sets up the filtering logic, display
29
+ # formatting, and selection criteria required to drive the search loop, as
30
+ # well as the output stream and prompt.
31
+ #
32
+ # @param match [ Proc ] a procedure that accepts a search pattern string and returns
33
+ # an array of matching objects.
34
+ # @param query [ Proc ] a procedure that accepts the current answer, the list of
35
+ # matches, and the current selector index to generate the string representation
36
+ # of the results list.
37
+ # @param found [ Proc ] a procedure that accepts the current answer, the list of
38
+ # matches, and the current selector index to determine the final selected object.
39
+ # @param output [ IO ] the output stream where the interface will be rendered.
40
+ # Defaults to STDOUT.
41
+ # @param prompt [ String ] a format string used as the user prompt.
42
+ # Defaults to 'Search? %s'.
43
+ # @param state [ SearchUI::Search::State, nil ] an initial state object containing
44
+ # the starting answer and selector position. Defaults to a new State with an
45
+ # empty answer and selector set to 0.
33
46
  def initialize(
34
47
  match:,
35
48
  query:,
36
49
  found:,
37
50
  output: STDOUT,
38
- prompt: 'Search? %s'
51
+ prompt: 'Search? %s',
52
+ state: nil
39
53
  )
40
54
  @match = match
41
55
  @query = query
42
56
  @found = found
43
57
  @output = output
44
58
  @prompt = prompt
45
- @selector = 0
46
- @max_selector = nil
47
- @answer = ''
59
+ @state = state || State.new('', 0)
48
60
  end
49
61
 
62
+ # Reads the current internal state of the search interface, containing the
63
+ # current input answer and the active selection index.
64
+ #
65
+ # @return [ SearchUI::Search::State ] the current state object tracking
66
+ # the user's search progress and cursor position
67
+ attr_reader :state
68
+
50
69
  # Starts the interactive search interface and handles user input until a
51
70
  # selection is made or the process is cancelled.
52
71
  #
@@ -54,16 +73,16 @@ class SearchUI::Search
54
73
  # is made, or nil if the process is cancelled
55
74
  def start
56
75
  @output.print reset
57
- @matches = @match.(@answer)
58
- @selector = @selector.clamp(0, [ @matches.size - 1, 0 ].max)
59
- result = @query.(@answer, @matches, @selector)
76
+ @matches = @match.(@state.answer)
77
+ @state.selector = @state.selector.clamp(0, [ @matches.size - 1, 0 ].max)
78
+ result = @query.(@state.answer, @matches, @state.selector)
60
79
  loop do
61
80
  @output.print clear_screen
62
- @output.print move_home { @prompt % @answer + ?\n + result }
81
+ @output.print move_home { @prompt % @state.answer + ?\n + result }
63
82
  case getc
64
83
  when true
65
84
  @output.print clear_screen, move_home, reset
66
- if result = @found.(@answer, @matches, @selector)
85
+ if result = @found.(@state.answer, @matches, @state.selector)
67
86
  return result
68
87
  else
69
88
  return nil
@@ -71,26 +90,33 @@ class SearchUI::Search
71
90
  when false
72
91
  return nil
73
92
  end
74
- @matches = @match.(@answer)
75
- @selector = @selector.clamp(0, [ @matches.size - 1, 0 ].max)
76
- result = @query.(@answer, @matches, @selector)
93
+ @matches = @match.(@state.answer)
94
+ @state.selector = @state.selector.clamp(0, [ @matches.size - 1, 0 ].max)
95
+ result = @query.(@state.answer, @matches, @state.selector)
77
96
  end
78
97
  end
79
98
 
80
99
  private
81
100
 
82
- # Reads and processes a single character input from stdin, handling special
101
+ # Reads and processes a single character input from STDIN, handling special
83
102
  # key sequences and updating the search state accordingly.
84
103
  #
85
104
  # This method manages raw terminal input to capture user keystrokes,
86
- # interpreting control characters and escape sequences for navigation,
87
- # selection, and editing operations. It temporarily disables terminal echo
88
- # and sets raw mode to ensure proper input handling.
105
+ # interpreting control characters and ANSI escape sequences:
106
+ # - Up/Down arrows: Navigate the result selector.
107
+ # - Enter (`\r`): Confirms the current selection.
108
+ # - Ctrl-C (`\x03`): Cancels the search operation.
109
+ # - Ctrl-K (`\v`): Clears the current search answer.
110
+ # - Backspace (`\x7f`): Deletes the last character of the answer.
111
+ # - Note: Any modification to the search answer resets the selector to 0.
112
+ #
113
+ # It temporarily disables terminal echo and sets raw mode to ensure proper
114
+ # input handling.
89
115
  #
90
- # @return [ Boolean, nil ] returns true when the Enter key is pressed to
91
- # confirm selection, false when Ctrl+C is pressed to cancel the operation, or
92
- # nil for all other inputs
93
- # which update the search state and require further processing
116
+ # @return [ Boolean, nil ]
117
+ # - `true`: The Enter key was pressed to confirm selection.
118
+ # - `false`: Ctrl-C was pressed to cancel the operation.
119
+ # - `nil`: Input updated the search state or was ignored.
94
120
  def getc
95
121
  print hide_cursor
96
122
  system 'stty raw -echo'
@@ -103,27 +129,27 @@ class SearchUI::Search
103
129
  STDIN.getc == ?[ or return nil
104
130
  STDIN.getc =~ /\A([AB])\z/ or return nil
105
131
  if $1 == ?A
106
- @selector -= 1
132
+ @state.selector -= 1
107
133
  else
108
- @selector += 1
134
+ @state.selector += 1
109
135
  end
110
- @selector = [ @selector, 0 ].max
136
+ @state.selector = [ @state.selector, 0 ].max
111
137
  nil
112
138
  when ?\r
113
139
  true
114
140
  when "\x7f"
115
- @selector = 0
116
- @answer.chop!
141
+ @state.selector = 0
142
+ @state.answer.chop!
117
143
  nil
118
- when "\v"
119
- @selector = 0
120
- @answer.clear
144
+ when ?\v
145
+ @state.selector = 0
146
+ @state.answer.clear
121
147
  nil
122
148
  when /\A[\x00-\x1f]\z/
123
149
  nil
124
150
  else
125
- @selector = 0
126
- @answer << c
151
+ @state.selector = 0
152
+ @state.answer << c
127
153
  nil
128
154
  end
129
155
  ensure
@@ -1,6 +1,6 @@
1
1
  module SearchUI
2
2
  # SearchUI version
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/search_ui.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: search_ui 0.1.0 ruby lib
2
+ # stub: search_ui 0.2.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "search_ui".freeze
6
- s.version = "0.1.0".freeze
6
+ s.version = "0.2.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
@@ -18,13 +18,13 @@ Gem::Specification.new do |s|
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "SearchUI -- Search User Interface".freeze, "--main".freeze, "README.md".freeze]
20
20
  s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
21
- s.rubygems_version = "4.0.3".freeze
21
+ s.rubygems_version = "4.0.10".freeze
22
22
  s.summary = "Library to provide a user interface for searching in a console".freeze
23
23
  s.test_files = ["spec/search_ui/wrapper_spec.rb".freeze, "spec/spec_helper.rb".freeze]
24
24
 
25
25
  s.specification_version = 4
26
26
 
27
- s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.17.0".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.17.1".freeze])
28
28
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.0".freeze])
29
29
  s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.0".freeze])
30
30
  s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 2.17.0
18
+ version: 2.17.1
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 2.17.0
25
+ version: 2.17.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  requirements: []
161
- rubygems_version: 4.0.3
161
+ rubygems_version: 4.0.10
162
162
  specification_version: 4
163
163
  summary: Library to provide a user interface for searching in a console
164
164
  test_files: