Skip to content
Brett Terpstra edited this page Feb 18, 2022 · 7 revisions

You can add your own commands to Doing by placing ruby files in ~/.config/doing/commands. You can change the location of this folder by adding a path to your config file:

---
plugins:
  command_path: ~/my/path

Doing uses GLI to add subcommands. The Doing module (including configuration, logging, and prompt tools) is always available, and the active WWID object (including the in-memory contents of the parsed Doing file) is available in the global options, the first argument passed to a command block (global[:wwid]).

You can find some example commands in the Doing repo. These mostly show how to use existing commands and apply pre-determined flags and options to create more natural language commands (shortcuts, kind of).

An example command:

desc "Test Stuff"
long_desc "This command is coming from #{__FILE__}"
command [:test] do |c|
  c.action do |global, options, args|
    path = Doing.config.settings.dig('plugins', 'command_path')
    Doing.logger.info('Test:', "Command from #{path}")

    puts global[:wwid].views.join("\t")
  end
end

Put a command like this in your command directory, and when you run doing help, you should see your command listed.

$ doing help test

NAME
    test - Test Stuff

SYNOPSIS

    doing [global options] test



DESCRIPTION
    This command is coming from ~/.config/doing/commands/test.rb

A more detailed example can be seen in the wiki command example.

Commands as Shortcuts

If you want to create a command that serves as a shortcut for an existing command but with preset command line options, duplicate the command from the source code (in bin/doing) and manually set the options keys. Then you can call the original command with those options:

# in the action block of your command:
cmd = commands[:view]
options = { before: 'saturday', after: 'sunday' }
action = cmd.send(:get_action, nil)
return action.call(global_options, options, args)

Adding Subcommands

You can nest commands inside each other (e.g. doing config set ...) using the GLI parser. If you're creating custom commands and can nest them inside parent commands, it means less pollution of the (already heavily populated) top-level namespace.

You can also add a subcommands to an existing command by grabbing the existing command from the commands object. For example, if you wanted a subcommand of search called fuzzy, called with doing search fuzzy "fuzzy search", you could add it like this:

search = commands[:search]

search.desc 'A custom fuzzy searching method'
search.arg_name 'SEARCH_PATTERN'
search.command :fuzzy do |fuzzy|
  fuzzy
  fuzzy.action do |global, options, args|
    
  end
end

All default commands are accessible in this way, and this will work for any files loaded from your plugins.command_path folder.