na 1.2.63 → 1.2.64

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: 8913d21ba15ed1f470aa073fbdd6a9d3cb081e1d7d99f09bbb11a56b4bac7167
4
- data.tar.gz: ed3bff3d476c30cb44d2c1d5a0ddb553278f496952a2459585c15ed1f402af30
3
+ metadata.gz: c2accac212d5f998f830299693f13e3ec27e692b1bc5f460bcd977fb1ce95042
4
+ data.tar.gz: ad75051381180b3d4cc99fe3edb841a591e76ca649eaa051a12752f6066a1ed2
5
5
  SHA512:
6
- metadata.gz: 68f9d3099ff4e2903e612252f17f56fe7c936b1eb2f854ce87f6866464b1a206eec80518ef673dc4f91e30c070a84b11165cd5f442c65f5c4c94593416cf2748
7
- data.tar.gz: 0340b85bdac9837612ad361cd9da0fe96af557697f8e38ac77097a6dd5da0e22031e098c67348de035a95982c7f27445df5fa8bbab0087e6030ab87d6c22a014
6
+ metadata.gz: 96a9f0120855bf9569dd5d35f7701c24196185fa0d82a12e143486687072778cca636369264c45b286e0e4030722cb817258f585f399e50929b3f500bdea47f9
7
+ data.tar.gz: bd58a4c3872fb7ad608f15bdc31fd954f8f7581f168c30e7db3c1e11986df884905a964cfcd263d7807a3f583e22d22e33e0f8c9a46842407a5096d5f17b2271
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 1.2.64
2
+
3
+ 2024-06-20 12:25
4
+
5
+ #### NEW
6
+
7
+ - `na move ACTION --to PROJECT` command to allow quickly moving actions around
8
+
1
9
  ### 1.2.63
2
10
 
3
11
  2023-12-14 13:56
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.63)
4
+ na (1.2.64)
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,8 +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.63
13
- .
12
+ The current version of `na` is 1.2.64.
14
13
 
15
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.
16
15
 
@@ -77,14 +76,14 @@ SYNOPSIS
77
76
  na [global options] command [command options] [arguments...]
78
77
 
79
78
  VERSION
80
- 1.2.63
79
+ 1.2.64
81
80
 
82
81
  GLOBAL OPTIONS
83
82
  -a, --add - Add a next action (deprecated, for backwards compatibility)
84
83
  --add_at=POSITION - Add all new/moved entries at [s]tart or [e]nd of target project (default: start)
85
84
  --[no-]color - Colorize output (default: enabled)
86
85
  --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)
86
+ -d, --depth=DEPTH - Recurse to depth (default: 1)
88
87
  --[no-]debug - Display verbose output
89
88
  --ext=EXT - File extension to consider a todo file (default: taskpaper)
90
89
  -f, --file=PATH - Use a single file as global todo, use initconfig to make permanent (default: none)
@@ -109,6 +108,7 @@ COMMANDS
109
108
  help - Shows a list of commands or help for one command
110
109
  init, create - Create a new todo file in the current directory
111
110
  initconfig - Initialize the config file using current global options
111
+ move - Move an existing action to a different section
112
112
  next, show - Show next actions
113
113
  open - Open a todo file in the default editor
114
114
  projects - Show list of projects for a file
@@ -264,6 +264,48 @@ EXAMPLES
264
264
  na init warpspeed
265
265
  ```
266
266
 
267
+ ##### move
268
+
269
+ Move an action between projects. Argument is a search term, if left blank a prompt will allow you to enter terms. If no `--to` project is specified, a menu will be shown of projects in the target file.
270
+
271
+ Examples:
272
+
273
+ - `na move` (enter a search term, select a file/destination)
274
+ - `na move "Bug description"` (find matching action and show a menu of project destinations)
275
+ - `na move "Bug description" --to Bugs (move matching action to Bugs project)
276
+
277
+ ```
278
+ NAME
279
+ move - Move an existing action to a different section
280
+
281
+ SYNOPSIS
282
+
283
+ na [global options] move [command options] ACTION
284
+
285
+ DESCRIPTION
286
+ Provides an easy way to move an action. If multiple todo files are found in the current directory, a menu will allow you to pick which file to act on.
287
+
288
+ COMMAND OPTIONS
289
+ --all - Act on all matches immediately (no menu)
290
+ --at=POSITION - When moving task, add at [s]tart or [e]nd of target project (default: none)
291
+ -d, --depth=DEPTH - Search for files X directories deep (default: 1)
292
+ -e, --regex - Interpret search pattern as regular expression
293
+ --file=PATH - Specify the file to search for the task (default: none)
294
+ --from=PROJECT[/SUBPROJECT] - Search for actions in a specific project (default: none)
295
+ --in, --todo=TODO_FILE - Use a known todo file, partial matches allowed (default: none)
296
+ -n, --note - Prompt for additional notes. Input will be appended to any existing note. If STDIN input (piped) is detected, it will be used as a note.
297
+ -o, --overwrite - Overwrite note instead of appending
298
+ --[no-]search_notes - Include notes in search (default: enabled)
299
+ --tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
300
+ --to=PROJECT - Move action to specific project. If not provided, a menu will be shown (default: none)
301
+ -x, --exact - Match pattern exactly
302
+
303
+ EXAMPLE
304
+
305
+ # Find "A bug in inbox" action and move it to section Bugs
306
+ na move "A bug in inbox" --to Bugs
307
+ ```
308
+
267
309
  ##### next, show
268
310
 
269
311
  Examples:
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ class App
4
+ extend GLI::App
5
+ desc 'Move an existing action to a different section'
6
+ long_desc 'Provides an easy way to move an action.
7
+
8
+ If multiple todo files are found in the current directory, a menu will
9
+ allow you to pick which file to act on.'
10
+ arg_name 'ACTION'
11
+ command %i[move] do |c|
12
+ c.example 'na move "A bug in inbox" --to Bugs',
13
+ desc: 'Find "A bug in inbox" action and move it to section Bugs'
14
+
15
+ c.desc 'Prompt for additional notes. Input will be appended to any existing note.
16
+ If STDIN input (piped) is detected, it will be used as a note.'
17
+ c.switch %i[n note], negatable: false
18
+
19
+ c.desc 'Overwrite note instead of appending'
20
+ c.switch %i[o overwrite], negatable: false
21
+
22
+ c.desc 'Move action to specific project. If not provided, a menu will be shown'
23
+ c.arg_name 'PROJECT'
24
+ c.flag %i[to]
25
+
26
+ c.desc 'When moving task, add at [s]tart or [e]nd of target project'
27
+ c.arg_name 'POSITION'
28
+ c.flag %i[at], must_match: /^[sbea].*?$/i
29
+
30
+ c.desc 'Search for actions in a specific project'
31
+ c.arg_name 'PROJECT[/SUBPROJECT]'
32
+ c.flag %i[from]
33
+
34
+ c.desc 'Use a known todo file, partial matches allowed'
35
+ c.arg_name 'TODO_FILE'
36
+ c.flag %i[in todo]
37
+
38
+ c.desc 'Specify the file to search for the task'
39
+ c.arg_name 'PATH'
40
+ c.flag %i[file]
41
+
42
+ c.desc 'Search for files X directories deep'
43
+ c.arg_name 'DEPTH'
44
+ c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
45
+
46
+ c.desc 'Include notes in search'
47
+ c.switch %i[search_notes], negatable: true, default_value: true
48
+
49
+ c.desc 'Match actions containing tag. Allows value comparisons'
50
+ c.arg_name 'TAG'
51
+ c.flag %i[tagged], multiple: true
52
+
53
+ c.desc 'Act on all matches immediately (no menu)'
54
+ c.switch %i[all], negatable: false
55
+
56
+ c.desc 'Interpret search pattern as regular expression'
57
+ c.switch %i[e regex], negatable: false
58
+
59
+ c.desc 'Match pattern exactly'
60
+ c.switch %i[x exact], negatable: false
61
+
62
+ c.action do |global_options, options, args|
63
+ reader = TTY::Reader.new
64
+
65
+ args.concat(options[:search]) unless options[:search].nil?
66
+
67
+ append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/i
68
+
69
+ options[:done] = true
70
+
71
+ action = if args.count.positive?
72
+ args.join(' ').strip
73
+ else
74
+ NA.request_input(options, prompt: 'Enter a task to search for')
75
+ end
76
+ if action
77
+ tokens = nil
78
+ if options[:exact]
79
+ tokens = action
80
+ elsif options[:regex]
81
+ tokens = Regexp.new(action, Regexp::IGNORECASE)
82
+ else
83
+ tokens = []
84
+ all_req = action !~ /[+!-]/ && !options[:or]
85
+
86
+ action.split(/ /).each do |arg|
87
+ m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
88
+ tokens.push({
89
+ token: m['tok'],
90
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
91
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
92
+ })
93
+ end
94
+ end
95
+ end
96
+
97
+ if (action.nil? || action.empty?) && options[:tagged].empty?
98
+ NA.notify("#{NA.theme[:error]}Empty input, cancelled", exit_code: 1)
99
+ end
100
+
101
+ all_req = options[:tagged].join(' ') !~ /[+!-]/ && !options[:or]
102
+ tags = []
103
+ options[:tagged].join(',').split(/ *, */).each do |arg|
104
+ m = arg.match(/^(?<req>[+!-])?(?<tag>[^ =<>$~\^]+?) *(?:(?<op>[=<>~]{1,2}|[*$\^]=) *(?<val>.*?))?$/)
105
+
106
+ tags.push({
107
+ tag: m['tag'].wildcard_to_rx,
108
+ comp: m['op'],
109
+ value: m['val'],
110
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
111
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
112
+ })
113
+ end
114
+
115
+ stdin_note = NA.stdin ? NA.stdin.split("\n") : []
116
+
117
+ line_note = if options[:note] && $stdin.isatty
118
+ puts stdin_note unless stdin_note.nil?
119
+ if TTY::Which.exist?('gum')
120
+ args = ['--placeholder "Enter a note, CTRL-d to save"']
121
+ args << '--char-limit 0'
122
+ args << '--width $(tput cols)'
123
+ gum = TTY::Which.which('gum')
124
+ `#{gum} write #{args.join(' ')}`.strip.split("\n")
125
+ else
126
+ NA.notify("#{NA.theme[:prompt]}Enter a note, {bw}CTRL-d#{NA.theme[:prompt]} to end editing:#{NA.theme[:action]}")
127
+ reader.read_multiline
128
+ end
129
+ end
130
+
131
+ note = stdin_note.empty? ? [] : stdin_note
132
+ note.concat(line_note) unless line_note.nil? || line_note.empty?
133
+
134
+ if options[:file]
135
+ file = File.expand_path(options[:file])
136
+ NA.notify("#{NA.theme[:error]}File not found", exit_code: 1) unless File.exist?(file)
137
+
138
+ targets = [file]
139
+ elsif options[:todo]
140
+ todo = []
141
+ options[:todo].split(/ *, */).each do |a|
142
+ m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
143
+ todo.push({
144
+ token: m['tok'],
145
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
146
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
147
+ })
148
+ end
149
+ dirs = NA.match_working_dir(todo)
150
+
151
+ if dirs.count == 1
152
+ targets = [dirs[0]]
153
+ elsif dirs.count.positive?
154
+ targets = NA.select_file(dirs, multiple: true)
155
+ NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1) unless targets && targets.count.positive?
156
+ else
157
+ NA.notify("#{NA.theme[:error]}Todo not found", exit_code: 1) unless targets && targets.count.positive?
158
+
159
+ end
160
+ else
161
+ files = NA.find_files_matching({
162
+ depth: options[:depth],
163
+ done: options[:done],
164
+ project: options[:from],
165
+ regex: options[:regex],
166
+ require_na: false,
167
+ search: tokens,
168
+ tag: tags
169
+ })
170
+ NA.notify("#{NA.theme[:error]}No todo file found", exit_code: 1) if files.count.zero?
171
+
172
+ targets = files.count > 1 ? NA.select_file(files, multiple: true) : [files[0]]
173
+ NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1) unless files.count.positive?
174
+ end
175
+
176
+ target_proj = if options[:to]
177
+ options[:to]
178
+ else
179
+ todo = NA::Todo.new(require_na: false, file_path: targets[0])
180
+ projects = todo.projects
181
+ menu = projects.each_with_object([]) { |proj, arr| arr << proj.project }
182
+
183
+ NA.choose_from(menu, prompt: 'Move to: ', multiple: false, sorted: false)
184
+ end
185
+
186
+ NA.notify("#{NA.theme[:error]}No target selected", exit_code: 1) unless target_proj
187
+
188
+ NA.notify("#{NA.theme[:error]}No search terms provided", exit_code: 1) if tokens.nil? && options[:tagged].empty?
189
+
190
+ targets.each do |target|
191
+ NA.update_action(target, tokens,
192
+ all: options[:all],
193
+ append: append,
194
+ move: target_proj,
195
+ note: note,
196
+ overwrite: options[:overwrite],
197
+ project: options[:from],
198
+ search_note: options[:search_notes],
199
+ tagged: tags)
200
+ end
201
+ end
202
+ end
203
+ end
@@ -425,7 +425,7 @@ module NA
425
425
  end
426
426
 
427
427
  def project_hierarchy(actions)
428
- parents = { actions: []}
428
+ parents = { actions: [] }
429
429
  actions.each do |a|
430
430
  parent = a.parent
431
431
  current_parent = parents
@@ -958,7 +958,7 @@ module NA
958
958
  end
959
959
 
960
960
  return false if res&.strip&.size&.zero?
961
- pp NA::Color.uncolor(NA::Color.template(res))
961
+ # pp NA::Color.uncolor(NA::Color.template(res))
962
962
  multiple ? NA::Color.uncolor(NA::Color.template(res)).split(/\n/) : NA::Color.uncolor(NA::Color.template(res))
963
963
  end
964
964
 
data/lib/na/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.2.63'
2
+ VERSION = '1.2.64'
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.2.62<!--END VER-->.
12
+ The current version of `na` is <!--VER-->1.2.63<!--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
 
@@ -112,6 +112,20 @@ Unless `--exact` is specified, search is tokenized and combined with AND, so `na
112
112
  @cli(bundle exec bin/na help init)
113
113
  ```
114
114
 
115
+ ##### move
116
+
117
+ Move an action between projects. Argument is a search term, if left blank a prompt will allow you to enter terms. If no `--to` project is specified, a menu will be shown of projects in the target file.
118
+
119
+ Examples:
120
+
121
+ - `na move` (enter a search term, select a file/destination)
122
+ - `na move "Bug description"` (find matching action and show a menu of project destinations)
123
+ - `na move "Bug description" --to Bugs (move matching action to Bugs project)
124
+
125
+ ```
126
+ @cli(bundle exec bin/na help move)
127
+ ```
128
+
115
129
  ##### next, show
116
130
 
117
131
  Examples:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: na
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.63
4
+ version: 1.2.64
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-14 00:00:00.000000000 Z
11
+ date: 2024-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -199,7 +199,6 @@ extra_rdoc_files:
199
199
  - na.rdoc
200
200
  files:
201
201
  - ".travis.yml"
202
- - '0'
203
202
  - CHANGELOG.md
204
203
  - Gemfile
205
204
  - Gemfile.lock
@@ -216,6 +215,7 @@ files:
216
215
  - bin/commands/edit.rb
217
216
  - bin/commands/find.rb
218
217
  - bin/commands/init.rb
218
+ - bin/commands/move.rb
219
219
  - bin/commands/next.rb
220
220
  - bin/commands/open.rb
221
221
  - bin/commands/projects.rb
@@ -276,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
276
  - !ruby/object:Gem::Version
277
277
  version: '0'
278
278
  requirements: []
279
- rubygems_version: 3.4.0.dev
279
+ rubygems_version: 3.2.15
280
280
  signing_key:
281
281
  specification_version: 4
282
282
  summary: A command line tool for adding and listing project todos
data/0 DELETED
File without changes