journal-cli 1.0.20 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5120e9c5386b63b05c8d1e866614db4bc5ce4f46e5e627f6562edb22af812d5d
4
- data.tar.gz: 69a663f28a74aa7440d0555038bad8e5273693b33a400125c49df98415c0b2df
3
+ metadata.gz: 484b18a0188aa705a9941742377f52ac7314fd8ea0e29c01d078df8334368543
4
+ data.tar.gz: 2c1b6036031cd9d9cabf3fdcafbf923c768730f6420ac1c031d2a9211901650c
5
5
  SHA512:
6
- metadata.gz: 56d29c600492daeffe8186e34dc1370ac91a0bfbec0cd460986f88d293b2b4a1569d031ef78c7c7faaf3863bbb415d19ce618231969601b932a59db27b110a09
7
- data.tar.gz: 1cb774c8c202b213d3aa08babd13ef0b07602f15f4a687150df1a101834f049c23db423cb1716d25bbf9012e7bedab4c9e80ba0934e6f131b8bda4fa9467e67a
6
+ metadata.gz: c0799f9b88143f38ca52b515de35453e2edbbd6b97325e1a0e0c9c4748014995ca15e3423be014b129234573daaca82d769ca16e0c541a3e8d4976492e9984db
7
+ data.tar.gz: 5164b850be461d04c6a81f83c4b0ec3b278fffbabbf61b60926813e19ce1f89cd66310ed5913d62887839fe2c0c6734769bb93efd2fed37396b97f20eadeccaf
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 1.0.21
2
+
3
+ 2023-09-13 11:00
4
+
5
+ #### IMPROVED
6
+
7
+ - If gum is installed, continue using it, but no longer require gum to function
8
+
1
9
  ### 1.0.20
2
10
 
3
11
  2023-09-12 19:10
data/Gemfile.lock CHANGED
@@ -1,8 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- journal-cli (1.0.20)
4
+ journal-cli (1.0.21)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
+ tty-reader (~> 0.9, >= 0.9.0)
7
+ tty-which (~> 0.5, >= 0.5.0)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
@@ -74,7 +76,15 @@ GEM
74
76
  terminal-table (3.0.2)
75
77
  unicode-display_width (>= 1.1.1, < 3)
76
78
  thor (1.2.1)
79
+ tty-cursor (0.7.1)
80
+ tty-reader (0.9.0)
81
+ tty-cursor (~> 0.7)
82
+ tty-screen (~> 0.8)
83
+ wisper (~> 2.0)
84
+ tty-screen (0.8.1)
85
+ tty-which (0.5.0)
77
86
  unicode-display_width (2.3.0)
87
+ wisper (2.0.1)
78
88
  yard (0.9.34)
79
89
 
80
90
  PLATFORMS
data/README.md CHANGED
@@ -9,12 +9,6 @@ The `journal` command reads a journal definition and provides command line promp
9
9
 
10
10
  ## Installation
11
11
 
12
- First, you need [Gum](https://github.com/charmbracelet/gum) installed. The easiest way is with [Homebrew](https://brew.sh/):
13
-
14
- ```
15
- $ brew install gum
16
- ```
17
-
18
12
  Use RubyGems to install journal:
19
13
 
20
14
  ```
@@ -29,7 +23,17 @@ $ gem install --user-install journal-cli
29
23
 
30
24
  > I've noticed lately with `asdf` that I have to run `asdf reshim` after installing gems containing binaries.
31
25
 
32
- If you want to use Day One with journal, you'll need to [install the Day One CLI](https://dayoneapp.com/guides/tips-and-tutorials/command-line-interface-cli/).
26
+ If [Gum](https://github.com/charmbracelet/gum) is installed, it will be used for prettier input prompts and editing. The easiest way is with [Homebrew](https://brew.sh/):
27
+
28
+ ```
29
+ $ brew install gum
30
+ ```
31
+
32
+ If you want to use Day One with Journal, you'll need to [install the Day One CLI](https://dayoneapp.com/guides/tips-and-tutorials/command-line-interface-cli/). It's just one command:
33
+
34
+ ```
35
+ sudo bash /Applications/Day\ One.app/Contents/Resources/install_cli.sh
36
+ ```
33
37
 
34
38
  ## Configuration
35
39
 
@@ -137,12 +141,13 @@ A question `type` can be one of:
137
141
  - `text` or `string` will request a single-line string, submitted on return
138
142
  - `multiline` for multiline strings (opens a readline editor, use ctrl-d to save)
139
143
  - `weather` will just insert current weather data with no prompt
140
- - `integer` or `number` will request numeric input
144
+ - `number` or `float` will request numeric input, stored as a float (decimal)
145
+ - `integer` will convert numeric input to the nearest integer
141
146
  - `date` will request a natural language date which will be parsed into a date object
142
147
 
143
148
  ### Naming Keys
144
149
 
145
- If you want data stored in a nested object, you can set a question type to `dictionary` and set the prompt to `null` (or just leave the key out), but give it a key that will serve as the parent in the object. Then in the nested questions, give them a key in the dot format `[PARENT_KEY].[CHILD_KEY]`. Section keys automatically nest their children, but if you want to go deeper, you could have a question with the key `health` and type `dictionary`, then have questions with keys like `health.rating` and `health.notes`. If the section key was `status`, the resulting dictionary would look like this in the JSON:
150
+ If you want data stored in a nested object, you can set a question type to `dictionary` and set the prompt to `null` (or just leave the key out), but give it a key that will serve as the parent in the object. Then in the nested questions, give them a key in the dot format `[PARENT_KEY].[CHILD_KEY]`. Section keys automatically nest their questions, but if you want to go deeper, you could have a question with the key `health` and type `dictionary`, then have questions with keys like `health.rating` and `health.notes`. If the section key was `status`, the resulting dictionary would look like this in the JSON:
146
151
 
147
152
  ```json
148
153
  {
data/journal-cli.gemspec CHANGED
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables << 'journal'
28
28
  spec.require_paths << "lib"
29
29
 
30
+ spec.add_runtime_dependency('tty-which', '~> 0.5', '>= 0.5.0')
31
+ spec.add_runtime_dependency('tty-reader', '~> 0.9', '>= 0.9.0')
30
32
  spec.add_development_dependency "bundler", "~> 2.0"
31
33
  spec.add_development_dependency "gem-release", "~> 2.2"
32
34
  spec.add_development_dependency "parse_gemspec-cli", "~> 1.0"
@@ -3,7 +3,7 @@
3
3
  module Journal
4
4
  # Individual question
5
5
  class Question
6
- attr_reader :key, :type, :min, :max, :prompt, :secondary_prompt
6
+ attr_reader :key, :type, :min, :max, :prompt, :secondary_prompt, :gum
7
7
 
8
8
  ##
9
9
  ## Initializes the given question.
@@ -19,6 +19,7 @@ module Journal
19
19
  @max = question['max']&.to_i || 5
20
20
  @prompt = question['prompt'] || nil
21
21
  @secondary_prompt = question['secondary_prompt'] || nil
22
+ @gum = TTY::Which.exist?('gum')
22
23
  end
23
24
 
24
25
  ##
@@ -30,15 +31,17 @@ module Journal
30
31
  return nil if @prompt.nil?
31
32
 
32
33
  case @type
33
- when /^(int|num)/i
34
+ when /^int/i
35
+ read_number(integer: true)
36
+ when /^(float|num)/i
34
37
  read_number
35
38
  when /^(text|string|line)/i
36
39
  read_line
37
40
  when /^(weather|forecast)/i
38
41
  Weather.new(Journal.config['weather_api'], Journal.config['zip'])
39
- when /^multi/
42
+ when /^multi/i
40
43
  read_lines
41
- when /^date/
44
+ when /^(date|time)/i
42
45
  read_date
43
46
  end
44
47
  end
@@ -46,24 +49,28 @@ module Journal
46
49
  private
47
50
 
48
51
  ##
49
- ## Read a numeric entry
52
+ ## Read a numeric entry using gum or TTY::Reader
53
+ ##
54
+ ## @param [Boolean] integer Round result to nearest integer
50
55
  ##
51
56
  ## @return [Number] integer response
52
57
  ##
53
- def read_number
58
+ ##
59
+ def read_number(integer: false)
54
60
  Journal.notify("{by}#{@prompt} {c}({bw}#{@min}{c}-{bw}#{@max})")
55
- res = `gum input --placeholder "#{@prompt} (#{@min}-#{@max})"`.strip
56
- return nil if res.strip.empty?
57
61
 
58
- res = res.to_f
62
+ res = @gum ? read_number_gum : read_line_tty
63
+
64
+ res = integer ? res.to_f.round : res.to_f
59
65
 
60
66
  res = read_number if res < @min || res > @max
61
67
  res
62
68
  end
63
69
 
64
70
  def read_date(prompt: nil)
65
- Journal.notify("{by}#{prompt.nil? ? @prompt : prompt} (natural language)")
66
- line = `gum input --placeholder "#{@prompt} (blank to end editing)"`
71
+ prompt ||= @prompt
72
+ Journal.notify("{by}#{prompt} (natural language)")
73
+ line = @gum ? read_line_gum(prompt) : read_line_tty
67
74
  Chronic.parse(line)
68
75
  end
69
76
 
@@ -78,9 +85,10 @@ module Journal
78
85
  ##
79
86
  def read_line(prompt: nil)
80
87
  output = []
81
- Journal.notify("{by}#{prompt.nil? ? @prompt : @secondary_prompt}")
88
+ prompt ||= @prompt
89
+ Journal.notify("{by}#{prompt}")
82
90
 
83
- line = `gum input --placeholder "#{@prompt} (blank to end editing)"`
91
+ line = @gum ? read_line_gum(prompt) : read_line_tty
84
92
  return output.join("\n") if line =~ /^ *$/
85
93
 
86
94
  output << line
@@ -99,13 +107,75 @@ module Journal
99
107
  ##
100
108
  def read_lines(prompt: nil)
101
109
  output = []
102
- Journal.notify("{by}#{prompt.nil? ? @prompt : @secondary_prompt} {c}({bw}CTRL-d{c} to save)'")
103
- line = `gum write --placeholder "#{prompt}" --width 80 --char-limit 0`
110
+ prompt ||= @prompt
111
+ Journal.notify("{by}#{prompt} {c}({bw}CTRL-d{c} to save)'")
112
+ line = @gum ? read_multiline_gum(prompt) : read_mutliline_tty
104
113
  return output.join("\n") if line.strip.empty?
105
114
 
106
115
  output << line
107
116
  output << read_lines(prompt: @secondary_prompt) unless @secondary_prompt.nil?
108
117
  output.join("\n").strip
109
118
  end
119
+
120
+ ##
121
+ ## Read a numeric entry using gum
122
+ ##
123
+ ## @param [Boolean] integer Round result to nearest integer
124
+ ##
125
+ ## @return [Number] integer response
126
+ ##
127
+ ##
128
+ def read_number_gum
129
+ res = `gum input --placeholder "#{@min}-#{@max}"`.strip
130
+ return nil if res.strip.empty?
131
+
132
+ res
133
+ end
134
+
135
+ ##
136
+ ## Read a single line entry using TTY::Reader
137
+ ##
138
+ ## @param [Boolean] integer Round result to nearest integer
139
+ ##
140
+ ## @return [Number] integer response
141
+ ##
142
+ def read_line_tty
143
+ reader = TTY::Reader.new
144
+ res = reader.read_line('>> ')
145
+ return nil if res.strip.empty?
146
+
147
+ res
148
+ end
149
+
150
+ ##
151
+ ## Read a single line entry using gum
152
+ ##
153
+ ## @param [Boolean] integer Round result to nearest integer
154
+ ##
155
+ ## @return [Number] integer response
156
+ ##
157
+ def read_line_gum(prompt)
158
+ `gum input --placeholder "#{prompt} (blank to end answer)"`
159
+ end
160
+
161
+ ##
162
+ ## Read a multiline entry using TTY::Reader
163
+ ##
164
+ ## @return [string] multiline input
165
+ ##
166
+ def read_mutliline_tty
167
+ reader = TTY::Reader.new
168
+ res = reader.read_multiline
169
+ res.join("\n")
170
+ end
171
+
172
+ ##
173
+ ## Read a multiline entry using gum
174
+ ##
175
+ ## @return [string] multiline input
176
+ ##
177
+ def read_multiline_gum(prompt)
178
+ `gum write --placeholder "#{prompt}" --width 80 --char-limit 0`
179
+ end
110
180
  end
111
181
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Journal
4
- VERSION = '1.0.20'
4
+ VERSION = '1.0.21'
5
5
  end
data/lib/journal-cli.rb CHANGED
@@ -7,6 +7,8 @@ require 'yaml'
7
7
  require 'chronic'
8
8
  require 'fileutils'
9
9
 
10
+ require 'tty-which'
11
+ require 'tty-reader'
10
12
  require_relative 'journal-cli/version'
11
13
  require_relative 'journal-cli/color'
12
14
  require_relative 'journal-cli/data'
data/src/_README.md CHANGED
@@ -12,12 +12,6 @@ The `journal` command reads a journal definition and provides command line promp
12
12
 
13
13
  ## Installation
14
14
 
15
- First, you need [Gum](https://github.com/charmbracelet/gum) installed. The easiest way is with [Homebrew](https://brew.sh/):
16
-
17
- ```
18
- $ brew install gum
19
- ```
20
-
21
15
  Use RubyGems to install journal:
22
16
 
23
17
  ```
@@ -32,7 +26,17 @@ $ gem install --user-install journal-cli
32
26
 
33
27
  > I've noticed lately with `asdf` that I have to run `asdf reshim` after installing gems containing binaries.
34
28
 
35
- If you want to use Day One with journal, you'll need to [install the Day One CLI](https://dayoneapp.com/guides/tips-and-tutorials/command-line-interface-cli/).
29
+ If [Gum](https://github.com/charmbracelet/gum) is installed, it will be used for prettier input prompts and editing. The easiest way is with [Homebrew](https://brew.sh/):
30
+
31
+ ```
32
+ $ brew install gum
33
+ ```
34
+
35
+ If you want to use Day One with Journal, you'll need to [install the Day One CLI](https://dayoneapp.com/guides/tips-and-tutorials/command-line-interface-cli/). It's just one command:
36
+
37
+ ```
38
+ sudo bash /Applications/Day\ One.app/Contents/Resources/install_cli.sh
39
+ ```
36
40
 
37
41
  ## Configuration
38
42
 
@@ -140,12 +144,13 @@ A question `type` can be one of:
140
144
  - `text` or `string` will request a single-line string, submitted on return
141
145
  - `multiline` for multiline strings (opens a readline editor, use ctrl-d to save)
142
146
  - `weather` will just insert current weather data with no prompt
143
- - `integer` or `number` will request numeric input
147
+ - `number` or `float` will request numeric input, stored as a float (decimal)
148
+ - `integer` will convert numeric input to the nearest integer
144
149
  - `date` will request a natural language date which will be parsed into a date object
145
150
 
146
151
  ### Naming Keys
147
152
 
148
- If you want data stored in a nested object, you can set a question type to `dictionary` and set the prompt to `null` (or just leave the key out), but give it a key that will serve as the parent in the object. Then in the nested questions, give them a key in the dot format `[PARENT_KEY].[CHILD_KEY]`. Section keys automatically nest their children, but if you want to go deeper, you could have a question with the key `health` and type `dictionary`, then have questions with keys like `health.rating` and `health.notes`. If the section key was `status`, the resulting dictionary would look like this in the JSON:
153
+ If you want data stored in a nested object, you can set a question type to `dictionary` and set the prompt to `null` (or just leave the key out), but give it a key that will serve as the parent in the object. Then in the nested questions, give them a key in the dot format `[PARENT_KEY].[CHILD_KEY]`. Section keys automatically nest their questions, but if you want to go deeper, you could have a question with the key `health` and type `dictionary`, then have questions with keys like `health.rating` and `health.notes`. If the section key was `status`, the resulting dictionary would look like this in the JSON:
149
154
 
150
155
  ```json
151
156
  {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: journal-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.20
4
+ version: 1.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
@@ -10,6 +10,46 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2023-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tty-which
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.5'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.5.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.5'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.5.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: tty-reader
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.9.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.9'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.9.0
13
53
  - !ruby/object:Gem::Dependency
14
54
  name: bundler
15
55
  requirement: !ruby/object:Gem::Requirement