Module: Rush::Completion

Included in:
Shell
Defined in:
lib/rush/shell/completion.rb

Overview

Paths, executables and methods copmletion module.

Constant Summary collapse

TEMPLATES =
{
  constant: {
    regexp: /[A-Z](\w|_)+/,
    method: :complete_constant
  },
  object_constant: {
    regexp: /^([A-Z](\w|_)+::)+[A-Z](\w|_)+$/,
    method: :complete_object_constant
  },
  global_method: {
    regexp: /^[a-z](\w|_)+$/,
    method: :complete_global_method
  },
  method: {
    regexp: /^(((\w|_)+(\.|::))+)((\w|_)+)$/,
    method: :complete_method
  },
  path: {
    regexp: /^(\w|_|.|:| )+[\[\/][\'\"].*$/,
    method: :complete_path
  }
}

Instance Method Summary collapse

Instance Method Details

#complete(input) ⇒ Object

The complete method itself. Types of completed lines:

kernel constants, global variables, executables:
  CON<tab> -- constant;
  met<tab> -- method/variable name;
  execu<tab> -- executable file from PATH environment variable;
given module/class constants:
  Object::CON<tab> -- constant of given module/class;
methods:
  Object.met<tab> -- method of object;
  Object.method1.meth<tab>;
  variable.met<tab>;
  variable.method1.method2.met<tab> -- method number N in chain;
paths:
  box['pa<tab. -- relative to box path;
  box['path/to/fi<tab> -- relative path with multiple lvls;
  box/'pa<tab> -- another syntax to relative path;
  box/'path/to/fi<tab> -- the same;

Parameters:

  • input (String)

    part of line from last space/beginning of line.



27
28
29
30
31
32
33
# File 'lib/rush/shell/completion.rb', line 27

def complete(input)
  TEMPLATES.values
    .select { |x| x[:regexp].match input }
    .map    { |x| send x[:method], input }
    .flatten
    .compact
end

#complete_constant(input) ⇒ Object



58
59
60
# File 'lib/rush/shell/completion.rb', line 58

def complete_constant(input)
  Object.constants.map(&:to_s).select { |x| x.start_with? input }.sort
end

#complete_for(the_binding, method_part) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/rush/shell/completion.rb', line 81

def complete_for(the_binding, method_part)
  lvars = eval('local_variables', the_binding)
  gvars = eval('global_variables', the_binding)
  ivars = eval('instance_variables', the_binding)
  mets = eval('methods', the_binding)
  (executables + lvars + gvars + ivars + mets)
    .map(&:to_s)
    .select { |e| e.start_with? method_part }
end

#complete_global_method(input) ⇒ Object



70
71
72
# File 'lib/rush/shell/completion.rb', line 70

def complete_global_method(input)
  complete_for(pure_binding, input)
end

#complete_method(input) ⇒ Object



74
75
76
77
78
79
# File 'lib/rush/shell/completion.rb', line 74

def complete_method(input)
  receiver, delimiter, method_part = *input.rpartition('.')
  the_binding = eval(receiver, pure_binding).instance_eval('binding')
  complete_for(the_binding, method_part)
    .map { |x| receiver + delimiter + x }
end

#complete_object_constant(input) ⇒ Object



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

def complete_object_constant(input)
  receiver, delimiter, const_part = *input.rpartition('::')
  eval(receiver, pure_binding).constants
    .map(&:to_s)
    .select { |x| x.start_with? const_part }
    .map    { |x| receiver + delimiter + x }
end

#complete_path(input) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rush/shell/completion.rb', line 95

def complete_path(input)
  delimiters = %w([' [" /' /")
  delimiter = delimiters.find { |x| input.include? x }
  object, _, path = *input.rpartition(delimiter)
  path_done, _, path_part = path.rpartition('/')
  return [] unless eval(object, pure_binding).class == Rush::Dir
  box = eval(object + "/'" + path_done + "'", pure_binding)
  box.entries
    .map(&:name)
    .select { |x| x.start_with? path_part }
    .map { |x| object + delimiter + path_done + '/' + x }
end

#executablesObject



91
92
93
# File 'lib/rush/shell/completion.rb', line 91

def executables
  Rush::Path.executables
end