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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55b7ddb12d306be2cb815400d4e729deff8badfbde55ede0f9edba78c380eb44
4
- data.tar.gz: ae0720108810db518693959f3a8faf20c7ca985d6aaf3c39bac94327d45f25db
3
+ metadata.gz: 8a831d67abfd0bae05156f047b6baf44428bc4940058e43bfb9825b5d91c4177
4
+ data.tar.gz: 7fb70e39e9feb75edfabe3461697ddfb0145cf449205c25068471687952908d0
5
5
  SHA512:
6
- metadata.gz: 8fc47bdc0c93bc964714c89d791655f1d385de0dfbf6af5202ec18c17f1be951efb02fcd4d9b0ac9b298cbb163e8a9e836a5c4d752bf9bad5299cc0d38983463
7
- data.tar.gz: d2a3db96531609429775b9caf32308691afc6023ffaf2d8aae39df3d763e99b497a3efe763e821033ab725240e925ddd23a5385dac15d0a3bd5f3cb9f7c23ac1
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbnotes (0.4.13)
4
+ rbnotes (0.4.18)
5
5
  textrepo (~> 0.5.8)
6
6
  unicode-display_width (~> 1.7)
7
7
 
@@ -23,4 +23,4 @@ DEPENDENCIES
23
23
  textrepo (~> 0.5.8)
24
24
 
25
25
  BUNDLED WITH
26
- 2.2.3
26
+ 2.2.15
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Rbnotes
2
2
 
3
3
  [![Build Status](https://github.com/mnbi/rbnotes/workflows/Build/badge.svg)](https://github.com/mnbi/rbnotes/actions?query=workflow%3A"Build")
4
+ [![CodeFactor](https://www.codefactor.io/repository/github/mnbi/rbnotes/badge)](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
@@ -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
@@ -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
- # 1. conf[:editor] (conf is the 1st arg of execute method)
23
- # 2. ENV["EDITOR"]
24
- # 3. "nano"
25
- # 4. "vi"
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
- while args.size > 0
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 one of followings:
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
- template = File.readlines(template_path, chomp: true) if FileTest.exist?(template_path)
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
- while args.size > 0
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
- while args.size > 0
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 ignored.
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
- while args.size > 0
58
- arg = args.shift
59
- case arg
60
- when "-w", "--week"
61
- @opts[:enum_week] = true
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
- @repo = Textrepo.init(conf)
74
- notes = utils.find_notes(patterns, @repo)
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(notes).each { |date, timestamps|
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
- @repo.read(timestamp), pad)
79
+ repo.read(timestamp), pad)
83
80
  }
84
81
  }
85
82
  else
86
- notes.each { |timestamp|
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 [-w|--week][STAMP_PATTERN|KEYWORD]
93
+ #{Rbnotes::NAME} list [OPTIONS] [STAMP_PATTERN|KEYWORD]
98
94
 
99
- Show a list of notes. When no arguments, make a list with all notes
100
- in the repository. When specified STAMP_PATTERN, only those match the
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
- while args.size > 0
15
- arg = args.shift
16
- case arg
17
- when "-w", "--week"
18
- @opts[:enum_week] = true
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
- @repo = Textrepo.init(conf)
26
+ repo = Textrepo.init(conf)
27
+
28
+ stamps = utils.find_notes(patterns, repo)
29
+ return if stamps.empty?
29
30
 
30
31
  list = []
31
- utils.find_notes(patterns, @repo).each { |timestamp|
32
- list << utils.make_headline(timestamp, @repo.read(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. Each
5
- # argument must be a string which can be converted into
6
- # Textrepo::Timestamp object.
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
- # A string for Textrepo::Timestamp must be:
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
- stamps = Rbnotes.utils.read_multiple_timestamps(args)
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
- content = stamps.map { |stamp| [stamp, repo.read(stamp)] }.to_h
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 [TIMESTAMP...]
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
- Show the content of given notes. TIMESTAMP must be a fully qualified
41
- one, such "20201016165130" or "20201016165130_012" if it has a suffix.
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, [column, 72].min)]
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
- while args.size > 0
14
- arg = args.shift
15
- case arg
16
- when "-y", "--yearly"
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
- while args.size > 0
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| Textrepo::Timestamp.parse_s(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
- arg = args.shift
151
- begin
152
- patterns = timestamp_patterns_in_week(arg.dup)
153
- rescue InvalidTimestampPatternAsDateError => _e
154
- raise InvalidTimestampPatternAsDateError, args.unshift(arg)
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 = arg || Textrepo::Timestamp.now[0, 8]
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 KEYWORDS.include?(arg)
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.uniq
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
  #
@@ -1,4 +1,4 @@
1
1
  module Rbnotes
2
- VERSION = "0.4.13"
3
- RELEASE = "2021-03-30"
2
+ VERSION = "0.4.18"
3
+ RELEASE = "2021-04-29"
4
4
  end
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.13
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-03-30 00:00:00.000000000 Z
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.3
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.