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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb14c4a36c28fce7e726c0a4c5b50680e05b9efa87c2f41d02a1af3040027401
4
- data.tar.gz: 461c9f651ec9838548288efd9b972d7d21ffeca11089fe01b92a10676ce018bc
3
+ metadata.gz: 3d0dbc271a5a8f1812c5ef0596031d5ca9fc726efe0cde91e1172840d15acb61
4
+ data.tar.gz: 44599dadd458ebfcb610fcf80b5326231404f199f61b6e195b103bb4a095ff06
5
5
  SHA512:
6
- metadata.gz: e664e139c0927e205b8f16c3d7036d8912ed5e75aa2da772d8ac5a11b0a3fc72cec49cbb4f07fb45cb533130ed49f10efa4b348d5b708f7840b04b9492347252
7
- data.tar.gz: f1b9bb77e3d73d73dd6d3b4ac4db52979cf6345d7cb5231106fec6670e914116375762619bfe67c9697caa5622b65053935edee91bf21116d07be69b9d16ee4c
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.29)
4
+ na (1.2.30)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  gli (~> 2.21.0)
7
7
  mdless (~> 1.0, >= 1.0.32)
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.29
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.29
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: 3)
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 - Add a new next action
101
- archive - Mark an action as @done and archive
102
- changes, changelog - Display the changelog
103
- complete, finish - Find and mark an action as @done
104
- edit - Open a todo file in the default editor
105
- find, grep - Find actions matching a search pattern
106
- help - Shows a list of commands or help for one command
107
- init, create - Create a new todo file in the current directory
108
- initconfig - Initialize the config file using current global options
109
- next, show - Show next actions
110
- projects - Show list of projects for a file
111
- prompt - Show or install prompt hooks for the current shell
112
- saved - Execute a saved search
113
- tagged - Find actions matching a tag
114
- todos - Show list of known todo files
115
- update - Update an existing action
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
- desc 'Add a new next action'
4
- long_desc 'Provides an easy way to store todos while you work. Add quick
5
- reminders and (if you set up Prompt Hooks) they\'ll automatically display
6
- next time you enter the directory.
7
-
8
- If multiple todo files are found in the current directory, a menu will
9
- allow you to pick to which file the action gets added.'
10
- arg_name 'ACTION'
11
- command :add do |c|
12
- c.example 'na add "A cool feature I thought of @idea"', desc: 'Add a new action to the Inbox, including a tag'
13
- c.example 'na add "A bug I need to fix" -p 4 -n',
14
- desc: 'Add a new action to the Inbox, set its @priority to 4, and prompt for an additional note.'
15
- c.example 'na add "An action item (with a note)"',
16
- desc: 'A parenthetical at the end of an action is interpreted as a note'
17
-
18
- c.desc 'Prompt for additional notes. STDIN input (piped) will be treated as a note if present.'
19
- c.switch %i[n note], negatable: false
20
-
21
- c.desc 'Add a priority level 1-5'
22
- c.arg_name 'PRIO'
23
- c.flag %i[p priority], must_match: /[1-5]/, type: :integer, default_value: 0
24
-
25
- c.desc 'Add action to specific project'
26
- c.arg_name 'PROJECT'
27
- c.default_value 'Inbox'
28
- c.flag %i[to project proj]
29
-
30
- c.desc 'Add task at [s]tart or [e]nd of target project'
31
- c.arg_name 'POSITION'
32
- c.flag %i[at], must_match: /^[sbea].*?$/i
33
-
34
- c.desc 'Add to a known todo file, partial matches allowed'
35
- c.arg_name 'TODO_FILE'
36
- c.flag %i[in todo]
37
-
38
- c.desc 'Use a tag other than the default next action tag'
39
- c.arg_name 'TAG'
40
- c.flag %i[t tag]
41
-
42
- c.desc 'Don\'t add next action tag to new entry'
43
- c.switch %i[x], negatable: false
44
-
45
- c.desc 'Specify the file to which the task should be added'
46
- c.arg_name 'PATH'
47
- c.flag %i[f file]
48
-
49
- c.desc 'Mark task as @done with date'
50
- c.switch %i[finish done], negatable: false
51
-
52
- c.desc 'Search for files X directories deep'
53
- c.arg_name 'DEPTH'
54
- c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
55
-
56
- c.action do |global_options, options, args|
57
- reader = TTY::Reader.new
58
- append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/
59
-
60
- if NA.global_file
61
- target = File.expand_path(NA.global_file)
62
- unless File.exist?(target)
63
- res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
64
- if res
65
- basename = File.basename(target, ".#{NA.extension}")
66
- NA.create_todo(target, basename, template: global_options[:template])
67
- else
68
- puts NA::Color.template('{r}Cancelled{x}')
69
- Process.exit 1
70
- end
71
- end
72
- elsif options[:file]
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
- end
84
- elsif options[:todo]
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
- res = NA.yn(NA::Color.template("{by}Specified file not found, create #{todo}"), default: true)
104
- NA.notify('{r}Cancelled{x}', exit_code: 1) unless res
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
- basename = File.basename(target, ".#{NA.extension}")
107
- NA.create_todo(target, basename, template: global_options[:template])
108
- end
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
- end
122
- target = files.count > 1 ? NA.select_file(files) : files[0]
123
- NA.notify('{r}Cancelled{x}', exit_code: 1) unless files.count.positive? && File.exist?(target)
124
-
125
- end
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
- action = if args.count.positive?
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
- if options[:priority]&.to_i&.positive?
142
- action = "#{action.gsub(/@priority\(\d+\)/, '')} @priority(#{options[:priority]})"
143
- end
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
- note_rx = /^(.+) \((.*?)\)$/
146
- split_note = if action =~ note_rx
147
- n = Regexp.last_match(2)
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
- action = "#{action.gsub(/#{na_tag}\b/, '')}#{na_tag}"
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
- stdin_note = NA.stdin ? NA.stdin.split("\n") : []
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
- line_note = if options[:note] && $stdin.isatty
165
- puts stdin_note unless stdin_note.nil?
166
- if TTY::Which.exist?('gum')
167
- args = ['--placeholder "Enter additional note, CTRL-d to save"']
168
- args << '--char-limit 0'
169
- args << '--width $(tput cols)'
170
- `gum write #{args.join(' ')}`.strip.split("\n")
171
- else
172
- puts NA::Color.template('{bm}Enter a note, {bw}CTRL-d{bm} to end editing{bw}')
173
- reader.read_multiline
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
- note = stdin_note.empty? ? [] : stdin_note
178
- note.concat(split_note) unless split_note.nil?
179
- note.concat(line_note) unless line_note.nil?
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
- NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
183
+ NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
184
+ end
182
185
  end
183
186
  end
@@ -1,56 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Mark an action as @done and archive'
4
- arg_name 'ACTION'
5
- command %i[archive] do |c|
6
- c.example 'na archive "An existing task"',
7
- desc: 'Find "An existing task", mark @done if needed, and move to archive'
8
-
9
- c.desc 'Prompt for additional notes. Input will be appended to any existing note.
10
- If STDIN input (piped) is detected, it will be used as a note.'
11
- c.switch %i[n note], negatable: false
12
-
13
- c.desc 'Overwrite note instead of appending'
14
- c.switch %i[o overwrite], negatable: false
15
-
16
- c.desc 'Archive all done tasks'
17
- c.switch %i[done], negatable: false
18
-
19
- c.desc 'Specify the file to search for the task'
20
- c.arg_name 'PATH'
21
- c.flag %i[file]
22
-
23
- c.desc 'Search for files X directories deep'
24
- c.arg_name 'DEPTH'
25
- c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
26
-
27
- c.desc 'Match actions containing tag. Allows value comparisons'
28
- c.arg_name 'TAG'
29
- c.flag %i[tagged], multiple: true
30
-
31
- c.desc 'Act on all matches immediately (no menu)'
32
- c.switch %i[all], negatable: false
33
-
34
- c.desc 'Interpret search pattern as regular expression'
35
- c.switch %i[e regex], negatable: false
36
-
37
- c.desc 'Match pattern exactly'
38
- c.switch %i[x exact], negatable: false
39
-
40
- c.action do |global, options, args|
41
- if options[:done]
42
- options[:tagged] = ['done']
43
- options[:all] = true
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