Skip to main content

CLI Interface

Pragtical includes a flexible and extensible command-line interface that allows users to interact with the editor or invoke tools programmatically. As a plugin developer you can extend the CLI to provide custom commands related to the plugin you are developing.

This guide explains how to:

  • Register new commands
  • Add flags and arguments
  • Implement command logic

Registering Custom Commands

To register a custom command, call cli.register(command: core.cli.command) with the command table.

Basic Template

local cli = require "core.cli"

cli.register {
command = "mycmd",
description = "What this command does",
usage = "<arg1> [arg2]",
min_arguments = 1,
max_arguments = 2,
flags = {
{
name = "force",
short_name = "f",
description = "Force action",
type = "boolean"
},
{
name = "tags",
short_name = "t",
description = "Comma-separated tags",
type = "list"
}
},
arguments = {
arg1 = "First argument description",
arg2 = "Optional second argument"
},
execute = function(flags, args)
-- Process logic
print("Custom command executed!")
end
}

Command Table Fields

FieldTypeDescription
commandstringThe subcommand name
descriptionstringShort description shown in help/list
long_descriptionstring?Optional multiline help section
usagestring?Usage string shown in help
min_argumentsinteger?Minimum number of arguments
max_argumentsintegerMax number of arguments (-1 for unlimited)
flagscore.cli.flag[]?Array of supported flags
argumentstable<string,string>?Argument names and their descriptions
executefunction(flags, args)Function to call when invoked
exit_editorboolean (default: true)Whether to exit the editor after executing the command

Flags

FieldTypeDescription
namestringLong flag name (e.g. verbose for --verbose)
short_namestringShort name (e.g. v for -v)
descriptionstringDescription shown in help
type"empty"|...Type: "empty", "string", "number", "boolean", "list"
valueanyAssigned value (populated during parsing)

Subcommands

Commands can have nested subcommands using the subcommands field. Each subcommand is itself a core.cli.command.

cli.register {
command = "tool",
description = "Main tool command",
subcommands = {
{
command = "clean",
description = "Cleans stuff",
execute = function() print("Cleaning") end
},
{
command = "build",
description = "Builds stuff",
execute = function() print("Building") end
}
}
}

Usage:

pragtical tool clean
pragtical tool build

Setting the Default Command

The default command runs when no subcommand is given, while not advised you even have the ability to override or extend it:

--- Modify the core one
table.insert(cli.commands.default.flags, {
name = "myflag",
short_name = "m",
description = "Some custom flag"
})

local old_execute = cli.commands.default.execute
cli.commands.default.execute = function(flags, args)
-- do something custom here
old_execute(flags, args) -- call into original execute
end

--- Replaces it entirely
cli.set_default {
flags = {
{
name = "debug",
short_name = "d",
description = "Enable debug mode",
type = "boolean"
}
},
execute = function(flags, args)
print("Running default logic")
end
}

Unregistering a Command

cli.unregister("mycmd")

API Documentation

More details about the CLI interface can be seen on the core.cli API page.