Module: Rvim::Completion

Defined in:
lib/rvim/completion.rb

Class Method Summary collapse

Class Method Details

.base_at(line, byte_pointer) ⇒ Object

Walk left from byte_pointer over word characters; return the byte slice.



52
53
54
55
56
57
58
59
60
# File 'lib/rvim/completion.rb', line 52

def self.base_at(line, byte_pointer)
  return '' if line.nil? || line.empty?

  i = byte_pointer
  while i > 0 && line.byteslice(i - 1, 1) =~ /\w/
    i -= 1
  end
  line.byteslice(i, byte_pointer - i) || ''
end

.base_start(line, byte_pointer) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/rvim/completion.rb', line 62

def self.base_start(line, byte_pointer)
  return byte_pointer if line.nil? || line.empty?

  i = byte_pointer
  i -= 1 while i > 0 && line.byteslice(i - 1, 1) =~ /\w/
  i
end

.candidates(buffer_lines, base, infercase: false) ⇒ Object

Collect unique w+ tokens from all buffer lines, drop the bare base, filter to those starting with base, sort alphabetically. base = ” returns every distinct word.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rvim/completion.rb', line 8

def self.candidates(buffer_lines, base, infercase: false)
  seen = {}
  buffer_lines.each do |line|
    line.to_s.scan(/\w+/) { |w| seen[w] = true }
  end
  base = base.to_s
  seen.delete(base)
  words = seen.keys

  unless base.empty?
    if infercase
      base_lower = base.downcase
      words = words.select { |w| w.downcase.start_with?(base_lower) }
      words = words.map { |w| match_case_to_base(w, base) }
    else
      words = words.select { |w| w.start_with?(base) }
    end
  end

  words.sort
end

.candidates_dictionary(base) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/rvim/completion.rb', line 96

def self.candidates_dictionary(base)
  return [] unless defined?(Rvim::Spell)

  dict = Rvim::Spell.dict
  return [] if dict.empty? || base.to_s.empty?

  dict.select { |w| w.start_with?(base.to_s.downcase) }.sort.first(50)
end

.candidates_files(base) ⇒ Object



90
91
92
93
94
# File 'lib/rvim/completion.rb', line 90

def self.candidates_files(base)
  glob = base.to_s.empty? ? '*' : "#{base}*"
  paths = Dir.glob(glob)
  paths.map { |p| File.directory?(p) ? "#{p}/" : p }.sort
end

.candidates_lines(buffer_lines, base_line) ⇒ Object



105
106
107
108
109
110
# File 'lib/rvim/completion.rb', line 105

def self.candidates_lines(buffer_lines, base_line)
  base = base_line.to_s
  filtered = buffer_lines.uniq.reject { |l| l.to_s.empty? }
  filtered = filtered.select { |l| l.to_s.start_with?(base) } unless base.empty?
  filtered.reject { |l| l.to_s == base }.sort
end

.match_case_to_base(candidate, base) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rvim/completion.rb', line 30

def self.match_case_to_base(candidate, base)
  return candidate if base.empty?

  n = [base.length, candidate.length].min
  adjusted = candidate.dup
  n.times do |i|
    bc = base[i]
    cc = candidate[i]
    next if bc.nil? || cc.nil?

    adjusted[i] = if bc =~ /[A-Z]/
                   cc.upcase
                 elsif bc =~ /[a-z]/
                   cc.downcase
                 else
                   cc
                 end
  end
  adjusted
end

.path_base_at(line, byte_pointer) ⇒ Object

Filename completion: base is the run of non-whitespace characters to the left of the cursor (so paths like ‘lib/foo’ work).



72
73
74
75
76
77
78
79
80
# File 'lib/rvim/completion.rb', line 72

def self.path_base_at(line, byte_pointer)
  return '' if line.nil? || line.empty?

  i = byte_pointer
  while i > 0 && line.byteslice(i - 1, 1) !~ /\s/
    i -= 1
  end
  line.byteslice(i, byte_pointer - i) || ''
end

.path_base_start(line, byte_pointer) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/rvim/completion.rb', line 82

def self.path_base_start(line, byte_pointer)
  return byte_pointer if line.nil? || line.empty?

  i = byte_pointer
  i -= 1 while i > 0 && line.byteslice(i - 1, 1) !~ /\s/
  i
end