na 1.2.29 → 1.2.30
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +1 -1
- data/README.md +28 -20
- data/bin/commands/add.rb +167 -164
- data/bin/commands/archive.rb +54 -51
- data/bin/commands/changes.rb +18 -15
- data/bin/commands/complete.rb +50 -47
- data/bin/commands/completed.rb +99 -0
- data/bin/commands/edit.rb +37 -34
- data/bin/commands/find.rb +109 -106
- data/bin/commands/init.rb +22 -19
- data/bin/commands/next.rb +135 -131
- data/bin/commands/projects.rb +27 -24
- data/bin/commands/prompt.rb +41 -38
- data/bin/commands/saved.rb +42 -34
- data/bin/commands/tagged.rb +137 -134
- data/bin/commands/todos.rb +23 -20
- data/bin/commands/update.rb +215 -207
- data/bin/na +7 -1166
- data/lib/na/array.rb +13 -0
- data/lib/na/help_monkey_patch.rb +32 -0
- data/lib/na/next_action.rb +3 -2
- data/lib/na/pager.rb +94 -0
- data/lib/na/string.rb +10 -0
- data/lib/na/version.rb +1 -1
- data/lib/na.rb +2 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d0dbc271a5a8f1812c5ef0596031d5ca9fc726efe0cde91e1172840d15acb61
|
4
|
+
data.tar.gz: 44599dadd458ebfcb610fcf80b5326231404f199f61b6e195b103bb4a095ff06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 448bea330450c05446027995d4ea6ccdb5cdf80fa43672d8ccb08a808ca9a171fbd80aa2d7e2054568c458411b25037db66b644e0bde43e8ac614b9b469d97cc
|
7
|
+
data.tar.gz: 146ed95b595f010a5964134f4eba2701ccd7a9b103c692941a8fb68052023f29b09ffabffba74dbc93a20a64397fe8417f9ab0343bde9a3af8d292bfa2351e6f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
### 1.2.30
|
2
|
+
|
3
|
+
2023-08-29 06:50
|
4
|
+
|
5
|
+
#### NEW
|
6
|
+
|
7
|
+
- `na completed` to show completed actions with date ranges and search patterns
|
8
|
+
- Pagination using system pager
|
9
|
+
|
10
|
+
#### IMPROVED
|
11
|
+
|
12
|
+
- When replacing a priority tag, remove any space before it the action text
|
13
|
+
- Restore command decomposition
|
14
|
+
- Allow multiple saved searches to be executed at once
|
15
|
+
- `--restore` flag for update command to remove @done tags
|
16
|
+
- Pagination for help output
|
17
|
+
|
18
|
+
#### FIXED
|
19
|
+
|
20
|
+
- `--done` flag not working on `na next`
|
21
|
+
- Missing descriptions in help examples
|
22
|
+
|
1
23
|
### 1.2.29
|
2
24
|
|
3
25
|
2023-08-21 11:08
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
_If you're one of the rare people like me who find this useful, feel free to
|
10
10
|
[buy me some coffee][donate]._
|
11
11
|
|
12
|
-
The current version of `na` is 1.2.
|
12
|
+
The current version of `na` is 1.2.30
|
13
13
|
.
|
14
14
|
|
15
15
|
`na` ("next action") is a command line tool designed to make it easy to see what your next actions are for any project, right from the command line. It works with TaskPaper-formatted files (but any plain text format will do), looking for `@na` tags (or whatever you specify) in todo files in your current folder.
|
@@ -77,42 +77,44 @@ SYNOPSIS
|
|
77
77
|
na [global options] command [command options] [arguments...]
|
78
78
|
|
79
79
|
VERSION
|
80
|
-
1.2.
|
80
|
+
1.2.30
|
81
81
|
|
82
82
|
GLOBAL OPTIONS
|
83
83
|
-a, --add - Add a next action (deprecated, for backwards compatibility)
|
84
84
|
--add_at=POSITION - Add all new/moved entries at [s]tart or [e]nd of target project (default: start)
|
85
85
|
--[no-]color - Colorize output (default: enabled)
|
86
86
|
--cwd_as=TYPE - Use current working directory as [p]roject, [t]ag, or [n]one (default: none)
|
87
|
-
-d, --depth=DEPTH - Recurse to depth (default:
|
87
|
+
-d, --depth=DEPTH - Recurse to depth (default: 1)
|
88
88
|
--[no-]debug - Display verbose output
|
89
89
|
--ext=EXT - File extension to consider a todo file (default: taskpaper)
|
90
90
|
-f, --file=PATH - Use a single file as global todo, use initconfig to make permanent (default: none)
|
91
91
|
--help - Show this message
|
92
92
|
-n, --note - Prompt for additional notes (deprecated, for backwards compatibility)
|
93
93
|
-p, --priority=PRIORITY - Set a priority 0-5 (deprecated, for backwards compatibility) (default: none)
|
94
|
+
--[no-]pager - Enable pagination (default: enabled)
|
94
95
|
-r, --[no-]recurse - Recurse 3 directories deep (deprecated, for backwards compatability)
|
95
96
|
-t, --na_tag=TAG - Tag to consider a next action (default: na)
|
96
97
|
--template=PATH - Provide a template for new/blank todo files, use initconfig to make permanent (default: none)
|
97
98
|
--version - Display the program version
|
98
99
|
|
99
100
|
COMMANDS
|
100
|
-
add
|
101
|
-
archive
|
102
|
-
changes, changelog
|
103
|
-
complete, finish
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
101
|
+
add - Add a new next action
|
102
|
+
archive - Mark an action as @done and archive
|
103
|
+
changes, changelog - Display the changelog
|
104
|
+
complete, finish - Find and mark an action as @done
|
105
|
+
completed, finished - Display completed actions
|
106
|
+
edit - Open a todo file in the default editor
|
107
|
+
find, grep - Find actions matching a search pattern
|
108
|
+
help - Shows a list of commands or help for one command
|
109
|
+
init, create - Create a new todo file in the current directory
|
110
|
+
initconfig - Initialize the config file using current global options
|
111
|
+
next, show - Show next actions
|
112
|
+
projects - Show list of projects for a file
|
113
|
+
prompt - Show or install prompt hooks for the current shell
|
114
|
+
saved - Execute a saved search
|
115
|
+
tagged - Find actions matching a tag
|
116
|
+
todos - Show list of known todo files
|
117
|
+
update - Update an existing action
|
116
118
|
```
|
117
119
|
|
118
120
|
#### Commands
|
@@ -339,7 +341,7 @@ NAME
|
|
339
341
|
|
340
342
|
SYNOPSIS
|
341
343
|
|
342
|
-
na [global options] saved [command options] [SEARCH_TITLE]
|
344
|
+
na [global options] saved [command options] [SEARCH_TITLE]...
|
343
345
|
|
344
346
|
DESCRIPTION
|
345
347
|
Run without argument to list saved searches
|
@@ -350,14 +352,19 @@ COMMAND OPTIONS
|
|
350
352
|
|
351
353
|
EXAMPLES
|
352
354
|
|
355
|
+
# save a search called "maybelater"
|
353
356
|
na tagged "+maybe,+priority<=3" --save maybelater
|
354
357
|
|
358
|
+
# perform the search named "maybelater"
|
355
359
|
na saved maybelater
|
356
360
|
|
361
|
+
# perform the search named "maybelater", assuming no other searches match "maybe"
|
357
362
|
na saved maybe
|
358
363
|
|
364
|
+
# na run with no command and a single argument automatically performs a matching saved search
|
359
365
|
na maybe
|
360
366
|
|
367
|
+
# list available searches
|
361
368
|
na saved
|
362
369
|
```
|
363
370
|
|
@@ -484,6 +491,7 @@ COMMAND OPTIONS
|
|
484
491
|
-o, --overwrite - Overwrite note instead of appending
|
485
492
|
-p, --priority=PRIO - Add/change a priority level 1-5 (default: 0)
|
486
493
|
-r, --remove=TAG - Remove a tag to the action (may be used more than once, default: none)
|
494
|
+
--restore - Remove @done tag from action
|
487
495
|
-t, --tag=TAG - Add a tag to the action, @tag(values) allowed (may be used more than once, default: none)
|
488
496
|
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
489
497
|
--to, --project, --proj=PROJECT - Move action to specific project (default: none)
|
data/bin/commands/add.rb
CHANGED
@@ -1,183 +1,186 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
target = File.expand_path(options[:file])
|
74
|
-
unless File.exist?(target)
|
75
|
-
res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
|
76
|
-
if res
|
77
|
-
basename = File.basename(target, ".#{NA.extension}")
|
78
|
-
NA.create_todo(target, basename, template: global_options[:template])
|
79
|
-
else
|
80
|
-
puts NA::Color.template('{r}Cancelled{x}')
|
81
|
-
Process.exit 1
|
3
|
+
class App
|
4
|
+
extend GLI::App
|
5
|
+
desc 'Add a new next action'
|
6
|
+
long_desc 'Provides an easy way to store todos while you work. Add quick
|
7
|
+
reminders and (if you set up Prompt Hooks) they\'ll automatically display
|
8
|
+
next time you enter the directory.
|
9
|
+
|
10
|
+
If multiple todo files are found in the current directory, a menu will
|
11
|
+
allow you to pick to which file the action gets added.'
|
12
|
+
arg_name 'ACTION'
|
13
|
+
command :add do |c|
|
14
|
+
c.example 'na add "A cool feature I thought of @idea"', desc: 'Add a new action to the Inbox, including a tag'
|
15
|
+
c.example 'na add "A bug I need to fix" -p 4 -n',
|
16
|
+
desc: 'Add a new action to the Inbox, set its @priority to 4, and prompt for an additional note.'
|
17
|
+
c.example 'na add "An action item (with a note)"',
|
18
|
+
desc: 'A parenthetical at the end of an action is interpreted as a note'
|
19
|
+
|
20
|
+
c.desc 'Prompt for additional notes. STDIN input (piped) will be treated as a note if present.'
|
21
|
+
c.switch %i[n note], negatable: false
|
22
|
+
|
23
|
+
c.desc 'Add a priority level 1-5'
|
24
|
+
c.arg_name 'PRIO'
|
25
|
+
c.flag %i[p priority], must_match: /[1-5]/, type: :integer, default_value: 0
|
26
|
+
|
27
|
+
c.desc 'Add action to specific project'
|
28
|
+
c.arg_name 'PROJECT'
|
29
|
+
c.default_value 'Inbox'
|
30
|
+
c.flag %i[to project proj]
|
31
|
+
|
32
|
+
c.desc 'Add task at [s]tart or [e]nd of target project'
|
33
|
+
c.arg_name 'POSITION'
|
34
|
+
c.flag %i[at], must_match: /^[sbea].*?$/i
|
35
|
+
|
36
|
+
c.desc 'Add to a known todo file, partial matches allowed'
|
37
|
+
c.arg_name 'TODO_FILE'
|
38
|
+
c.flag %i[in todo]
|
39
|
+
|
40
|
+
c.desc 'Use a tag other than the default next action tag'
|
41
|
+
c.arg_name 'TAG'
|
42
|
+
c.flag %i[t tag]
|
43
|
+
|
44
|
+
c.desc 'Don\'t add next action tag to new entry'
|
45
|
+
c.switch %i[x], negatable: false
|
46
|
+
|
47
|
+
c.desc 'Specify the file to which the task should be added'
|
48
|
+
c.arg_name 'PATH'
|
49
|
+
c.flag %i[f file]
|
50
|
+
|
51
|
+
c.desc 'Mark task as @done with date'
|
52
|
+
c.switch %i[finish done], negatable: false
|
53
|
+
|
54
|
+
c.desc 'Search for files X directories deep'
|
55
|
+
c.arg_name 'DEPTH'
|
56
|
+
c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
|
57
|
+
|
58
|
+
c.action do |global_options, options, args|
|
59
|
+
reader = TTY::Reader.new
|
60
|
+
append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/
|
61
|
+
|
62
|
+
if NA.global_file
|
63
|
+
target = File.expand_path(NA.global_file)
|
64
|
+
unless File.exist?(target)
|
65
|
+
res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
|
66
|
+
if res
|
67
|
+
basename = File.basename(target, ".#{NA.extension}")
|
68
|
+
NA.create_todo(target, basename, template: global_options[:template])
|
69
|
+
else
|
70
|
+
puts NA::Color.template('{r}Cancelled{x}')
|
71
|
+
Process.exit 1
|
72
|
+
end
|
82
73
|
end
|
83
|
-
|
84
|
-
|
85
|
-
todo = []
|
86
|
-
all_req = options[:todo] !~ /[+!\-]/
|
87
|
-
options[:todo].split(/ *, */).each do |a|
|
88
|
-
m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
89
|
-
todo.push({
|
90
|
-
token: m['tok'],
|
91
|
-
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
92
|
-
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
93
|
-
})
|
94
|
-
end
|
95
|
-
dirs = NA.match_working_dir(todo)
|
96
|
-
if dirs.count.positive?
|
97
|
-
target = dirs[0]
|
98
|
-
else
|
99
|
-
todo = "#{options[:todo].sub(/#{NA.extension}$/, '')}.#{NA.extension}"
|
100
|
-
target = File.expand_path(todo)
|
74
|
+
elsif options[:file]
|
75
|
+
target = File.expand_path(options[:file])
|
101
76
|
unless File.exist?(target)
|
77
|
+
res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
|
78
|
+
if res
|
79
|
+
basename = File.basename(target, ".#{NA.extension}")
|
80
|
+
NA.create_todo(target, basename, template: global_options[:template])
|
81
|
+
else
|
82
|
+
puts NA::Color.template('{r}Cancelled{x}')
|
83
|
+
Process.exit 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
elsif options[:todo]
|
87
|
+
todo = []
|
88
|
+
all_req = options[:todo] !~ /[+!\-]/
|
89
|
+
options[:todo].split(/ *, */).each do |a|
|
90
|
+
m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
91
|
+
todo.push({
|
92
|
+
token: m['tok'],
|
93
|
+
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
94
|
+
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
95
|
+
})
|
96
|
+
end
|
97
|
+
dirs = NA.match_working_dir(todo)
|
98
|
+
if dirs.count.positive?
|
99
|
+
target = dirs[0]
|
100
|
+
else
|
101
|
+
todo = "#{options[:todo].sub(/#{NA.extension}$/, '')}.#{NA.extension}"
|
102
|
+
target = File.expand_path(todo)
|
103
|
+
unless File.exist?(target)
|
102
104
|
|
103
|
-
|
104
|
-
|
105
|
+
res = NA.yn(NA::Color.template("{by}Specified file not found, create #{todo}"), default: true)
|
106
|
+
NA.notify('{r}Cancelled{x}', exit_code: 1) unless res
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
basename = File.basename(target, ".#{NA.extension}")
|
109
|
+
NA.create_todo(target, basename, template: global_options[:template])
|
110
|
+
end
|
109
111
|
|
110
|
-
end
|
111
|
-
else
|
112
|
-
files = NA.find_files(depth: options[:depth])
|
113
|
-
if files.count.zero?
|
114
|
-
res = NA.yn(NA::Color.template('{by}No todo file found, create one'), default: true)
|
115
|
-
if res
|
116
|
-
basename = File.expand_path('.').split('/').last
|
117
|
-
target = "#{basename}.#{NA.extension}"
|
118
|
-
NA.create_todo(target, basename, template: global_options[:template])
|
119
|
-
files = NA.find_files(depth: 1)
|
120
112
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
113
|
+
else
|
114
|
+
files = NA.find_files(depth: options[:depth])
|
115
|
+
if files.count.zero?
|
116
|
+
res = NA.yn(NA::Color.template('{by}No todo file found, create one'), default: true)
|
117
|
+
if res
|
118
|
+
basename = File.expand_path('.').split('/').last
|
119
|
+
target = "#{basename}.#{NA.extension}"
|
120
|
+
NA.create_todo(target, basename, template: global_options[:template])
|
121
|
+
files = NA.find_files(depth: 1)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
target = files.count > 1 ? NA.select_file(files) : files[0]
|
125
|
+
NA.notify('{r}Cancelled{x}', exit_code: 1) unless files.count.positive? && File.exist?(target)
|
126
126
|
|
127
|
-
|
128
|
-
args.join(' ').strip
|
129
|
-
elsif $stdin.isatty && TTY::Which.exist?('gum')
|
130
|
-
`gum input --placeholder "Enter a task" --char-limit=500 --width=#{TTY::Screen.columns}`.strip
|
131
|
-
elsif $stdin.isatty
|
132
|
-
puts NA::Color.template('{bm}Enter task:{x}')
|
133
|
-
reader.read_line(NA::Color.template('{by}> {bw}')).strip
|
134
|
-
end
|
135
|
-
|
136
|
-
if action.nil? || action.empty?
|
137
|
-
puts 'Empty input, cancelled'
|
138
|
-
Process.exit 1
|
139
|
-
end
|
127
|
+
end
|
140
128
|
|
141
|
-
|
142
|
-
|
143
|
-
|
129
|
+
action = if args.count.positive?
|
130
|
+
args.join(' ').strip
|
131
|
+
elsif $stdin.isatty && TTY::Which.exist?('gum')
|
132
|
+
`gum input --placeholder "Enter a task" --char-limit=500 --width=#{TTY::Screen.columns}`.strip
|
133
|
+
elsif $stdin.isatty
|
134
|
+
puts NA::Color.template('{bm}Enter task:{x}')
|
135
|
+
reader.read_line(NA::Color.template('{by}> {bw}')).strip
|
136
|
+
end
|
137
|
+
|
138
|
+
if action.nil? || action.empty?
|
139
|
+
puts 'Empty input, cancelled'
|
140
|
+
Process.exit 1
|
141
|
+
end
|
144
142
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
action.sub!(note_rx, '\1').strip!
|
149
|
-
n
|
150
|
-
end
|
151
|
-
|
152
|
-
na_tag = NA.na_tag
|
153
|
-
if options[:x]
|
154
|
-
na_tag = ''
|
155
|
-
else
|
156
|
-
na_tag = options[:tag] unless options[:tag].nil?
|
157
|
-
na_tag = " @#{na_tag}"
|
158
|
-
end
|
143
|
+
if options[:priority]&.to_i&.positive?
|
144
|
+
action = "#{action.gsub(/@priority\(\d+\)/, '')} @priority(#{options[:priority]})"
|
145
|
+
end
|
159
146
|
|
160
|
-
|
147
|
+
note_rx = /^(.+) \((.*?)\)$/
|
148
|
+
split_note = if action =~ note_rx
|
149
|
+
n = Regexp.last_match(2)
|
150
|
+
action.sub!(note_rx, '\1').strip!
|
151
|
+
n
|
152
|
+
end
|
161
153
|
|
162
|
-
|
154
|
+
na_tag = NA.na_tag
|
155
|
+
if options[:x]
|
156
|
+
na_tag = ''
|
157
|
+
else
|
158
|
+
na_tag = options[:tag] unless options[:tag].nil?
|
159
|
+
na_tag = " @#{na_tag}"
|
160
|
+
end
|
163
161
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
162
|
+
action = "#{action.gsub(/#{na_tag}\b/, '')}#{na_tag}"
|
163
|
+
|
164
|
+
stdin_note = NA.stdin ? NA.stdin.split("\n") : []
|
165
|
+
|
166
|
+
line_note = if options[:note] && $stdin.isatty
|
167
|
+
puts stdin_note unless stdin_note.nil?
|
168
|
+
if TTY::Which.exist?('gum')
|
169
|
+
args = ['--placeholder "Enter additional note, CTRL-d to save"']
|
170
|
+
args << '--char-limit 0'
|
171
|
+
args << '--width $(tput cols)'
|
172
|
+
`gum write #{args.join(' ')}`.strip.split("\n")
|
173
|
+
else
|
174
|
+
puts NA::Color.template('{bm}Enter a note, {bw}CTRL-d{bm} to end editing{bw}')
|
175
|
+
reader.read_multiline
|
176
|
+
end
|
174
177
|
end
|
175
|
-
end
|
176
178
|
|
177
|
-
|
178
|
-
|
179
|
-
|
179
|
+
note = stdin_note.empty? ? [] : stdin_note
|
180
|
+
note.concat(split_note) unless split_note.nil?
|
181
|
+
note.concat(line_note) unless line_note.nil?
|
180
182
|
|
181
|
-
|
183
|
+
NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
|
184
|
+
end
|
182
185
|
end
|
183
186
|
end
|
data/bin/commands/archive.rb
CHANGED
@@ -1,56 +1,59 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
options[:
|
3
|
+
class App
|
4
|
+
extend GLI::App
|
5
|
+
desc 'Mark an action as @done and archive'
|
6
|
+
arg_name 'ACTION'
|
7
|
+
command %i[archive] do |c|
|
8
|
+
c.example 'na archive "An existing task"',
|
9
|
+
desc: 'Find "An existing task", mark @done if needed, and move to archive'
|
10
|
+
|
11
|
+
c.desc 'Prompt for additional notes. Input will be appended to any existing note.
|
12
|
+
If STDIN input (piped) is detected, it will be used as a note.'
|
13
|
+
c.switch %i[n note], negatable: false
|
14
|
+
|
15
|
+
c.desc 'Overwrite note instead of appending'
|
16
|
+
c.switch %i[o overwrite], negatable: false
|
17
|
+
|
18
|
+
c.desc 'Archive all done tasks'
|
19
|
+
c.switch %i[done], negatable: false
|
20
|
+
|
21
|
+
c.desc 'Specify the file to search for the task'
|
22
|
+
c.arg_name 'PATH'
|
23
|
+
c.flag %i[file]
|
24
|
+
|
25
|
+
c.desc 'Search for files X directories deep'
|
26
|
+
c.arg_name 'DEPTH'
|
27
|
+
c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
|
28
|
+
|
29
|
+
c.desc 'Match actions containing tag. Allows value comparisons'
|
30
|
+
c.arg_name 'TAG'
|
31
|
+
c.flag %i[tagged], multiple: true
|
32
|
+
|
33
|
+
c.desc 'Act on all matches immediately (no menu)'
|
34
|
+
c.switch %i[all], negatable: false
|
35
|
+
|
36
|
+
c.desc 'Interpret search pattern as regular expression'
|
37
|
+
c.switch %i[e regex], negatable: false
|
38
|
+
|
39
|
+
c.desc 'Match pattern exactly'
|
40
|
+
c.switch %i[x exact], negatable: false
|
41
|
+
|
42
|
+
c.action do |global, options, args|
|
43
|
+
if options[:done]
|
44
|
+
options[:tagged] = ['done']
|
45
|
+
options[:all] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
options[:done] = true
|
49
|
+
options[:finish] = true
|
50
|
+
options[:project] = 'Archive'
|
51
|
+
options[:archive] = true
|
52
|
+
options[:a] = true
|
53
|
+
|
54
|
+
cmd = commands[:update]
|
55
|
+
action = cmd.send(:get_action, nil)
|
56
|
+
action.call(global, options, args)
|
44
57
|
end
|
45
|
-
|
46
|
-
options[:done] = true
|
47
|
-
options[:finish] = true
|
48
|
-
options[:project] = 'Archive'
|
49
|
-
options[:archive] = true
|
50
|
-
options[:a] = true
|
51
|
-
|
52
|
-
cmd = commands[:update]
|
53
|
-
action = cmd.send(:get_action, nil)
|
54
|
-
action.call(global, options, args)
|
55
58
|
end
|
56
59
|
end
|