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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92a40acdde96bfe4a27a093edf4e0f909b23b1c300d6be4f742323ac4e9233be
4
- data.tar.gz: bfddb6edfe9cddf7a631819bd980708fd816d2853b3146f348c2095b1ca7aee2
3
+ metadata.gz: ac0a37d801443c68aaee6eee3b6c4a31461a61d4221c7a073beb0f176d7d7424
4
+ data.tar.gz: d04d6bd01a3104f6858e9a797af728486b80a8482b6644a09940a6272ae2ec4b
5
5
  SHA512:
6
- metadata.gz: 77fd24c44ea1b7dba5fb2feb8d36e625972b7662c3032d96ffb7af28843cc08ad16f911fb58778b7cfc831b329859effb04134168517eb596f1da4e9d62cc001
7
- data.tar.gz: 212c87e2f59706bd6ed9b5e4cec2ecbd629e9b344a7538f653d8b278dd0f9e62aeb2ceada2d2ed8ef12421fc8c54396ec6e2462b77fe28f90d90946a6aed3967
6
+ metadata.gz: 7ec40b0dd9ff9f154cc22e5d1cb2df700fae82e9c8118110d72b0ea3aeed46a0bd7543955e8b491f99816a9c5dea8ede5866534c362abbb771a3fefbe8d346d9
7
+ data.tar.gz: c66d44910edfe4200655b6775665ead7836b47dd7b8b20385da29ee21ce6ba38d5fef0f99b2da009385d9962204cf491d3ee928b2c255bd5d2ce278d8a4c15fa
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 1.0.6
2
+
3
+ 2022-09-28 04:22
4
+
5
+ #### NEW
6
+
7
+ - `na prompt [show|install]` command to help with adding prompt hooks to your shell
8
+
1
9
  ### 1.0.5
2
10
 
3
11
  2022-09-28 01:53
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.0.4)
4
+ na (1.0.5)
5
5
  gli (~> 2.21.0)
6
6
  tty-reader (~> 0.9, >= 0.9.0)
7
7
  tty-screen (~> 0.8, >= 0.8.1)
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.4.
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[verbose]
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, global_options[:ext], files: files)
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 = global_options[: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, ".#{global_options[:ext]}")
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, extension: global_options[:ext])
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}.#{global_options[:ext]}"
182
+ target = "#{basename}.#{NA.extension}"
185
183
  NA.create_todo(target, basename)
186
- files = NA.find_files(depth: 1, extension: global_options[:ext])
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, global_options[:ext], files: files)
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, global_options[:ext], files: files)
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}.#{global_options[:ext]}"
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, extension: global_options[:ext])
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[:verbose]
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
 
@@ -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, extension: 'taskpaper')
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, extension, files: nil)
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, extension: extension).count > 1
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, extension: 'taskpaper', na_tag: 'na', query: nil, tag: nil, search: nil)
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, extension: extension)
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
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.0.5'
2
+ VERSION = '1.0.6'
3
3
  end
data/lib/na.rb CHANGED
@@ -11,3 +11,4 @@ require 'na/colors.rb'
11
11
  require 'na/string.rb'
12
12
  require 'na/action.rb'
13
13
  require 'na/next_action.rb'
14
+ require 'na/prompt.rb'
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.4<!--END VER-->.
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.5
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