na 1.2.80 → 1.2.82
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/.rubocop.yml +8 -2
 - data/.rubocop_todo.yml +33 -538
 - data/CHANGELOG.md +27 -0
 - data/Gemfile +2 -0
 - data/Gemfile.lock +27 -10
 - data/README.md +66 -21
 - data/Rakefile +6 -0
 - data/bin/commands/next.rb +4 -0
 - data/bin/commands/scan.rb +84 -0
 - data/bin/commands/update.rb +291 -14
 - data/bin/na +7 -7
 - data/lib/na/action.rb +103 -38
 - data/lib/na/actions.rb +79 -77
 - data/lib/na/array.rb +11 -7
 - data/lib/na/benchmark.rb +21 -9
 - data/lib/na/colors.rb +84 -86
 - data/lib/na/editor.rb +22 -22
 - data/lib/na/hash.rb +32 -9
 - data/lib/na/help_monkey_patch.rb +9 -1
 - data/lib/na/next_action.rb +347 -305
 - data/lib/na/pager.rb +38 -14
 - data/lib/na/project.rb +14 -1
 - data/lib/na/prompt.rb +25 -3
 - data/lib/na/string.rb +94 -133
 - data/lib/na/theme.rb +37 -31
 - data/lib/na/todo.rb +153 -132
 - data/lib/na/version.rb +3 -1
 - data/lib/na.rb +1 -0
 - data/na.gemspec +4 -2
 - data/scripts/generate-fish-completions.rb +18 -21
 - data/src/_README.md +17 -5
 - data/test_performance.rb +5 -5
 - metadata +53 -24
 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            PATH
         
     | 
| 
       2 
2 
     | 
    
         
             
              remote: .
         
     | 
| 
       3 
3 
     | 
    
         
             
              specs:
         
     | 
| 
       4 
     | 
    
         
            -
                na (1.2. 
     | 
| 
      
 4 
     | 
    
         
            +
                na (1.2.82)
         
     | 
| 
       5 
5 
     | 
    
         
             
                  chronic (~> 0.10, >= 0.10.2)
         
     | 
| 
       6 
6 
     | 
    
         
             
                  git (~> 3.0.0)
         
     | 
| 
       7 
7 
     | 
    
         
             
                  gli (~> 2.21.0)
         
     | 
| 
         @@ -14,14 +14,14 @@ PATH 
     | 
|
| 
       14 
14 
     | 
    
         
             
            GEM
         
     | 
| 
       15 
15 
     | 
    
         
             
              remote: https://rubygems.org/
         
     | 
| 
       16 
16 
     | 
    
         
             
              specs:
         
     | 
| 
       17 
     | 
    
         
            -
                activesupport (8.0 
     | 
| 
      
 17 
     | 
    
         
            +
                activesupport (8.1.0)
         
     | 
| 
       18 
18 
     | 
    
         
             
                  base64
         
     | 
| 
       19 
     | 
    
         
            -
                  benchmark (>= 0.3)
         
     | 
| 
       20 
19 
     | 
    
         
             
                  bigdecimal
         
     | 
| 
       21 
20 
     | 
    
         
             
                  concurrent-ruby (~> 1.0, >= 1.3.1)
         
     | 
| 
       22 
21 
     | 
    
         
             
                  connection_pool (>= 2.2.5)
         
     | 
| 
       23 
22 
     | 
    
         
             
                  drb
         
     | 
| 
       24 
23 
     | 
    
         
             
                  i18n (>= 1.6, < 2)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  json
         
     | 
| 
       25 
25 
     | 
    
         
             
                  logger (>= 1.4.2)
         
     | 
| 
       26 
26 
     | 
    
         
             
                  minitest (>= 5.1)
         
     | 
| 
       27 
27 
     | 
    
         
             
                  securerandom (>= 0.3)
         
     | 
| 
         @@ -30,11 +30,12 @@ GEM 
     | 
|
| 
       30 
30 
     | 
    
         
             
                addressable (2.8.7)
         
     | 
| 
       31 
31 
     | 
    
         
             
                  public_suffix (>= 2.0.2, < 7.0)
         
     | 
| 
       32 
32 
     | 
    
         
             
                base64 (0.3.0)
         
     | 
| 
       33 
     | 
    
         
            -
                 
     | 
| 
       34 
     | 
    
         
            -
                 
     | 
| 
      
 33 
     | 
    
         
            +
                bigdecimal (3.3.1)
         
     | 
| 
      
 34 
     | 
    
         
            +
                bump (0.6.1)
         
     | 
| 
       35 
35 
     | 
    
         
             
                chronic (0.10.2)
         
     | 
| 
       36 
36 
     | 
    
         
             
                concurrent-ruby (1.3.5)
         
     | 
| 
       37 
     | 
    
         
            -
                connection_pool (2.5. 
     | 
| 
      
 37 
     | 
    
         
            +
                connection_pool (2.5.4)
         
     | 
| 
      
 38 
     | 
    
         
            +
                diff-lcs (1.6.2)
         
     | 
| 
       38 
39 
     | 
    
         
             
                drb (2.2.3)
         
     | 
| 
       39 
40 
     | 
    
         
             
                git (3.0.2)
         
     | 
| 
       40 
41 
     | 
    
         
             
                  activesupport (>= 5.0)
         
     | 
| 
         @@ -44,15 +45,29 @@ GEM 
     | 
|
| 
       44 
45 
     | 
    
         
             
                gli (2.21.5)
         
     | 
| 
       45 
46 
     | 
    
         
             
                i18n (1.14.7)
         
     | 
| 
       46 
47 
     | 
    
         
             
                  concurrent-ruby (~> 1.0)
         
     | 
| 
      
 48 
     | 
    
         
            +
                json (2.15.2)
         
     | 
| 
       47 
49 
     | 
    
         
             
                logger (1.7.0)
         
     | 
| 
       48 
50 
     | 
    
         
             
                mdless (1.0.37)
         
     | 
| 
       49 
     | 
    
         
            -
                minitest (5. 
     | 
| 
       50 
     | 
    
         
            -
                ostruct (0.6. 
     | 
| 
      
 51 
     | 
    
         
            +
                minitest (5.26.0)
         
     | 
| 
      
 52 
     | 
    
         
            +
                ostruct (0.6.3)
         
     | 
| 
       51 
53 
     | 
    
         
             
                process_executer (1.3.0)
         
     | 
| 
       52 
54 
     | 
    
         
             
                public_suffix (6.0.2)
         
     | 
| 
       53 
55 
     | 
    
         
             
                rake (13.3.0)
         
     | 
| 
       54 
     | 
    
         
            -
                rchardet (1. 
     | 
| 
      
 56 
     | 
    
         
            +
                rchardet (1.10.0)
         
     | 
| 
       55 
57 
     | 
    
         
             
                rdoc (4.3.0)
         
     | 
| 
      
 58 
     | 
    
         
            +
                rspec (3.13.0)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  rspec-core (~> 3.13.0)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  rspec-expectations (~> 3.13.0)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  rspec-mocks (~> 3.13.0)
         
     | 
| 
      
 62 
     | 
    
         
            +
                rspec-core (3.13.3)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  rspec-support (~> 3.13.0)
         
     | 
| 
      
 64 
     | 
    
         
            +
                rspec-expectations (3.13.5)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  rspec-support (~> 3.13.0)
         
     | 
| 
      
 67 
     | 
    
         
            +
                rspec-mocks (3.13.4)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  rspec-support (~> 3.13.0)
         
     | 
| 
      
 70 
     | 
    
         
            +
                rspec-support (3.13.6)
         
     | 
| 
       56 
71 
     | 
    
         
             
                securerandom (0.4.1)
         
     | 
| 
       57 
72 
     | 
    
         
             
                tty-cursor (0.7.1)
         
     | 
| 
       58 
73 
     | 
    
         
             
                tty-reader (0.9.0)
         
     | 
| 
         @@ -65,7 +80,7 @@ GEM 
     | 
|
| 
       65 
80 
     | 
    
         
             
                tty-which (0.5.0)
         
     | 
| 
       66 
81 
     | 
    
         
             
                tzinfo (2.0.6)
         
     | 
| 
       67 
82 
     | 
    
         
             
                  concurrent-ruby (~> 1.0)
         
     | 
| 
       68 
     | 
    
         
            -
                uri (1.0. 
     | 
| 
      
 83 
     | 
    
         
            +
                uri (1.0.4)
         
     | 
| 
       69 
84 
     | 
    
         
             
                wisper (2.0.1)
         
     | 
| 
       70 
85 
     | 
    
         | 
| 
       71 
86 
     | 
    
         
             
            PLATFORMS
         
     | 
| 
         @@ -82,10 +97,12 @@ PLATFORMS 
     | 
|
| 
       82 
97 
     | 
    
         
             
              x86_64-linux-musl
         
     | 
| 
       83 
98 
     | 
    
         | 
| 
       84 
99 
     | 
    
         
             
            DEPENDENCIES
         
     | 
| 
      
 100 
     | 
    
         
            +
              bump (~> 0.6.0)
         
     | 
| 
       85 
101 
     | 
    
         
             
              minitest (~> 5.14)
         
     | 
| 
       86 
102 
     | 
    
         
             
              na!
         
     | 
| 
       87 
103 
     | 
    
         
             
              rake
         
     | 
| 
       88 
104 
     | 
    
         
             
              rdoc (~> 4.3)
         
     | 
| 
      
 105 
     | 
    
         
            +
              rspec (~> 3.0)
         
     | 
| 
       89 
106 
     | 
    
         
             
              tty-spinner (~> 0.9, >= 0.9.0)
         
     | 
| 
       90 
107 
     | 
    
         | 
| 
       91 
108 
     | 
    
         
             
            BUNDLED WITH
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -9,9 +9,9 @@ 
     | 
|
| 
       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. 
     | 
| 
      
 12 
     | 
    
         
            +
            The current version of `na` is 1.2.82.
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       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. 
     | 
| 
      
 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 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
            Used with Taskpaper files, it can add new action items quickly from the command line, automatically tagging them as next actions. It can also mark actions as completed, delete them, archive them, and move them between projects.
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
         @@ -48,7 +48,7 @@ You can list next actions in files in the current directory by typing `na`. By d 
     | 
|
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
            #### Adding todos
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
            You can also quickly add todo items from the command line with the `add` subcommand. The script will look for a file in the current directory with a `.taskpaper` extension (configurable). 
     | 
| 
      
 51 
     | 
    
         
            +
            You can also quickly add todo items from the command line with the `add` subcommand. The script will look for a file in the current directory with a `.taskpaper` extension (configurable).
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
            If found, it will try to locate an `Inbox:` project, or create one if it doesn't exist. Any arguments after `add` will be combined to create a new task in TaskPaper format. They will automatically be assigned as next actions (tagged `@na`) and will show up when `na` lists the tasks for the project.
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
         @@ -76,7 +76,7 @@ SYNOPSIS 
     | 
|
| 
       76 
76 
     | 
    
         
             
                na [global options] command [command options] [arguments...]
         
     | 
| 
       77 
77 
     | 
    
         | 
| 
       78 
78 
     | 
    
         
             
            VERSION
         
     | 
| 
       79 
     | 
    
         
            -
                1.2. 
     | 
| 
      
 79 
     | 
    
         
            +
                1.2.82
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
       81 
81 
     | 
    
         
             
            GLOBAL OPTIONS
         
     | 
| 
       82 
82 
     | 
    
         
             
                -a, --add               - Add a next action (deprecated, for backwards compatibility)
         
     | 
| 
         @@ -116,6 +116,7 @@ COMMANDS 
     | 
|
| 
       116 
116 
     | 
    
         
             
                prompt              - Show or install prompt hooks for the current shell
         
     | 
| 
       117 
117 
     | 
    
         
             
                restore, unfinish   - Find and remove @done tag from an action
         
     | 
| 
       118 
118 
     | 
    
         
             
                saved               - Execute a saved search
         
     | 
| 
      
 119 
     | 
    
         
            +
                scan                - Scan a directory tree for todo files and cache them
         
     | 
| 
       119 
120 
     | 
    
         
             
                tag                 - Add tags to matching action(s)
         
     | 
| 
       120 
121 
     | 
    
         
             
                tagged              - Find actions matching a tag
         
     | 
| 
       121 
122 
     | 
    
         
             
                todos               - Show list of known todo files
         
     | 
| 
         @@ -133,7 +134,7 @@ If you run the `add` command with no arguments, you'll be asked for input on the 
     | 
|
| 
       133 
134 
     | 
    
         | 
| 
       134 
135 
     | 
    
         
             
            ###### Adding notes
         
     | 
| 
       135 
136 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
            Use the `--note` switch to add a note. If STDIN (piped) input is present when this switch is used, it will be included in the note. A prompt will be displayed for adding additional notes, which will be appended to any STDIN note passed. Press CTRL-d to end editing and save the note. 
     | 
| 
      
 137 
     | 
    
         
            +
            Use the `--note` switch to add a note. If STDIN (piped) input is present when this switch is used, it will be included in the note. A prompt will be displayed for adding additional notes, which will be appended to any STDIN note passed. Press CTRL-d to end editing and save the note.
         
     | 
| 
       137 
138 
     | 
    
         | 
| 
       138 
139 
     | 
    
         
             
            Notes are not displayed by the `next/tagged/find` commands unless `--notes` is specified.
         
     | 
| 
       139 
140 
     | 
    
         | 
| 
         @@ -335,6 +336,7 @@ COMMAND OPTIONS 
     | 
|
| 
       335 
336 
     | 
    
         
             
                --[no-]done                            - Include @done actions
         
     | 
| 
       336 
337 
     | 
    
         
             
                --exact                                - Search query is exact text match (not tokens)
         
     | 
| 
       337 
338 
     | 
    
         
             
                --file=TODO_FILE                       - Display matches from specific todo file ([relative] path) (default: none)
         
     | 
| 
      
 339 
     | 
    
         
            +
                --hidden                               - Include hidden directories while traversing
         
     | 
| 
       338 
340 
     | 
    
         
             
                --in, --todo=TODO                      - Display matches from a known todo file anywhere in history (short name) (may be used more than once, default: none)
         
     | 
| 
       339 
341 
     | 
    
         
             
                --nest                                 - Output actions nested by file
         
     | 
| 
       340 
342 
     | 
    
         
             
                --no_file                              - No filename in output
         
     | 
| 
         @@ -426,6 +428,44 @@ EXAMPLES 
     | 
|
| 
       426 
428 
     | 
    
         
             
                na saved
         
     | 
| 
       427 
429 
     | 
    
         
             
            ```
         
     | 
| 
       428 
430 
     | 
    
         | 
| 
      
 431 
     | 
    
         
            +
            ##### scan
         
     | 
| 
      
 432 
     | 
    
         
            +
             
     | 
| 
      
 433 
     | 
    
         
            +
            Scan a directory tree for todo files and cache them in tdlist.txt. Avoids duplicates and can optionally prune non-existent entries.
         
     | 
| 
      
 434 
     | 
    
         
            +
             
     | 
| 
      
 435 
     | 
    
         
            +
            Scan reports how many files were added and, if --prune is used, how many were pruned. With --dry-run, it lists the full file paths that would be added and/or pruned.
         
     | 
| 
      
 436 
     | 
    
         
            +
             
     | 
| 
      
 437 
     | 
    
         
            +
            ```
         
     | 
| 
      
 438 
     | 
    
         
            +
            NAME
         
     | 
| 
      
 439 
     | 
    
         
            +
                scan - Scan a directory tree for todo files and cache them
         
     | 
| 
      
 440 
     | 
    
         
            +
             
     | 
| 
      
 441 
     | 
    
         
            +
            SYNOPSIS
         
     | 
| 
      
 442 
     | 
    
         
            +
             
     | 
| 
      
 443 
     | 
    
         
            +
                na [global options] scan [command options] [PATH]
         
     | 
| 
      
 444 
     | 
    
         
            +
             
     | 
| 
      
 445 
     | 
    
         
            +
            DESCRIPTION
         
     | 
| 
      
 446 
     | 
    
         
            +
                Searches PATH (default: current directory) for files matching the current NA.extension and adds their absolute paths to the tdlist.txt cache. Avoids duplicates. Optionally prunes non-existent entries from the cache. 
         
     | 
| 
      
 447 
     | 
    
         
            +
             
     | 
| 
      
 448 
     | 
    
         
            +
            COMMAND OPTIONS
         
     | 
| 
      
 449 
     | 
    
         
            +
                -d, --depth=DEPTH - Recurse to depth (1..N or i/inf for infinite) (default: 5)
         
     | 
| 
      
 450 
     | 
    
         
            +
                --hidden          - Include hidden directories and files while scanning
         
     | 
| 
      
 451 
     | 
    
         
            +
                -n, --dry-run     - Show what would be added/pruned, but do not write tdlist.txt
         
     | 
| 
      
 452 
     | 
    
         
            +
                -p, --prune       - Prune removed files from cache after scan
         
     | 
| 
      
 453 
     | 
    
         
            +
             
     | 
| 
      
 454 
     | 
    
         
            +
            EXAMPLES
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
                # Scan current directory up to default depth (5)
         
     | 
| 
      
 457 
     | 
    
         
            +
                na scan
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                # Scan a specific path up to depth 3
         
     | 
| 
      
 460 
     | 
    
         
            +
                na scan -d 3 ~/Projects
         
     | 
| 
      
 461 
     | 
    
         
            +
             
     | 
| 
      
 462 
     | 
    
         
            +
                # Scan current directory recursively with no depth limit
         
     | 
| 
      
 463 
     | 
    
         
            +
                na scan -d inf
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
                # Prune non-existent entries from the cache (in addition to scanning)
         
     | 
| 
      
 466 
     | 
    
         
            +
                na scan --prune
         
     | 
| 
      
 467 
     | 
    
         
            +
            ```
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
       429 
469 
     | 
    
         
             
            ##### tagged
         
     | 
| 
       430 
470 
     | 
    
         | 
| 
       431 
471 
     | 
    
         
             
            Example: `na tagged feature +maybe`.
         
     | 
| 
         @@ -438,45 +478,48 @@ To perform a string comparison, you can use `*=` (contains), `^=` (starts with), 
     | 
|
| 
       438 
478 
     | 
    
         | 
| 
       439 
479 
     | 
    
         
             
            ```
         
     | 
| 
       440 
480 
     | 
    
         
             
            NAME
         
     | 
| 
       441 
     | 
    
         
            -
                 
     | 
| 
      
 481 
     | 
    
         
            +
                tagged - Find actions matching a tag
         
     | 
| 
       442 
482 
     | 
    
         | 
| 
       443 
483 
     | 
    
         
             
            SYNOPSIS
         
     | 
| 
       444 
484 
     | 
    
         | 
| 
       445 
     | 
    
         
            -
                na [global options]  
     | 
| 
      
 485 
     | 
    
         
            +
                na [global options] tagged [command options] TAG[=VALUE]
         
     | 
| 
       446 
486 
     | 
    
         | 
| 
       447 
487 
     | 
    
         
             
            DESCRIPTION
         
     | 
| 
       448 
     | 
    
         
            -
                 
     | 
| 
      
 488 
     | 
    
         
            +
                Finds actions with tags matching the arguments. An action is shown if it   contains all of the tags listed. Add a + before a tag to make it required   and others optional. You can specify values using TAG=VALUE pairs.   Use <, >, and = for numeric comparisons, and *=, ^=, $=, or =~ (regex) for text comparisons.   Date comparisons use natural language (`na tagged "due<=today"`) and   are detected automatically. 
         
     | 
| 
       449 
489 
     | 
    
         | 
| 
       450 
490 
     | 
    
         
             
            COMMAND OPTIONS
         
     | 
| 
       451 
     | 
    
         
            -
                -- 
     | 
| 
       452 
     | 
    
         
            -
                -d, --depth=DEPTH                      - Recurse to depth (default: none)
         
     | 
| 
      
 491 
     | 
    
         
            +
                -d, --depth=DEPTH                      - Recurse to depth (default: 1)
         
     | 
| 
       453 
492 
     | 
    
         
             
                --[no-]done                            - Include @done actions
         
     | 
| 
       454 
493 
     | 
    
         
             
                --exact                                - Search query is exact text match (not tokens)
         
     | 
| 
       455 
     | 
    
         
            -
                -- 
     | 
| 
       456 
     | 
    
         
            -
                --in, --todo=TODO                      - Display matches from a known todo file anywhere in history (short name) (may be used more than once, default: none)
         
     | 
| 
      
 494 
     | 
    
         
            +
                --in=TODO_PATH                         - Show actions from a specific todo file in history. May use wildcards (* and ?) (default: none)
         
     | 
| 
       457 
495 
     | 
    
         
             
                --nest                                 - Output actions nested by file
         
     | 
| 
       458 
496 
     | 
    
         
             
                --no_file                              - No filename in output
         
     | 
| 
       459 
497 
     | 
    
         
             
                --[no-]notes                           - Include notes in output
         
     | 
| 
      
 498 
     | 
    
         
            +
                -o, --or                               - Combine tags with OR, displaying actions matching ANY of the tags
         
     | 
| 
       460 
499 
     | 
    
         
             
                --omnifocus                            - Output actions nested by file and project
         
     | 
| 
       461 
     | 
    
         
            -
                -p, --prio, --priority=PRIORITY        - Match actions with priority, allows <>= comparison (may be used more than once, default: none)
         
     | 
| 
       462 
500 
     | 
    
         
             
                --proj, --project=PROJECT[/SUBPROJECT] - Show actions from a specific project (default: none)
         
     | 
| 
       463 
501 
     | 
    
         
             
                --regex                                - Search query is regular expression
         
     | 
| 
       464 
502 
     | 
    
         
             
                --save=TITLE                           - Save this search for future use (default: none)
         
     | 
| 
       465 
503 
     | 
    
         
             
                --search, --find, --grep=QUERY         - Filter results using search terms (may be used more than once, default: none)
         
     | 
| 
       466 
504 
     | 
    
         
             
                --[no-]search_notes                    - Include notes in search (default: enabled)
         
     | 
| 
       467 
     | 
    
         
            -
                - 
     | 
| 
       468 
     | 
    
         
            -
                --tagged=TAG                           - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
         
     | 
| 
      
 505 
     | 
    
         
            +
                -v, --invert                           - Show actions not matching tags
         
     | 
| 
       469 
506 
     | 
    
         | 
| 
       470 
507 
     | 
    
         
             
            EXAMPLES
         
     | 
| 
       471 
508 
     | 
    
         | 
| 
       472 
     | 
    
         
            -
                #  
     | 
| 
       473 
     | 
    
         
            -
                na  
     | 
| 
      
 509 
     | 
    
         
            +
                # Show all actions tagged @maybe
         
     | 
| 
      
 510 
     | 
    
         
            +
                na tagged maybe
         
     | 
| 
       474 
511 
     | 
    
         | 
| 
       475 
     | 
    
         
            -
                #  
     | 
| 
       476 
     | 
    
         
            -
                na  
     | 
| 
      
 512 
     | 
    
         
            +
                # Show all actions tagged @feature AND @idea, recurse 3 levels
         
     | 
| 
      
 513 
     | 
    
         
            +
                na tagged -d 3 "feature, idea"
         
     | 
| 
       477 
514 
     | 
    
         | 
| 
       478 
     | 
    
         
            -
                #  
     | 
| 
       479 
     | 
    
         
            -
                na  
     | 
| 
      
 515 
     | 
    
         
            +
                # Show all actions tagged @feature OR @idea
         
     | 
| 
      
 516 
     | 
    
         
            +
                na tagged --or "feature, idea"
         
     | 
| 
      
 517 
     | 
    
         
            +
             
     | 
| 
      
 518 
     | 
    
         
            +
                # Show actions with @priority(4) or @priority(5)
         
     | 
| 
      
 519 
     | 
    
         
            +
                na tagged "priority>=4"
         
     | 
| 
      
 520 
     | 
    
         
            +
             
     | 
| 
      
 521 
     | 
    
         
            +
                # Show actions with a due date coming up in the next 2 days
         
     | 
| 
      
 522 
     | 
    
         
            +
                na tagged "due<in 2 days"
         
     | 
| 
       480 
523 
     | 
    
         
             
            ```
         
     | 
| 
       481 
524 
     | 
    
         | 
| 
       482 
525 
     | 
    
         
             
            ##### todos
         
     | 
| 
         @@ -512,6 +555,8 @@ If more than one file is matched, a menu will be presented, multiple selections 
     | 
|
| 
       512 
555 
     | 
    
         | 
| 
       513 
556 
     | 
    
         
             
            Any time an update action is carried out, a backup of the file before modification will be made in the same directory with a `.` prepended and `.bak` appended (e.g. `marked.taskpaper` is copied to `.marked.taskpaper.bak`). Only one undo step is available, but if something goes wrong (and this feature is still experimental, so be wary), you can just copy the ".bak" file back to the original.
         
     | 
| 
       514 
557 
     | 
    
         | 
| 
      
 558 
     | 
    
         
            +
            > **Note:** When using the `update` command, if you have [fzf](https://github.com/junegunn/fzf) installed, menus for selecting files or actions will support multi-select (tab to mark multiple, return to confirm). If [gum](https://github.com/charmbracelet/gum) is installed, multi-select is also supported (use j/k/x to navigate and mark). If neither is available, a simple prompt is used. This makes it easy to apply updates to multiple actions at once.
         
     | 
| 
      
 559 
     | 
    
         
            +
             
     | 
| 
       515 
560 
     | 
    
         
             
            ###### Marking a task as complete
         
     | 
| 
       516 
561 
     | 
    
         | 
| 
       517 
562 
     | 
    
         
             
            You can mark an action complete using `--finish`, which will add a dated @done tag to the action. You can also mark it @done and immediately move it to the Archive project using `--archive`.
         
     | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/bin/commands/next.rb
    CHANGED
    
    | 
         @@ -19,6 +19,9 @@ class App 
     | 
|
| 
       19 
19 
     | 
    
         
             
                c.arg_name "DEPTH"
         
     | 
| 
       20 
20 
     | 
    
         
             
                c.flag %i[d depth], type: :integer, must_match: /^[1-9]$/
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
                c.desc "Include hidden directories while traversing"
         
     | 
| 
      
 23 
     | 
    
         
            +
                c.switch %i[hidden], negatable: false, default_value: false
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       22 
25 
     | 
    
         
             
                c.desc "Show next actions from all known todo files (in any directory)"
         
     | 
| 
       23 
26 
     | 
    
         
             
                c.switch %i[all], negatable: false, default_value: false
         
     | 
| 
       24 
27 
     | 
    
         | 
| 
         @@ -217,6 +220,7 @@ class App 
     | 
|
| 
       217 
220 
     | 
    
         
             
                  file_path = options[:file] ? File.expand_path(options[:file]) : nil
         
     | 
| 
       218 
221 
     | 
    
         | 
| 
       219 
222 
     | 
    
         
             
                  todo = NA::Todo.new({ depth: depth,
         
     | 
| 
      
 223 
     | 
    
         
            +
                                        hidden: options[:hidden],
         
     | 
| 
       220 
224 
     | 
    
         
             
                                        done: options[:done],
         
     | 
| 
       221 
225 
     | 
    
         
             
                                        file_path: file_path,
         
     | 
| 
       222 
226 
     | 
    
         
             
                                        project: options[:project],
         
     | 
| 
         @@ -0,0 +1,84 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class App
         
     | 
| 
      
 4 
     | 
    
         
            +
              extend GLI::App
         
     | 
| 
      
 5 
     | 
    
         
            +
              desc 'Scan a directory tree for todo files and cache them'
         
     | 
| 
      
 6 
     | 
    
         
            +
              long_desc 'Searches PATH (default: current directory) for files matching the current NA.extension
         
     | 
| 
      
 7 
     | 
    
         
            +
            and adds their absolute paths to the tdlist.txt cache. Avoids duplicates. Optionally prunes
         
     | 
| 
      
 8 
     | 
    
         
            +
            non-existent entries from the cache.'
         
     | 
| 
      
 9 
     | 
    
         
            +
              arg_name 'PATH', optional: true
         
     | 
| 
      
 10 
     | 
    
         
            +
              command %i[scan] do |c|
         
     | 
| 
      
 11 
     | 
    
         
            +
                c.example 'na scan', desc: 'Scan current directory up to default depth (5)'
         
     | 
| 
      
 12 
     | 
    
         
            +
                c.example 'na scan -d 3 ~/Projects', desc: 'Scan a specific path up to depth 3'
         
     | 
| 
      
 13 
     | 
    
         
            +
                c.example 'na scan -d inf', desc: 'Scan current directory recursively with no depth limit'
         
     | 
| 
      
 14 
     | 
    
         
            +
                c.example 'na scan --prune', desc: 'Prune non-existent entries from the cache (in addition to scanning)'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                c.desc 'Recurse to depth (1..N or i/inf for infinite)'
         
     | 
| 
      
 17 
     | 
    
         
            +
                c.arg_name 'DEPTH'
         
     | 
| 
      
 18 
     | 
    
         
            +
                c.default_value '5'
         
     | 
| 
      
 19 
     | 
    
         
            +
                c.flag %i[d depth], must_match: /^(\d+|i\w*)$/i
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                c.desc 'Prune removed files from cache after scan'
         
     | 
| 
      
 22 
     | 
    
         
            +
                c.switch %i[p prune], negatable: false, default_value: false
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                c.desc 'Include hidden directories and files while scanning'
         
     | 
| 
      
 25 
     | 
    
         
            +
                c.switch %i[hidden], negatable: false, default_value: false
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                c.desc 'Show what would be added/pruned, but do not write tdlist.txt'
         
     | 
| 
      
 28 
     | 
    
         
            +
                c.switch %i[n dry-run], negatable: false, default_value: false
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                c.action do |_global_options, options, args|
         
     | 
| 
      
 31 
     | 
    
         
            +
                  base = args.first || Dir.pwd
         
     | 
| 
      
 32 
     | 
    
         
            +
                  ext = NA.extension
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  # Parse depth: numeric or starts-with-i for infinite
         
     | 
| 
      
 35 
     | 
    
         
            +
                  depth_arg = (options[:depth] || '5').to_s
         
     | 
| 
      
 36 
     | 
    
         
            +
                  infinite = depth_arg =~ /^i/i ? true : false
         
     | 
| 
      
 37 
     | 
    
         
            +
                  depth = infinite ? nil : depth_arg.to_i
         
     | 
| 
      
 38 
     | 
    
         
            +
                  depth = 5 if depth.nil? && !infinite
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Prepare existing cache
         
     | 
| 
      
 41 
     | 
    
         
            +
                  db = NA.database_path
         
     | 
| 
      
 42 
     | 
    
         
            +
                  existing = if File.exist?(db)
         
     | 
| 
      
 43 
     | 
    
         
            +
                               File.read(db).split(/\n/).map(&:strip)
         
     | 
| 
      
 44 
     | 
    
         
            +
                             else
         
     | 
| 
      
 45 
     | 
    
         
            +
                               []
         
     | 
| 
      
 46 
     | 
    
         
            +
                             end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  found = []
         
     | 
| 
      
 49 
     | 
    
         
            +
                  Dir.chdir(base) do
         
     | 
| 
      
 50 
     | 
    
         
            +
                    patterns = if infinite
         
     | 
| 
      
 51 
     | 
    
         
            +
                                 ["*.#{ext}", "**/*.#{ext}"]
         
     | 
| 
      
 52 
     | 
    
         
            +
                               else
         
     | 
| 
      
 53 
     | 
    
         
            +
                                 (1..[depth, 1].max).map { |d| (d > 1 ? ('*/' * (d - 1)) : '') + "*.#{ext}" }
         
     | 
| 
      
 54 
     | 
    
         
            +
                               end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    pattern = patterns.length == 1 ? patterns.first : "{#{patterns.join(',')}}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                    files = Dir.glob(pattern, File::FNM_DOTMATCH)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    # Exclude hidden dirs/files (any segment starting with '.') unless --hidden
         
     | 
| 
      
 58 
     | 
    
         
            +
                    files.reject! { |f| f.split('/').any? { |seg| seg.start_with?('.') && seg !~ /^\.\.?$/ } } unless options[:hidden]
         
     | 
| 
      
 59 
     | 
    
         
            +
                    found = files.map { |f| File.expand_path(f) }
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  merged = (existing + found).map(&:strip).uniq.sort
         
     | 
| 
      
 63 
     | 
    
         
            +
                  merged.select! { |f| File.exist?(f) } if options[:prune]
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  added_files = (merged - existing)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  pruned_files = options[:prune] ? (existing - merged) : []
         
     | 
| 
      
 67 
     | 
    
         
            +
                  added = added_files.count
         
     | 
| 
      
 68 
     | 
    
         
            +
                  pruned = pruned_files.count
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  if options[:dry_run]
         
     | 
| 
      
 71 
     | 
    
         
            +
                    msg = "#{NA.theme[:success]}Dry run: would add #{added} file#{added == 1 ? '' : 's'}"
         
     | 
| 
      
 72 
     | 
    
         
            +
                    msg << ", prune #{pruned} file#{pruned == 1 ? '' : 's'}" if options[:prune]
         
     | 
| 
      
 73 
     | 
    
         
            +
                    NA.notify(msg)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    NA.notify("{bw}Would add:{x}\n#{added_files.join("\n")}") if added_files.any?
         
     | 
| 
      
 75 
     | 
    
         
            +
                    NA.notify("{bw}Would prune:{x}\n#{pruned_files.join("\n")}") if options[:prune] && pruned_files.any?
         
     | 
| 
      
 76 
     | 
    
         
            +
                  else
         
     | 
| 
      
 77 
     | 
    
         
            +
                    File.open(db, 'w') { |f| f.puts merged.join("\n") }
         
     | 
| 
      
 78 
     | 
    
         
            +
                    msg = "#{NA.theme[:success]}Scan complete: #{NA.theme[:filename]}#{added}{x}#{NA.theme[:success]} added"
         
     | 
| 
      
 79 
     | 
    
         
            +
                    msg << ", #{NA.theme[:filename]}#{pruned}{x}#{NA.theme[:success]} pruned" if options[:prune]
         
     | 
| 
      
 80 
     | 
    
         
            +
                    NA.notify(msg)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     |