na 1.2.29 → 1.2.31

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,19 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Display the changelog'
4
- command %i[changes changelog] do |c|
5
- c.action do |_, _, _|
6
- changelog = File.expand_path(File.join(File.dirname(__FILE__), '..', 'CHANGELOG.md'))
7
- pagers = [
8
- 'mdless',
9
- 'mdcat',
10
- 'bat',
11
- ENV['PAGER'],
12
- 'less -FXr',
13
- ENV['GIT_PAGER'],
14
- 'more -r'
15
- ]
16
- pager = pagers.find { |cmd| TTY::Which.exist?(cmd.split.first) }
17
- system %(#{pager} "#{changelog}")
3
+ class App
4
+ extend GLI::App
5
+ desc 'Display the changelog'
6
+ command %i[changes changelog] do |c|
7
+ c.action do |_, _, _|
8
+ changelog = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'CHANGELOG.md'))
9
+ pagers = [
10
+ 'mdless',
11
+ 'mdcat',
12
+ 'bat',
13
+ ENV['PAGER'],
14
+ 'less -FXr',
15
+ ENV['GIT_PAGER'],
16
+ 'more -r'
17
+ ]
18
+ pager = pagers.find { |cmd| TTY::Which.exist?(cmd.split.first) }
19
+ system %(#{pager} "#{changelog}")
20
+ end
18
21
  end
19
22
  end
@@ -1,51 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Find and mark an action as @done'
4
- arg_name 'ACTION'
5
- command %i[complete finish] do |c|
6
- c.example 'na complete "An existing task"',
7
- desc: 'Find "An existing task" and mark @done'
8
- c.example 'na finish "An existing task"',
9
- desc: 'Alias for complete'
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 'Add a @done tag to action and move to Archive'
19
- c.switch %i[a archive], 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
- options[:finish] = true
44
- options[:f] = true
45
- options[:project] = 'Archive' if options[:archive]
46
-
47
- cmd = commands[:update]
48
- action = cmd.send(:get_action, nil)
49
- action.call(global, options, args)
3
+ class App
4
+ extend GLI::App
5
+ desc 'Find and mark an action as @done'
6
+ arg_name 'ACTION'
7
+ command %i[complete finish] do |c|
8
+ c.example 'na complete "An existing task"',
9
+ desc: 'Find "An existing task" and mark @done'
10
+ c.example 'na finish "An existing task"',
11
+ desc: 'Alias for complete'
12
+
13
+ c.desc 'Prompt for additional notes. Input will be appended to any existing note.
14
+ If STDIN input (piped) is detected, it will be used as a note.'
15
+ c.switch %i[n note], negatable: false
16
+
17
+ c.desc 'Overwrite note instead of appending'
18
+ c.switch %i[o overwrite], negatable: false
19
+
20
+ c.desc 'Add a @done tag to action and move to Archive'
21
+ c.switch %i[a archive], negatable: false
22
+
23
+ c.desc 'Specify the file to search for the task'
24
+ c.arg_name 'PATH'
25
+ c.flag %i[file]
26
+
27
+ c.desc 'Search for files X directories deep'
28
+ c.arg_name 'DEPTH'
29
+ c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
30
+
31
+ c.desc 'Match actions containing tag. Allows value comparisons'
32
+ c.arg_name 'TAG'
33
+ c.flag %i[tagged], multiple: true
34
+
35
+ c.desc 'Act on all matches immediately (no menu)'
36
+ c.switch %i[all], negatable: false
37
+
38
+ c.desc 'Interpret search pattern as regular expression'
39
+ c.switch %i[e regex], negatable: false
40
+
41
+ c.desc 'Match pattern exactly'
42
+ c.switch %i[x exact], negatable: false
43
+
44
+ c.action do |global, options, args|
45
+ options[:finish] = true
46
+ options[:f] = true
47
+ options[:project] = 'Archive' if options[:archive]
48
+
49
+ cmd = commands[:update]
50
+ action = cmd.send(:get_action, nil)
51
+ action.call(global, options, args)
52
+ end
50
53
  end
51
54
  end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ class App
4
+ extend GLI::App
5
+ desc 'Display completed actions'
6
+ long_desc 'Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown
7
+ (partial matches allowed). Add a + before a token to make it required, e.g. `na completed +feature +maybe`,
8
+ add a - or ! to ignore matches containing that token.'
9
+ arg_name 'PATTERN', optional: true, multiple: true
10
+ command %i[completed finished] do |c|
11
+ c.example 'na completed', desc: 'display completed actions'
12
+ c.example 'na completed --before "2 days ago"',
13
+ desc: 'display actions completed more than two days ago'
14
+ c.example 'na completed --on yesterday',
15
+ desc: 'display actions completed yesterday'
16
+ c.example 'na completed --after "1 week ago"',
17
+ desc: 'display actions completed in the last week'
18
+ c.example 'na completed feature',
19
+ desc: 'display completed actions matcning "feature"'
20
+
21
+ c.desc 'Display actions completed before (natural language) date string'
22
+ c.arg_name 'DATE_STRING'
23
+ c.flag %i[b before]
24
+
25
+ c.desc 'Display actions completed on (natural language) date string'
26
+ c.arg_name 'DATE_STRING'
27
+ c.flag %i[on]
28
+
29
+ c.desc 'Display actions completed after (natural language) date string'
30
+ c.arg_name 'DATE_STRING'
31
+ c.flag %i[a after]
32
+
33
+ c.desc 'Combine before, on, and/or after with OR, displaying actions matching ANY of the ranges'
34
+ c.switch %i[o or], negatable: false
35
+
36
+ c.desc 'Recurse to depth'
37
+ c.arg_name 'DEPTH'
38
+ c.flag %i[d depth], type: :integer, must_match: /^\d+$/
39
+
40
+ c.desc 'Show actions from a specific todo file in history. May use wildcards (* and ?)'
41
+ c.arg_name 'TODO_PATH'
42
+ c.flag %i[in]
43
+
44
+ c.desc 'Include notes in output'
45
+ c.switch %i[notes], negatable: true, default_value: false
46
+
47
+ c.desc 'Show actions from a specific project'
48
+ c.arg_name 'PROJECT[/SUBPROJECT]'
49
+ c.flag %i[proj project]
50
+
51
+ c.desc 'Match actions containing tag. Allows value comparisons'
52
+ c.arg_name 'TAG'
53
+ c.flag %i[tagged], multiple: true
54
+
55
+ c.desc 'Output actions nested by file'
56
+ c.switch %[nest], negatable: false
57
+
58
+ c.desc 'Output actions nested by file and project'
59
+ c.switch %[omnifocus], negatable: false
60
+
61
+ c.desc 'Save this search for future use'
62
+ c.arg_name 'TITLE'
63
+ c.flag %i[save]
64
+
65
+ c.action do |_global_options, options, args|
66
+ tag_string = []
67
+ if options[:before] || options[:on] || options[:after]
68
+ tag_string << "done<#{options[:before]}" if options[:before]
69
+ tag_string << "done=#{options[:on]}" if options[:on]
70
+ tag_string << "done>#{options[:after]}" if options[:after]
71
+ else
72
+ tag_string << 'done'
73
+ end
74
+
75
+ tag_string.concat(options[:tagged]) if options[:tagged]
76
+
77
+ if args.empty?
78
+ cmd_string = %(tagged --done "#{tag_string.join(',')}")
79
+ else
80
+ cmd_string = %(find --tagged "#{tag_string.join(',')}" --done #{args.join(' ')})
81
+ end
82
+
83
+ cmd_string += ' --or' if options[:or]
84
+ cmd_string += %( --in "#{options[:in]}") if options[:in]
85
+ cmd_string += %( --project "#{options[:project]}") if options[:project]
86
+ cmd_string += %( --depth #{options[:depth]}) if options[:depth]
87
+ cmd_string += ' --nest' if options[:nest]
88
+ cmd_string += ' --omnifocus' if options[:omnifocus]
89
+ cmd_string += " --#{options[:notes] ? 'notes' : 'no-notes' }"
90
+
91
+ if options[:save]
92
+ title = options[:save].gsub(/[^a-z0-9]/, '_').gsub(/_+/, '_')
93
+ NA.save_search(title, cmd_string)
94
+ end
95
+
96
+ exit run(Shellwords.shellsplit(cmd_string))
97
+ end
98
+ end
99
+ end
data/bin/commands/edit.rb CHANGED
@@ -1,45 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Open a todo file in the default editor'
4
- long_desc 'Let the system choose the defualt, (e.g. TaskPaper), or specify a command line utility (e.g. vim).
5
- If more than one todo file is found, a menu is displayed.'
6
- command %i[edit] do |c|
7
- c.example 'na edit', desc: 'Open the main todo file in the default editor'
8
- c.example 'na edit -d 3 -a vim', desc: 'Display a menu of all todo files three levels deep from the
9
- current directory, open selection in vim.'
3
+ class App
4
+ extend GLI::App
5
+ desc 'Open a todo file in the default editor'
6
+ long_desc 'Let the system choose the defualt, (e.g. TaskPaper), or specify a command line utility (e.g. vim).
7
+ If more than one todo file is found, a menu is displayed.'
8
+ command %i[edit] do |c|
9
+ c.example 'na edit', desc: 'Open the main todo file in the default editor'
10
+ c.example 'na edit -d 3 -a vim', desc: 'Display a menu of all todo files three levels deep from the
11
+ current directory, open selection in vim.'
10
12
 
11
- c.desc 'Recurse to depth'
12
- c.arg_name 'DEPTH'
13
- c.default_value 1
14
- c.flag %i[d depth], type: :integer, must_match: /^\d+$/
13
+ c.desc 'Recurse to depth'
14
+ c.arg_name 'DEPTH'
15
+ c.default_value 1
16
+ c.flag %i[d depth], type: :integer, must_match: /^\d+$/
15
17
 
16
- c.desc 'Specify an editor CLI'
17
- c.arg_name 'EDITOR'
18
- c.flag %i[e editor]
18
+ c.desc 'Specify an editor CLI'
19
+ c.arg_name 'EDITOR'
20
+ c.flag %i[e editor]
19
21
 
20
- c.desc 'Specify a Mac app'
21
- c.arg_name 'EDITOR'
22
- c.flag %i[a app]
22
+ c.desc 'Specify a Mac app'
23
+ c.arg_name 'EDITOR'
24
+ c.flag %i[a app]
23
25
 
24
- c.action do |global_options, options, args|
25
- depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
26
- 3
27
- else
28
- options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
29
- end
30
- files = NA.find_files(depth: depth)
31
- files.delete_if { |f| f !~ /.*?(#{args.join('|')}).*?.#{NA.extension}/ } if args.count.positive?
26
+ c.action do |global_options, options, args|
27
+ depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
28
+ 3
29
+ else
30
+ options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
31
+ end
32
+ files = NA.find_files(depth: depth)
33
+ files.delete_if { |f| f !~ /.*?(#{args.join('|')}).*?.#{NA.extension}/ } if args.count.positive?
32
34
 
33
- file = if files.count > 1
34
- NA.select_file(files)
35
- else
36
- files[0]
37
- end
35
+ file = if files.count > 1
36
+ NA.select_file(files)
37
+ else
38
+ files[0]
39
+ end
38
40
 
39
- if options[:editor]
40
- system options[:editor], file
41
- else
42
- NA.edit_file(file: file, app: options[:app])
41
+ if options[:editor]
42
+ system options[:editor], file
43
+ else
44
+ NA.edit_file(file: file, app: options[:app])
45
+ end
43
46
  end
44
47
  end
45
48
  end
data/bin/commands/find.rb CHANGED
@@ -1,135 +1,138 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Find actions matching a search pattern'
4
- long_desc 'Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown
5
- (partial matches allowed). Add a + before a token to make it required, e.g. `na find +feature +maybe`,
6
- add a - or ! to ignore matches containing that token.'
7
- arg_name 'PATTERN'
8
- command %i[find grep] do |c|
9
- c.example 'na find feature idea swift', desc: 'Find all actions containing feature, idea, and swift'
10
- c.example 'na find feature idea -swift', desc: 'Find all actions containing feature and idea but NOT swift'
11
- c.example 'na find -x feature idea', desc: 'Find all actions containing the exact text "feature idea"'
3
+ class App
4
+ extend GLI::App
5
+ desc 'Find actions matching a search pattern'
6
+ long_desc 'Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown
7
+ (partial matches allowed). Add a + before a token to make it required, e.g. `na find +feature +maybe`,
8
+ add a - or ! to ignore matches containing that token.'
9
+ arg_name 'PATTERN'
10
+ command %i[find grep] do |c|
11
+ c.example 'na find feature idea swift', desc: 'Find all actions containing feature, idea, and swift'
12
+ c.example 'na find feature idea -swift', desc: 'Find all actions containing feature and idea but NOT swift'
13
+ c.example 'na find -x feature idea', desc: 'Find all actions containing the exact text "feature idea"'
12
14
 
13
- c.desc 'Interpret search pattern as regular expression'
14
- c.switch %i[e regex], negatable: false
15
+ c.desc 'Interpret search pattern as regular expression'
16
+ c.switch %i[e regex], negatable: false
15
17
 
16
- c.desc 'Match pattern exactly'
17
- c.switch %i[x exact], negatable: false
18
+ c.desc 'Match pattern exactly'
19
+ c.switch %i[x exact], negatable: false
18
20
 
19
- c.desc 'Recurse to depth'
20
- c.arg_name 'DEPTH'
21
- c.flag %i[d depth], type: :integer, must_match: /^\d+$/
21
+ c.desc 'Recurse to depth'
22
+ c.arg_name 'DEPTH'
23
+ c.flag %i[d depth], type: :integer, must_match: /^\d+$/
22
24
 
23
- c.desc 'Show actions from a specific todo file in history. May use wildcards (* and ?)'
24
- c.arg_name 'TODO_PATH'
25
- c.flag %i[in]
25
+ c.desc 'Show actions from a specific todo file in history. May use wildcards (* and ?)'
26
+ c.arg_name 'TODO_PATH'
27
+ c.flag %i[in]
26
28
 
27
- c.desc 'Include notes in output'
28
- c.switch %i[notes], negatable: true, default_value: false
29
+ c.desc 'Include notes in output'
30
+ c.switch %i[notes], negatable: true, default_value: false
29
31
 
30
- c.desc 'Combine search tokens with OR, displaying actions matching ANY of the terms'
31
- c.switch %i[o or], negatable: false
32
+ c.desc 'Combine search tokens with OR, displaying actions matching ANY of the terms'
33
+ c.switch %i[o or], negatable: false
32
34
 
33
- c.desc 'Show actions from a specific project'
34
- c.arg_name 'PROJECT[/SUBPROJECT]'
35
- c.flag %i[proj project]
35
+ c.desc 'Show actions from a specific project'
36
+ c.arg_name 'PROJECT[/SUBPROJECT]'
37
+ c.flag %i[proj project]
36
38
 
37
- c.desc 'Match actions containing tag. Allows value comparisons'
38
- c.arg_name 'TAG'
39
- c.flag %i[tagged], multiple: true
39
+ c.desc 'Match actions containing tag. Allows value comparisons'
40
+ c.arg_name 'TAG'
41
+ c.flag %i[tagged], multiple: true
40
42
 
41
- c.desc 'Include @done actions'
42
- c.switch %i[done]
43
+ c.desc 'Include @done actions'
44
+ c.switch %i[done]
43
45
 
44
- c.desc 'Show actions not matching search pattern'
45
- c.switch %i[v invert], negatable: false
46
+ c.desc 'Show actions not matching search pattern'
47
+ c.switch %i[v invert], negatable: false
46
48
 
47
- c.desc 'Save this search for future use'
48
- c.arg_name 'TITLE'
49
- c.flag %i[save]
49
+ c.desc 'Save this search for future use'
50
+ c.arg_name 'TITLE'
51
+ c.flag %i[save]
50
52
 
51
- c.desc 'Output actions nested by file'
52
- c.switch %[nest], negatable: false
53
+ c.desc 'Output actions nested by file'
54
+ c.switch %[nest], negatable: false
53
55
 
54
- c.desc 'Output actions nested by file and project'
55
- c.switch %[omnifocus], negatable: false
56
+ c.desc 'Output actions nested by file and project'
57
+ c.switch %[omnifocus], negatable: false
56
58
 
57
- c.action do |global_options, options, args|
58
- options[:nest] = true if options[:omnifocus]
59
+ c.action do |global_options, options, args|
60
+ options[:nest] = true if options[:omnifocus]
59
61
 
60
- if options[:save]
61
- title = options[:save].gsub(/[^a-z0-9]/, '_').gsub(/_+/, '_')
62
- NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '').split(' ').map { |t| %("#{t}") }.join(' ')}")
63
- end
62
+ if options[:save]
63
+ title = options[:save].gsub(/[^a-z0-9]/, '_').gsub(/_+/, '_')
64
+ NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '').split(' ').map { |t| %("#{t}") }.join(' ')}")
65
+ end
64
66
 
65
67
 
66
- depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
67
- 3
68
- else
69
- options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
70
- end
71
-
72
- all_req = options[:tagged].join(' ') !~ /[+!\-]/ && !options[:or]
73
- tags = []
74
- options[:tagged].join(',').split(/ *, */).each do |arg|
75
- m = arg.match(/^(?<req>[+\-!])?(?<tag>[^ =<>$\^]+?)(?:(?<op>[=<>]{1,2}|[*$\^]=)(?<val>.*?))?$/)
76
-
77
- tags.push({
78
- tag: m['tag'].wildcard_to_rx,
79
- comp: m['op'],
80
- value: m['val'],
81
- required: all_req || (!m['req'].nil? && m['req'] == '+'),
82
- negate: !m['req'].nil? && m['req'] =~ /[!\-]/
83
- })
84
- end
68
+ depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
69
+ 3
70
+ else
71
+ options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
72
+ end
85
73
 
86
- tokens = nil
87
- if options[:exact]
88
- tokens = args.join(' ')
89
- elsif options[:regex]
90
- tokens = Regexp.new(args.join(' '), Regexp::IGNORECASE)
91
- else
92
- tokens = []
93
- all_req = args.join(' ') !~ /[+!\-]/ && !options[:or]
94
-
95
- args.join(' ').split(/ /).each do |arg|
96
- m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
97
- tokens.push({
98
- token: m['tok'],
99
- required: all_req || (!m['req'].nil? && m['req'] == '+'),
100
- negate: !m['req'].nil? && m['req'] =~ /[!\-]/
101
- })
102
- end
103
- end
74
+ all_req = options[:tagged].join(' ') !~ /[+!\-]/ && !options[:or]
75
+ tags = []
76
+ options[:tagged].join(',').split(/ *, */).each do |arg|
77
+ m = arg.match(/^(?<req>[+\-!])?(?<tag>[^ =<>$\^]+?)(?:(?<op>[=<>]{1,2}|[*$\^]=)(?<val>.*?))?$/)
104
78
 
105
- todo = nil
106
- if options[:in]
107
- todo = []
108
- options[:in].split(/ *, */).each do |a|
109
- m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
110
- todo.push({
111
- token: m['tok'],
79
+ tags.push({
80
+ tag: m['tag'].wildcard_to_rx,
81
+ comp: m['op'],
82
+ value: m['val'],
112
83
  required: all_req || (!m['req'].nil? && m['req'] == '+'),
113
84
  negate: !m['req'].nil? && m['req'] =~ /[!\-]/
114
85
  })
115
86
  end
116
- end
117
87
 
118
- files, actions, = NA.parse_actions(depth: depth,
119
- done: options[:done],
120
- query: todo,
121
- search: tokens,
122
- tag: tags,
123
- negate: options[:invert],
124
- regex: options[:regex],
125
- project: options[:project],
126
- require_na: false)
127
- regexes = if tokens.is_a?(Array)
128
- tokens.delete_if { |token| token[:negate] }.map { |token| token[:token] }
129
- else
130
- [tokens]
131
- end
88
+ tokens = nil
89
+ if options[:exact]
90
+ tokens = args.join(' ')
91
+ elsif options[:regex]
92
+ tokens = Regexp.new(args.join(' '), Regexp::IGNORECASE)
93
+ else
94
+ tokens = []
95
+ all_req = args.join(' ') !~ /[+!\-]/ && !options[:or]
96
+
97
+ args.join(' ').split(/ /).each do |arg|
98
+ m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
99
+ tokens.push({
100
+ token: m['tok'],
101
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
102
+ negate: !m['req'].nil? && m['req'] =~ /[!\-]/
103
+ })
104
+ end
105
+ end
132
106
 
133
- NA.output_actions(actions, depth, files: files, regexes: regexes, notes: options[:notes], nest: options[:nest], nest_projects: options[:omnifocus])
107
+ todo = nil
108
+ if options[:in]
109
+ todo = []
110
+ options[:in].split(/ *, */).each do |a|
111
+ m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
112
+ todo.push({
113
+ token: m['tok'],
114
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
115
+ negate: !m['req'].nil? && m['req'] =~ /[!\-]/
116
+ })
117
+ end
118
+ end
119
+
120
+ files, actions, = NA.parse_actions(depth: depth,
121
+ done: options[:done],
122
+ query: todo,
123
+ search: tokens,
124
+ tag: tags,
125
+ negate: options[:invert],
126
+ regex: options[:regex],
127
+ project: options[:project],
128
+ require_na: false)
129
+ regexes = if tokens.is_a?(Array)
130
+ tokens.delete_if { |token| token[:negate] }.map { |token| token[:token] }
131
+ else
132
+ [tokens]
133
+ end
134
+
135
+ NA.output_actions(actions, depth, files: files, regexes: regexes, notes: options[:notes], nest: options[:nest], nest_projects: options[:omnifocus])
136
+ end
134
137
  end
135
138
  end
data/bin/commands/init.rb CHANGED
@@ -1,28 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Create a new todo file in the current directory'
4
- arg_name 'PROJECT', optional: true
5
- command %i[init create] do |c|
6
- c.example 'na init', desc: 'Generate a new todo file, prompting for project name'
7
- c.example 'na init warpspeed', desc: 'Generate a new todo for a project called warpspeed'
3
+ class App
4
+ extend GLI::App
5
+ desc 'Create a new todo file in the current directory'
6
+ arg_name 'PROJECT', optional: true
7
+ command %i[init create] do |c|
8
+ c.example 'na init', desc: 'Generate a new todo file, prompting for project name'
9
+ c.example 'na init warpspeed', desc: 'Generate a new todo for a project called warpspeed'
8
10
 
9
- c.action do |global_options, _options, args|
10
- reader = TTY::Reader.new
11
- if args.count.positive?
12
- project = args.join(' ')
13
- elsif
14
- project = File.expand_path('.').split('/').last
15
- project = reader.read_line(NA::Color.template('{y}Project name {bw}> {x}'), value: project).strip if $stdin.isatty
16
- end
11
+ c.action do |global_options, _options, args|
12
+ reader = TTY::Reader.new
13
+ if args.count.positive?
14
+ project = args.join(' ')
15
+ elsif
16
+ project = File.expand_path('.').split('/').last
17
+ project = reader.read_line(NA::Color.template('{y}Project name {bw}> {x}'), value: project).strip if $stdin.isatty
18
+ end
17
19
 
18
- target = "#{project}.#{NA.extension}"
20
+ target = "#{project}.#{NA.extension}"
19
21
 
20
- if File.exist?(target)
21
- res = NA.yn(NA::Color.template("{r}File {bw}#{target}{r} already exists, overwrite it"), default: false)
22
- Process.exit 1 unless res
22
+ if File.exist?(target)
23
+ res = NA.yn(NA::Color.template("{r}File {bw}#{target}{r} already exists, overwrite it"), default: false)
24
+ Process.exit 1 unless res
23
25
 
24
- end
26
+ end
25
27
 
26
- NA.create_todo(target, project, template: global_options[:template])
28
+ NA.create_todo(target, project, template: global_options[:template])
29
+ end
27
30
  end
28
31
  end