mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Extensions
- Created scripts/extensions/README to describe samples. - Created sample extension scripts of each type.
This commit is contained in:
parent
bac4610580
commit
60a5d271f4
10 changed files with 335 additions and 55 deletions
16
scripts/add-ons/README
Normal file
16
scripts/add-ons/README
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
External Scripts
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Add-on scripts are executed vi an alias mechanism in taskwarrior. This has the
|
||||||
|
effect of this command:
|
||||||
|
|
||||||
|
task <script> <arguments>
|
||||||
|
|
||||||
|
resulting in the ultimate execution of:
|
||||||
|
|
||||||
|
<script> <arguments>
|
||||||
|
|
||||||
|
All external scripts are treated in the same manner, and have no access to the
|
||||||
|
taskwarrior internals.
|
||||||
|
|
||||||
|
---
|
|
@ -1,8 +1,100 @@
|
||||||
There are several types of extension:
|
Extensions
|
||||||
|
----------
|
||||||
|
|
||||||
- Hook-based
|
Extensions are Lua scripts that require installation and configuration, and when
|
||||||
- User Defined Attribute
|
invoked have access to taskwarrior internals through a Lua API.
|
||||||
- Command
|
|
||||||
- Format
|
There are several types of extension. Each type has different requirements, and
|
||||||
- DOM
|
is called in different ways.
|
||||||
|
|
||||||
|
All extensions must be installed, which means they must implement the 'install'
|
||||||
|
function, which provides:
|
||||||
|
|
||||||
|
- Type One of: program, task, uda, command, format, dom
|
||||||
|
- Name Single word name
|
||||||
|
- Version Version string
|
||||||
|
- Description One to two line description
|
||||||
|
- Author Author's name
|
||||||
|
- Contact Author's contact
|
||||||
|
- License Distribution License
|
||||||
|
- Copyright Copyright notice
|
||||||
|
|
||||||
|
|
||||||
|
Program Hooks
|
||||||
|
-------------
|
||||||
|
|
||||||
|
These are scripts that are triggered by program-level events. The supported
|
||||||
|
program hooks are:
|
||||||
|
|
||||||
|
on-launch As soon as is convenient after program launch
|
||||||
|
on-exit As late as possible while still providing API
|
||||||
|
on-file-read Immediately before reading a data file
|
||||||
|
on-file-write Immediately after writing a data file
|
||||||
|
on-synch Immediately before a synch operation
|
||||||
|
on-merge Immediately before a merge operation
|
||||||
|
on-gc Immediately before a GC operation
|
||||||
|
|
||||||
|
When a program hook script is invoked, there is no context, so no arguments are
|
||||||
|
passed to the script.
|
||||||
|
|
||||||
|
|
||||||
|
Task Hooks
|
||||||
|
----------
|
||||||
|
|
||||||
|
These scripts are triggered by task-specific events. The supported task hooks
|
||||||
|
are:
|
||||||
|
|
||||||
|
on-task-add Immediately prior to committing an added task
|
||||||
|
on-task-modify Immediately prior to committing a modified task
|
||||||
|
on-task-complete Immediately prior to committing a completed task
|
||||||
|
on-task-delete Immediately prior to committing a deleted task
|
||||||
|
|
||||||
|
When a task hook script is invoked, the context is a specific task, and so the
|
||||||
|
task uuid is passed as the only argument.
|
||||||
|
|
||||||
|
|
||||||
|
User Defined Attribute
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
It is possible to create a user-defined attribute with a UDA extension. These
|
||||||
|
extensions must provide:
|
||||||
|
|
||||||
|
- Data type (string, date, duration, integer, real, custom)
|
||||||
|
- Custom types must implement a compare function for sorting
|
||||||
|
- Default format rendering
|
||||||
|
- Allowed value checking
|
||||||
|
|
||||||
|
|
||||||
|
Command
|
||||||
|
-------
|
||||||
|
|
||||||
|
It is possible to implement a command using an extension. These extensions must
|
||||||
|
provide:
|
||||||
|
|
||||||
|
- BNF command syntax
|
||||||
|
- Declaration as read-only or write command, which allows taskwarrior to
|
||||||
|
allow this command when the database is read-only
|
||||||
|
- Declaration of whether the command displays ID values, which instructs
|
||||||
|
taskwarrior to run a GC beforehan
|
||||||
|
|
||||||
|
|
||||||
|
Format
|
||||||
|
------
|
||||||
|
|
||||||
|
A format extension is one that provides custom rendering for an attribute.
|
||||||
|
These extensions must provide:
|
||||||
|
|
||||||
|
- Must implement a format function.
|
||||||
|
|
||||||
|
|
||||||
|
DOM
|
||||||
|
---
|
||||||
|
|
||||||
|
DOM extensions provide a DOM address and can be called to respond to that name.
|
||||||
|
These extensions must provide:
|
||||||
|
|
||||||
|
- DOM name
|
||||||
|
- Evaluation function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
45
scripts/extensions/command.lua
Normal file
45
scripts/extensions/command.lua
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
-- Command Extension.
|
||||||
|
-- Implementing 'random'.
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'command', -- Type
|
||||||
|
'random', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Displays a random pending task', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: Valid Taskwarrior BNF, minimally defining a production rule that
|
||||||
|
-- has the same name as the command itself
|
||||||
|
function syntax ()
|
||||||
|
return 'random ::= "random" ;'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: 1 --> command does not modify data
|
||||||
|
-- 0 --> command modifies data
|
||||||
|
function read_only ()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: 1 --> command displays task ID
|
||||||
|
-- 0 --> no ID dispalyed
|
||||||
|
function display_id ()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: 1, 'error' --> command failed
|
||||||
|
-- 0, nil --> success
|
||||||
|
function execute ()
|
||||||
|
return 1, 'Not implemented'
|
||||||
|
end
|
||||||
|
|
24
scripts/extensions/dom.lua
Normal file
24
scripts/extensions/dom.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
-- DOM Extension.
|
||||||
|
-- Implementing 'system.load.average'.
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'dom', -- Type
|
||||||
|
'system.load.average', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Provides access to system load', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: The DOM reference to evaluate
|
||||||
|
-- Returns: The value from the DOM lookup
|
||||||
|
-- Note: 'name' may include '*' wildcards
|
||||||
|
function lookup (name)
|
||||||
|
return 1.23 -- Fake load average
|
||||||
|
end
|
||||||
|
|
23
scripts/extensions/format.lua
Normal file
23
scripts/extensions/format.lua
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
-- Format Extension.
|
||||||
|
-- Implementing 'uuid.short'
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'format', -- Type
|
||||||
|
'uuid.short', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Provides short formatted UUIDs', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Argument: Value to be formatted
|
||||||
|
-- Returns: Formatted value
|
||||||
|
function format (value)
|
||||||
|
return string.sub (value, 0, 8)
|
||||||
|
end
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- taskwarrior - a command line task list manager.
|
|
||||||
--
|
|
||||||
-- Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
|
|
||||||
-- All rights reserved.
|
|
||||||
--
|
|
||||||
-- This program is free software; you can redistribute it and/or modify it under
|
|
||||||
-- the terms of the GNU General Public License as published by the Free Software
|
|
||||||
-- Foundation; either version 2 of the License, or (at your option) any later
|
|
||||||
-- version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
-- details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License along with
|
|
||||||
-- this program; if not, write to the
|
|
||||||
--
|
|
||||||
-- Free Software Foundation, Inc.,
|
|
||||||
-- 51 Franklin Street, Fifth Floor,
|
|
||||||
-- Boston, MA
|
|
||||||
-- 02110-1301
|
|
||||||
-- USA
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- Extension to implement 'priority' as a user-defined attribute.
|
|
||||||
|
|
||||||
-- Required for all extensions.
|
|
||||||
function install ()
|
|
||||||
return 'Priority', -- Name
|
|
||||||
1.0, -- Version
|
|
||||||
'uda', -- Type
|
|
||||||
'Implements priority attribute', -- Description
|
|
||||||
'Paul Beckingham', -- Author
|
|
||||||
'paul@beckingham.net', -- Contact
|
|
||||||
'© 2011, Göteborg Bit Factory' -- Copyright
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO Required for UDA extensions.
|
|
||||||
|
|
31
scripts/extensions/program_hook.lua
Normal file
31
scripts/extensions/program_hook.lua
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
-- Program Hook Extension.
|
||||||
|
-- Implementing goodbye message.
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'program', -- Type
|
||||||
|
'goodbye', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Simply says goodbye', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: String identifying valid program hook
|
||||||
|
function hook ()
|
||||||
|
return 'on-exit'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: 1, 'error' --> failure
|
||||||
|
-- 0, nil --> success
|
||||||
|
function goodbye ()
|
||||||
|
print ('Goodbye.')
|
||||||
|
return 0, nil
|
||||||
|
end
|
||||||
|
|
36
scripts/extensions/task_hook.lua
Normal file
36
scripts/extensions/task_hook.lua
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
-- Task Hook Extension.
|
||||||
|
-- Implementing encouragement message.
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'task', -- Type
|
||||||
|
'encourage', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Positive feedback', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: String identifying valid program hook
|
||||||
|
function hook ()
|
||||||
|
return 'on-task-complete'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: 1, 'error' --> failure
|
||||||
|
-- 0, nil --> success
|
||||||
|
function encourage ()
|
||||||
|
-- Only provide encouragement if the verbosity settings allow it.
|
||||||
|
verbosity = task_get ('rc.verbose')
|
||||||
|
if string.find (verbosity, 'encourage') ~= nil
|
||||||
|
then
|
||||||
|
print ('Good work.')
|
||||||
|
end
|
||||||
|
return 0, nil
|
||||||
|
end
|
||||||
|
|
61
scripts/extensions/uda.lua
Normal file
61
scripts/extensions/uda.lua
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
-- User Defined Attribute Extension.
|
||||||
|
-- Implementing 'priority'.
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: An 8-element list of installation details. Only called once, on
|
||||||
|
-- installation of the extension.
|
||||||
|
function install ()
|
||||||
|
return 'uda', -- Type
|
||||||
|
'priority', -- Name
|
||||||
|
1.0, -- Version
|
||||||
|
'Implements priority attribute', -- Description
|
||||||
|
'Paul Beckingham', -- Author
|
||||||
|
'paul@beckingham.net', -- Contact
|
||||||
|
'GPLv2', -- License
|
||||||
|
'© 2011, Göteborg Bit Factory' -- Copyright
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Arguments: None
|
||||||
|
-- Returns: Data type
|
||||||
|
function type ()
|
||||||
|
return 'custom'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: proposed value
|
||||||
|
-- Returns: 1 --> allowed
|
||||||
|
-- 0 --> disallowed
|
||||||
|
function allowed (value)
|
||||||
|
if value == 'H' ||
|
||||||
|
value == 'M' ||
|
||||||
|
value == 'L' ||
|
||||||
|
value == '' then
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: left and right values to compare
|
||||||
|
-- Returns: 1 --> left < right
|
||||||
|
-- 0 --> left >= right
|
||||||
|
function compare (left, right)
|
||||||
|
if left == 'M' && right == 'H' then
|
||||||
|
return 1
|
||||||
|
elseif left == 'L' && (right == 'H' || right == 'M') then
|
||||||
|
return 1
|
||||||
|
elseif left == '' then
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Arguments: Raw data
|
||||||
|
-- Returns: Formatted data
|
||||||
|
-- Note: Shown here is a pass-through format, doing no formatting. This is
|
||||||
|
-- the default behavior if the format function is not implemented.
|
||||||
|
function format (value)
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include <API.h>
|
#include <API.h>
|
||||||
|
|
||||||
extern Context context;
|
extern Context context;
|
||||||
Task* the_task = NULL;
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBLUA
|
#ifdef HAVE_LIBLUA
|
||||||
|
|
||||||
|
@ -122,6 +121,7 @@ static int api_task_set (lua_State* L)
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// TODO Error!
|
// TODO Error!
|
||||||
|
lua_pushstring (L, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,16 +223,10 @@ bool API::callTaskHook (
|
||||||
// Prepare args.
|
// Prepare args.
|
||||||
lua_pushnumber (L, current.id);
|
lua_pushnumber (L, current.id);
|
||||||
|
|
||||||
// Expose the task.
|
|
||||||
the_task = ¤t;
|
|
||||||
|
|
||||||
// Make call.
|
// Make call.
|
||||||
if (lua_pcall (L, 1, 2, 0) != 0)
|
if (lua_pcall (L, 1, 2, 0) != 0)
|
||||||
throw std::string ("Error calling '") + function + "' - " + lua_tostring (L, -1) + ".";
|
throw std::string ("Error calling '") + function + "' - " + lua_tostring (L, -1) + ".";
|
||||||
|
|
||||||
// Hide the task.
|
|
||||||
the_task = NULL;
|
|
||||||
|
|
||||||
// Call successful - get return values.
|
// Call successful - get return values.
|
||||||
if (!lua_isnumber (L, -2))
|
if (!lua_isnumber (L, -2))
|
||||||
throw std::string ("Error: '") + function + "' did not return a success indicator.";
|
throw std::string ("Error: '") + function + "' did not return a success indicator.";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue