na 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -2
- data/bin/na +63 -18
- data/lib/na/next_action.rb +16 -16
- data/lib/na/prompt.rb +61 -0
- data/lib/na/version.rb +1 -1
- data/lib/na.rb +1 -0
- data/src/README.md +1 -2
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac0a37d801443c68aaee6eee3b6c4a31461a61d4221c7a073beb0f176d7d7424
|
4
|
+
data.tar.gz: d04d6bd01a3104f6858e9a797af728486b80a8482b6644a09940a6272ae2ec4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ec40b0dd9ff9f154cc22e5d1cb2df700fae82e9c8118110d72b0ea3aeed46a0bd7543955e8b491f99816a9c5dea8ede5866534c362abbb771a3fefbe8d346d9
|
7
|
+
data.tar.gz: c66d44910edfe4200655b6775665ead7836b47dd7b8b20385da29ee21ce6ba38d5fef0f99b2da009385d9962204cf491d3ee928b2c255bd5d2ce278d8a4c15fa
|
data/CHANGELOG.md
CHANGED
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.0.
|
12
|
+
The current version of `na` is 1.0.5.
|
13
13
|
|
14
14
|
`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.
|
15
15
|
|
@@ -293,7 +293,6 @@ Fish (in ~/.config/fish/conf.d/*.fish):
|
|
293
293
|
|
294
294
|
```fish
|
295
295
|
function __should_na --on-variable PWD
|
296
|
-
# function __should_na --on-event fish_prompt
|
297
296
|
test -s (basename $PWD)".taskpaper" && na
|
298
297
|
end
|
299
298
|
```
|
data/bin/na
CHANGED
@@ -48,7 +48,7 @@ class App
|
|
48
48
|
flag %i[d depth], type: :integer, must_match: /^\d+$/
|
49
49
|
|
50
50
|
desc 'Display verbose output'
|
51
|
-
switch %i[
|
51
|
+
switch %i[debug]
|
52
52
|
|
53
53
|
desc 'Show next actions'
|
54
54
|
arg_name 'OPTIONAL_QUERY'
|
@@ -94,11 +94,9 @@ class App
|
|
94
94
|
tag = options[:tag] == global_options[:na_tag] ? nil : options[:tag]
|
95
95
|
files, actions = NA.parse_actions(depth: depth,
|
96
96
|
query: tokens,
|
97
|
-
extension: global_options[:ext],
|
98
|
-
na_tag: global_options[:na_tag],
|
99
97
|
tag: tag)
|
100
98
|
|
101
|
-
NA.output_actions(actions, depth,
|
99
|
+
NA.output_actions(actions, depth, files: files)
|
102
100
|
end
|
103
101
|
end
|
104
102
|
|
@@ -148,7 +146,7 @@ class App
|
|
148
146
|
action = "#{action.gsub(/@priority\(\d+\)/, '')} @priority(#{options[:priority]})"
|
149
147
|
end
|
150
148
|
|
151
|
-
na_tag =
|
149
|
+
na_tag = NA.na_tag
|
152
150
|
na_tag = options[:tag] unless options[:tag].nil?
|
153
151
|
|
154
152
|
action = "#{action.gsub(/@#{na_tag}/, '')} @#{na_tag}"
|
@@ -167,7 +165,7 @@ class App
|
|
167
165
|
print NA::Color.template('{by}Specified file not found, create it? {w}(y/{g}N{w}){x} ')
|
168
166
|
res = reader.read_char
|
169
167
|
if res =~ /y/i
|
170
|
-
basename = File.basename(target, ".#{
|
168
|
+
basename = File.basename(target, ".#{NA.extension}")
|
171
169
|
NA.create_todo(target, basename)
|
172
170
|
else
|
173
171
|
puts NA::Color.template('{r}Cancelled{x}')
|
@@ -175,15 +173,15 @@ class App
|
|
175
173
|
end
|
176
174
|
end
|
177
175
|
else
|
178
|
-
files = NA.find_files(depth: 1
|
176
|
+
files = NA.find_files(depth: 1)
|
179
177
|
if files.count == 0
|
180
178
|
print NA::Color.template('{by}No todo file found, create one? {w}(y/{g}N{w}){x} ')
|
181
179
|
res = reader.read_char
|
182
180
|
if res =~ /y/i
|
183
181
|
basename = File.expand_path('.').split('/').last
|
184
|
-
target = "#{basename}.#{
|
182
|
+
target = "#{basename}.#{NA.extension}"
|
185
183
|
NA.create_todo(target, basename)
|
186
|
-
files = NA.find_files(depth: 1
|
184
|
+
files = NA.find_files(depth: 1)
|
187
185
|
end
|
188
186
|
end
|
189
187
|
target = files.count > 1 ? NA.select_file(files) : files[0]
|
@@ -236,10 +234,8 @@ class App
|
|
236
234
|
end
|
237
235
|
|
238
236
|
files, actions = NA.parse_actions(depth: depth,
|
239
|
-
extension: global_options[:ext],
|
240
|
-
na_tag: global_options[:na_tag],
|
241
237
|
search: tokens)
|
242
|
-
NA.output_actions(actions, depth,
|
238
|
+
NA.output_actions(actions, depth, files: files)
|
243
239
|
end
|
244
240
|
end
|
245
241
|
|
@@ -278,10 +274,8 @@ class App
|
|
278
274
|
end
|
279
275
|
|
280
276
|
files, actions = NA.parse_actions(depth: depth,
|
281
|
-
extension: global_options[:ext],
|
282
|
-
na_tag: global_options[:na_tag],
|
283
277
|
tag: tags)
|
284
|
-
NA.output_actions(actions, depth,
|
278
|
+
NA.output_actions(actions, depth, files: files)
|
285
279
|
end
|
286
280
|
end
|
287
281
|
|
@@ -300,7 +294,7 @@ class App
|
|
300
294
|
project = reader.read_line(NA::Color.template('{y}Project name {bw}> {x}'), value: project).strip
|
301
295
|
end
|
302
296
|
|
303
|
-
target = "#{project}.#{
|
297
|
+
target = "#{project}.#{NA.extension}"
|
304
298
|
|
305
299
|
if File.exist?(target)
|
306
300
|
print NA::Color.template("{r}File {bw}#{target}{r} already exists, overwrite it? {br}y{w}/{bg}N{x} ")
|
@@ -339,7 +333,7 @@ class App
|
|
339
333
|
else
|
340
334
|
options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
|
341
335
|
end
|
342
|
-
files = NA.find_files(depth: depth
|
336
|
+
files = NA.find_files(depth: depth)
|
343
337
|
file = if files.count > 1
|
344
338
|
NA.select_file(files)
|
345
339
|
else
|
@@ -354,8 +348,59 @@ class App
|
|
354
348
|
end
|
355
349
|
end
|
356
350
|
|
351
|
+
desc 'Show or install prompt hooks for the current shell'
|
352
|
+
long_desc 'Installing the prompt hook allows you to automatically
|
353
|
+
list next actions when you cd into a directory'
|
354
|
+
command %i[prompt] do |c|
|
355
|
+
c.desc 'Output the prompt hook for the current shell to STDOUT. Pass an argument to specify a shell (zsh, bash, fish)'
|
356
|
+
c.arg_name '[SHELL]'
|
357
|
+
c.command %i[show] do |s|
|
358
|
+
s.action do |global_options, options, args|
|
359
|
+
if args.count.positive?
|
360
|
+
shell = args[0]
|
361
|
+
else
|
362
|
+
shell = File.basename(ENV['SHELL'])
|
363
|
+
end
|
364
|
+
|
365
|
+
case shell
|
366
|
+
when /^f/i
|
367
|
+
NA::Prompt.show_prompt_hook(:fish)
|
368
|
+
when /^z/i
|
369
|
+
NA::Prompt.show_prompt_hook(:zsh)
|
370
|
+
when /^b/i
|
371
|
+
NA::Prompt.show_prompt_hook(:bash)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
c.desc 'Install the hook for the current shell to the appropriate startup file.'
|
377
|
+
c.arg_name '[SHELL]'
|
378
|
+
c.command %i[install] do |s|
|
379
|
+
s.action do |global_options, options, args|
|
380
|
+
if args.count.positive?
|
381
|
+
shell = args[0]
|
382
|
+
else
|
383
|
+
shell = File.basename(ENV['SHELL'])
|
384
|
+
end
|
385
|
+
|
386
|
+
case shell
|
387
|
+
when /^f/i
|
388
|
+
NA::Prompt.install_prompt_hook(:fish)
|
389
|
+
when /^z/i
|
390
|
+
NA::Prompt.install_prompt_hook(:zsh)
|
391
|
+
when /^b/i
|
392
|
+
NA::Prompt.install_prompt_hook(:bash)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
|
399
|
+
|
357
400
|
pre do |global, command, options, args|
|
358
|
-
NA.verbose = global[:
|
401
|
+
NA.verbose = global[:debug]
|
402
|
+
NA.extension = global[:ext]
|
403
|
+
NA.na_tag = global[:na_tag]
|
359
404
|
true
|
360
405
|
end
|
361
406
|
|
data/lib/na/next_action.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Next Action methods
|
4
4
|
module NA
|
5
5
|
class << self
|
6
|
-
attr_accessor :verbose
|
6
|
+
attr_accessor :verbose, :extension, :na_tag
|
7
7
|
|
8
8
|
def create_todo(target, basename)
|
9
9
|
File.open(target, 'w') do |f|
|
@@ -22,11 +22,11 @@ module NA
|
|
22
22
|
ENDCONTENT
|
23
23
|
f.puts(content)
|
24
24
|
end
|
25
|
-
puts NA::Color.template("{y}Created {bw}#{target}{x}")
|
25
|
+
$stderr.puts NA::Color.template("{y}Created {bw}#{target}{x}")
|
26
26
|
end
|
27
27
|
|
28
|
-
def find_files(depth: 1
|
29
|
-
`find . -name "*.#{extension}" -maxdepth #{depth}`.strip.split("\n")
|
28
|
+
def find_files(depth: 1)
|
29
|
+
`find . -name "*.#{NA.extension}" -maxdepth #{depth}`.strip.split("\n")
|
30
30
|
end
|
31
31
|
|
32
32
|
def select_file(files)
|
@@ -39,7 +39,7 @@ module NA
|
|
39
39
|
elsif TTY::Which.exist?('fzf')
|
40
40
|
res = choose_from(files, prompt: 'Use which file?')
|
41
41
|
unless res
|
42
|
-
puts 'No file selected, cancelled'
|
42
|
+
$stderr.puts 'No file selected, cancelled'
|
43
43
|
Process.exit 1
|
44
44
|
end
|
45
45
|
|
@@ -69,17 +69,17 @@ module NA
|
|
69
69
|
|
70
70
|
File.open(file, 'w') { |f| f.puts content }
|
71
71
|
|
72
|
-
puts NA::Color.template("{by}Task added to {bw}#{file}{x}")
|
72
|
+
$stderr.puts NA::Color.template("{by}Task added to {bw}#{file}{x}")
|
73
73
|
end
|
74
74
|
|
75
|
-
def output_actions(actions, depth,
|
75
|
+
def output_actions(actions, depth, files: nil)
|
76
76
|
template = if files&.count.positive?
|
77
77
|
if files.count == 1
|
78
78
|
'%parent%action'
|
79
79
|
else
|
80
80
|
'%filename%parent%action'
|
81
81
|
end
|
82
|
-
elsif NA.find_files(depth: depth
|
82
|
+
elsif NA.find_files(depth: depth).count > 1
|
83
83
|
if depth > 1
|
84
84
|
'%filename%parent%action'
|
85
85
|
else
|
@@ -89,13 +89,13 @@ module NA
|
|
89
89
|
'%parent%action'
|
90
90
|
end
|
91
91
|
if files && @verbose
|
92
|
-
puts files.map { |f| NA::Color.template("{dw}#{f}{x}") }
|
92
|
+
$stderr.puts files.map { |f| NA::Color.template("{dw}#{f}{x}") }
|
93
93
|
end
|
94
94
|
|
95
95
|
puts actions.map { |action| action.pretty(template: { output: template }) }
|
96
96
|
end
|
97
97
|
|
98
|
-
def parse_actions(depth: 1,
|
98
|
+
def parse_actions(depth: 1, query: nil, tag: nil, search: nil)
|
99
99
|
actions = []
|
100
100
|
required = []
|
101
101
|
optional = []
|
@@ -122,10 +122,10 @@ module NA
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
na_tag = "@#{na_tag.sub(/^@/, '')}"
|
125
|
+
na_tag = "@#{NA.na_tag.sub(/^@/, '')}"
|
126
126
|
|
127
127
|
if query.nil?
|
128
|
-
files = find_files(depth: depth
|
128
|
+
files = find_files(depth: depth)
|
129
129
|
else
|
130
130
|
files = match_working_dir(query)
|
131
131
|
end
|
@@ -156,8 +156,8 @@ module NA
|
|
156
156
|
|
157
157
|
end
|
158
158
|
|
159
|
-
action = line.sub(/^[ \t]*- /, '').sub(/ #{na_tag}/, '')
|
160
|
-
new_action = NA::Action.new(file, File.basename(file, ".#{extension}"), parent.dup, action)
|
159
|
+
action = line.sub(/^[ \t]*- /, '').sub(/ #{NA.na_tag}/, '')
|
160
|
+
new_action = NA::Action.new(file, File.basename(file, ".#{NA.extension}"), parent.dup, action)
|
161
161
|
actions.push(new_action)
|
162
162
|
end
|
163
163
|
end
|
@@ -220,7 +220,7 @@ module NA
|
|
220
220
|
dirs.delete_if { |d| !d.matches(any: optional, all: required) }
|
221
221
|
dirs.sort.uniq
|
222
222
|
else
|
223
|
-
puts NA::Color.template('{r}No na database found{x}')
|
223
|
+
$stderr.puts NA::Color.template('{r}No na database found{x}')
|
224
224
|
Process.exit 1
|
225
225
|
end
|
226
226
|
end
|
@@ -269,7 +269,7 @@ module NA
|
|
269
269
|
if 'xdg-open'.available?
|
270
270
|
`xdg-open #{Shellwords.escape(file)}`
|
271
271
|
else
|
272
|
-
puts NA::Color.template('{r}Unable to determine executable for `open`.{x}')
|
272
|
+
$stderr.puts NA::Color.template('{r}Unable to determine executable for `open`.{x}')
|
273
273
|
end
|
274
274
|
end
|
275
275
|
end
|
data/lib/na/prompt.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NA
|
4
|
+
# Prompt Hooks
|
5
|
+
module Prompt
|
6
|
+
class << self
|
7
|
+
def prompt_hook(shell)
|
8
|
+
case shell
|
9
|
+
when :zsh
|
10
|
+
<<~EOHOOK
|
11
|
+
# zsh prompt hook for na
|
12
|
+
chpwd() { na }
|
13
|
+
EOHOOK
|
14
|
+
when :fish
|
15
|
+
<<~EOHOOK
|
16
|
+
# Fish Prompt Command
|
17
|
+
function __should_na --on-variable PWD
|
18
|
+
test -s (basename $PWD)".#{NA.extension}" && na
|
19
|
+
end
|
20
|
+
EOHOOK
|
21
|
+
when :bash
|
22
|
+
<<~EOHOOK
|
23
|
+
# Bash PROMPT_COMMAND for na
|
24
|
+
last_command_was_cd() {
|
25
|
+
[[ $(history 1|sed -e "s/^[ ]*[0-9]*[ ]*//") =~ ^((cd|z|j|jump|g|f|pushd|popd|exit)([ ]|$)) ]] && na
|
26
|
+
}
|
27
|
+
if [[ -z "$PROMPT_COMMAND" ]]; then
|
28
|
+
PROMPT_COMMAND="eval 'last_command_was_cd'"
|
29
|
+
else
|
30
|
+
echo $PROMPT_COMMAND | grep -v -q "last_command_was_cd" && PROMPT_COMMAND="$PROMPT_COMMAND;"'eval "last_command_was_cd"'
|
31
|
+
fi
|
32
|
+
EOHOOK
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def prompt_file(shell)
|
37
|
+
files = {
|
38
|
+
zsh: '~/.zshrc',
|
39
|
+
fish: '~/.config/fish/conf.d/na.fish',
|
40
|
+
bash: '~/.bash_profile'
|
41
|
+
}
|
42
|
+
|
43
|
+
files[shell]
|
44
|
+
end
|
45
|
+
|
46
|
+
def show_prompt_hook(shell)
|
47
|
+
file = prompt_file(shell)
|
48
|
+
|
49
|
+
$stderr.puts NA::Color.template("{bw}# Add this to {y}#{file}{x}")
|
50
|
+
puts prompt_hook(shell)
|
51
|
+
end
|
52
|
+
|
53
|
+
def install_prompt_hook(shell)
|
54
|
+
file = prompt_file(shell)
|
55
|
+
|
56
|
+
File.open(File.expand_path(file), 'a') { |f| f.puts prompt_hook(shell) }
|
57
|
+
$stderr.puts NA::Color.template("{y}Added {bw}#{shell}{xy} prompt hook to {bw}#{file}{x}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/na/version.rb
CHANGED
data/lib/na.rb
CHANGED
data/src/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 <!--VER-->1.0.
|
12
|
+
The current version of `na` is <!--VER-->1.0.5<!--END VER-->.
|
13
13
|
|
14
14
|
`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.
|
15
15
|
|
@@ -293,7 +293,6 @@ Fish (in ~/.config/fish/conf.d/*.fish):
|
|
293
293
|
|
294
294
|
```fish
|
295
295
|
function __should_na --on-variable PWD
|
296
|
-
# function __should_na --on-event fish_prompt
|
297
296
|
test -s (basename $PWD)".taskpaper" && na
|
298
297
|
end
|
299
298
|
```
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: na
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
@@ -170,6 +170,7 @@ files:
|
|
170
170
|
- lib/na/action.rb
|
171
171
|
- lib/na/colors.rb
|
172
172
|
- lib/na/next_action.rb
|
173
|
+
- lib/na/prompt.rb
|
173
174
|
- lib/na/string.rb
|
174
175
|
- lib/na/version.rb
|
175
176
|
- na.gemspec
|