doing 2.1.89 → 2.1.90
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/.irbrc +2 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +251 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +5 -3
- data/bin/commands/changes.rb +3 -1
- data/bin/commands/choose.rb +2 -0
- data/bin/commands/colors.rb +5 -3
- data/bin/commands/commands_accepting.rb +3 -3
- data/bin/commands/completion.rb +2 -1
- data/bin/commands/config.rb +8 -6
- data/bin/commands/done.rb +19 -12
- data/bin/commands/finish.rb +4 -2
- data/bin/commands/grep.rb +9 -5
- data/bin/commands/import.rb +14 -11
- data/bin/commands/install_fzf.rb +4 -2
- data/bin/commands/last.rb +31 -27
- data/bin/commands/meanwhile.rb +6 -2
- data/bin/commands/note.rb +6 -3
- data/bin/commands/now.rb +2 -0
- data/bin/commands/open.rb +6 -1
- data/bin/commands/plugins.rb +2 -0
- data/bin/commands/recent.rb +47 -33
- data/bin/commands/reset.rb +7 -3
- data/bin/commands/rotate.rb +6 -3
- data/bin/commands/sections.rb +3 -3
- data/bin/commands/select.rb +2 -0
- data/bin/commands/show.rb +24 -20
- data/bin/commands/since.rb +10 -3
- data/bin/commands/tag.rb +18 -16
- data/bin/commands/tag_dir.rb +5 -2
- data/bin/commands/tags.rb +17 -17
- data/bin/commands/template.rb +8 -2
- data/bin/commands/today.rb +10 -2
- data/bin/commands/undo.rb +2 -0
- data/bin/commands/update.rb +9 -7
- data/bin/commands/view.rb +11 -8
- data/bin/commands/views.rb +2 -0
- data/bin/commands/yesterday.rb +6 -1
- data/bin/doing +54 -57
- data/docs/doc/Array.html +3 -3
- data/docs/doc/BooleanTermParser/Clause.html +3 -3
- data/docs/doc/BooleanTermParser/Operator.html +3 -3
- data/docs/doc/BooleanTermParser/Query.html +3 -3
- data/docs/doc/BooleanTermParser/QueryParser.html +3 -3
- data/docs/doc/BooleanTermParser/QueryTransformer.html +3 -3
- data/docs/doc/BooleanTermParser.html +3 -3
- data/docs/doc/Doing/ArrayCleanup.html +3 -3
- data/docs/doc/Doing/ArrayNestedHash.html +3 -3
- data/docs/doc/Doing/ArrayTags.html +9 -9
- data/docs/doc/Doing/ByDayExport.html +3 -3
- data/docs/doc/Doing/CSVExport.html +4 -4
- data/docs/doc/Doing/CalendarImport.html +4 -4
- data/docs/doc/Doing/Change.html +3 -3
- data/docs/doc/Doing/Changes.html +3 -3
- data/docs/doc/Doing/ChronifyArray.html +3 -3
- data/docs/doc/Doing/ChronifyNumeric.html +3 -3
- data/docs/doc/Doing/ChronifyString.html +6 -6
- data/docs/doc/Doing/Color.html +88 -47
- data/docs/doc/Doing/Completion/BashCompletions.html +3 -3
- data/docs/doc/Doing/Completion/FigCompletions.html +3 -3
- data/docs/doc/Doing/Completion/FishCompletions.html +3 -3
- data/docs/doc/Doing/Completion/StringUtils.html +3 -3
- data/docs/doc/Doing/Completion/ZshCompletions.html +3 -3
- data/docs/doc/Doing/Completion.html +5 -5
- data/docs/doc/Doing/Configuration.html +6 -6
- data/docs/doc/Doing/DayOneRenderer.html +3 -3
- data/docs/doc/Doing/DayoneExport.html +4 -4
- data/docs/doc/Doing/DoingExport.html +5 -5
- data/docs/doc/Doing/DoingImport.html +4 -4
- data/docs/doc/Doing/Entry.html +3 -3
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +3 -3
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +3 -3
- data/docs/doc/Doing/Errors/DoingStandardError.html +3 -3
- data/docs/doc/Doing/Errors/EmptyInput.html +3 -3
- data/docs/doc/Doing/Errors/HistoryLimitError.html +3 -3
- data/docs/doc/Doing/Errors/InvalidPlugin.html +3 -3
- data/docs/doc/Doing/Errors/MissingBackupFile.html +3 -3
- data/docs/doc/Doing/Errors/NoResults.html +3 -3
- data/docs/doc/Doing/Errors/PluginException.html +3 -3
- data/docs/doc/Doing/Errors/UserCancelled.html +3 -3
- data/docs/doc/Doing/Errors/WrongCommand.html +3 -3
- data/docs/doc/Doing/Errors.html +3 -3
- data/docs/doc/Doing/HTMLExport.html +4 -4
- data/docs/doc/Doing/Hooks.html +3 -16
- data/docs/doc/Doing/Item.html +4 -4
- data/docs/doc/Doing/ItemDates.html +3 -3
- data/docs/doc/Doing/ItemQuery.html +3 -3
- data/docs/doc/Doing/ItemState.html +3 -3
- data/docs/doc/Doing/ItemTags.html +3 -3
- data/docs/doc/Doing/Items.html +3 -3
- data/docs/doc/Doing/JSONExport.html +4 -4
- data/docs/doc/Doing/JSONImport.html +4 -4
- data/docs/doc/Doing/Logger.html +183 -3
- data/docs/doc/Doing/MarkdownExport.html +4 -4
- data/docs/doc/Doing/Note.html +3 -3
- data/docs/doc/Doing/Pager.html +54 -58
- data/docs/doc/Doing/Plugins.html +3 -3
- data/docs/doc/Doing/Prompt.html +4 -4
- data/docs/doc/Doing/PromptChoose.html +3 -3
- data/docs/doc/Doing/PromptFZF.html +3 -3
- data/docs/doc/Doing/PromptInput.html +3 -3
- data/docs/doc/Doing/PromptSTD.html +3 -3
- data/docs/doc/Doing/PromptYN.html +3 -3
- data/docs/doc/Doing/Section.html +3 -3
- data/docs/doc/Doing/StringHighlight.html +3 -3
- data/docs/doc/Doing/StringNormalize.html +3 -3
- data/docs/doc/Doing/StringQuery.html +4 -4
- data/docs/doc/Doing/StringTags.html +3 -3
- data/docs/doc/Doing/StringTransform.html +3 -3
- data/docs/doc/Doing/StringTruncate.html +3 -3
- data/docs/doc/Doing/StringURL.html +3 -3
- data/docs/doc/Doing/SymbolNormalize.html +5 -5
- data/docs/doc/Doing/TaskPaperExport.html +4 -4
- data/docs/doc/Doing/TemplateExport.html +5 -5
- data/docs/doc/Doing/TemplateString.html +7 -7
- data/docs/doc/Doing/TimingImport.html +4 -4
- data/docs/doc/Doing/Types.html +3 -3
- data/docs/doc/Doing/Util/Backup.html +4 -17
- data/docs/doc/Doing/Util.html +56 -61
- data/docs/doc/Doing/Version.html +3 -3
- data/docs/doc/Doing/WWID.html +6 -4
- data/docs/doc/Doing.html +4 -4
- data/docs/doc/FalseClass.html +3 -3
- data/docs/doc/GLI/Commands/Help.html +5 -5
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +3 -3
- data/docs/doc/GLI/Commands.html +3 -3
- data/docs/doc/GLI.html +3 -3
- data/docs/doc/Hash.html +4 -4
- data/docs/doc/Numeric.html +3 -3
- data/docs/doc/Object.html +3 -3
- data/docs/doc/PhraseParser/Operator.html +3 -3
- data/docs/doc/PhraseParser/PhraseClause.html +3 -3
- data/docs/doc/PhraseParser/Query.html +3 -3
- data/docs/doc/PhraseParser/QueryParser.html +3 -3
- data/docs/doc/PhraseParser/QueryTransformer.html +3 -3
- data/docs/doc/PhraseParser/TermClause.html +3 -3
- data/docs/doc/PhraseParser.html +3 -3
- data/docs/doc/Status.html +3 -3
- data/docs/doc/String.html +51 -5
- data/docs/doc/Symbol.html +3 -3
- data/docs/doc/Time.html +3 -3
- data/docs/doc/TrueClass.html +3 -3
- data/docs/doc/_index.html +4 -4
- data/docs/doc/class_list.html +6 -3
- data/docs/doc/css/full_list.css +3 -3
- data/docs/doc/css/style.css +6 -0
- data/docs/doc/file.README.html +3 -3
- data/docs/doc/file_list.html +5 -2
- data/docs/doc/frames.html +1 -1
- data/docs/doc/index.html +3 -3
- data/docs/doc/js/app.js +294 -264
- data/docs/doc/js/full_list.js +30 -4
- data/docs/doc/method_list.html +443 -392
- data/docs/doc/top-level-namespace.html +3 -3
- data/doing.gemspec +2 -0
- data/doing.rdoc +1 -1
- data/example_plugin.rb +1 -4
- data/lib/doing/add_options.rb +2 -2
- data/lib/doing/array/cleanup.rb +2 -0
- data/lib/doing/array/nested_hash.rb +2 -0
- data/lib/doing/boolean_term_parser.rb +3 -3
- data/lib/doing/changelog/changes.rb +4 -5
- data/lib/doing/changelog/version.rb +8 -11
- data/lib/doing/chronify/array.rb +4 -4
- data/lib/doing/chronify/string.rb +5 -4
- data/lib/doing/cli_status.rb +7 -2
- data/lib/doing/colors.rb +93 -51
- data/lib/doing/completion/bash_completion.rb +36 -39
- data/lib/doing/completion/completion_string.rb +2 -1
- data/lib/doing/completion/fig_completion.rb +33 -33
- data/lib/doing/completion/fish_completion.rb +22 -23
- data/lib/doing/completion/zsh_completion.rb +5 -5
- data/lib/doing/completion.rb +7 -4
- data/lib/doing/configuration.rb +21 -13
- data/lib/doing/errors.rb +1 -4
- data/lib/doing/good.rb +1 -1
- data/lib/doing/hash.rb +4 -4
- data/lib/doing/help_monkey_patch.rb +1 -1
- data/lib/doing/hooks.rb +6 -2
- data/lib/doing/item/dates.rb +3 -1
- data/lib/doing/item/query.rb +10 -10
- data/lib/doing/item/state.rb +2 -0
- data/lib/doing/logger.rb +113 -45
- data/lib/doing/markdown_document_listener.rb +25 -25
- data/lib/doing/normalize.rb +1 -1
- data/lib/doing/pager.rb +73 -29
- data/lib/doing/plugin_manager.rb +4 -5
- data/lib/doing/plugins/export/byday.rb +1 -1
- data/lib/doing/plugins/export/dayone_export.rb +28 -27
- data/lib/doing/plugins/export/doing_export.rb +1 -1
- data/lib/doing/plugins/export/html_export.rb +3 -3
- data/lib/doing/plugins/export/json_export.rb +4 -5
- data/lib/doing/plugins/export/markdown_export.rb +10 -2
- data/lib/doing/plugins/export/taskpaper_export.rb +1 -0
- data/lib/doing/plugins/export/template_export.rb +110 -107
- data/lib/doing/plugins/import/calendar_import.rb +1 -1
- data/lib/doing/plugins/import/doing_import.rb +2 -2
- data/lib/doing/plugins/import/timing_import.rb +3 -3
- data/lib/doing/prompt/choose.rb +5 -6
- data/lib/doing/prompt/fzf.rb +3 -2
- data/lib/doing/prompt/input.rb +7 -6
- data/lib/doing/prompt/yn.rb +9 -11
- data/lib/doing/string/tags.rb +7 -4
- data/lib/doing/string/transform.rb +15 -10
- data/lib/doing/string/truncate.rb +1 -0
- data/lib/doing/string/url.rb +1 -1
- data/lib/doing/template_string.rb +13 -9
- data/lib/doing/time.rb +4 -2
- data/lib/doing/util.rb +12 -11
- data/lib/doing/util_backup.rb +29 -26
- data/lib/doing/version.rb +3 -1
- data/lib/doing/wwid/display.rb +182 -151
- data/lib/doing/wwid/editor.rb +13 -12
- data/lib/doing/wwid/filetools.rb +13 -11
- data/lib/doing/wwid/filter.rb +41 -40
- data/lib/doing/wwid/guess.rb +6 -8
- data/lib/doing/wwid/interactive.rb +9 -9
- data/lib/doing/wwid/modify.rb +53 -53
- data/lib/doing/wwid/timers.rb +4 -5
- data/lib/doing/wwid/wwid.rb +0 -0
- data/lib/doing/wwid/wwidutil.rb +8 -10
- data/lib/examples/commands/wiki.rb +2 -0
- data/lib/examples/plugins/capture_thing_import.rb +1 -1
- data/lib/examples/plugins/say_export.rb +1 -2
- data/lib/examples/plugins/wiki_export/wiki_export.rb +3 -4
- data/lib/helpers/fzf/test/test_go.rb +5 -5
- data/lib/helpers/threaded_tests.rb +20 -20
- data/lib/helpers/threaded_tests_string.rb +2 -0
- data/rdoc_to_mmd.rb +5 -4
- data/rdocfixer.rb +1 -2
- data/scripts/deploy.rb +3 -4
- data/scripts/generate_bash_completions.rb +40 -43
- data/scripts/generate_fish_completions.rb +17 -15
- data/scripts/generate_zsh_completions.rb +9 -7
- data/scripts/setting_replace.rb +1 -0
- data/scripts/sort_commands.rb +4 -2
- data/yard_templates/default/method_details/setup.rb +3 -1
- metadata +3 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'stringio'
|
|
2
4
|
require 'time'
|
|
3
5
|
require 'fileutils'
|
|
@@ -10,7 +12,7 @@ module GLI
|
|
|
10
12
|
@exe = app.exe_name
|
|
11
13
|
if File.exist?('COMMANDS.md') # Back up existing README
|
|
12
14
|
FileUtils.mv('COMMANDS.md', 'COMMANDS.bak')
|
|
13
|
-
|
|
15
|
+
warn 'Backing up existing COMMANDS.md'
|
|
14
16
|
end
|
|
15
17
|
@io = File.new('COMMANDS.md', 'w')
|
|
16
18
|
@nest = '#'
|
|
@@ -18,8 +20,7 @@ module GLI
|
|
|
18
20
|
@parent_command = []
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
def beginning
|
|
22
|
-
end
|
|
23
|
+
def beginning; end
|
|
23
24
|
|
|
24
25
|
# Called when processing has completed
|
|
25
26
|
def ending
|
|
@@ -61,32 +62,32 @@ module GLI
|
|
|
61
62
|
@io.puts "*v#{version}*"
|
|
62
63
|
@io.puts
|
|
63
64
|
# Hacking in the overview file
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
return unless File.exist?('OVERVIEW.md')
|
|
66
|
+
|
|
67
|
+
@io.puts IO.read('OVERVIEW.md')
|
|
68
|
+
@io.puts
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
def options
|
|
71
72
|
if @nest.size == 1
|
|
72
|
-
@io.puts
|
|
73
|
+
@io.puts '## Global Options'
|
|
73
74
|
else
|
|
74
|
-
@io.puts header(
|
|
75
|
+
@io.puts header('Options', 1)
|
|
75
76
|
end
|
|
76
77
|
@io.puts
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
# Gives you a flag in the current context
|
|
80
81
|
def flag(name, aliases, desc, long_desc, default_value, arg_name, must_match, _type)
|
|
81
|
-
invocations = ([name] + Array(aliases)).map { |_| "
|
|
82
|
+
invocations = ([name] + Array(aliases)).map { |_| "`#{add_dashes(_)}`" }.join(' | ')
|
|
82
83
|
usage = "#{invocations} #{arg_name || 'arg'}"
|
|
83
84
|
@io.puts header(usage, 2)
|
|
84
85
|
@io.puts
|
|
85
86
|
@io.puts String(desc).strip
|
|
86
87
|
@io.puts "\n*Default Value:* `#{default_value || 'None'}`\n" unless default_value.nil?
|
|
87
|
-
@io.puts "\n*Must Match:* `#{must_match
|
|
88
|
+
@io.puts "\n*Must Match:* `#{must_match}`\n" unless must_match.nil?
|
|
88
89
|
cmd_desc = String(long_desc).strip
|
|
89
|
-
@io.puts "> #{cmd_desc}\n" unless cmd_desc.
|
|
90
|
+
@io.puts "> #{cmd_desc}\n" unless cmd_desc.empty?
|
|
90
91
|
@io.puts
|
|
91
92
|
end
|
|
92
93
|
|
|
@@ -94,22 +95,21 @@ module GLI
|
|
|
94
95
|
def switch(name, aliases, desc, long_desc, negatable)
|
|
95
96
|
if negatable
|
|
96
97
|
name = "[no-]#{name}" if name.to_s.length > 1
|
|
97
|
-
aliases = aliases.map { |_|
|
|
98
|
+
aliases = aliases.map { |_| _.to_s.length > 1 ? "[no-]#{_}" : _ }
|
|
98
99
|
end
|
|
99
|
-
invocations = ([name] + aliases).map { |_| "
|
|
100
|
-
@io.puts header(
|
|
100
|
+
invocations = ([name] + aliases).map { |_| "`#{add_dashes(_).strip}`" }.join('|')
|
|
101
|
+
@io.puts header(invocations.to_s, 2)
|
|
101
102
|
@io.puts
|
|
102
103
|
@io.puts String(desc).strip
|
|
103
104
|
cmd_desc = String(long_desc).strip
|
|
104
|
-
@io.puts "\n> #{cmd_desc}\n" unless cmd_desc.
|
|
105
|
+
@io.puts "\n> #{cmd_desc}\n" unless cmd_desc.empty?
|
|
105
106
|
@io.puts
|
|
106
107
|
end
|
|
107
108
|
|
|
108
|
-
def end_options
|
|
109
|
-
end
|
|
109
|
+
def end_options; end
|
|
110
110
|
|
|
111
111
|
def commands
|
|
112
|
-
@io.puts header(
|
|
112
|
+
@io.puts header('Commands', 1)
|
|
113
113
|
@io.puts
|
|
114
114
|
increment_nest
|
|
115
115
|
end
|
|
@@ -124,7 +124,7 @@ module GLI
|
|
|
124
124
|
@io.puts "*#{String(desc).strip}*"
|
|
125
125
|
@io.puts
|
|
126
126
|
cmd_desc = String(long_desc).strip.split("\n").map { |_| "> #{_}" }.join("\n")
|
|
127
|
-
@io.puts "#{cmd_desc}\n\n" unless cmd_desc.
|
|
127
|
+
@io.puts "#{cmd_desc}\n\n" unless cmd_desc.empty?
|
|
128
128
|
increment_nest
|
|
129
129
|
end
|
|
130
130
|
|
|
@@ -156,16 +156,16 @@ module GLI
|
|
|
156
156
|
if @nest.size + increment > 6
|
|
157
157
|
"**#{content}**"
|
|
158
158
|
else
|
|
159
|
-
"#{@nest}#{'#'*increment} #{content}"
|
|
159
|
+
"#{@nest}#{'#' * increment} #{content}"
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
-
def increment_nest(increment=1)
|
|
164
|
-
@nest = "#{@nest}#{'#'*increment}"
|
|
163
|
+
def increment_nest(increment = 1)
|
|
164
|
+
@nest = "#{@nest}#{'#' * increment}"
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
def decrement_nest(increment=1)
|
|
168
|
-
@nest.gsub!(/#{'#'*increment}$/, '')
|
|
167
|
+
def decrement_nest(increment = 1)
|
|
168
|
+
@nest.gsub!(/#{'#' * increment}$/, '')
|
|
169
169
|
end
|
|
170
170
|
end
|
|
171
171
|
end
|
data/lib/doing/normalize.rb
CHANGED
data/lib/doing/pager.rb
CHANGED
|
@@ -14,9 +14,7 @@ module Doing
|
|
|
14
14
|
# Enable/disable pagination
|
|
15
15
|
#
|
|
16
16
|
# @param should_paginate [Boolean] true to paginate
|
|
17
|
-
|
|
18
|
-
@paginate = should_paginate
|
|
19
|
-
end
|
|
17
|
+
attr_writer :paginate
|
|
20
18
|
|
|
21
19
|
# Page output. If @paginate is false, just dump to
|
|
22
20
|
# STDOUT
|
|
@@ -29,48 +27,94 @@ module Doing
|
|
|
29
27
|
return
|
|
30
28
|
end
|
|
31
29
|
|
|
30
|
+
# Smart pagination: skip pager for small outputs
|
|
31
|
+
if should_skip_pager?(text)
|
|
32
|
+
puts text
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Use external pager (IO.popen for best performance and UX)
|
|
37
|
+
external_pager(text)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# External pager using IO.popen for optimal performance and UX
|
|
41
|
+
def external_pager(text)
|
|
32
42
|
pager = which_pager
|
|
33
|
-
Doing.logger.debug('Pager:', "Using #{pager}")
|
|
43
|
+
Doing.logger.debug('Pager:', "Using external pager: #{pager}")
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
begin
|
|
46
|
+
IO.popen(pager, 'w') do |io|
|
|
47
|
+
io.write(text)
|
|
48
|
+
io.close_write
|
|
49
|
+
end
|
|
50
|
+
rescue SystemCallError => e
|
|
51
|
+
# Fallback to direct output if pager fails
|
|
52
|
+
puts text
|
|
53
|
+
Doing.logger.debug('Pager:', "Pager failed, using direct output: #{e}")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
36
56
|
|
|
37
|
-
|
|
57
|
+
private
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
read_io.close
|
|
59
|
+
# Smart pagination: skip pager for small outputs
|
|
60
|
+
def should_skip_pager?(text)
|
|
61
|
+
return true if text.nil? || text.empty?
|
|
43
62
|
|
|
44
|
-
|
|
45
|
-
IO.select [input]
|
|
63
|
+
line_count = text.lines.count
|
|
46
64
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rescue SystemCallError => e
|
|
50
|
-
raise Errors::DoingStandardError, "Pager error, #{e}"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
65
|
+
# Always paginate if output is very large (more than 200 lines)
|
|
66
|
+
return false if line_count > 200
|
|
53
67
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
# Check if output fits within 150% of terminal height
|
|
69
|
+
term_height = terminal_height
|
|
70
|
+
if term_height > 0
|
|
71
|
+
# Only paginate if output is 150% of terminal height or more
|
|
72
|
+
# This allows scrolling up half a page for reasonable outputs
|
|
73
|
+
threshold = (term_height * 1.5).to_i
|
|
74
|
+
return true if line_count < threshold
|
|
60
75
|
end
|
|
61
76
|
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
# Fallback: skip pager for small outputs (less than 50 lines)
|
|
78
|
+
# This covers most typical doing commands while avoiding pager overhead
|
|
79
|
+
line_count < 50
|
|
64
80
|
end
|
|
65
81
|
|
|
66
|
-
|
|
82
|
+
# Get terminal height, with caching and fallback
|
|
83
|
+
def terminal_height
|
|
84
|
+
@terminal_height ||= begin
|
|
85
|
+
# Try TTY::Screen first (most reliable)
|
|
86
|
+
if defined?(TTY::Screen) && TTY::Screen.respond_to?(:height)
|
|
87
|
+
TTY::Screen.height
|
|
88
|
+
# Fallback to stty
|
|
89
|
+
elsif system('stty size >/dev/null 2>&1')
|
|
90
|
+
`stty size`.split.first.to_i
|
|
91
|
+
# Fallback to tput
|
|
92
|
+
elsif system('tput lines >/dev/null 2>&1')
|
|
93
|
+
`tput lines`.to_i
|
|
94
|
+
# Last resort: assume 24 lines
|
|
95
|
+
else
|
|
96
|
+
24
|
|
97
|
+
end
|
|
98
|
+
rescue StandardError
|
|
99
|
+
24
|
|
100
|
+
end
|
|
101
|
+
end
|
|
67
102
|
|
|
68
103
|
def git_pager
|
|
69
|
-
|
|
104
|
+
@git_pager ||= begin
|
|
105
|
+
if TTY::Which.exist?('git')
|
|
106
|
+
result = `#{TTY::Which.which('git')} config --get-all core.pager 2>/dev/null`.strip
|
|
107
|
+
result.empty? ? nil : result
|
|
108
|
+
else
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
rescue StandardError
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
70
114
|
end
|
|
71
115
|
|
|
72
116
|
def pagers
|
|
73
|
-
[
|
|
117
|
+
@pagers ||= [
|
|
74
118
|
Doing.setting('editors.pager'),
|
|
75
119
|
ENV['PAGER'],
|
|
76
120
|
'less -FXr',
|
data/lib/doing/plugin_manager.rb
CHANGED
|
@@ -59,7 +59,6 @@ module Doing
|
|
|
59
59
|
paths.map { |d| File.expand_path(d) }
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
|
|
63
62
|
# Register a plugin
|
|
64
63
|
#
|
|
65
64
|
# @param title [String|Array] The name of the
|
|
@@ -209,7 +208,7 @@ module Doing
|
|
|
209
208
|
def plugin_regex(type: :export)
|
|
210
209
|
type = valid_type(type)
|
|
211
210
|
pattern = []
|
|
212
|
-
plugins[type].
|
|
211
|
+
plugins[type].each_value do |options|
|
|
213
212
|
pattern << options[:trigger].normalize_trigger
|
|
214
213
|
end
|
|
215
214
|
Regexp.new("^(?:#{pattern.sort.uniq.join('|')})$", true)
|
|
@@ -227,7 +226,7 @@ module Doing
|
|
|
227
226
|
type = valid_type(type)
|
|
228
227
|
templates = []
|
|
229
228
|
plugs = plugins[type].clone
|
|
230
|
-
plugs.delete_if { |_t, o| o[:templates].nil? }.
|
|
229
|
+
plugs.delete_if { |_t, o| o[:templates].nil? }.each_value do |options|
|
|
231
230
|
options[:templates].each do |t|
|
|
232
231
|
out = t[:name]
|
|
233
232
|
out += " (#{t[:format]})" if t.key?(:format)
|
|
@@ -251,7 +250,7 @@ module Doing
|
|
|
251
250
|
type = valid_type(type)
|
|
252
251
|
pattern = []
|
|
253
252
|
plugs = plugins[type].clone
|
|
254
|
-
plugs.delete_if { |_, o| o[:templates].nil? }.
|
|
253
|
+
plugs.delete_if { |_, o| o[:templates].nil? }.each_value do |options|
|
|
255
254
|
options[:templates].each do |t|
|
|
256
255
|
pattern << t[:trigger].normalize_trigger
|
|
257
256
|
end
|
|
@@ -274,7 +273,7 @@ module Doing
|
|
|
274
273
|
## @return [String] string content of template for trigger
|
|
275
274
|
##
|
|
276
275
|
def template_for_trigger(trigger, type: :export, save_to: nil)
|
|
277
|
-
plugins[valid_type(type)].clone.delete_if { |_t, o| o[:templates].nil? }.
|
|
276
|
+
plugins[valid_type(type)].clone.delete_if { |_t, o| o[:templates].nil? }.each_value do |options|
|
|
278
277
|
options[:templates].each do |t|
|
|
279
278
|
next unless trigger =~ /^(?:#{t[:trigger].normalize_trigger})$/
|
|
280
279
|
|
|
@@ -38,7 +38,7 @@ module Doing
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
width = wwid.config['plugins']['byday']['item_width'].to_i || 60
|
|
41
|
-
divider = "{wd}+{xk}#{'-' *10}{wd}+{xk}#{'-' * width}{wd}+{xk}#{'-' * 8}{wd}+{x}"
|
|
41
|
+
divider = "{wd}+{xk}#{'-' * 10}{wd}+{xk}#{'-' * width}{wd}+{xk}#{'-' * 8}{wd}+{x}"
|
|
42
42
|
out = []
|
|
43
43
|
out << divider
|
|
44
44
|
out << "{wd}|{xm}date {wd}|{xbw}item#{' ' * (width - 4)}{wd}|{xy}duration{wd}|{x}"
|
|
@@ -17,7 +17,7 @@ module Doing
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def get_binding
|
|
20
|
-
binding
|
|
20
|
+
binding
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -44,7 +44,6 @@ module Doing
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def self.render(wwid, items, variables: {})
|
|
47
|
-
|
|
48
47
|
return unless items.good?
|
|
49
48
|
|
|
50
49
|
config = Doing.settings
|
|
@@ -82,15 +81,18 @@ module Doing
|
|
|
82
81
|
tags.concat(i.tag_array).sort!.uniq!
|
|
83
82
|
flagged = day_flagged = true if i.tags?(config['marker_tag'])
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
if i.title =~ /@done\((\d{4}-\d\d-\d\d \d\d:\d\d.*?)\)/ && opt[:times]
|
|
85
|
+
interval = wwid.get_interval(i,
|
|
86
|
+
record: true)
|
|
87
|
+
end
|
|
86
88
|
interval ||= false
|
|
87
89
|
human_time = false
|
|
88
90
|
if interval
|
|
89
91
|
d, h, m = wwid.get_interval(i, formatted: false).format_time
|
|
90
92
|
human_times = []
|
|
91
|
-
human_times << format('%<d>d day%<p>s', d: d, p: d == 1 ? '' : 's') if d
|
|
92
|
-
human_times << format('%<h>d hour%<p>s', h: h, p: h == 1 ? '' : 's') if h
|
|
93
|
-
human_times << format('%<m>d minute%<p>s', m: m, p: m == 1 ? '' : 's') if m
|
|
93
|
+
human_times << format('%<d>d day%<p>s', d: d, p: d == 1 ? '' : 's') if d.positive?
|
|
94
|
+
human_times << format('%<h>d hour%<p>s', h: h, p: h == 1 ? '' : 's') if h.positive?
|
|
95
|
+
human_times << format('%<m>d minute%<p>s', m: m, p: m == 1 ? '' : 's') if m.positive?
|
|
94
96
|
human_time = human_times.join(', ')
|
|
95
97
|
end
|
|
96
98
|
|
|
@@ -111,27 +113,24 @@ module Doing
|
|
|
111
113
|
}
|
|
112
114
|
all_items << item
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
if
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
days[date_key][:entries].push(item)
|
|
119
|
-
else
|
|
120
|
-
days[date_key] ||= { tags: [], entries: [], starred: false }
|
|
121
|
-
days[date_key][:starred] = true if day_flagged
|
|
122
|
-
days[date_key][:tags] = days[date_key][:tags].concat(i.tag_array).sort.uniq
|
|
123
|
-
days[date_key][:entries].push(item)
|
|
124
|
-
end
|
|
116
|
+
days[date_key] ||= { tags: [], entries: [], starred: false } unless days.key?(date_key)
|
|
117
|
+
days[date_key][:starred] = true if day_flagged
|
|
118
|
+
days[date_key][:tags] = days[date_key][:tags].concat(i.tag_array).sort.uniq
|
|
119
|
+
days[date_key][:entries].push(item)
|
|
125
120
|
end
|
|
126
121
|
|
|
127
|
-
|
|
128
122
|
template = if config['export_templates']['dayone'] && File.exist?(File.expand_path(config['export_templates']['dayone']))
|
|
129
123
|
IO.read(File.expand_path(config['export_templates']['dayone']))
|
|
130
124
|
else
|
|
131
125
|
self.template('dayone')
|
|
132
126
|
end
|
|
133
127
|
|
|
134
|
-
totals = opt[:totals]
|
|
128
|
+
totals = if opt[:totals]
|
|
129
|
+
wwid.tag_times(format: :markdown, sort_by: opt[:sort_tags],
|
|
130
|
+
sort_order: opt[:tag_order])
|
|
131
|
+
else
|
|
132
|
+
''
|
|
133
|
+
end
|
|
135
134
|
|
|
136
135
|
case digest
|
|
137
136
|
when :day
|
|
@@ -162,18 +161,19 @@ module Doing
|
|
|
162
161
|
end
|
|
163
162
|
else
|
|
164
163
|
to_dayone(template: template,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
title: variables[:page_title],
|
|
165
|
+
items: all_items,
|
|
166
|
+
totals: totals,
|
|
167
|
+
date: Time.now,
|
|
168
|
+
tags: tags,
|
|
169
|
+
starred: flagged)
|
|
171
170
|
end
|
|
172
171
|
|
|
173
172
|
@out = ''
|
|
174
173
|
end
|
|
175
174
|
|
|
176
|
-
def self.to_dayone(template: self.template(nil), title: 'doing', items: [], totals: '', date: Time.now, tags: [],
|
|
175
|
+
def self.to_dayone(template: self.template(nil), title: 'doing', items: [], totals: '', date: Time.now, tags: [],
|
|
176
|
+
starred: false)
|
|
177
177
|
mdx = DayOneRenderer.new(title, items, totals)
|
|
178
178
|
|
|
179
179
|
engine = ERB.new(template)
|
|
@@ -201,7 +201,8 @@ module Doing
|
|
|
201
201
|
f.puts plist.to_plist
|
|
202
202
|
end
|
|
203
203
|
|
|
204
|
-
Doing.logger.count(:exported, level: :info, count: items.count,
|
|
204
|
+
Doing.logger.count(:exported, level: :info, count: items.count,
|
|
205
|
+
message: '%count %items exported to Day One import folder')
|
|
205
206
|
end
|
|
206
207
|
|
|
207
208
|
Doing::Plugins.register 'dayone', :export, self
|
|
@@ -51,7 +51,7 @@ module Doing
|
|
|
51
51
|
|
|
52
52
|
items_out << {
|
|
53
53
|
date: i.date.strftime('%a %-I:%M%p'),
|
|
54
|
-
title: title.gsub(/(@[^ (]+(\(.*?\))?)/im, '<span class="tag">\1</span>').strip,
|
|
54
|
+
title: title.gsub(/(@[^ (]+(\(.*?\))?)/im, '<span class="tag">\1</span>').strip, # + " #{note}"
|
|
55
55
|
note: note,
|
|
56
56
|
time: interval,
|
|
57
57
|
section: i.section
|
|
@@ -74,10 +74,10 @@ module Doing
|
|
|
74
74
|
engine = Haml::Engine.new(template)
|
|
75
75
|
Doing.logger.debug('HTML Export:', "#{items_out.count} items output to HTML")
|
|
76
76
|
@out = engine.render(Object.new,
|
|
77
|
-
|
|
77
|
+
{ :@items => items_out, :@page_title => variables[:page_title], :@style => style,
|
|
78
|
+
:@totals => totals })
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
Doing::Plugins.register 'html', :export, self
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
|
-
|
|
@@ -21,10 +21,10 @@ module Doing
|
|
|
21
21
|
{
|
|
22
22
|
'section' => '',
|
|
23
23
|
'items' => [],
|
|
24
|
-
'timers' =>
|
|
24
|
+
'timers' => ''
|
|
25
25
|
}.to_json
|
|
26
26
|
when 'timeline'
|
|
27
|
-
|
|
27
|
+
'<html></html>'
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -62,7 +62,7 @@ module Doing
|
|
|
62
62
|
i = {
|
|
63
63
|
date: i.date,
|
|
64
64
|
end_date: end_date,
|
|
65
|
-
title: title.strip,
|
|
65
|
+
title: title.strip, # + " #{note}"
|
|
66
66
|
section: i.section,
|
|
67
67
|
note: note.to_s(prefix: ''),
|
|
68
68
|
time: interval.time_string(format: :clock),
|
|
@@ -78,7 +78,7 @@ module Doing
|
|
|
78
78
|
when 'timeline'
|
|
79
79
|
new_item = {
|
|
80
80
|
'id' => index + 1,
|
|
81
|
-
'content' => title.strip,
|
|
81
|
+
'content' => title.strip, # + " #{note}"
|
|
82
82
|
'title' => title.strip + " (#{interval.time_string(format: :clock)})",
|
|
83
83
|
'start' => i.date.strftime('%F %T'),
|
|
84
84
|
'type' => 'box',
|
|
@@ -151,4 +151,3 @@ module Doing
|
|
|
151
151
|
Doing::Plugins.register 'timeline', :export, self
|
|
152
152
|
end
|
|
153
153
|
end
|
|
154
|
-
|
|
@@ -52,7 +52,10 @@ module Doing
|
|
|
52
52
|
|
|
53
53
|
title = "#{title} @section(#{i.section})" unless variables[:is_single]
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
if i.title =~ /@done\((\d{4}-\d\d-\d\d \d\d:\d\d.*?)\)/ && opt[:times]
|
|
56
|
+
interval = wwid.get_interval(i,
|
|
57
|
+
record: true)
|
|
58
|
+
end
|
|
56
59
|
interval ||= false
|
|
57
60
|
|
|
58
61
|
finished = i.title =~ /(?<= |^)@done/ ? true : false
|
|
@@ -77,7 +80,12 @@ module Doing
|
|
|
77
80
|
self.template(nil)
|
|
78
81
|
end
|
|
79
82
|
|
|
80
|
-
totals = opt[:totals]
|
|
83
|
+
totals = if opt[:totals]
|
|
84
|
+
wwid.tag_times(format: :markdown, sort_by: opt[:sort_tags],
|
|
85
|
+
sort_order: opt[:tag_order])
|
|
86
|
+
else
|
|
87
|
+
''
|
|
88
|
+
end
|
|
81
89
|
|
|
82
90
|
mdx = MarkdownRenderer.new(variables[:page_title], all_items, totals)
|
|
83
91
|
Doing.logger.debug('Markdown Export:', "#{all_items.count} items output to Markdown")
|
|
@@ -24,6 +24,7 @@ module Doing
|
|
|
24
24
|
options[:tags_color] = false
|
|
25
25
|
options[:output] = 'template'
|
|
26
26
|
options[:template] = '- %title @date(%date)%note'
|
|
27
|
+
options[:disable_color] = true
|
|
27
28
|
|
|
28
29
|
Doing.logger.debug('TaskPaper Export:', "#{items.count} items output to TaskPaper format")
|
|
29
30
|
@out = wwid.list_section(options)
|