Class: Rubino::Commands::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/commands/loader.rb

Overview

Discovers and manages custom slash commands from configured paths.

Constant Summary collapse

COMMAND_GLOB =
"*.md"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: nil) ⇒ Loader

Returns a new instance of Loader.



9
10
11
12
13
# File 'lib/rubino/commands/loader.rb', line 9

def initialize(config: nil)
  @config = config || Rubino.configuration
  @commands = {}
  @discovered = false
end

Class Method Details

.default_command_pathsObject

Default search paths, with the home sentinel resolved to a real dir. Used by the loader and the “/commands” empty-state copy so both report the directories actually searched (RUBINO_HOME-aware).



73
74
75
# File 'lib/rubino/commands/loader.rb', line 73

def self.default_command_paths
  Array(Config::Defaults.to_hash.dig("commands", "paths")).map { |p| resolve_path(p) }
end

.resolve_path(dir) ⇒ Object

Resolves a configured commands path to an absolute directory, expanding the <RUBINO_HOME>/commands sentinel against the resolved home (RUBINO_HOME -> else ~/.rubino) instead of a literal ~/.rubino (#38).



80
81
82
83
84
85
86
87
# File 'lib/rubino/commands/loader.rb', line 80

def self.resolve_path(dir)
  if dir.to_s.start_with?(Config::Defaults::HOME_COMMANDS_PATH)
    suffix = dir.to_s.sub(Config::Defaults::HOME_COMMANDS_PATH, "")
    File.join(Config::Loader.default_home_path, "commands#{suffix}")
  else
    File.expand_path(dir)
  end
end

Instance Method Details

#allObject

Returns all discovered commands



32
33
34
35
# File 'lib/rubino/commands/loader.rb', line 32

def all
  discover! unless @discovered
  @commands.values
end

#discover!Object

Discovers all available commands



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rubino/commands/loader.rb', line 16

def discover!
  @commands.clear
  command_paths.each do |dir|
    expanded = self.class.resolve_path(dir)
    next unless File.directory?(expanded)

    Dir.glob(File.join(expanded, COMMAND_GLOB)).each do |path|
      cmd = Command.new(path: path)
      @commands[cmd.name] = cmd
    end
  end
  @discovered = true
  @commands
end

#find(name) ⇒ Object

Finds a command by name (without the leading /)



38
39
40
41
# File 'lib/rubino/commands/loader.rb', line 38

def find(name)
  discover! unless @discovered
  @commands[name.to_s.sub(%r{\A/}, "")]
end

#namesObject

Returns command names for autocomplete



60
61
62
# File 'lib/rubino/commands/loader.rb', line 60

def names
  all.map { |c| "/#{c.name}" }
end

#parse(input) ⇒ Object

Parses a slash command input into [command_name, arguments]



49
50
51
52
53
54
55
56
57
# File 'lib/rubino/commands/loader.rb', line 49

def parse(input)
  stripped = input.strip
  return nil unless stripped.start_with?("/")

  parts = stripped[1..].split(/\s+/, 2)
  command_name = parts[0]
  arguments = parts[1] || ""
  [command_name, arguments]
end

#slash_command?(input) ⇒ Boolean

Returns true if input starts with a slash command

Returns:

  • (Boolean)


44
45
46
# File 'lib/rubino/commands/loader.rb', line 44

def slash_command?(input)
  input.strip.start_with?("/")
end