Skip to content
Kward Search API index

Class: Kward::PromptInterface::EditorSearch

Inherits:
Object
  • Object
show all
Defined in:
lib/kward/prompt_interface/editor/search.rb

Overview

Incremental search state and operations for editor buffers.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(direction: :forward) ⇒ EditorSearch

Returns a new instance of EditorSearch.



33
34
35
36
37
38
39
# File 'lib/kward/prompt_interface/editor/search.rb', line 33

def initialize(direction: :forward)
  @active = false
  @query = +""
  @direction = direction
  @origin_cursor = nil
  @current_match = nil
end

Instance Attribute Details

#directionObject (readonly)

Returns the value of attribute direction.



7
8
9
# File 'lib/kward/prompt_interface/editor/search.rb', line 7

def direction
  @direction
end

#queryObject (readonly)

Returns the value of attribute query.



7
8
9
# File 'lib/kward/prompt_interface/editor/search.rb', line 7

def query
  @query
end

Class Method Details

.case_sensitive?(query) ⇒ Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/kward/prompt_interface/editor/search.rb', line 29

def self.case_sensitive?(query)
  query.to_s.match?(/[[:upper:]]/)
end

.match_ranges(text, query, base_offset: 0) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/kward/prompt_interface/editor/search.rb', line 9

def self.match_ranges(text, query, base_offset: 0)
  query = query.to_s
  return [] if query.empty?

  haystack, needle = normalized_pair(text.to_s, query)
  ranges = []
  start = 0
  while (index = haystack.index(needle, start))
    ranges << [base_offset + index, base_offset + index + query.length]
    start = index + [query.length, 1].max
  end
  ranges
end

.normalized_pair(buffer, query) ⇒ Object



23
24
25
26
27
# File 'lib/kward/prompt_interface/editor/search.rb', line 23

def self.normalized_pair(buffer, query)
  return [buffer, query] if case_sensitive?(query)

  [buffer.downcase, query.downcase]
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/kward/prompt_interface/editor/search.rb', line 41

def active?
  @active == true
end

#append(text, buffer:, cursor:) ⇒ Object



62
63
64
65
# File 'lib/kward/prompt_interface/editor/search.rb', line 62

def append(text, buffer:, cursor:)
  @query << text.to_s
  live_result(buffer: buffer, cursor: cursor)
end

#begin(direction = :forward, cursor: nil) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/kward/prompt_interface/editor/search.rb', line 45

def begin(direction = :forward, cursor: nil)
  @active = true
  @direction = direction
  @query = +""
  @origin_cursor = cursor
  @current_match = nil
  status_prefix
end

#cancel(restore_cursor: true) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/kward/prompt_interface/editor/search.rb', line 54

def cancel(restore_cursor: true)
  @active = false
  cursor = @origin_cursor if restore_cursor
  @origin_cursor = nil
  @current_match = nil
  { cursor: cursor, status: "Search cancelled", found: false }
end

#confirm(buffer:, cursor:) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/kward/prompt_interface/editor/search.rb', line 72

def confirm(buffer:, cursor:)
  confirmed_query = @query.to_s
  @active = false
  @origin_cursor = nil
  return { status: "Search cancelled", found: false } if confirmed_query.empty?

  if @current_match
    return { cursor: @current_match, status: "Found: #{confirmed_query}", found: true }
  end

  repeat(buffer: buffer, cursor: cursor, direction: @direction, query: confirmed_query)
ensure
  @current_match = nil
end

#delete_character(buffer:, cursor:) ⇒ Object



67
68
69
70
# File 'lib/kward/prompt_interface/editor/search.rb', line 67

def delete_character(buffer:, cursor:)
  @query = @query[0...-1].to_s
  live_result(buffer: buffer, cursor: cursor)
end

#repeat(buffer:, cursor:, direction: @direction, query: @query) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/kward/prompt_interface/editor/search.rb', line 87

def repeat(buffer:, cursor:, direction: @direction, query: @query)
  query = query.to_s
  return { status: "No previous search", found: false } if query.empty?

  @query = query
  @direction = direction
  index = find_match(buffer, query, cursor, direction)

  if index
    { cursor: index, status: "Found: #{query}", found: true }
  else
    { status: "No match: #{query}", found: false }
  end
end