doing 1.0.90 → 2.0.2.pre

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHORS +19 -0
  3. data/CHANGELOG.md +590 -0
  4. data/COMMANDS.md +1181 -0
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +110 -0
  7. data/LICENSE +23 -0
  8. data/README.md +14 -697
  9. data/Rakefile +79 -0
  10. data/_config.yml +1 -0
  11. data/bin/doing +1037 -481
  12. data/doing.fish +278 -0
  13. data/doing.gemspec +34 -0
  14. data/doing.rdoc +1759 -0
  15. data/example_plugin.rb +209 -0
  16. data/generate_completions.sh +4 -0
  17. data/img/doing-colors.jpg +0 -0
  18. data/img/doing-printf-wrap-800.jpg +0 -0
  19. data/img/doing-show-note-formatting-800.jpg +0 -0
  20. data/lib/completion/_doing.zsh +151 -0
  21. data/lib/completion/doing.bash +416 -0
  22. data/lib/completion/doing.fish +278 -0
  23. data/lib/doing/array.rb +8 -0
  24. data/lib/doing/cli_status.rb +66 -0
  25. data/lib/doing/colors.rb +136 -0
  26. data/lib/doing/configuration.rb +310 -0
  27. data/lib/doing/errors.rb +102 -0
  28. data/lib/doing/hash.rb +31 -0
  29. data/lib/doing/hooks.rb +59 -0
  30. data/lib/doing/item.rb +155 -0
  31. data/lib/doing/log_adapter.rb +342 -0
  32. data/lib/doing/markdown_document_listener.rb +174 -0
  33. data/lib/doing/note.rb +59 -0
  34. data/lib/doing/pager.rb +95 -0
  35. data/lib/doing/plugin_manager.rb +208 -0
  36. data/lib/doing/plugins/export/csv_export.rb +48 -0
  37. data/lib/doing/plugins/export/html_export.rb +83 -0
  38. data/lib/doing/plugins/export/json_export.rb +140 -0
  39. data/lib/doing/plugins/export/markdown_export.rb +85 -0
  40. data/lib/doing/plugins/export/taskpaper_export.rb +34 -0
  41. data/lib/doing/plugins/export/template_export.rb +141 -0
  42. data/lib/doing/plugins/import/cal_to_json.scpt +0 -0
  43. data/lib/doing/plugins/import/calendar_import.rb +76 -0
  44. data/lib/doing/plugins/import/doing_import.rb +144 -0
  45. data/lib/doing/plugins/import/timing_import.rb +78 -0
  46. data/lib/doing/string.rb +346 -0
  47. data/lib/doing/symbol.rb +16 -0
  48. data/lib/doing/time.rb +18 -0
  49. data/lib/doing/util.rb +186 -0
  50. data/lib/doing/version.rb +1 -1
  51. data/lib/doing/wwid.rb +1838 -2266
  52. data/lib/doing/wwidfile.rb +117 -0
  53. data/lib/doing.rb +43 -2
  54. data/lib/examples/commands/wiki.rb +80 -0
  55. data/lib/examples/plugins/hooks.rb +22 -0
  56. data/lib/examples/plugins/say_export.rb +202 -0
  57. data/lib/examples/plugins/templates/wiki.css +169 -0
  58. data/lib/examples/plugins/templates/wiki.haml +27 -0
  59. data/lib/examples/plugins/templates/wiki_index.haml +18 -0
  60. data/lib/examples/plugins/wiki_export.rb +87 -0
  61. data/lib/templates/doing-markdown.erb +5 -0
  62. data/man/doing.1 +964 -0
  63. data/man/doing.1.html +711 -0
  64. data/man/doing.1.ronn +600 -0
  65. data/package-lock.json +3 -0
  66. data/rdoc_to_mmd.rb +42 -0
  67. data/rdocfixer.rb +13 -0
  68. data/scripts/generate_bash_completions.rb +210 -0
  69. data/scripts/generate_fish_completions.rb +201 -0
  70. data/scripts/generate_zsh_completions.rb +164 -0
  71. metadata +82 -6
  72. data/lib/doing/helpers.rb +0 -121
data/example_plugin.rb ADDED
@@ -0,0 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ # title: Export plugin example
4
+ # description: Speak the most recent entry (macOS)
5
+ # author: Brett Terpstra
6
+ # url: https://brettterpstra.com
7
+
8
+ # Example
9
+ #
10
+ # doing show -o sayit
11
+ #
12
+ # ## Configuration
13
+ #
14
+ # Change what the plugin says by generating a template with
15
+ # `doing template --type say`, saving it to a file, and
16
+ # putting the path to that file in `export_templates->say` in
17
+ # .doingrc.
18
+ #
19
+ # export_templates:
20
+ # say: /path/to/template.txt
21
+ #
22
+ # Use a different voice by adding a `say_voice` key to your
23
+ # .doingrc. Use `say -v ?` to see available voices.
24
+ #
25
+ # say_voice: Zarvox
26
+
27
+ module Doing
28
+ ##
29
+ ## @brief Plugin class
30
+ ##
31
+ class SayExport
32
+ include Doing::Util
33
+
34
+ #-------------------------------------------------------
35
+ ## Plugin Settings. A plugin must have a self.settings
36
+ ## method that returns a hash with plugin settings.
37
+ ##
38
+ ## trigger: (required) Regular expression to match
39
+ ## FORMAT when used with `--output FORMAT`. Registered
40
+ ## name of plugin must be able to match the trigger, but
41
+ ## alternatives can be included
42
+ ##
43
+ ## templates: (optional) Array of templates this plugin
44
+ ## can export (plugin must have :template method)
45
+ ##
46
+ ## Each template is a hash containing:
47
+ ## - name: display name for template
48
+ ## - trigger: regular expression for
49
+ ## `template --type FORMAT`
50
+ ##
51
+ ## If a template is included, a config key will
52
+ ## automatically be added for the user to override
53
+ ## The config key will be available at:
54
+ ##
55
+ ## wwid.config['export_templates'][PLUGIN_NAME]
56
+ ##
57
+ ## config: (optional) A Hash which will be
58
+ ## added to the main configuration in the plugins section.
59
+ ## Options defined here are included when config file is
60
+ ## created or updated with `config --update`. Use this to
61
+ ## add new configuration keys, not to override existing
62
+ ## ones.
63
+ ##
64
+ ## The configuration keys will be available at:
65
+ ##
66
+ ## wwid.config['plugins'][PLUGIN_NAME][KEY]
67
+ ##
68
+ ## @brief Method to return plugin settings (required)
69
+ ##
70
+ ## @return Hash of settings for this plugin
71
+ ##
72
+ def self.settings
73
+ {
74
+ trigger: 'say(?:it)?',
75
+ templates: [
76
+ { name: 'say', trigger: 'say(?:it)?' }
77
+ ],
78
+ config: {
79
+ 'say_voice' => 'Fiona'
80
+ }
81
+ }
82
+ end
83
+
84
+
85
+ #-------------------------------------------------------
86
+ ## Output a template. Only required if template(s) are
87
+ ## included in settings. The method should return a
88
+ ## string (not output it to the STDOUT).
89
+ ##
90
+ ## @brief Method to return template (optional)
91
+ ##
92
+ ## @param trigger The trigger passed to the
93
+ ## template function. When this
94
+ ## method defines multiple
95
+ ## templates, the trigger can be
96
+ ## used to determine which one is
97
+ ## output.
98
+ ##
99
+ ## @return (String) template contents
100
+ ##
101
+ def self.template(trigger)
102
+ return unless trigger =~ /^say(it)?$/
103
+
104
+ 'On %date, you were %title, recorded in section %section%took'
105
+ end
106
+
107
+
108
+ ##
109
+ ## @brief Render data received from an output
110
+ ## command
111
+ ##
112
+ ## @param wwid The wwid object with config
113
+ ## and public methods
114
+ ## @param items An array of items to be output
115
+ ## { <Date>date, <String>title,
116
+ ## <String>section, <Array>note }
117
+ ## @param variables Additional variables including
118
+ ## flags passed to command
119
+ ## (variables[:options])
120
+ ##
121
+ ## @return (String) Rendered output
122
+ ##
123
+ def self.render(wwid, items, variables: {})
124
+ return if items.nil? || items.empty?
125
+
126
+ # the :options key includes the flags passed to the
127
+ # command that called the plugin use `puts
128
+ # variables.inspect` to see properties and methods
129
+ # when run
130
+ opt = variables[:options]
131
+
132
+ # This plugin just grabs the last item in the `items`
133
+ # list (which could be the oldest or newest, depending
134
+ # on the sort order of the command that called the
135
+ # plugin). Most of the time you'll want to use :each
136
+ # or :map to generate output.
137
+ i = items[-1]
138
+
139
+ # Format the item. Items are a hash with 4 keys: date,
140
+ # title, section (parent section), and note. Start
141
+ # time is in item.date. The wwid object has some
142
+ # methods for calculation and formatting, including
143
+ # wwid.item.end_date to convert the @done timestamp to
144
+ # an end date.
145
+ if opt[:times]
146
+ interval = i.interval
147
+
148
+ if interval
149
+ took = '. You finished on '
150
+ finished_at = i.end_date
151
+ took += finished_at.strftime('%A %B %e at %I:%M%p')
152
+
153
+ d, h, m = wwid.fmt_time(interval)
154
+ took += ' and it took'
155
+ took += " #{d.to_i} days" if d.to_i.positive?
156
+ took += " #{h.to_i} hours" if h.to_i.positive?
157
+ took += " #{m.to_i} minutes" if m.to_i.positive?
158
+ end
159
+ end
160
+
161
+ date = i.date.strftime('%A %B %e at %I:%M%p')
162
+ title = i.title.gsub(/@/, 'hashtag ')
163
+ tpl = template('say')
164
+
165
+ if wwid.config['export_templates'].key?('say')
166
+ cfg_tpl = wwid.config['export_templates']['say']
167
+ tpl = cfg_tpl unless cfg_tpl.nil? || cfg_tpl.empty?
168
+ end
169
+ output = tpl.dup
170
+ output.gsub!(/%date/, date)
171
+ output.gsub!(/%title/, title)
172
+ output.gsub!(/%section/, i.section)
173
+ output.gsub!(/%took/, took || '')
174
+
175
+ # Debugging output
176
+ # warn "Saying: #{output}"
177
+
178
+ # To provide results on the command line after the
179
+ # command runs, use Doing.logger, which responds to
180
+ # :debug, :info, :warn, and :error. e.g.:
181
+ #
182
+ # Doing.logger.info("This plugin has run")
183
+ # Doing.logger.error("This message will be displayed even if run in --quiet mode.")
184
+ #
185
+ # Results are
186
+ # provided on STDERR unless doing is run with
187
+ # `--stdout` or non-interactively.
188
+ Doing.logger.info('Spoke the last entry. Did you hear it?')
189
+
190
+ # This export runs a command for fun, most plugins won't
191
+ voice = wwid.config['plugins']['say']['say_voice'] || 'Alex'
192
+ `say -v "#{voice}" "#{output}"`
193
+
194
+ # Return the result (don't output to terminal with puts or print)
195
+ output
196
+ end
197
+
198
+ # Register the plugin with doing.
199
+ # Doing::Plugins.register 'NAME', TYPE, Class
200
+ #
201
+ # Name should be lowercase, no spaces
202
+ #
203
+ # TYPE is :import or :export
204
+ #
205
+ # Class is the plugin class (e.g. Doing::SayExport), or
206
+ # self if called within the class
207
+ Doing::Plugins.register 'say', :export, self
208
+ end
209
+ end
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ scripts/generate_fish_completions.rb > lib/completion/doing.fish
4
+ scripts/generate_bash_completions.rb > lib/completion/doing.bash
Binary file
Binary file
@@ -0,0 +1,151 @@
1
+ #compdef doing
2
+
3
+ local ret=1 state
4
+
5
+ _arguments \
6
+ ':subcommand:->subcommand' \
7
+ '*::options:->options' && ret=0
8
+
9
+ case $state in
10
+ subcommand)
11
+ local -a subcommands
12
+ subcommands=(
13
+ 'help:Shows a list of commands or help for one command'
14
+ 'now:Add an entry'
15
+ 'note:Add a note to the last entry'
16
+ 'meanwhile:Finish any running @meanwhile tasks and optionally create a new one'
17
+ 'later:Add an item to the Later section'
18
+ 'done:Add a completed item with @done(date). No argument finishes last entry.'
19
+ 'finish:Mark last X entries as @done'
20
+ 'tag:Tag last entry'
21
+ 'mark:Mark last entry as highlighted'
22
+ 'show:List all entries'
23
+ 'grep:Search for entries'
24
+ 'recent:List recent entries'
25
+ 'today:List entries from today'
26
+ 'yesterday:List entries from yesterday'
27
+ 'last:Show the last entry'
28
+ 'sections:List sections'
29
+ 'choose:Select a section to display from a menu'
30
+ 'add_section:Add a new section to the "doing" file'
31
+ 'view:Display a user-created view'
32
+ 'views:List available custom views'
33
+ 'archive:Move entries in between sections'
34
+ 'open:Open the "doing" file in an editor'
35
+ 'config:Edit the configuration file'
36
+ 'undo:Undo the last change to the doing_file'
37
+ )
38
+ _describe -t subcommands 'doing subcommand' subcommands && ret=0
39
+ ;;
40
+
41
+ options)
42
+ age=({-a,--age=}"[Age (oldest/newest) (default: newest)]")
43
+ app=({-a,--app=}"[Edit entry with specified app (default: none)")
44
+ archive=({-a,--archive}"[Archive previous @meanwhile entry]")
45
+ back="--back=[Backdate start time (4pm|20m|2h|yesterday noon) (default: none)]"
46
+ boolean=({-b,--boolean=}"[Tag boolean (AND,OR,NONE) (default: OR)]")
47
+ bool=({-b,--bool=}"[Tag boolean (default: AND)]")
48
+ count=({-c,--count=}"[How many recent entries to tag (default: 1)]")
49
+ count=({-c,--count=}"[Max count to show (default: 0)]")
50
+ date=({-d,--date}"[Include date (default: enabled)]")
51
+ editor=( {-e,--editor}"[Edit entry with $EDITOR]")
52
+ finish=({-f,--finish_last}"[Timed entry, marks last entry in section as @done]")
53
+ file=({-f,--file=}"[Specify alternate doing file (default: none)]")
54
+ noarchive="--no-archive[Don't archive previous @meanwhile entry]"
55
+ nodate="--no-date[Don't include date]"
56
+ noeditor="--no-editor[Don't edit entry with $EDITOR]"
57
+ note=({-n,--note=}"[Note (default: none)]")
58
+ notimes="--no-times[Don't show time intervals on @done tasks.]"
59
+ nototals="--no-totals[Don't show intervals with totals at the end of output]"
60
+ output=({-o,--output=}"[Output to export format (csv|html) (default: none)]")
61
+ remove=({-r,--remove}"[Replace/Remove last entry's note]")
62
+ section=({-s,--section=}"[Section (default: Currently)]")
63
+ sort=({-s,--sort=}"[Sort order (asc/desc) (default: asc)]")
64
+ times=({-t,--times}"[Show time intervals on @done tasks (default: enabled)]")
65
+ took=({-t,--took=}"[Set completion date to start date plus XX(mhd) or (HH:MM) (default: none)]")
66
+ totals="--totals[Show intervals with totals at the end of output]"
67
+
68
+ case $words[1] in
69
+ now)
70
+ args=( $back $noeditor $editor $note $section $finish )
71
+ ;;
72
+
73
+ note)
74
+ args=( $section $editor $remove )
75
+ ;;
76
+
77
+ meanwhile)
78
+ args=( $back $noeditor $editor $note $section $archive $noarchive )
79
+ ;;
80
+
81
+ later)
82
+ args=( $back $noeditor $editor $note $app )
83
+ ;;
84
+
85
+ done)
86
+ args=( $back $took $section $remove $date $nodate $archive $editor $noeditor )
87
+ ;;
88
+
89
+ finish)
90
+ args=( $back $took $section $date $nodate $archive $editor $noeditor )
91
+ ;;
92
+
93
+ tag)
94
+ args=( $section $count $date $remove )
95
+ ;;
96
+
97
+ mark)
98
+ args=( $section $remove )
99
+ ;;
100
+
101
+ show)
102
+ args=( $boolean $count $age $sort $output $times $notimes $totals $nototals )
103
+ ;;
104
+
105
+ grep)
106
+ args=( $section $output $times $notimes $totals $nototals )
107
+ ;;
108
+
109
+ recent)
110
+ args=( $section $times $notimes $totals $nototals )
111
+ ;;
112
+
113
+ today)
114
+ args=( $output $times $notimes $totals $nototals )
115
+ ;;
116
+
117
+ yesterday)
118
+ args=( $output $times $notimes $totals $nototals )
119
+ ;;
120
+
121
+ view)
122
+ args=( $section $count $output $times $notimes $totals $nototals )
123
+ ;;
124
+
125
+ archive)
126
+ args=( $keep $to $bool )
127
+ ;;
128
+
129
+ open)
130
+ args=(
131
+ "-a [open with app name (default:none)"
132
+ "-b [open with app bundle id (default: none)"
133
+ "-e [open with $EDITOR]"
134
+ )
135
+ ;;
136
+
137
+ config)
138
+ args=( $editor )
139
+ ;;
140
+
141
+ undo)
142
+ args=( $file )
143
+ ;;
144
+
145
+ esac
146
+
147
+ _arguments $args && ret=0
148
+ ;;
149
+ esac
150
+
151
+ return ret