na 1.1.10 → 1.1.11

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: 7d9dd176974a6c4c20be90d5051c7608469ea7b105537a7859697e3be4050ea5
4
- data.tar.gz: b201fecc68568c3b80c6626eb425929d2f50faf6a1bd5fe5bae076021ea0d8b1
3
+ metadata.gz: b309ba145cf0859f1a9011cf62268261766338d79cb956810fab9c64863c37f2
4
+ data.tar.gz: 6fc7e065d4d85bf70b9122634414274e6a44d640ffffeeee7409e9102115f11d
5
5
  SHA512:
6
- metadata.gz: 169372ba631178c20af2af22e461ba0a6c9fcb7e7e5421d71464b1f180ad766bcd2888d30305354554e24ab86c366c12ffdbab9cc2e0f6c7c03f48f402a32679
7
- data.tar.gz: c6ea88026936d1f0fe6d9c822945bd7f9ecf351a67871d5fbe27673a2142ef03502fb1759d20d817b4ab8f435942cf6bbdfa24829e535c9684fe507549ac5bee
6
+ metadata.gz: 63ee0b1ac9370533379956e8cd5f6571c8d39731c12c02404b2912d5cb97f49d32c988e4d23c12c50d1b2080412296bc58351680122abd26281580c49d93f722
7
+ data.tar.gz: b7500123c7ea092acc42ccba0873942fe871bd201405e3ef2faa66f3d155c3d0ac60b530078d962114a4d0d66bdb8ea427b1452873c14e2b06419cb2675e822e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 1.1.11
2
+
3
+ 2022-10-05 08:56
4
+
5
+ #### IMPROVED
6
+
7
+ - Respect na_tag setting when creating new todo file
8
+ - Code cleanup
9
+
1
10
  ### 1.1.10
2
11
 
3
12
  2022-10-05 08:19
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.1.10)
4
+ na (1.1.11)
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.1.10
12
+ The current version of `na` is 1.1.11
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.
data/bin/na CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
3
5
  require 'gli'
4
6
  require 'na'
5
7
 
8
+ # Main application
6
9
  class App
7
10
  extend GLI::App
8
11
 
@@ -123,7 +126,7 @@ class App
123
126
 
124
127
  c.desc 'Add action to specific project'
125
128
  c.default_value 'Inbox'
126
- c.flag %[to]
129
+ c.flag %i[to]
127
130
 
128
131
  c.desc 'Use a tag other than the default next action tag'
129
132
  c.arg_name 'TAG'
@@ -136,7 +139,7 @@ class App
136
139
  c.arg_name 'PATH'
137
140
  c.flag %i[f file]
138
141
 
139
- c.action do |global_options, options, args|
142
+ c.action do |_global_options, options, args|
140
143
  reader = TTY::Reader.new
141
144
  action = if args.count.positive?
142
145
  args.join(' ').strip
@@ -168,7 +171,10 @@ class App
168
171
 
169
172
  note = if options[:note]
170
173
  if TTY::Which.exist?('gum')
171
- `gum write --placeholder "Enter a note, CTRL-d to save" --width $(tput cols) --char-limit 0`.strip.split("\n")
174
+ args = ['--placeholder "Enter a note, CTRL-d to save"']
175
+ args << '--char-limit 0'
176
+ args << '--width $(tput cols)'
177
+ `gum write #{args.join(' ')}`.strip.split("\n")
172
178
  else
173
179
  puts NA::Color.template('{bm}Enter a note, {bw}CTRL-d{bm} to end editing{bw}')
174
180
  reader.read_multiline
@@ -190,7 +196,7 @@ class App
190
196
  end
191
197
  else
192
198
  files = NA.find_files(depth: 1)
193
- if files.count == 0
199
+ if files.count.zero?
194
200
  print NA::Color.template('{by}No todo file found, create one? {w}(y/{g}N{w}){x} ')
195
201
  res = reader.read_char
196
202
  if res =~ /y/i
@@ -256,10 +262,10 @@ class App
256
262
  end
257
263
  end
258
264
 
259
-
260
265
  desc 'Find actions matching a tag'
261
266
  long_desc 'Finds actions with tags matching the arguments. An action is shown if it
262
- contains any of the tags listed. Add a + before a tag to make it required. You can specify values using TAG=VALUE pairs.'
267
+ contains any of the tags listed. Add a + before a tag to make it required.
268
+ You can specify values using TAG=VALUE pairs.'
263
269
  arg_name 'TAG [VALUE]'
264
270
  command %i[tagged] do |c|
265
271
  c.example 'na tagged +maybe', desc: 'Show all actions tagged @maybe'
@@ -304,7 +310,7 @@ class App
304
310
  c.example 'na init', desc: 'Generate a new todo file, prompting for project name'
305
311
  c.example 'na init warpspeed', desc: 'Generate a new todo for a project called warpspeed'
306
312
 
307
- c.action do |global_options, _, args|
313
+ c.action do |_global_options, _options, args|
308
314
  reader = TTY::Reader.new
309
315
  if args.count.positive?
310
316
  project = args.join(' ')
@@ -346,7 +352,7 @@ class App
346
352
  c.arg_name 'EDITOR'
347
353
  c.flag %i[a app]
348
354
 
349
- c.action do |global_options, options, args|
355
+ c.action do |global_options, options, _args|
350
356
  depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
351
357
  3
352
358
  else
@@ -371,15 +377,16 @@ class App
371
377
  long_desc 'Installing the prompt hook allows you to automatically
372
378
  list next actions when you cd into a directory'
373
379
  command %i[prompt] do |c|
374
- c.desc 'Output the prompt hook for the current shell to STDOUT. Pass an argument to specify a shell (zsh, bash, fish)'
380
+ c.desc 'Output the prompt hook for the current shell to STDOUT. Pass an argument to
381
+ specify a shell (zsh, bash, fish)'
375
382
  c.arg_name '[SHELL]'
376
383
  c.command %i[show] do |s|
377
- s.action do |global_options, options, args|
378
- if args.count.positive?
379
- shell = args[0]
380
- else
381
- shell = File.basename(ENV['SHELL'])
382
- end
384
+ s.action do |_global_options, _options, args|
385
+ shell = if args.count.positive?
386
+ args[0]
387
+ else
388
+ File.basename(ENV['SHELL'])
389
+ end
383
390
 
384
391
  case shell
385
392
  when /^f/i
@@ -395,12 +402,12 @@ class App
395
402
  c.desc 'Install the hook for the current shell to the appropriate startup file.'
396
403
  c.arg_name '[SHELL]'
397
404
  c.command %i[install] do |s|
398
- s.action do |global_options, options, args|
399
- if args.count.positive?
400
- shell = args[0]
401
- else
402
- shell = File.basename(ENV['SHELL'])
403
- end
405
+ s.action do |_global_options, _options, args|
406
+ shell = if args.count.positive?
407
+ args[0]
408
+ else
409
+ File.basename(ENV['SHELL'])
410
+ end
404
411
 
405
412
  case shell
406
413
  when /^f/i
@@ -414,7 +421,7 @@ class App
414
421
  end
415
422
  end
416
423
 
417
- pre do |global, command, options, args|
424
+ pre do |global, _command, _options, _args|
418
425
  NA.verbose = global[:debug]
419
426
  NA.extension = global[:ext]
420
427
  NA.na_tag = global[:na_tag]
@@ -432,9 +439,7 @@ class App
432
439
  case exception
433
440
  when GLI::UnknownCommand
434
441
  cmd = ['add']
435
- if ARGV.count.positive?
436
- cmd.concat(ARGV.unshift($first_arg))
437
- end
442
+ cmd.concat(ARGV.unshift($first_arg)) if ARGV.count.positive?
438
443
 
439
444
  exit run(cmd)
440
445
  when SystemExit
@@ -5,10 +5,17 @@ module NA
5
5
  class << self
6
6
  attr_accessor :verbose, :extension, :na_tag
7
7
 
8
+ def notify(msg, exit_code: false)
9
+ $stderr.puts NA::Color.template("{x}#{msg}{x}")
10
+ if exit_code && exit_code.is_a?(Number)
11
+ Process.exit exit_code
12
+ end
13
+ end
14
+
8
15
  def create_todo(target, basename)
9
16
  File.open(target, 'w') do |f|
10
17
  content = <<~ENDCONTENT
11
- Inbox: @inbox
18
+ Inbox:
12
19
  #{basename}:
13
20
  \tFeature Requests:
14
21
  \tIdeas:
@@ -18,11 +25,11 @@ module NA
18
25
  \tTop Priority @search(@priority = 5 and not @done)
19
26
  \tHigh Priority @search(@priority > 3 and not @done)
20
27
  \tMaybe @search(@maybe)
21
- \tNext @search(@na and not @done and not project = \"Archive\")
28
+ \tNext @search(@#{NA.na_tag} and not @done and not project = \"Archive\")
22
29
  ENDCONTENT
23
30
  f.puts(content)
24
31
  end
25
- $stderr.puts NA::Color.template("{y}Created {bw}#{target}{x}")
32
+ notify("{y}Created {bw}#{target}")
26
33
  end
27
34
 
28
35
  def find_files(depth: 1)
@@ -41,8 +48,7 @@ module NA
41
48
  elsif TTY::Which.exist?('fzf')
42
49
  res = choose_from(files, prompt: 'Use which file?')
43
50
  unless res
44
- $stderr.puts 'No file selected, cancelled'
45
- Process.exit 1
51
+ notify('{r}No file selected, cancelled', exit_code: 1)
46
52
  end
47
53
 
48
54
  res.strip
@@ -71,7 +77,7 @@ module NA
71
77
 
72
78
  File.open(file, 'w') { |f| f.puts content }
73
79
 
74
- $stderr.puts NA::Color.template("{by}Task added to {bw}#{file}{x}")
80
+ notify("{by}Task added to {bw}#{file}")
75
81
  end
76
82
 
77
83
  def output_actions(actions, depth, files: nil)
@@ -91,7 +97,7 @@ module NA
91
97
  '%parent%action'
92
98
  end
93
99
  if files && @verbose
94
- $stderr.puts files.map { |f| NA::Color.template("{dw}#{f}{x}") }
100
+ files.map { |f| notify("{dw}#{f}") }
95
101
  end
96
102
 
97
103
  puts actions.map { |action| action.pretty(template: { output: template }) }
@@ -188,11 +194,7 @@ module NA
188
194
  def choose_from(options, prompt: 'Make a selection: ', multiple: false, sorted: true, fzf_args: [])
189
195
  return nil unless $stdout.isatty
190
196
 
191
- # fzf_args << '-1' # User is expecting a menu, and even if only one it seves as confirmation
192
- default_args = []
193
- default_args << %(--prompt="#{prompt}")
194
- default_args << "--height=#{options.count + 2}"
195
- default_args << '--info=inline'
197
+ default_args = [%(--prompt="#{prompt}"), "--height=#{options.count + 2}", '--info=inline']
196
198
  default_args << '--multi' if multiple
197
199
  header = "esc: cancel,#{multiple ? ' tab: multi-select, ctrl-a: select all,' : ''} return: confirm"
198
200
  default_args << %(--header="#{header}")
@@ -205,33 +207,50 @@ module NA
205
207
  res
206
208
  end
207
209
 
210
+ ##
211
+ ## Get path to database of known todo files
212
+ ##
213
+ ## @return [String] File path
214
+ ##
208
215
  def database_path
209
216
  db_dir = File.expand_path('~/.local/share/na')
217
+ # Create directory if needed
210
218
  FileUtils.mkdir_p(db_dir) unless File.directory?(db_dir)
211
219
  db_file = 'tdlist.txt'
212
220
  File.join(db_dir, db_file)
213
221
  end
214
222
 
215
- def match_working_dir(search)
223
+ ##
224
+ ## Find a matching path using semi-fuzzy matching.
225
+ ## Search tokens can include ! and + to negate or make
226
+ ## required.
227
+ ##
228
+ ## @param search [Array] search tokens to match
229
+ ## @param distance [Integer] allowed distance
230
+ ## between characters
231
+ ##
232
+ def match_working_dir(search, distance: 1)
216
233
  optional = []
217
234
  required = []
218
235
 
219
236
  search&.each do |t|
220
- new_rx = t[:token].to_s.split('').join('.{0,1}')
237
+ # Make "search" into "s.{0,1}e.{0,1}a.{0,1}r.{0,1}c.{0,1}h"
238
+ new_rx = t[:token].to_s.split('').join(".{0,#{distance}}")
221
239
 
222
240
  optional.push(new_rx)
223
241
  required.push(new_rx) if t[:required]
224
242
  end
225
243
 
244
+ match_dir(optional, required)
245
+ end
246
+
247
+ def match_dir(optional, required)
226
248
  file = database_path
227
- if File.exist?(file)
228
- dirs = IO.read(file).split("\n")
229
- dirs.delete_if { |d| !d.matches(any: optional, all: required) }
230
- dirs.sort.uniq
231
- else
232
- $stderr.puts NA::Color.template('{r}No na database found{x}')
233
- Process.exit 1
234
- end
249
+ notify('{r}No na database found', exit_code: 1) unless File.exist?(file)
250
+
251
+ dirs = IO.read(file).split("\n")
252
+ dirs.delete_if { |d| !d.matches(any: optional, all: required) }
253
+ dirs.sort.uniq
235
254
  end
236
255
 
237
256
  def save_working_dir(todo_file)
@@ -258,6 +277,26 @@ module NA
258
277
  os_open(file, app: app) if file && File.exist?(file)
259
278
  end
260
279
 
280
+ def darwin_open(file, app: nil)
281
+ if app
282
+ `open -a "#{app}" #{Shellwords.escape(file)}`
283
+ else
284
+ `open #{Shellwords.escape(file)}`
285
+ end
286
+ end
287
+
288
+ def win_open(file)
289
+ `start #{Shellwords.escape(file)}`
290
+ end
291
+
292
+ def linux_open(file)
293
+ if TTY::Which.exist?('xdg-open')
294
+ `xdg-open #{Shellwords.escape(file)}`
295
+ else
296
+ notify('{r}Unable to determine executable for `xdg-open`.')
297
+ end
298
+ end
299
+
261
300
  ##
262
301
  ## Platform-agnostic open command
263
302
  ##
@@ -267,19 +306,11 @@ module NA
267
306
  os = RbConfig::CONFIG['target_os']
268
307
  case os
269
308
  when /darwin.*/i
270
- if app
271
- `open -a "#{app}" #{Shellwords.escape(file)}`
272
- else
273
- `open #{Shellwords.escape(file)}`
274
- end
309
+ darwin_open(file, app: app)
275
310
  when /mingw|mswin/i
276
- `start #{Shellwords.escape(file)}`
311
+ win_open(file)
277
312
  else
278
- if 'xdg-open'.available?
279
- `xdg-open #{Shellwords.escape(file)}`
280
- else
281
- $stderr.puts NA::Color.template('{r}Unable to determine executable for `open`.{x}')
282
- end
313
+ linux_open(file)
283
314
  end
284
315
  end
285
316
  end
data/lib/na/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.1.10'
2
+ VERSION = '1.1.11'
3
3
  end
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.1.9<!--END VER-->.
12
+ The current version of `na` is <!--VER-->1.1.10<!--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
 
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.1.10
4
+ version: 1.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra