gm-notepad 0.0.4 → 0.0.5
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/README.md +20 -17
- data/Rakefile +1 -1
- data/exe/gm-notepad +1 -16
- data/lib/gm/notepad/configuration.rb +130 -0
- data/lib/gm/notepad/input_handlers/comment_handler.rb +2 -2
- data/lib/gm/notepad/input_processor.rb +2 -26
- data/lib/gm/notepad/line_evaluator.rb +3 -1
- data/lib/gm/notepad/line_renderer.rb +4 -33
- data/lib/gm/notepad/pad.rb +5 -44
- data/lib/gm/notepad/readline.rb +5 -0
- data/lib/gm/notepad/table.rb +2 -4
- data/lib/gm/notepad/table_entry.rb +1 -4
- data/lib/gm/notepad/table_registry.rb +10 -20
- data/lib/gm/notepad/version.rb +1 -1
- data/lib/gm/notepad.rb +3 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf576a76ad9f5f2c4676b9a14d9f3557eeddddf74e2050ebc17a97e3d9f65f65
|
4
|
+
data.tar.gz: 81b1342b09f2321b1efa7dbd3b53acedc21303d27ce8bdb2b3e56888805b896c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78d7865d2e222c20e8acb490637b0442426bad4fb9d739cfb32bbb1f4c283ac92ca5037e96ec80b58bb8bdab55ad48b7dd3d699ac5b28f1817bdc86e4b6cb696
|
7
|
+
data.tar.gz: 00262af2d6920303a49c22946cf7224f8e09e6b0bfe8da2275ae283ce097079256e61574e3bb00f19c17dd48fe0d13aa4a4fd06d85ad0028806cf3661924edd2
|
data/README.md
CHANGED
@@ -43,8 +43,6 @@ line and render it to one or more of the buffers.
|
|
43
43
|
|
44
44
|
## Examples
|
45
45
|
|
46
|
-
### Simple Help
|
47
|
-
|
48
46
|
First, take a look at the help: `$ gm-notepad -h`
|
49
47
|
|
50
48
|
```console
|
@@ -100,10 +98,10 @@ glob: `./**/*.txt`.
|
|
100
98
|
|
101
99
|
Included in the gem's test suite are four files:
|
102
100
|
|
103
|
-
*
|
104
|
-
*
|
105
|
-
*
|
106
|
-
*
|
101
|
+
* ./spec/fixtures/name.txt
|
102
|
+
* ./spec/fixtures/first-name.txt
|
103
|
+
* ./spec/fixtures/last-name.txt
|
104
|
+
* ./spec/fixtures/location.csv
|
107
105
|
|
108
106
|
When I run `gm-notepad -l`, `gm-notepad` does the following:
|
109
107
|
|
@@ -209,34 +207,39 @@ entry has a 1 in 3 chance of being randomly chosen.
|
|
209
207
|
- [X] Colorize puts to `interactive` buffer
|
210
208
|
- [X] Disable colors as a configuration option
|
211
209
|
- [ ] Write expected interface document
|
212
|
-
- [ ]
|
210
|
+
- [ ] Allow `{critical[2d6+1]}` to roll the dice then lookup the value in the critical table
|
211
|
+
- [X] Skip table lines that begin with `#`
|
213
212
|
- [X] Skip processing input lines that begin with `#`
|
214
|
-
- [ ] Allow configuration to specify colors
|
215
213
|
- [X] Allow configuration to specify table delimiter
|
216
|
-
- [ ] Allow option to add a table to memory (instead of writing the table)
|
217
214
|
- [ ] Add option to dump all tables to the given directory
|
218
215
|
- [X] Allow configuration for where to dump data
|
219
216
|
- [ ] Normalize `WriteToTableHandler` to use a renderer
|
220
217
|
- [ ] Normalize `WriteToTableHandler` to deliver on `grep` and `index` behavior
|
221
218
|
- [X] Gracefully handle requesting an entry from a table with an index that does not exist (e.g. with test data try `+name[23]`)
|
222
219
|
- [X] Gracefully handle `+name[]`, where "name" is a registered table
|
223
|
-
- [ ] Add time to live for line expansion (to prevent infinite loops)
|
220
|
+
- [ ] Add time to live for line expansion (to prevent infinite loops); I suspect 100 to be reasonable
|
224
221
|
- [X] Enable "up" and "down" to scroll through history
|
225
222
|
- [ ] Add config that expands dice results while including the requested roll
|
226
|
-
- [ ] Determine feasibility of adding dice to the `{}` expansion syntax (instead of the `[]` syntax)
|
227
223
|
- [X] Add index name when rendering table entries
|
228
224
|
- [ ] Gracefully handle loading a malformed data file (maybe?)
|
229
225
|
- [ ] Add force write results to `output`
|
230
226
|
- [X] Add concept of history
|
231
227
|
- [ ] When expanding tables account for line expansion (via \n and \t)
|
232
228
|
- [ ] Separate the InputHandler into pre-amble (e.g. allow overrides to where we are writing, determine what command we are writing)
|
229
|
+
- [X] Create a configuration object that captures the initial input (reduce passing around parameters and persisting copies of the config)
|
230
|
+
- [ ] Add concept of "journal entry"; its not a table (perhaps) but something that you could capture notes.
|
231
|
+
- [ ] Add column handling `{table[][]}`
|
232
|
+
- [X] Support `\{\{table}-name}` You should be able to do `\{\{culture}-name}` and first evaluate to `{arabic-name}` and then get a value from the `arabic-name` table
|
233
|
+
- [X] Ensure index names are lower-case
|
234
|
+
- [ ] Hit 100% spec coverage
|
235
|
+
|
236
|
+
### Stretch TODO
|
237
|
+
|
233
238
|
- [ ] Handle a `.gm-notepadrc` to inject default configurations
|
239
|
+
- [ ] Allow configuration to specify colors
|
240
|
+
- [ ] Aspiration: Enable `\{\{monster}[ac]}` to pick a random monster and then fetch that monster's AC
|
241
|
+
- [ ] Allow option to add a table to memory (instead of writing the table)
|
234
242
|
- [ ] Add auto table expansion for "{}"
|
235
243
|
- [ ] Add auto table expansion for "+"
|
236
244
|
- [ ] Add auto index expansion for "["
|
237
|
-
- [ ]
|
238
|
-
- [ ] Aspiration: Enable `{{monster}[ac]}` to pick a random monster and then fetch that monster's AC
|
239
|
-
- [ ] Add concept of "journal entry"; its not a table (perhaps) but something that you could capture notes.
|
240
|
-
- [ ] Add column handling `{table[][]}`
|
241
|
-
- [X] Support `{{table}-name}` You should be able to do `{{culture}-name}` and first evaluate to `{arabic-name}` and then get a value from the `arabic-name` table
|
242
|
-
- [X] Ensure index names are lower-case
|
245
|
+
- [ ] Determine feasibility of adding dice to the `{}` expansion syntax (instead of the `[]` syntax)
|
data/Rakefile
CHANGED
@@ -17,7 +17,7 @@ namespace :commitment do
|
|
17
17
|
lastrun_filename = File.expand_path('../coverage/.last_run.json', __FILE__)
|
18
18
|
if File.exist?(lastrun_filename)
|
19
19
|
coverage_percentage = JSON.parse(File.read(lastrun_filename)).fetch('result').fetch('covered_percent').to_i
|
20
|
-
EXPECTED_COVERAGE_GOAL =
|
20
|
+
EXPECTED_COVERAGE_GOAL = 97
|
21
21
|
if coverage_percentage < EXPECTED_COVERAGE_GOAL
|
22
22
|
abort("ERROR: Code Coverage Goal Not Met:\n\t#{coverage_percentage}%\tExpected\n\t#{EXPECTED_COVERAGE_GOAL}%\tActual")
|
23
23
|
else
|
data/exe/gm-notepad
CHANGED
@@ -2,22 +2,7 @@
|
|
2
2
|
require 'gm/notepad'
|
3
3
|
|
4
4
|
require 'optparse'
|
5
|
-
config =
|
6
|
-
report_config: false,
|
7
|
-
defer_output: false,
|
8
|
-
filesystem_directory: '.',
|
9
|
-
interactive_buffer: $stderr,
|
10
|
-
interactive_color: true,
|
11
|
-
output_color: false,
|
12
|
-
list_tables: false,
|
13
|
-
output_buffer: $stdout,
|
14
|
-
paths: ['.'],
|
15
|
-
column_delimiter: Gm::Notepad::DEFAULT_COLUMN_DELIMITER,
|
16
|
-
shell_prompt: Gm::Notepad::DEFAULT_SHELL_PROMPT,
|
17
|
-
skip_readlines: false,
|
18
|
-
table_extension: '.txt',
|
19
|
-
with_timestamp: false
|
20
|
-
}
|
5
|
+
config = Gm::Notepad::Configuration::CLI_CONFIG_DEFAULTS.clone
|
21
6
|
|
22
7
|
command_name = File.basename(__FILE__)
|
23
8
|
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'gm/notepad/defaults'
|
2
|
+
module Gm
|
3
|
+
module Notepad
|
4
|
+
# Global configuration values
|
5
|
+
class Configuration
|
6
|
+
CLI_CONFIG_DEFAULTS = {
|
7
|
+
report_config: false,
|
8
|
+
defer_output: false,
|
9
|
+
filesystem_directory: '.',
|
10
|
+
interactive_buffer: $stderr,
|
11
|
+
interactive_color: true,
|
12
|
+
output_color: false,
|
13
|
+
list_tables: false,
|
14
|
+
output_buffer: $stdout,
|
15
|
+
paths: ['.'],
|
16
|
+
column_delimiter: Gm::Notepad::DEFAULT_COLUMN_DELIMITER,
|
17
|
+
shell_prompt: Gm::Notepad::DEFAULT_SHELL_PROMPT,
|
18
|
+
skip_readlines: false,
|
19
|
+
table_extension: '.txt',
|
20
|
+
with_timestamp: false
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
# NOTE: ORDER MATTERS! I have a temporal dependency in these
|
24
|
+
# defaults
|
25
|
+
INTERNAL_CONFIG_DEFAULTS_METHOD_NAMES = [
|
26
|
+
:table_registry,
|
27
|
+
:input_handler_registry,
|
28
|
+
:input_processor,
|
29
|
+
:renderer,
|
30
|
+
]
|
31
|
+
|
32
|
+
def self.init!(target:, from_config: [], additional_params: [], &block)
|
33
|
+
# Need to rebind the parameter
|
34
|
+
_additional_params = additional_params
|
35
|
+
target.define_method(:initialize) do |config: nil, **params|
|
36
|
+
@config = config || CLI_CONFIG_DEFAULTS
|
37
|
+
from_config.each do |method_name|
|
38
|
+
send("#{method_name}=", @config[method_name])
|
39
|
+
end
|
40
|
+
_additional_params.each do |key|
|
41
|
+
send("#{key}=", params.fetch(key))
|
42
|
+
end
|
43
|
+
instance_exec(&block) if block
|
44
|
+
end
|
45
|
+
from_config.each do |method_name|
|
46
|
+
target.module_exec do
|
47
|
+
attr_accessor(method_name)
|
48
|
+
protected "#{method_name}="
|
49
|
+
end
|
50
|
+
end
|
51
|
+
_additional_params.each do |method_name|
|
52
|
+
target.module_exec do
|
53
|
+
attr_accessor(method_name)
|
54
|
+
protected "#{method_name}="
|
55
|
+
end
|
56
|
+
end
|
57
|
+
target.attr_reader :config
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(input_handler_registry: nil, table_registry: nil, renderer: nil, input_processor: nil, **overrides)
|
61
|
+
CLI_CONFIG_DEFAULTS.each_pair do |key, default_value|
|
62
|
+
value = overrides.fetch(key, default_value)
|
63
|
+
if !value.is_a?(IO)
|
64
|
+
value = value.clone
|
65
|
+
value.freeze
|
66
|
+
end
|
67
|
+
self.send("#{key}=", value)
|
68
|
+
end
|
69
|
+
self.table_registry = (table_registry || default_table_registry)
|
70
|
+
self.input_handler_registry = (input_handler_registry || default_input_handler_registry)
|
71
|
+
self.renderer = (renderer || default_renderer)
|
72
|
+
self.input_processor = (input_processor || default_input_processor)
|
73
|
+
end
|
74
|
+
attr_reader(*CLI_CONFIG_DEFAULTS.keys)
|
75
|
+
attr_reader(*INTERNAL_CONFIG_DEFAULTS_METHOD_NAMES)
|
76
|
+
|
77
|
+
def to_hash
|
78
|
+
config = CLI_CONFIG_DEFAULTS.keys.each_with_object({}) do |key, mem|
|
79
|
+
mem[key] = send(key)
|
80
|
+
end
|
81
|
+
INTERNAL_CONFIG_DEFAULTS_METHOD_NAMES.each_with_object(config) do |key, mem|
|
82
|
+
mem[key] = send(key)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def [](value)
|
87
|
+
public_send(value)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
attr_writer(*CLI_CONFIG_DEFAULTS.keys)
|
92
|
+
attr_writer(*INTERNAL_CONFIG_DEFAULTS_METHOD_NAMES)
|
93
|
+
|
94
|
+
def default_input_processor
|
95
|
+
require "gm/notepad/input_processor"
|
96
|
+
InputProcessor.new(config: self)
|
97
|
+
end
|
98
|
+
|
99
|
+
def default_table_registry
|
100
|
+
require "gm/notepad/table_registry"
|
101
|
+
TableRegistry.load_for(config: self)
|
102
|
+
end
|
103
|
+
|
104
|
+
def default_renderer
|
105
|
+
require 'gm/notepad/line_renderer'
|
106
|
+
LineRenderer.new(config: self)
|
107
|
+
end
|
108
|
+
|
109
|
+
def default_input_handler_registry
|
110
|
+
# Order matters. The first registered will be the first to
|
111
|
+
# answer "Can you handle the input?"
|
112
|
+
require "gm/notepad/input_handler_registry"
|
113
|
+
require "gm/notepad/input_handlers/help_handler"
|
114
|
+
require "gm/notepad/input_handlers/comment_handler"
|
115
|
+
require "gm/notepad/input_handlers/query_table_handler"
|
116
|
+
require "gm/notepad/input_handlers/query_table_names_handler"
|
117
|
+
require "gm/notepad/input_handlers/write_to_table_handler"
|
118
|
+
require "gm/notepad/input_handlers/write_line_handler"
|
119
|
+
InputHandlerRegistry.new do |registry|
|
120
|
+
registry.register(handler: InputHandlers::HelpHandler)
|
121
|
+
registry.register(handler: InputHandlers::CommentHandler)
|
122
|
+
registry.register(handler: InputHandlers::QueryTableHandler)
|
123
|
+
registry.register(handler: InputHandlers::QueryTableNamesHandler)
|
124
|
+
registry.register(handler: InputHandlers::WriteToTableHandler)
|
125
|
+
registry.register(handler: InputHandlers::WriteLineHandler)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -3,10 +3,10 @@ module Gm
|
|
3
3
|
module Notepad
|
4
4
|
module InputHandlers
|
5
5
|
class CommentHandler < DefaultHandler
|
6
|
-
|
6
|
+
COMMENT_PREFIX = '#'.freeze
|
7
7
|
|
8
8
|
def self.handles?(input:)
|
9
|
-
return false unless input[0] ==
|
9
|
+
return false unless input[0] == COMMENT_PREFIX
|
10
10
|
true
|
11
11
|
end
|
12
12
|
|
@@ -1,12 +1,9 @@
|
|
1
|
-
|
1
|
+
require 'gm/notepad/configuration'
|
2
2
|
module Gm
|
3
3
|
module Notepad
|
4
4
|
# Responsible for processing the given input into a renderable state
|
5
5
|
class InputProcessor
|
6
|
-
|
7
|
-
self.table_registry = table_registry
|
8
|
-
self.input_handler_registry = config.fetch(:input_handler_registry) { default_input_handler_registry }
|
9
|
-
end
|
6
|
+
Configuration.init!(target: self, from_config: [:table_registry, :input_handler_registry])
|
10
7
|
|
11
8
|
def process(input:)
|
12
9
|
processor = build_for(input: input)
|
@@ -15,9 +12,6 @@ module Gm
|
|
15
12
|
end
|
16
13
|
end
|
17
14
|
|
18
|
-
attr_accessor :table_registry, :input_handler_registry
|
19
|
-
private :table_registry=, :input_handler_registry
|
20
|
-
|
21
15
|
private
|
22
16
|
|
23
17
|
def build_for(input:)
|
@@ -26,24 +20,6 @@ module Gm
|
|
26
20
|
handler.table_registry = table_registry
|
27
21
|
handler
|
28
22
|
end
|
29
|
-
|
30
|
-
def default_input_handler_registry
|
31
|
-
require "gm/notepad/input_handler_registry"
|
32
|
-
require "gm/notepad/input_handlers/help_handler"
|
33
|
-
require "gm/notepad/input_handlers/comment_handler"
|
34
|
-
require "gm/notepad/input_handlers/query_table_handler"
|
35
|
-
require "gm/notepad/input_handlers/query_table_names_handler"
|
36
|
-
require "gm/notepad/input_handlers/write_to_table_handler"
|
37
|
-
require "gm/notepad/input_handlers/write_line_handler"
|
38
|
-
InputHandlerRegistry.new do |registry|
|
39
|
-
registry.register(handler: InputHandlers::HelpHandler)
|
40
|
-
registry.register(handler: InputHandlers::CommentHandler)
|
41
|
-
registry.register(handler: InputHandlers::QueryTableHandler)
|
42
|
-
registry.register(handler: InputHandlers::QueryTableNamesHandler)
|
43
|
-
registry.register(handler: InputHandlers::WriteToTableHandler)
|
44
|
-
registry.register(handler: InputHandlers::WriteLineHandler)
|
45
|
-
end
|
46
|
-
end
|
47
23
|
end
|
48
24
|
end
|
49
25
|
end
|
@@ -7,9 +7,11 @@ module Gm
|
|
7
7
|
DICE_REGEXP = %r{(?<dice_container>\[(?<dice>[^\]]+)\])}
|
8
8
|
def call(line:, table_lookup_function:, expand_line: true)
|
9
9
|
return line unless expand_line
|
10
|
-
|
10
|
+
match = line.match(TABLE_NAME_REGEXP)
|
11
|
+
while match
|
11
12
|
evaluated_table_name = table_lookup_function.call(table_name: match[:table_name].strip)
|
12
13
|
line = line.sub(match[:table_name_container], evaluated_table_name)
|
14
|
+
match = line.match(TABLE_NAME_REGEXP)
|
13
15
|
end
|
14
16
|
while match = line.match(DICE_REGEXP)
|
15
17
|
if parsed_dice = Dice.parse(match[:dice])
|
@@ -1,21 +1,18 @@
|
|
1
|
+
require 'gm/notepad/configuration'
|
1
2
|
require 'time'
|
2
3
|
require 'term/ansicolor'
|
3
4
|
module Gm
|
4
5
|
module Notepad
|
5
6
|
# Responsible for rendering lines to the corresponding buffers
|
6
7
|
class LineRenderer
|
7
|
-
|
8
|
-
self.config = config
|
9
|
-
self.output_buffer = output_buffer
|
10
|
-
self.interactive_buffer = interactive_buffer
|
11
|
-
@defer_output = defer_output
|
8
|
+
Configuration.init!(target: self, from_config: [:with_timestamp, :defer_output, :output_buffer, :interactive_buffer]) do
|
12
9
|
@lines = []
|
13
10
|
yield(self) if block_given?
|
14
11
|
end
|
15
12
|
|
16
13
|
def call(lines, to_output: false, to_interactive: true, as_of: Time.now)
|
17
14
|
render_interactive(lines) if to_interactive
|
18
|
-
render_output(lines, defer_output: defer_output, as_of: as_of) if to_output
|
15
|
+
render_output(lines, defer_output: config[:defer_output], as_of: as_of) if to_output
|
19
16
|
end
|
20
17
|
|
21
18
|
def close!
|
@@ -25,15 +22,6 @@ module Gm
|
|
25
22
|
|
26
23
|
private
|
27
24
|
|
28
|
-
attr_accessor :config
|
29
|
-
|
30
|
-
# When true, we defer_output writing until we close the notepad
|
31
|
-
# When false, we write immediately to the output buffer
|
32
|
-
attr_reader :defer_output
|
33
|
-
|
34
|
-
# The receiver of interactive messages
|
35
|
-
attr_reader :interactive_buffer
|
36
|
-
|
37
25
|
def interactive_buffer=(buffer)
|
38
26
|
if config[:interactive_color]
|
39
27
|
@interactive_buffer = BufferWrapper.new(buffer, color: :faint, as: :interactive)
|
@@ -42,9 +30,6 @@ module Gm
|
|
42
30
|
end
|
43
31
|
end
|
44
32
|
|
45
|
-
# The receiver of output
|
46
|
-
attr_reader :output_buffer
|
47
|
-
|
48
33
|
def output_buffer=(buffer)
|
49
34
|
if config[:output_color]
|
50
35
|
@output_buffer = BufferWrapper.new(buffer, color: :bold, as: :output)
|
@@ -53,15 +38,9 @@ module Gm
|
|
53
38
|
end
|
54
39
|
end
|
55
40
|
|
56
|
-
|
57
|
-
# When writing to output_buffer, should we prefix with a timestamp?
|
58
|
-
def with_timestamp?
|
59
|
-
config.fetch(:with_timestamp, false)
|
60
|
-
end
|
61
|
-
|
62
41
|
def render_output(lines, defer_output:, as_of:)
|
63
42
|
Array(lines).each do |line|
|
64
|
-
if with_timestamp
|
43
|
+
if config[:with_timestamp]
|
65
44
|
line = "#{as_of}\t#{line}"
|
66
45
|
end
|
67
46
|
if defer_output
|
@@ -77,14 +56,6 @@ module Gm
|
|
77
56
|
interactive_buffer.puts("=>\t#{line}")
|
78
57
|
end
|
79
58
|
end
|
80
|
-
|
81
|
-
def default_output_buffer
|
82
|
-
$stdout
|
83
|
-
end
|
84
|
-
|
85
|
-
def default_interactive_buffer
|
86
|
-
$stderr
|
87
|
-
end
|
88
59
|
end
|
89
60
|
|
90
61
|
# To provide a means for colorizing the output
|
data/lib/gm/notepad/pad.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
+
require 'gm/notepad/configuration'
|
1
2
|
module Gm
|
2
3
|
module Notepad
|
3
4
|
# Responsible for recording entries and then dumping them accordingly.
|
4
5
|
class Pad
|
5
|
-
|
6
|
-
def initialize(**config)
|
7
|
-
self.config = config
|
8
|
-
self.table_registry = config.fetch(:table_registry) { default_table_registry }
|
9
|
-
self.renderer = config.fetch(:renderer) { default_renderer }
|
10
|
-
self.input_processor = config.fetch(:input_processor) { default_input_processor }
|
6
|
+
Notepad::Configuration.init!(target: self, from_config: [:table_registry, :renderer, :input_processor]) do
|
11
7
|
open!
|
12
8
|
end
|
13
9
|
|
@@ -18,57 +14,22 @@ module Gm
|
|
18
14
|
end
|
19
15
|
|
20
16
|
def close!
|
21
|
-
|
17
|
+
renderer.close!
|
22
18
|
end
|
23
19
|
|
24
|
-
attr_reader :table_registry
|
25
|
-
|
26
20
|
private
|
27
21
|
|
28
|
-
attr_reader :renderer
|
29
22
|
def open!
|
30
|
-
return unless config
|
23
|
+
return unless config.report_config
|
31
24
|
lines = ["# Configuration Parameters:"]
|
32
25
|
config.each_pair do |key, value|
|
33
26
|
lines << "# config[#{key.inspect}] = #{value.inspect}"
|
34
27
|
end
|
35
28
|
# When running :list_tables by default I don't want to report
|
36
29
|
# that to the output buffer.
|
37
|
-
to_output = !config
|
30
|
+
to_output = !config.list_tables
|
38
31
|
renderer.call(lines, to_interactive: true, to_output: to_output)
|
39
32
|
end
|
40
|
-
|
41
|
-
attr_accessor :renderer, :input_processor
|
42
|
-
attr_writer :config, :table_registry
|
43
|
-
|
44
|
-
def default_input_processor
|
45
|
-
require "gm/notepad/input_processor"
|
46
|
-
InputProcessor.new(table_registry: table_registry)
|
47
|
-
end
|
48
|
-
|
49
|
-
def default_table_registry
|
50
|
-
require "gm/notepad/table_registry"
|
51
|
-
TableRegistry.load_for(**config)
|
52
|
-
end
|
53
|
-
|
54
|
-
def default_renderer
|
55
|
-
require 'gm/notepad/line_renderer'
|
56
|
-
LineRenderer.new(
|
57
|
-
with_timestamp: config.fetch(:with_timestamp, false),
|
58
|
-
defer_output: config.fetch(:defer_output, false),
|
59
|
-
output_buffer: config.fetch(:output_buffer, default_output_buffer),
|
60
|
-
interactive_buffer: config.fetch(:interactive_buffer, default_interactive_buffer),
|
61
|
-
**config
|
62
|
-
)
|
63
|
-
end
|
64
|
-
|
65
|
-
def default_output_buffer
|
66
|
-
$stdout
|
67
|
-
end
|
68
|
-
|
69
|
-
def default_interactive_buffer
|
70
|
-
$stderr
|
71
|
-
end
|
72
33
|
end
|
73
34
|
end
|
74
35
|
end
|
data/lib/gm/notepad/readline.rb
CHANGED
@@ -23,6 +23,11 @@ module Gm
|
|
23
23
|
# Hook-in the above completion function
|
24
24
|
::Readline.completion_proc = completion_function
|
25
25
|
|
26
|
+
# In the interactive shell, where are we sending the prompts?
|
27
|
+
# If this defaults to $stdout then if we are directing $stdout
|
28
|
+
# to a file, we end up typing blind into the terminal
|
29
|
+
::Readline.output = $stderr
|
30
|
+
|
26
31
|
def self.input_getter(**config)
|
27
32
|
-> { ::Readline.readline("#{config.fetch(:shell_prompt, ">")} ", true) }
|
28
33
|
end
|
data/lib/gm/notepad/table.rb
CHANGED
@@ -4,10 +4,7 @@ require "gm/notepad/table_entry"
|
|
4
4
|
module Gm
|
5
5
|
module Notepad
|
6
6
|
class Table
|
7
|
-
|
8
|
-
self.config = config
|
9
|
-
self.table_name = table_name
|
10
|
-
self.filename = filename
|
7
|
+
Configuration.init!(target: self, additional_params: [:table_name, :filename, :lines]) do
|
11
8
|
process(lines: lines)
|
12
9
|
end
|
13
10
|
|
@@ -58,6 +55,7 @@ module Gm
|
|
58
55
|
def process(lines:)
|
59
56
|
@table = {}
|
60
57
|
lines.each do |line|
|
58
|
+
next if line[0] == '#'
|
61
59
|
entry = TableEntry.new(line: line, **config)
|
62
60
|
entry.lookup_range.each do |i|
|
63
61
|
key = i.to_s
|
@@ -3,8 +3,7 @@ module Gm
|
|
3
3
|
module Notepad
|
4
4
|
TABLE_ENTRY_RANGE_MARKER = "-".freeze
|
5
5
|
class TableEntry
|
6
|
-
|
7
|
-
self.column_delimiter = column_delimiter
|
6
|
+
Configuration.init!(target: self, from_config: [:column_delimiter], additional_params: [:line]) do
|
8
7
|
self.lookup_column, self.entry_column = line.split(column_delimiter)
|
9
8
|
end
|
10
9
|
|
@@ -31,8 +30,6 @@ module Gm
|
|
31
30
|
|
32
31
|
private
|
33
32
|
|
34
|
-
attr_accessor :column_delimiter
|
35
|
-
|
36
33
|
def lookup_column=(input)
|
37
34
|
@lookup_column = input.strip.downcase.freeze
|
38
35
|
end
|
@@ -1,23 +1,20 @@
|
|
1
1
|
require "gm/notepad/table"
|
2
2
|
require "gm/notepad/exceptions"
|
3
|
+
require 'gm/notepad/line_evaluator'
|
3
4
|
|
4
5
|
module Gm
|
5
6
|
module Notepad
|
6
7
|
# Responsible for loading and registering all of the named tables
|
7
8
|
class TableRegistry
|
8
|
-
def self.load_for(
|
9
|
-
table_registry = new(
|
9
|
+
def self.load_for(config:)
|
10
|
+
table_registry = new(config: config)
|
10
11
|
table_registry.load!
|
11
12
|
table_registry
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
-
self.config = config
|
16
|
-
self.line_evaluator = line_evaluator
|
17
|
-
self.paths = config.fetch(:paths) { [] }
|
18
|
-
self.table_extension = config.fetch(:table_extension) { ".txt" }
|
19
|
-
self.filesystem_directory = config.fetch(:filesystem_directory) { "." }
|
15
|
+
Configuration.init!(target: self, from_config: [:paths, :table_extension, :filesystem_directory]) do
|
20
16
|
@registry = {}
|
17
|
+
@line_evaluator = LineEvaluator.new
|
21
18
|
end
|
22
19
|
|
23
20
|
def load!
|
@@ -29,16 +26,14 @@ module Gm
|
|
29
26
|
end
|
30
27
|
end
|
31
28
|
|
32
|
-
|
33
|
-
attr_accessor :line_evaluator, :paths, :table_extension, :filesystem_directory, :config
|
34
|
-
public
|
29
|
+
attr_reader :line_evaluator, :registry
|
35
30
|
|
36
31
|
def table_names
|
37
|
-
|
32
|
+
registry.keys.sort
|
38
33
|
end
|
39
34
|
|
40
35
|
def fetch_table(name:)
|
41
|
-
|
36
|
+
registry.fetch(name.downcase)
|
42
37
|
end
|
43
38
|
|
44
39
|
def append(table_name:, line:, write:)
|
@@ -76,13 +71,8 @@ module Gm
|
|
76
71
|
|
77
72
|
def register(table_name:, lines:, filename: nil)
|
78
73
|
table_name = table_name.downcase
|
79
|
-
raise DuplicateKeyError.new(key: table_name, object: self) if
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def default_line_evaluator
|
84
|
-
require 'gm/notepad/line_evaluator'
|
85
|
-
LineEvaluator.new
|
74
|
+
raise DuplicateKeyError.new(key: table_name, object: self) if registry.key?(table_name.downcase)
|
75
|
+
registry[table_name] = Table.new(config: config, table_name: table_name, lines: lines, filename: filename)
|
86
76
|
end
|
87
77
|
end
|
88
78
|
end
|
data/lib/gm/notepad/version.rb
CHANGED
data/lib/gm/notepad.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require "gm/notepad/version"
|
2
2
|
require "gm/notepad/defaults"
|
3
3
|
require "gm/notepad/pad"
|
4
|
+
require "gm/notepad/configuration"
|
4
5
|
module Gm
|
5
6
|
module Notepad
|
6
7
|
def self.new(*args)
|
7
|
-
|
8
|
+
config = Configuration.new(*args)
|
9
|
+
Pad.new(config: config)
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gm-notepad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- exe/gm-notepad
|
145
145
|
- gm-notepad.gemspec
|
146
146
|
- lib/gm/notepad.rb
|
147
|
+
- lib/gm/notepad/configuration.rb
|
147
148
|
- lib/gm/notepad/defaults.rb
|
148
149
|
- lib/gm/notepad/exceptions.rb
|
149
150
|
- lib/gm/notepad/input_handler_registry.rb
|