rbnotes 0.4.13 → 0.4.18
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/CHANGELOG.md +51 -0
- data/Gemfile.lock +2 -2
- data/README.md +48 -2
- data/exe/rbnotes +1 -1
- data/lib/rbnotes/commands.rb +1 -1
- data/lib/rbnotes/commands/add.rb +94 -24
- data/lib/rbnotes/commands/commands.rb +17 -12
- data/lib/rbnotes/commands/import.rb +21 -10
- data/lib/rbnotes/commands/list.rb +55 -23
- data/lib/rbnotes/commands/pick.rb +33 -12
- data/lib/rbnotes/commands/show.rb +75 -15
- data/lib/rbnotes/commands/statistics.rb +32 -13
- data/lib/rbnotes/commands/update.rb +21 -10
- data/lib/rbnotes/utils.rb +49 -11
- data/lib/rbnotes/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a831d67abfd0bae05156f047b6baf44428bc4940058e43bfb9825b5d91c4177
|
4
|
+
data.tar.gz: 7fb70e39e9feb75edfabe3461697ddfb0145cf449205c25068471687952908d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ea3b1ea6517130e5ba5ece651da8f3e30f1013aaa40aa375ad16fb09a7e07a033c7da4e59a721fade178ed4720cf804cb60cc843ea42cbcb177fdf81f947f01
|
7
|
+
data.tar.gz: 6a19760bdecd4b967717c30bed0974a8098d5b3f9e9df9a90bd81cd6b1498a6ba226f2e5654547f1ec67da9beb3d54c740ab9895163d8488df9801b74539f8aa
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,57 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
|
+
- (nothing to record here)
|
9
|
+
|
10
|
+
## [0.4.18] - 2021-04-29
|
11
|
+
### Added
|
12
|
+
- Use ERB to generate the initial content of a new note from the
|
13
|
+
template file (`add`) (#125)
|
14
|
+
|
15
|
+
### Fixed
|
16
|
+
- Add info about template feature of `add`: (#124)
|
17
|
+
- update help text of `add`,
|
18
|
+
- update `README.md`.
|
19
|
+
- Add description about `ugrep` to `README.md`. (#122)
|
20
|
+
- Fix issue #118: help text of `list` is wrong.
|
21
|
+
- Fix issue #119: a test for `Rbnotes::Utils` may fails.
|
22
|
+
- fix the test.
|
23
|
+
|
24
|
+
## [0.4.17] - 2021-04-21
|
25
|
+
### Added
|
26
|
+
- Change for the `show` command to accept keywords. (#84)
|
27
|
+
- Add `-r` option to the `show` command. (#110)
|
28
|
+
- which specifies to enable "raw" output mode.
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
- Update the help text for the `list` command. (#112, #113)
|
32
|
+
- Remove trailing spaces. (#108)
|
33
|
+
- Fix minor bugs:
|
34
|
+
- remove redundant use of an instance variable,
|
35
|
+
- change the behavior to exit when no notes found in the repo,
|
36
|
+
- `pick` and `show`
|
37
|
+
- change delimiter line size according to terminal column.
|
38
|
+
- `show`
|
39
|
+
|
40
|
+
## [0.4.16] - 2021-04-17
|
41
|
+
### Added
|
42
|
+
- Add a new configuration setting to change the default behavior of
|
43
|
+
the `list` (and `pick`) command. (#109)
|
44
|
+
|
45
|
+
## [0.4.15] - 2021-04-15
|
46
|
+
### Added
|
47
|
+
- Enable to use delimiters within a timestamp string. (#104)
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
- Fix issue #105: `list` ignores the 2nd arg when specified `-w`
|
51
|
+
option.
|
52
|
+
|
53
|
+
## [0.4.14] - 2021-04-10
|
54
|
+
### Added
|
55
|
+
- Add `-n` option to `show` command. (#102)
|
56
|
+
|
57
|
+
### Fixed
|
58
|
+
- Fix issue #100: modify to catch Textrepo::MissingTimestampError.
|
8
59
|
|
9
60
|
## [0.4.13] - 2021-03-30
|
10
61
|
### Changed
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Rbnotes
|
2
2
|
|
3
3
|
[](https://github.com/mnbi/rbnotes/actions?query=workflow%3A"Build")
|
4
|
+
[](https://www.codefactor.io/repository/github/mnbi/rbnotes)
|
4
5
|
|
5
6
|
Rbnotes is a simple utility to write a note in the single repository.
|
6
7
|
|
@@ -148,6 +149,7 @@ The short-hand notation of the home directory ("~") is usable.
|
|
148
149
|
|
149
150
|
##### Miscellaneous variables (optional)
|
150
151
|
|
152
|
+
- :template : specify a template file for `add` command
|
151
153
|
- :pager : specify a pager program
|
152
154
|
- :editor : specify a editor program
|
153
155
|
- :searcher: specify a program to perform search
|
@@ -169,13 +171,15 @@ don't have to set `:searcher_options` for them.
|
|
169
171
|
| `ggrep` | `["-i", "-n", "-H", "-R", "-E"]` |
|
170
172
|
| `gegrep` | `["-i", "-n", "-H", "-R"]` |
|
171
173
|
| `rg` | `["-S", "-n", "--no-heading", "--color", "never"]` |
|
174
|
+
| `ugrep` | `["-i", "-n", "-H", "-R", "--color=never"]` |
|
172
175
|
|
173
176
|
Those searcher names are used in macOS (with Homebrew). Any other OS
|
174
177
|
might use different names.
|
175
178
|
|
176
179
|
- `grep` and `egrep` -> BSD grep (macOS default)
|
177
|
-
- `ggrep` and `gegrep` -> GNU grep
|
178
|
-
- `rg` -> ripgrep
|
180
|
+
- `ggrep` and `gegrep` -> [GNU grep](https://www.gnu.org/software/grep/)
|
181
|
+
- `rg` -> [BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep)
|
182
|
+
- `ugrep` -> [Genivia/ugrep](https://github.com/Genivia/ugrep)
|
179
183
|
|
180
184
|
If the name is different, `:searcher_options` should be set with the
|
181
185
|
same value. For example, if you system use the name `gnugrep` as GNU
|
@@ -183,6 +187,48 @@ grep, and you want to use it as the searcher (that is, set `gnugrep`
|
|
183
187
|
to `:searcher`), you should set `:searcher_options` value with `["-i",
|
184
188
|
"-n", "-R", "-E"]`.
|
185
189
|
|
190
|
+
##### Template file for `add` command
|
191
|
+
|
192
|
+
`Add` command always searches a template file in the default
|
193
|
+
directory. The default directory is,
|
194
|
+
|
195
|
+
- `$XDG_CONIFG_HOME/rbnotes/templates` (if `$XDG_CONFIG_HOME` is defined)
|
196
|
+
|
197
|
+
or
|
198
|
+
|
199
|
+
- `$HOME/.config/rbnotes/templates`
|
200
|
+
|
201
|
+
If a file which named as `default.md` is found in the above directory,
|
202
|
+
it will use as a template file to generate the initial content of a
|
203
|
+
new note.
|
204
|
+
|
205
|
+
When a command line option or a setting of the configuration file is
|
206
|
+
specified to use a template file, `add` command will read it instead
|
207
|
+
of the default template file.
|
208
|
+
|
209
|
+
Command line option of `add` to specify a template file is:
|
210
|
+
|
211
|
+
``` shell
|
212
|
+
> rbntoes add -f /somewhere/template.md
|
213
|
+
```
|
214
|
+
|
215
|
+
See the above section about the configuration file setting to specify
|
216
|
+
a template file.
|
217
|
+
|
218
|
+
Though a template file can be written any format of text (markdown,
|
219
|
+
HTML, plain text, or ...), `add` command will process the content
|
220
|
+
using ERB. So, using ERB syntax, you can mix Ruby code in a template
|
221
|
+
file.
|
222
|
+
|
223
|
+
Here is a very simple and short example to use ERB syntax:
|
224
|
+
|
225
|
+
``` markdown
|
226
|
+
## <%= Time.now.strftime("%Y-%m-%d") %>
|
227
|
+
```
|
228
|
+
|
229
|
+
It just insert a date string like "2021-04-29" at the top of a new
|
230
|
+
note which generates by `add` command.
|
231
|
+
|
186
232
|
##### Default values for mandatory variables
|
187
233
|
|
188
234
|
All mandatory variables have their default values. Here is the list
|
data/exe/rbnotes
CHANGED
@@ -21,7 +21,7 @@ class App
|
|
21
21
|
file = args.shift
|
22
22
|
raise ArgumentError, args.unshift(arg) if file.nil?
|
23
23
|
file = File.expand_path(file)
|
24
|
-
raise ArgumentError, "no such file: %s" % file unless FileTest.exist?(file)
|
24
|
+
raise ArgumentError, "no such file: %s" % file unless FileTest.exist?(file)
|
25
25
|
@gopts[:conf_file] = file
|
26
26
|
when "-v", "--version"
|
27
27
|
args.clear
|
data/lib/rbnotes/commands.rb
CHANGED
@@ -192,7 +192,7 @@ string could be used as an argument of some rbnotes commands, such
|
|
192
192
|
"2020-11-06" -> "20201106000000"
|
193
193
|
"20201106" -> "20201106000000"
|
194
194
|
"2020-11-06 16" -> "20201106160000"
|
195
|
-
"2020-11-06 16:51" -> "20201106165100"
|
195
|
+
"2020-11-06 16:51" -> "20201106165100"
|
196
196
|
STAMP
|
197
197
|
end
|
198
198
|
end
|
data/lib/rbnotes/commands/add.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Rbnotes::Commands
|
2
2
|
|
3
|
+
require "erb"
|
4
|
+
|
3
5
|
##
|
4
6
|
# Adds a new note to the repository. If no options, a new timestamp
|
5
7
|
# is generated at the execution time, then it is attached to the
|
@@ -16,15 +18,39 @@ module Rbnotes::Commands
|
|
16
18
|
# "202011041722" : year, date and time (omit second part)
|
17
19
|
# "11041722" : date and time (omit year and second part)
|
18
20
|
#
|
21
|
+
# Also accepts an option with `-f FILENAME` (or `--template-file`)
|
22
|
+
# to specify a template file which will be the initial content of a
|
23
|
+
# new note.
|
24
|
+
#
|
19
25
|
# This command starts the external editor program to prepare text to
|
20
26
|
# store. The editor program will be searched in the following order:
|
21
27
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
28
|
+
# 1. conf[:editor] (conf is the 1st arg of execute method)
|
29
|
+
# 2. ENV["EDITOR"]
|
30
|
+
# 3. "nano"
|
31
|
+
# 4. "vi"
|
26
32
|
#
|
27
33
|
# If none of the above editor is available, the command fails.
|
34
|
+
#
|
35
|
+
# TEMPLATE FILE:
|
36
|
+
#
|
37
|
+
# This command search a file as its template which will be the initial
|
38
|
+
# conent of a new note when an option or a setting in the configuration
|
39
|
+
# file (`:template`) is specified a template file.
|
40
|
+
#
|
41
|
+
# Or, even if neither an option nor a setting about a template file is
|
42
|
+
# specified, it always searches the default directory to read a template
|
43
|
+
# file. The directory is:
|
44
|
+
#
|
45
|
+
# - $XDG_CONIFG_HOME/rbnotes/templates (if $XDG_CONFIG_HOME is defined)
|
46
|
+
# or
|
47
|
+
# - $HOME/.config/rbnotes/templates
|
48
|
+
#
|
49
|
+
# If a file, `default.md` exists in the above directory, it will used as
|
50
|
+
# a template.
|
51
|
+
#
|
52
|
+
# A template file can be written in ERB syntax. See ERB manual to know
|
53
|
+
# about how to mix ruby code and text content in ERB syntax.
|
28
54
|
|
29
55
|
class Add < Command
|
30
56
|
|
@@ -34,22 +60,7 @@ module Rbnotes::Commands
|
|
34
60
|
|
35
61
|
def execute(args, conf)
|
36
62
|
@opts = {}
|
37
|
-
|
38
|
-
arg = args.shift
|
39
|
-
case arg
|
40
|
-
when "-t", "--timestamp"
|
41
|
-
stamp_str = args.shift
|
42
|
-
raise ArgumentError, "missing timestamp: %s" % args.unshift(arg) if stamp_str.nil?
|
43
|
-
stamp_str = complement_timestamp_pattern(stamp_str)
|
44
|
-
@opts[:timestamp] = Textrepo::Timestamp.parse_s(stamp_str)
|
45
|
-
when "-f", "--template-file"
|
46
|
-
template_path = args.shift
|
47
|
-
@opts[:template] = template_path
|
48
|
-
else
|
49
|
-
args.unshift(arg)
|
50
|
-
break
|
51
|
-
end
|
52
|
-
end
|
63
|
+
parse_opts(args)
|
53
64
|
|
54
65
|
stamp = @opts[:timestamp] || Textrepo::Timestamp.new(Time.now)
|
55
66
|
|
@@ -93,16 +104,26 @@ usage:
|
|
93
104
|
Add a new note to the repository. If no options, a new timestamp is
|
94
105
|
generated at the execution time, then it is attached to the note.
|
95
106
|
|
107
|
+
OPTIONS:
|
108
|
+
-t, --timestamp STAMP_PATTERN
|
109
|
+
-f, --template-file FILENAME
|
110
|
+
|
96
111
|
Accept an option with `-t STAMP_PATTERN` (or `--timestamp`), a
|
97
|
-
timestamp is generated according to `STAMP_PATTERN`.
|
112
|
+
timestamp of a new note is generated according to `STAMP_PATTERN`.
|
113
|
+
|
114
|
+
Also accepts an option with `-f FILENAME` (or `--template-file`) to
|
115
|
+
specify a template file which will be the initial content of a new
|
116
|
+
note. See below section more about a template file.
|
98
117
|
|
99
|
-
STAMP_PATTERN could be
|
118
|
+
STAMP_PATTERN could be:
|
100
119
|
|
101
120
|
"20201104172230_078" : full qualified timestamp string
|
102
121
|
"20201104172230" : full qualified timestamp string (no suffix)
|
103
122
|
"202011041722" : year, date and time (omit second part)
|
104
123
|
"11041722" : date and time (omit year and second part)
|
105
124
|
|
125
|
+
EDITOR:
|
126
|
+
|
106
127
|
This command starts the external editor program to prepare text to
|
107
128
|
store. The editor program will be searched in the following order:
|
108
129
|
|
@@ -112,11 +133,55 @@ store. The editor program will be searched in the following order:
|
|
112
133
|
4. "vi"
|
113
134
|
|
114
135
|
If none of the above editor is available, the execution fails.
|
136
|
+
|
137
|
+
TEMPLATE FILE:
|
138
|
+
|
139
|
+
This command search a file as its template which will be the initial
|
140
|
+
conent of a new note when an option or a setting in the configuration
|
141
|
+
file (`:template`) is specified a template file.
|
142
|
+
|
143
|
+
Or, even if neither an option nor a setting about a template file is
|
144
|
+
specified, it always searches the default directory to read a template
|
145
|
+
file. The directory is:
|
146
|
+
|
147
|
+
- $XDG_CONIFG_HOME/rbnotes/templates (if $XDG_CONFIG_HOME is defined)
|
148
|
+
|
149
|
+
or
|
150
|
+
|
151
|
+
- $HOME/.config/rbnotes/templates
|
152
|
+
|
153
|
+
If a file, `default.md` exists in the above directory, it will used as
|
154
|
+
a template.
|
155
|
+
|
156
|
+
A template file can be written in ERB syntax. See ERB manual to know
|
157
|
+
about how to mix ruby code and text content in ERB syntax.
|
158
|
+
|
115
159
|
HELP
|
116
160
|
end
|
117
161
|
|
118
162
|
# :stopdoc:
|
163
|
+
|
119
164
|
private
|
165
|
+
|
166
|
+
def parse_opts(args)
|
167
|
+
while args.size > 0
|
168
|
+
arg = args.shift
|
169
|
+
case arg
|
170
|
+
when "-t", "--timestamp"
|
171
|
+
stamp_str = args.shift
|
172
|
+
raise ArgumentError, "missing timestamp: %s" % args.unshift(arg) if stamp_str.nil?
|
173
|
+
stamp_str = complement_timestamp_pattern(stamp_str)
|
174
|
+
@opts[:timestamp] = Textrepo::Timestamp.parse_s(stamp_str)
|
175
|
+
when "-f", "--template-file"
|
176
|
+
template_path = args.shift
|
177
|
+
@opts[:template] = template_path
|
178
|
+
else
|
179
|
+
args.unshift(arg)
|
180
|
+
break
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
120
185
|
def complement_timestamp_pattern(pattern)
|
121
186
|
stamp_str = nil
|
122
187
|
case pattern.to_s.size
|
@@ -138,10 +203,15 @@ HELP
|
|
138
203
|
|
139
204
|
if template_path
|
140
205
|
raise Rbnotes::NoTemplateFileError, template_path unless FileTest.exist?(template_path)
|
141
|
-
template = File.readlines(template_path, chomp: true)
|
142
206
|
else
|
143
207
|
template_path = default_template_file(conf)
|
144
|
-
|
208
|
+
return nil unless FileTest.exist?(template_path)
|
209
|
+
end
|
210
|
+
|
211
|
+
erb_source = File.read(template_path)
|
212
|
+
if erb_source and !erb_source.empty?
|
213
|
+
erb = ERB.new(erb_source)
|
214
|
+
template = erb.result.split("\n")
|
145
215
|
end
|
146
216
|
|
147
217
|
template
|
@@ -12,18 +12,7 @@ module Rbnotes::Commands
|
|
12
12
|
|
13
13
|
def execute(args, conf)
|
14
14
|
@opts = {}
|
15
|
-
|
16
|
-
arg = args.shift
|
17
|
-
case arg.to_s
|
18
|
-
when "" # no options
|
19
|
-
break
|
20
|
-
when "-d", "--deve-commands"
|
21
|
-
@opts[:print_deve_commands] = true
|
22
|
-
else # invalid options or args
|
23
|
-
args.unshift(arg)
|
24
|
-
raise ArgumentError, "invalid option or argument: %s" % args.join(" ")
|
25
|
-
end
|
26
|
-
end
|
15
|
+
parse_opts(args)
|
27
16
|
|
28
17
|
puts commands(@opts[:print_deve_commands]).join(" ")
|
29
18
|
end
|
@@ -42,8 +31,24 @@ HELP
|
|
42
31
|
end
|
43
32
|
|
44
33
|
# :stopdoc:
|
34
|
+
|
45
35
|
private
|
46
36
|
|
37
|
+
def parse_opts(args)
|
38
|
+
while args.size > 0
|
39
|
+
arg = args.shift
|
40
|
+
case arg.to_s
|
41
|
+
when "" # no options
|
42
|
+
break
|
43
|
+
when "-d", "--deve-commands"
|
44
|
+
@opts[:print_deve_commands] = true
|
45
|
+
else # invalid options or args
|
46
|
+
args.unshift(arg)
|
47
|
+
raise ArgumentError, "invalid option or argument: %s" % args.join(" ")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
47
52
|
##
|
48
53
|
# Enumerates all command names.
|
49
54
|
#
|
@@ -29,16 +29,7 @@ module Rbnotes::Commands
|
|
29
29
|
|
30
30
|
def execute(args, conf)
|
31
31
|
@opts = {}
|
32
|
-
|
33
|
-
arg = args.shift
|
34
|
-
case arg
|
35
|
-
when "-m", "--use-mtime"
|
36
|
-
@opts[:use_mtime] = true
|
37
|
-
else
|
38
|
-
args.unshift(arg)
|
39
|
-
break
|
40
|
-
end
|
41
|
-
end
|
32
|
+
parse_opts(args)
|
42
33
|
|
43
34
|
file = args.shift
|
44
35
|
unless file.nil?
|
@@ -116,5 +107,25 @@ If birthtime is not available on the system, use mtime (modification
|
|
116
107
|
time).
|
117
108
|
HELP
|
118
109
|
end
|
110
|
+
|
111
|
+
# :stopdoc:
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def parse_opts(args)
|
116
|
+
while args.size > 0
|
117
|
+
arg = args.shift
|
118
|
+
case arg
|
119
|
+
when "-m", "--use-mtime"
|
120
|
+
@opts[:use_mtime] = true
|
121
|
+
else
|
122
|
+
args.unshift(arg)
|
123
|
+
break
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# :startdoc:
|
129
|
+
|
119
130
|
end
|
120
131
|
end
|
@@ -10,13 +10,16 @@ module Rbnotes::Commands
|
|
10
10
|
"List notes"
|
11
11
|
end
|
12
12
|
|
13
|
+
DEFAULT_BEHAVIOR = "today" # :nodoc:
|
14
|
+
|
13
15
|
##
|
14
16
|
# Shows a list of notes in the repository. Arguments are
|
15
17
|
# optional. If several args are passed, each of them must be a
|
16
18
|
# timestamp pattern or a keyword.
|
17
19
|
#
|
18
20
|
# Any order of timestamp patterns and keywords mixture is
|
19
|
-
# acceptable. The redundant patterns are just
|
21
|
+
# acceptable. The redundant patterns or invalid patterns are just
|
22
|
+
# ignored.
|
20
23
|
#
|
21
24
|
# A timestamp pattern is a string which would match several
|
22
25
|
# Timestamp objects. A timestamp is an instance of
|
@@ -54,38 +57,31 @@ module Rbnotes::Commands
|
|
54
57
|
|
55
58
|
def execute(args, conf)
|
56
59
|
@opts = {}
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
when "-v", "--verbose"
|
63
|
-
@opts[:verbose] = true
|
64
|
-
else
|
65
|
-
args.unshift(arg)
|
66
|
-
break
|
67
|
-
end
|
60
|
+
parse_opts(args)
|
61
|
+
|
62
|
+
if args.empty? and !@opts[:enum_week]
|
63
|
+
default_behavior = conf[:list_default] || DEFAULT_BEHAVIOR
|
64
|
+
args << default_behavior
|
68
65
|
end
|
69
66
|
|
70
67
|
utils = Rbnotes.utils
|
71
68
|
patterns = utils.read_timestamp_patterns(args, enum_week: @opts[:enum_week])
|
72
69
|
|
73
|
-
|
74
|
-
|
70
|
+
repo = Textrepo.init(conf)
|
71
|
+
stamps = utils.find_notes(patterns, repo)
|
75
72
|
output = []
|
76
73
|
if @opts[:verbose]
|
77
|
-
collect_timestamps_by_date(
|
74
|
+
collect_timestamps_by_date(stamps).each { |date, timestamps|
|
78
75
|
output << "#{date} (#{timestamps.size})"
|
79
76
|
timestamps.each { |timestamp|
|
80
77
|
pad = " "
|
81
78
|
output << utils.make_headline(timestamp,
|
82
|
-
|
79
|
+
repo.read(timestamp), pad)
|
83
80
|
}
|
84
81
|
}
|
85
82
|
else
|
86
|
-
|
87
|
-
output << utils.make_headline(timestamp,
|
88
|
-
@repo.read(timestamp))
|
83
|
+
stamps.each { |timestamp|
|
84
|
+
output << utils.make_headline(timestamp, repo.read(timestamp))
|
89
85
|
}
|
90
86
|
end
|
91
87
|
puts output
|
@@ -94,13 +90,22 @@ module Rbnotes::Commands
|
|
94
90
|
def help # :nodoc:
|
95
91
|
puts <<HELP
|
96
92
|
usage:
|
97
|
-
#{Rbnotes::NAME} list [
|
93
|
+
#{Rbnotes::NAME} list [OPTIONS] [STAMP_PATTERN|KEYWORD]
|
98
94
|
|
99
|
-
Show a list of notes. When
|
100
|
-
|
101
|
-
pattern are listed. Instead of STAMP_PATTERN, some KEYWORDs could be
|
95
|
+
Show a list of notes. When specified several STAMP_PATTERNs, only
|
96
|
+
those match the pattern are listed. Also, some KEYWORDs could be
|
102
97
|
used.
|
103
98
|
|
99
|
+
When no STAMP_PATTERN or KEYWORD was specified, the behavior of this
|
100
|
+
command could be specified with a configuration setting,
|
101
|
+
":list_default:". The value must be one of valid keywords. If no
|
102
|
+
settings was also given, this command would behave like "today" was
|
103
|
+
specified as the setting.
|
104
|
+
|
105
|
+
OPTIONS:
|
106
|
+
-v, --verbose
|
107
|
+
-w, --week
|
108
|
+
|
104
109
|
STAMP_PATTERN must be:
|
105
110
|
|
106
111
|
(a) full qualified timestamp (with suffix): "20201030160200"
|
@@ -118,6 +123,18 @@ KEYWORD:
|
|
118
123
|
- "this_month" (or "tm")
|
119
124
|
- "last_month" (or "lm")
|
120
125
|
|
126
|
+
An option "--verbose" is acceptable. It specifies to counts number of
|
127
|
+
notes by each day, then put it with the date before notes. It looks
|
128
|
+
like as follows:
|
129
|
+
|
130
|
+
2021-04-19 (3)
|
131
|
+
20210419134222: Foo
|
132
|
+
20210419120235: Bar
|
133
|
+
20210419110057: Baz
|
134
|
+
2021-04-18 (1)
|
135
|
+
20210418125353: Hoge
|
136
|
+
:
|
137
|
+
|
121
138
|
An option "--week" is also acceptable. It specifies to enumerate all
|
122
139
|
days of a week. Typically, the option is used with a STAMP_PATTERN
|
123
140
|
which specifies a date, such "20201117", then it enumerates all days
|
@@ -135,6 +152,21 @@ HELP
|
|
135
152
|
|
136
153
|
private
|
137
154
|
|
155
|
+
def parse_opts(args)
|
156
|
+
while args.size > 0
|
157
|
+
arg = args.shift
|
158
|
+
case arg
|
159
|
+
when "-w", "--week"
|
160
|
+
@opts[:enum_week] = true
|
161
|
+
when "-v", "--verbose"
|
162
|
+
@opts[:verbose] = true
|
163
|
+
else
|
164
|
+
args.unshift(arg)
|
165
|
+
break
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
138
170
|
def collect_timestamps_by_date(timestamps)
|
139
171
|
result = {}
|
140
172
|
timestamps.map { |ts|
|
@@ -9,27 +9,28 @@ module Rbnotes::Commands
|
|
9
9
|
"Pick a timestamp with a picker program"
|
10
10
|
end
|
11
11
|
|
12
|
+
DEFAULT_BEHAVIOR = "today" # :nodoc:
|
13
|
+
|
12
14
|
def execute(args, conf)
|
13
15
|
@opts = {}
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
args.unshift(arg)
|
21
|
-
break
|
22
|
-
end
|
16
|
+
parse_opts(args)
|
17
|
+
|
18
|
+
if args.empty?
|
19
|
+
default_behavior = conf[:list_default] || DEFAULT_BEHAVIOR
|
20
|
+
args << default_behavior
|
23
21
|
end
|
24
22
|
|
25
23
|
utils = Rbnotes.utils
|
26
24
|
patterns = utils.read_timestamp_patterns(args, enum_week: @opts[:enum_week])
|
27
25
|
|
28
|
-
|
26
|
+
repo = Textrepo.init(conf)
|
27
|
+
|
28
|
+
stamps = utils.find_notes(patterns, repo)
|
29
|
+
return if stamps.empty?
|
29
30
|
|
30
31
|
list = []
|
31
|
-
|
32
|
-
list << utils.make_headline(timestamp,
|
32
|
+
stamps.each { |timestamp|
|
33
|
+
list << utils.make_headline(timestamp, repo.read(timestamp))
|
33
34
|
}
|
34
35
|
|
35
36
|
picker = conf[:picker]
|
@@ -61,5 +62,25 @@ is specified, it will behave as same as "list" command.
|
|
61
62
|
|
62
63
|
HELP
|
63
64
|
end
|
65
|
+
|
66
|
+
# :stopdoc:
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def parse_opts(args)
|
71
|
+
while args.size > 0
|
72
|
+
arg = args.shift
|
73
|
+
case arg
|
74
|
+
when "-w", "--week"
|
75
|
+
@opts[:enum_week] = true
|
76
|
+
else
|
77
|
+
args.unshift(arg)
|
78
|
+
break
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# :startdoc:
|
84
|
+
|
64
85
|
end
|
65
86
|
end
|
@@ -1,17 +1,16 @@
|
|
1
1
|
module Rbnotes::Commands
|
2
2
|
|
3
3
|
##
|
4
|
-
# Shows the content of the notes specified by arguments.
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# Shows the content of the notes specified by arguments. Arguments
|
5
|
+
# should be timestamp patterns or keywords. See the document for
|
6
|
+
# the `list` command to know about such arguments.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# "20201106112600" : year, date, time and sec
|
11
|
-
# "20201106112600_012" : with suffix
|
8
|
+
# Accepts an option with `-n NUMBER` (or `--num-of-lines`), to show
|
9
|
+
# the first NUMBER lines of the content of each note.
|
12
10
|
#
|
13
11
|
# If no argument is passed, reads the standard input for arguments.
|
14
|
-
|
12
|
+
# If a specified timestamp does not exist in the repository as a key,
|
13
|
+
# Rbnotes::MissingTimestampError will occur.
|
15
14
|
class Show < Command
|
16
15
|
|
17
16
|
def description # :nodoc:
|
@@ -19,13 +18,30 @@ module Rbnotes::Commands
|
|
19
18
|
end
|
20
19
|
|
21
20
|
def execute(args, conf)
|
22
|
-
|
21
|
+
@opts = {}
|
22
|
+
parse_opts(args)
|
23
|
+
|
23
24
|
repo = Textrepo.init(conf)
|
25
|
+
stamps = read_timestamps(args, repo)
|
26
|
+
return if stamps.empty?
|
27
|
+
|
28
|
+
content = stamps.map { |stamp|
|
29
|
+
begin
|
30
|
+
text = repo.read(stamp)
|
31
|
+
rescue Textrepo::MissingTimestampError => _
|
32
|
+
raise Rbnotes::MissingTimestampError, stamp
|
33
|
+
end
|
24
34
|
|
25
|
-
|
35
|
+
lines = text.size
|
36
|
+
if @opts[:num_of_lines].to_i > 0
|
37
|
+
lines = [@opts[:num_of_lines], lines].min
|
38
|
+
end
|
39
|
+
|
40
|
+
[stamp, text[0, lines]]
|
41
|
+
}.to_h
|
26
42
|
|
27
43
|
pager = conf[:pager]
|
28
|
-
unless pager.nil?
|
44
|
+
unless pager.nil? or @opts[:raw]
|
29
45
|
puts_with_pager(pager, make_output(content))
|
30
46
|
else
|
31
47
|
puts make_output(content)
|
@@ -35,10 +51,22 @@ module Rbnotes::Commands
|
|
35
51
|
def help # :nodoc:
|
36
52
|
puts <<HELP
|
37
53
|
usage:
|
38
|
-
#{Rbnotes::NAME} show [
|
54
|
+
#{Rbnotes::NAME} show [OPTIONS] [STAMP_PATTERN|KEYWORD...]
|
55
|
+
|
56
|
+
Show the content of given notes. It accepts timestamp patterns and
|
57
|
+
keywords like the `list` (or `pick`) command. See the help for the
|
58
|
+
`list` command to know more about stamp patterns and keywords.
|
59
|
+
|
60
|
+
OPTIONS:
|
61
|
+
-n, --num-of-lines NUMBER
|
62
|
+
-r, --raw
|
63
|
+
|
64
|
+
Accept an option with `-n NUMBER` (or `--num-of-lines`), to show the
|
65
|
+
first NUMBER lines of the content of each note.
|
39
66
|
|
40
|
-
|
41
|
-
|
67
|
+
Also accepts `-r` (or `--raw`) option to specify to use "raw" output,
|
68
|
+
which means no use any pager, no apply to any process to make output.
|
69
|
+
The behavior is intended to be used within a pipeline.
|
42
70
|
|
43
71
|
The command try to read its argument from the standard input when no
|
44
72
|
argument was passed in the command line.
|
@@ -49,6 +77,38 @@ HELP
|
|
49
77
|
|
50
78
|
private
|
51
79
|
|
80
|
+
def parse_opts(args)
|
81
|
+
while args.size > 0
|
82
|
+
arg = args.shift
|
83
|
+
case arg
|
84
|
+
when "-n", "--num-of-lines"
|
85
|
+
num_of_lines = args.shift
|
86
|
+
raise ArgumentError, "missing number: %s" % args.unshift(arg) if num_of_lines.nil?
|
87
|
+
|
88
|
+
num_of_lines = num_of_lines.to_i
|
89
|
+
raise ArgumentError, "illegal number (must be greater than 0): %d" % num_of_lines unless num_of_lines > 0
|
90
|
+
|
91
|
+
@opts[:num_of_lines] = num_of_lines
|
92
|
+
when "-r", "--raw"
|
93
|
+
@opts[:raw] = true
|
94
|
+
else
|
95
|
+
args.unshift(arg)
|
96
|
+
break
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def read_timestamps(args, repo)
|
102
|
+
utils = Rbnotes.utils
|
103
|
+
if args.empty?
|
104
|
+
stamps = utils.read_multiple_timestamps(args)
|
105
|
+
else
|
106
|
+
patterns = utils.read_timestamp_patterns(args)
|
107
|
+
stamps = utils.find_notes(patterns, repo)
|
108
|
+
end
|
109
|
+
stamps
|
110
|
+
end
|
111
|
+
|
52
112
|
def puts_with_pager(pager, output)
|
53
113
|
require "open3"
|
54
114
|
Open3.pipeline_w(pager) { |stdin|
|
@@ -66,7 +126,7 @@ HELP
|
|
66
126
|
|
67
127
|
_, column = IO.console_size
|
68
128
|
output = content.map { |timestamp, text|
|
69
|
-
ary = [make_heading(timestamp,
|
129
|
+
ary = [make_heading(timestamp, column - 10)]
|
70
130
|
ary.concat(text)
|
71
131
|
ary
|
72
132
|
}
|
@@ -9,20 +9,14 @@ module Rbnotes::Commands
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def execute(args, conf)
|
12
|
+
@opts = {}
|
13
|
+
parse_opts(args)
|
14
|
+
|
12
15
|
report = :total
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
report = :yearly
|
18
|
-
break
|
19
|
-
when "-m", "--monthly"
|
20
|
-
report = :monthly
|
21
|
-
break
|
22
|
-
else
|
23
|
-
args.unshift(arg)
|
24
|
-
raise ArgumentError, "invalid option or argument: %s" % args.join(" ")
|
25
|
-
end
|
16
|
+
if @opts[:yearly]
|
17
|
+
report = :yearly
|
18
|
+
elsif @opts[:monthly]
|
19
|
+
report = :monthly
|
26
20
|
end
|
27
21
|
|
28
22
|
stats = Rbnotes::Statistics.new(conf)
|
@@ -51,5 +45,30 @@ In the version #{Rbnotes::VERSION}, only number of notes is supported.
|
|
51
45
|
HELP
|
52
46
|
end
|
53
47
|
|
48
|
+
# :stopdoc:
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def parse_opts(args)
|
53
|
+
while args.size > 0
|
54
|
+
arg = args.shift
|
55
|
+
case arg
|
56
|
+
when "-y", "--yearly"
|
57
|
+
@opts[:yearly] = true
|
58
|
+
@opts[:monthly] = false
|
59
|
+
break
|
60
|
+
when "-m", "--monthly"
|
61
|
+
@opts[:yearly] = false
|
62
|
+
@opts[:monthly] = true
|
63
|
+
break
|
64
|
+
else
|
65
|
+
args.unshift(arg)
|
66
|
+
raise ArgumentError, "invalid option or argument: %s" % args.join(" ")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# :startdoc:
|
72
|
+
|
54
73
|
end
|
55
74
|
end
|
@@ -32,16 +32,7 @@ module Rbnotes::Commands
|
|
32
32
|
|
33
33
|
def execute(args, conf)
|
34
34
|
@opts = {}
|
35
|
-
|
36
|
-
arg = args.shift
|
37
|
-
case arg
|
38
|
-
when "-k", "--keep"
|
39
|
-
@opts[:keep_timestamp] = true
|
40
|
-
else
|
41
|
-
args.unshift(arg)
|
42
|
-
break
|
43
|
-
end
|
44
|
-
end
|
35
|
+
parse_opts(args)
|
45
36
|
|
46
37
|
target_stamp = Rbnotes.utils.read_timestamp(args)
|
47
38
|
editor = Rbnotes.utils.find_editor(conf[:editor])
|
@@ -100,5 +91,25 @@ editor program will be searched as same as add command. If none of
|
|
100
91
|
editors is available, the execution fails.
|
101
92
|
HELP
|
102
93
|
end
|
94
|
+
|
95
|
+
# :stopdoc:
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def parse_opts(args)
|
100
|
+
while args.size > 0
|
101
|
+
arg = args.shift
|
102
|
+
case arg
|
103
|
+
when "-k", "--keep"
|
104
|
+
@opts[:keep_timestamp] = true
|
105
|
+
else
|
106
|
+
args.unshift(arg)
|
107
|
+
break
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# :startdoc:
|
113
|
+
|
103
114
|
end
|
104
115
|
end
|
data/lib/rbnotes/utils.rb
CHANGED
@@ -103,6 +103,19 @@ module Rbnotes
|
|
103
103
|
tmpfile
|
104
104
|
end
|
105
105
|
|
106
|
+
# Acceptable delimiters to separate a timestamp string for human
|
107
|
+
# being to read and input easily.
|
108
|
+
#
|
109
|
+
# Here is some examples:
|
110
|
+
#
|
111
|
+
# - "2021-04-15 15:34:56" -> "20210415153456" (a timestamp string)
|
112
|
+
# - "2020-04-15_15:34:56" -> (same as above)
|
113
|
+
# - "2020-04-15-15-34-56" -> (same as above)
|
114
|
+
# - "2020 04 15 15 34 56" -> (same as above)
|
115
|
+
# - "2020-04-15" -> "20200415" (a timestamp pattern)
|
116
|
+
|
117
|
+
TIMESTAMP_DELIMITERS = /[-:_\s]/
|
118
|
+
|
106
119
|
##
|
107
120
|
# Generates a Textrepo::Timestamp object from a String which comes
|
108
121
|
# from the command line arguments. When no argument is given,
|
@@ -114,6 +127,8 @@ module Rbnotes
|
|
114
127
|
def read_timestamp(args)
|
115
128
|
str = args.shift || read_arg($stdin)
|
116
129
|
raise NoArgumentError if str.nil?
|
130
|
+
|
131
|
+
str = remove_delimiters_from_timestamp_string(str)
|
117
132
|
Textrepo::Timestamp.parse_s(str)
|
118
133
|
end
|
119
134
|
|
@@ -135,7 +150,10 @@ module Rbnotes
|
|
135
150
|
def read_multiple_timestamps(args)
|
136
151
|
strings = args.size < 1 ? read_multiple_args($stdin) : args
|
137
152
|
raise NoArgumentError if (strings.nil? || strings.empty?)
|
138
|
-
strings.uniq.map { |str|
|
153
|
+
strings.uniq.map { |str|
|
154
|
+
str = remove_delimiters_from_timestamp_string(str)
|
155
|
+
Textrepo::Timestamp.parse_s(str)
|
156
|
+
}
|
139
157
|
end
|
140
158
|
|
141
159
|
##
|
@@ -147,11 +165,15 @@ module Rbnotes
|
|
147
165
|
def read_timestamp_patterns(args, enum_week: false)
|
148
166
|
patterns = nil
|
149
167
|
if enum_week
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
168
|
+
args.unshift(Time.now.strftime("%Y%m%d")) if args.size == 0
|
169
|
+
patterns = []
|
170
|
+
while args.size > 0
|
171
|
+
arg = args.shift
|
172
|
+
begin
|
173
|
+
patterns.concat(timestamp_patterns_in_week(arg.dup))
|
174
|
+
rescue InvalidTimestampPatternAsDateError => _e
|
175
|
+
raise InvalidTimestampPatternAsDateError, args.unshift(arg)
|
176
|
+
end
|
155
177
|
end
|
156
178
|
else
|
157
179
|
patterns = expand_keyword_in_args(args)
|
@@ -174,7 +196,13 @@ module Rbnotes
|
|
174
196
|
# timestamp_patterns_in_week(String) -> [Array of Strings]
|
175
197
|
#
|
176
198
|
def timestamp_patterns_in_week(arg)
|
177
|
-
date_str =
|
199
|
+
date_str = nil
|
200
|
+
|
201
|
+
if arg
|
202
|
+
date_str = remove_delimiters_from_timestamp_string(arg)
|
203
|
+
else
|
204
|
+
date_str = Textrepo::Timestamp.now[0, 8]
|
205
|
+
end
|
178
206
|
|
179
207
|
case date_str.size
|
180
208
|
when "yyyymodd".size
|
@@ -220,23 +248,24 @@ module Rbnotes
|
|
220
248
|
# - "last_week" (or "lw")
|
221
249
|
# - "this_month" (or "tm")
|
222
250
|
# - "last_month" (or "lm")
|
251
|
+
# - "all"
|
223
252
|
#
|
224
253
|
# :call-seq:
|
225
254
|
# expand_keyword_in_args(Array of Strings) -> Array of Strings
|
226
255
|
#
|
227
256
|
def expand_keyword_in_args(args)
|
228
|
-
return [nil] if args.empty?
|
229
|
-
|
230
257
|
patterns = []
|
231
258
|
while args.size > 0
|
232
259
|
arg = args.shift
|
233
|
-
if
|
260
|
+
if arg == "all"
|
261
|
+
return [nil]
|
262
|
+
elsif KEYWORDS.include?(arg)
|
234
263
|
patterns.concat(expand_keyword(arg))
|
235
264
|
else
|
236
265
|
patterns << arg
|
237
266
|
end
|
238
267
|
end
|
239
|
-
patterns.sort
|
268
|
+
patterns.uniq.sort
|
240
269
|
end
|
241
270
|
|
242
271
|
##
|
@@ -322,6 +351,15 @@ module Rbnotes
|
|
322
351
|
}.compact
|
323
352
|
end
|
324
353
|
|
354
|
+
def remove_delimiters_from_timestamp_string(stamp_str) # :nodoc:
|
355
|
+
str = stamp_str.gsub(TIMESTAMP_DELIMITERS, "")
|
356
|
+
base_size = "yyyymiddhhmoss".size
|
357
|
+
if str.size > base_size # when suffix is specified
|
358
|
+
str = str[0...base_size] + "_" + str[base_size..-1]
|
359
|
+
end
|
360
|
+
str
|
361
|
+
end
|
362
|
+
|
325
363
|
##
|
326
364
|
# Expands a keyword to timestamp strings.
|
327
365
|
#
|
data/lib/rbnotes/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbnotes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mnbi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: textrepo
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
108
|
requirements: []
|
109
|
-
rubygems_version: 3.2.
|
109
|
+
rubygems_version: 3.2.15
|
110
110
|
signing_key:
|
111
111
|
specification_version: 4
|
112
112
|
summary: A simple utility to write a note.
|