Class: Lightning::Completion

Inherits:
Object
  • Object
show all
Defined in:
lib/lightning/completion.rb

Overview

This class returns completions for the last word typed for a given lightning function and its Function object. Inspired loosely by ryanb.

Regex Completion

By default, regular expressions can be used while completing to filter/match possible completions. For duplicate paths that offer their full paths in completion, this means their full paths can also match. One non-regexp shorthand is that a ‘*’ is converted to ‘.*’ for glob-like behavior.To revert to standard completion, toggle Lightning.config.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text_typed, function, shellescape = true) ⇒ Completion

Returns a new instance of Completion.



25
26
27
28
29
# File 'lib/lightning/completion.rb', line 25

def initialize(text_typed, function, shellescape=true)
  @text_typed = text_typed
  @function = function
  @shellescape = shellescape
end

Class Method Details

.complete(text_to_complete, function, shellescape = true) ⇒ Array

Returns completions that match last word typed

Returns:

  • (Array)

    Returns completions that match last word typed



14
15
16
17
# File 'lib/lightning/completion.rb', line 14

def self.complete(text_to_complete, function, shellescape=true)
  return error_array("No function found to complete.") unless function
  new(text_to_complete, function, shellescape).matches
end

.error_array(message) ⇒ Array

gets displayed and not completed

Returns:

  • (Array)

    Constructs completion error message. More than one element long to ensure error message



21
22
23
# File 'lib/lightning/completion.rb', line 21

def self.error_array(message)
  ["#Error: #{message}", "Please open an issue."]
end

Instance Method Details

#blob_to_regex(string) ⇒ Object



78
79
80
# File 'lib/lightning/completion.rb', line 78

def blob_to_regex(string)
  string.gsub(/^\*|([^\.])\*/) {|e| $1 ? $1 + ".*" : ".*" }
end

#get_matches(possible) ⇒ Array

Returns Selects possible completions that match using typed.

Parameters:

  • (Array)

Returns:

  • (Array)

    Selects possible completions that match using typed



44
45
46
47
# File 'lib/lightning/completion.rb', line 44

def get_matches(possible)
  Lightning.config[:complete_regex] ? possible.grep(/^#{blob_to_regex(typed)}/) :
    possible.select {|e| e[0, typed.length] == typed }
end

#match_when_completing_subdirectories(matched) ⇒ Array

Returns Generates completions when completing a directory above or below a basename.

Parameters:

  • (Array)

Returns:

  • (Array)

    Generates completions when completing a directory above or below a basename



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/lightning/completion.rb', line 51

def match_when_completing_subdirectories(matched)
  if matched.empty? && (top_dir = typed[/^([^\/]+)\//,1]) && !typed.include?('//')
    matched = possible_completions.grep(/^#{top_dir}/)

    # for typed = some/dir/file, top_dir = path and translated_dir = /full/bolt/path
    if matched.size == 1 && (translated_dir = @function.translate([top_dir])[0])
      short_dir = typed.sub(/\/([^\/]+)?$/, '')  # some/dir
      completed_dir = short_dir.sub(top_dir, translated_dir) #/full/bolt/path/some/dir
      completed_dir = File.expand_path(completed_dir) if completed_dir[/\/\.\.($|\/)/]
      matched = Dir.entries(completed_dir).delete_if {|e| %w{. ..}.include?(e) }.map {|f|
        File.directory?(completed_dir+'/'+f) ? File.join(short_dir,f) +'/' : File.join(short_dir,f)
      }
      matched = get_matches(matched)
    end
  end
  matched
end

#matchesArray

Returns Main method to determine and return completions that match.

Returns:

  • (Array)

    Main method to determine and return completions that match



32
33
34
35
36
37
38
39
40
# File 'lib/lightning/completion.rb', line 32

def matches
  matched = get_matches(possible_completions)
  matched = match_when_completing_subdirectories(matched)
  @shellescape ? matched.map {|e| Util.shellescape(e) } : matched
rescue SystemCallError
  self.class.error_array("Nonexistent directory.")
rescue RegexpError
  self.class.error_array("Invalid regular expression.")
end

#typedString

Returns Last word typed by user.

Returns:

  • (String)

    Last word typed by user



70
71
72
73
74
75
# File 'lib/lightning/completion.rb', line 70

def typed
  @typed ||= begin
    args = Shellwords.shellwords(@text_typed)
    !args[-1][/\s+/] && @text_typed[/\s+$/] ? '' : args[-1]
  end
end