markdown_exec 0.2.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8baa6b01b9d965c3a8856d08a86225457c09106c366ecd174f7f0e547f43f4a
4
- data.tar.gz: bd0348f31ddb1bb0cda0328e5c7dd3187e6692269e8b132849833ce1d44f5b0f
3
+ metadata.gz: 9b40d575297112f5a4bb934475b84251aeeab8f43de5dae963c8d3b1711c3edc
4
+ data.tar.gz: 9e3d3273dc3e3a0deb326fe30e3ff70b15e73f4fd9cea06c42f099f184903fad
5
5
  SHA512:
6
- metadata.gz: e6f8028d4fe4dea45bacb14e8cb12306d0ee975ac729c04d0f8db990a6ce92758b13400329358656d5902c85dd5411aef717210b0151de4ae2cec375f51b0b98
7
- data.tar.gz: 390dd965fe49ab4ac1651996fc7500ff971fbe71ce580ff807d8652b62aff5b50768ce971920e9f93682d5adb692cd5bcf99834b8b022c41734dc24f61cf940c
6
+ metadata.gz: 65654b5af78419591c41e3b50e0697b503ddf429c83312311335dd1b16d0d645c98b4e0c19d6c69446c42823861ca8f384788aeb4c1b5664804e4feecc39a45a
7
+ data.tar.gz: 866360b40733e8925c173582f3c59799e241bf48f52faffa4bfb03cd4c1a11c93f5b27305344b01c4b44a1518ef1c49961c7fbfbdb713638ed8261c8d87401c0
data/CHANGELOG.md CHANGED
@@ -3,7 +3,6 @@
3
3
  ## [ToDo]
4
4
 
5
5
  - pipe stdin to script
6
- - yes/no/write/clipboard/record/edit/history
7
6
  - present timestamp, result of last exec for each command
8
7
  - user settings
9
8
  - hidden w , w/o () in names
@@ -22,11 +21,30 @@
22
21
 
23
22
  - add shebang to saved script
24
23
 
24
+ - yes/no/write/clipboard/record/edit/history
25
+
26
+ - list, view saved output
27
+
28
+ ## [1.0.0] - 2022-04-26
29
+
30
+ ### Added
31
+
32
+ - Command `--pwd` to print the gem's home folder.
33
+ - Command `--select-recent-output` to select and open a recent output log file.
34
+ e.g. `MDE_OUTPUT_VIEWER_OPTIONS="-a '/Applications/Sublime Text.app'" mde --select-recent-output`
35
+ - Command `--tab-completions` to list the application options.
36
+ - Tab completion script for Bash shell.
37
+
38
+ ### Changed
39
+
40
+ - File names for saved scripts.
41
+ - Hide blocks with empty names, e.g. `:()`.
42
+
25
43
  ## [0.2.6] - 2022-04-07
26
44
 
27
45
  ### Changed
28
46
 
29
- - Fixed default values for command line options.
47
+ - Default values for command line options.
30
48
 
31
49
  ## [0.2.5] - 2022-04-03
32
50
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (0.2.5)
4
+ markdown_exec (1.0.0)
5
5
  open3 (~> 0.1.1)
6
6
  optparse (~> 0.1.1)
7
7
  tty-prompt (~> 0.23.1)
data/README.md CHANGED
@@ -55,6 +55,10 @@ Process `README.md` file in the current folder. Displays all the blocks in the f
55
55
 
56
56
  Select a block to execute from `my.md`.
57
57
 
58
+ #### `mde my.md myblock`
59
+
60
+ Execute the block named `myblock` from `my.md`.
61
+
58
62
  #### `mde .` or `mde -p .`
59
63
 
60
64
  Select a markdown file in the current folder. Select a block to execute from that file.
@@ -142,7 +146,27 @@ Boolean options configured with environment variables:
142
146
  - Specify variable on command line.
143
147
  e.g. `MDE_SAVE_EXECUTED_SCRIPT=1 mde`
144
148
 
145
- # Example blocks
149
+ ## Tab Completion
150
+
151
+ ### Install tab completion
152
+
153
+ Append a command to load the completion script to your shell configuration file:
154
+
155
+ ```bash :()
156
+ echo "source $(mde --pwd)/bin/tab_completion.sh" >> ~/.bash_profile
157
+ ```
158
+
159
+ ### Example Completions
160
+
161
+ Type tab at end of any of the following commands to see the options.
162
+ - `mde `
163
+ - `mde -`
164
+ - `mde --`
165
+ - `mde --o`
166
+ - `mde --filename my.md -`
167
+ - `mde --filename my.md --`
168
+
169
+ ## Example Blocks
146
170
 
147
171
  When prompted, select either the `awake` or `asleep` block.
148
172
 
@@ -166,17 +190,6 @@ export ACTIVITY=asleep
166
190
  echo "$TIME -> $ACTIVITY"
167
191
  ```
168
192
 
169
- ``` :missing_command
170
- fail
171
- ```
172
-
173
- ``` :exit_value
174
- echo "a"
175
- echo "b"
176
- echo "c" >>/dev/stderr
177
- grep nx Gemfile
178
- ```
179
-
180
193
  # License
181
194
 
182
195
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+
3
+ __filedirs()
4
+ {
5
+ local IFS=$'\n'
6
+ COMPREPLY=( $(compgen -o plusdirs -f -- "${cur}") )
7
+ }
8
+
9
+ _mde() {
10
+ local cur prev opts
11
+ cur="${COMP_WORDS[COMP_CWORD]}"
12
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
13
+ opts="$(mde --tab-completions)"
14
+
15
+ if [[ ${cur} == -* ]] ; then
16
+ COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
17
+ return 0
18
+ fi
19
+
20
+ __filedirs
21
+ }
22
+
23
+ complete -o filenames -F _mde mde
data/fixtures/exclude2.md CHANGED
@@ -7,3 +7,6 @@ b
7
7
  ``` :three
8
8
  c
9
9
  ```
10
+ ``` :()
11
+ d
12
+ ```
@@ -4,5 +4,5 @@ module MarkdownExec
4
4
  APP_NAME = 'MDE'
5
5
  APP_DESC = 'Markdown Executor'
6
6
  GEM_NAME = 'markdown_exec'
7
- VERSION = '0.2.6'
7
+ VERSION = '1.0.0'
8
8
  end
data/lib/markdown_exec.rb CHANGED
@@ -67,16 +67,13 @@ public
67
67
  def tap_inspect(format: nil, name: 'return')
68
68
  return self unless $pdebug
69
69
 
70
- fn = case format
71
- when :json
72
- :to_json
73
- when :string
74
- :to_s
75
- when :yaml
76
- :to_yaml
77
- else
78
- :inspect
79
- end
70
+ cvt = {
71
+ json: :to_json,
72
+ string: :to_s,
73
+ yaml: :to_yaml,
74
+ else: :inspect
75
+ }
76
+ fn = cvt.fetch(format, cvt[:else])
80
77
 
81
78
  puts "-> #{caller[0].scan(/in `?(\S+)'$/)[0][0]}()" \
82
79
  " #{name}: #{method(fn).call}"
@@ -102,10 +99,11 @@ module MarkdownExec
102
99
 
103
100
  def base_options
104
101
  menu_data
105
- .map do |_long_name, _short_name, env_var, _arg_name, _description, opt_name, default, _proc1| # rubocop:disable Metrics/ParameterLists
102
+ .map do |_long_name, _short_name, env_var, _arg_name, _description, opt_name, default, proc1| # rubocop:disable Metrics/ParameterLists
106
103
  next unless opt_name.present?
107
104
 
108
- [opt_name, env_bool(env_var, default: value_for_hash(default))]
105
+ value = env_str(env_var, default: value_for_hash(default))
106
+ [opt_name, proc1 ? proc1.call(value) : value]
109
107
  end.compact.to_h.merge(
110
108
  {
111
109
  mdheadings: true, # use headings (levels 1,2,3) in block lable
@@ -123,6 +121,7 @@ module MarkdownExec
123
121
  prompt_approve_block: 'Process?',
124
122
  prompt_select_block: 'Choose a block:',
125
123
  prompt_select_md: 'Choose a file:',
124
+ prompt_select_output: 'Choose a file:',
126
125
  saved_script_filename: nil, # calculated
127
126
  struct: true # allow get_block_summary()
128
127
  }
@@ -144,8 +143,10 @@ module MarkdownExec
144
143
  selected = get_block_by_name blocks_in_file, opts[:block_name]
145
144
 
146
145
  if opts[:ir_approve]
147
- write_command_file(opts, required_blocks) if opts[:save_executed_script]
146
+ write_command_file opts, required_blocks
148
147
  command_execute opts, required_blocks.flatten.join("\n")
148
+ save_execution_output
149
+ output_execution_summary
149
150
  end
150
151
 
151
152
  selected[:name]
@@ -221,41 +222,30 @@ module MarkdownExec
221
222
  # document and block reports
222
223
  #
223
224
  files = list_files_per_options(options)
224
- if @options[:list_blocks]
225
- fout_list (files.map do |file|
226
- make_block_labels(filename: file, struct: true)
227
- end).flatten(1)
228
- return
229
- end
230
-
231
- if @options[:list_default_yaml]
232
- fout_list list_default_yaml
233
- return
234
- end
235
-
236
- if @options[:list_docs]
237
- fout_list files
238
- return
239
- end
240
-
241
- if @options[:list_default_env]
242
- fout_list list_default_env
243
- return
244
- end
245
-
246
- if @options[:list_recent_scripts]
247
- fout_list list_recent_scripts
248
- return
249
- end
250
-
251
- if @options[:run_last_script]
252
- run_last_script
253
- return
254
- end
255
225
 
256
- if @options[:select_recent_script]
257
- select_recent_script
258
- return
226
+ simple_commands = {
227
+ doc_glob: -> { fout options[:md_filename_glob] },
228
+ list_blocks: lambda do
229
+ fout_list (files.map do |file|
230
+ make_block_labels(filename: file, struct: true)
231
+ end).flatten(1)
232
+ end,
233
+ list_default_yaml: -> { fout_list list_default_yaml },
234
+ list_docs: -> { fout_list files },
235
+ list_default_env: -> { fout_list list_default_env },
236
+ list_recent_output: -> { fout_list list_recent_output },
237
+ list_recent_scripts: -> { fout_list list_recent_scripts },
238
+ pwd: -> { fout File.expand_path('..', __dir__) },
239
+ run_last_script: -> { run_last_script },
240
+ select_recent_output: -> { select_recent_output },
241
+ select_recent_script: -> { select_recent_script },
242
+ tab_completions: -> { fout tab_completions }
243
+ }
244
+ simple_commands.each_key do |key|
245
+ if @options[key]
246
+ simple_commands[key].call
247
+ return # rubocop:disable Lint/NonLocalExitFromIterator
248
+ end
259
249
  end
260
250
 
261
251
  # process
@@ -266,8 +256,6 @@ module MarkdownExec
266
256
  struct: true
267
257
  )
268
258
  fout "saved_filespec: #{@execute_script_filespec}" if @options[:output_saved_script_filename]
269
- save_execution_output
270
- output_execution_summary
271
259
  end
272
260
 
273
261
  # standard output; not for debug
@@ -312,6 +300,11 @@ module MarkdownExec
312
300
  exit 1
313
301
  end
314
302
 
303
+ unless File.exist? opts[:filename]
304
+ fout 'Document is missing.'
305
+ exit 1
306
+ end
307
+
315
308
  fenced_start_and_end_match = Regexp.new opts[:fenced_start_and_end_match]
316
309
  fenced_start_ex = Regexp.new opts[:fenced_start_ex_match]
317
310
  block_title = ''
@@ -451,9 +444,28 @@ module MarkdownExec
451
444
  .tap_inspect
452
445
  end
453
446
 
447
+ def most_recent(arr)
448
+ return unless arr
449
+ return if arr.count < 1
450
+
451
+ arr.max.tap_inspect
452
+ end
453
+
454
+ def most_recent_list(arr)
455
+ return unless arr
456
+ return if (ac = arr.count) < 1
457
+
458
+ arr.sort[-[ac, options[:list_count]].min..].reverse.tap_inspect
459
+ end
460
+
461
+ def list_recent_output
462
+ most_recent_list(Dir.glob(File.join(@options[:saved_stdout_folder],
463
+ @options[:saved_stdout_glob]))).tap_inspect
464
+ end
465
+
454
466
  def list_recent_scripts
455
- Dir.glob(File.join(@options[:saved_script_folder],
456
- @options[:saved_script_glob])).sort[0..(options[:list_count] - 1)].reverse.tap_inspect
467
+ most_recent_list(Dir.glob(File.join(@options[:saved_script_folder],
468
+ @options[:saved_script_glob]))).tap_inspect
457
469
  end
458
470
 
459
471
  def make_block_label(block, call_options = {})
@@ -476,10 +488,9 @@ module MarkdownExec
476
488
  end
477
489
 
478
490
  def menu_data
479
- val_as_bool = ->(value) { value.to_i != 0 }
491
+ val_as_bool = ->(value) { value.class.to_s == 'String' ? (value.chomp != '0') : value }
480
492
  val_as_int = ->(value) { value.to_i }
481
493
  val_as_str = ->(value) { value.to_s }
482
- val_true = ->(_) { true }
483
494
 
484
495
  summary_head = [
485
496
  ['config', nil, nil, 'PATH', 'Read configuration file', nil, '.', lambda { |value|
@@ -490,26 +501,32 @@ module MarkdownExec
490
501
 
491
502
  # rubocop:disable Layout/LineLength
492
503
  summary_body = [
504
+ ['block-name', 'f', 'MDE_BLOCK_NAME', 'RELATIVE', 'Name of block', :block_name, nil, val_as_str],
493
505
  ['filename', 'f', 'MDE_FILENAME', 'RELATIVE', 'Name of document', :filename, nil, val_as_str],
494
- ['list-blocks', nil, nil, nil, 'List blocks', :list_blocks, nil, val_true],
506
+ ['list-blocks', nil, nil, nil, 'List blocks', :list_blocks, false, val_as_bool],
495
507
  ['list-count', nil, 'MDE_LIST_COUNT', 'NUM', 'Max. items to return in list', :list_count, 16, val_as_int],
496
- ['list-default-env', nil, nil, nil, 'List default configuration as environment variables', :list_default_env, nil, val_true],
497
- ['list-default-yaml', nil, nil, nil, 'List default configuration as YAML', :list_default_yaml, nil, val_true],
498
- ['list-docs', nil, nil, nil, 'List docs in current folder', :list_docs, nil, val_true],
499
- ['list-recent-scripts', nil, nil, nil, 'List recent saved scripts', :list_recent_scripts, nil, val_true],
508
+ ['list-default-env', nil, nil, nil, 'List default configuration as environment variables', :list_default_env, false, val_as_bool],
509
+ ['list-default-yaml', nil, nil, nil, 'List default configuration as YAML', :list_default_yaml, false, val_as_bool],
510
+ ['list-docs', nil, nil, nil, 'List docs in current folder', :list_docs, false, val_as_bool],
511
+ ['list-recent-output', nil, nil, nil, 'List recent saved output', :list_recent_output, false, val_as_bool],
512
+ ['list-recent-scripts', nil, nil, nil, 'List recent saved scripts', :list_recent_scripts, false, val_as_bool],
500
513
  ['logged-stdout-filename-prefix', nil, 'MDE_LOGGED_STDOUT_FILENAME_PREFIX', 'NAME', 'Name prefix for stdout files', :logged_stdout_filename_prefix, 'mde', val_as_str],
501
514
  ['output-execution-summary', nil, 'MDE_OUTPUT_EXECUTION_SUMMARY', 'BOOL', 'Display summary for execution', :output_execution_summary, false, val_as_bool],
502
515
  ['output-script', nil, 'MDE_OUTPUT_SCRIPT', 'BOOL', 'Display script prior to execution', :output_script, false, val_as_bool],
503
516
  ['output-stdout', nil, 'MDE_OUTPUT_STDOUT', 'BOOL', 'Display standard output from execution', :output_stdout, true, val_as_bool],
504
517
  ['path', 'p', 'MDE_PATH', 'PATH', 'Path to documents', :path, nil, val_as_str],
505
- ['run-last-script', nil, nil, nil, 'Run most recently saved script', :run_last_script, nil, val_true],
506
- ['select-recent-script', nil, nil, nil, 'Select and execute a recently saved script', :select_recent_script, nil, val_true],
518
+ ['pwd', nil, nil, nil, 'Gem home folder', :pwd, false, val_as_bool],
519
+ ['run-last-script', nil, nil, nil, 'Run most recently saved script', :run_last_script, false, val_as_bool],
507
520
  ['save-executed-script', nil, 'MDE_SAVE_EXECUTED_SCRIPT', 'BOOL', 'Save executed script', :save_executed_script, false, val_as_bool],
508
521
  ['save-execution-output', nil, 'MDE_SAVE_EXECUTION_OUTPUT', 'BOOL', 'Save standard output of the executed script', :save_execution_output, false, val_as_bool],
509
522
  ['saved-script-filename-prefix', nil, 'MDE_SAVED_SCRIPT_FILENAME_PREFIX', 'NAME', 'Name prefix for saved scripts', :saved_script_filename_prefix, 'mde', val_as_str],
510
523
  ['saved-script-folder', nil, 'MDE_SAVED_SCRIPT_FOLDER', 'SPEC', 'Saved script folder', :saved_script_folder, 'logs', val_as_str],
511
524
  ['saved-script-glob', nil, 'MDE_SAVED_SCRIPT_GLOB', 'SPEC', 'Glob matching saved scripts', :saved_script_glob, 'mde_*.sh', val_as_str],
512
525
  ['saved-stdout-folder', nil, 'MDE_SAVED_STDOUT_FOLDER', 'SPEC', 'Saved stdout folder', :saved_stdout_folder, 'logs', val_as_str],
526
+ ['saved-stdout-glob', nil, 'MDE_SAVED_STDOUT_GLOB', 'SPEC', 'Glob matching saved outputs', :saved_stdout_glob, 'mde_*.out.txt', val_as_str],
527
+ ['select-recent-output', nil, nil, nil, 'Select and execute a recently saved output', :select_recent_output, false, val_as_bool],
528
+ ['select-recent-script', nil, nil, nil, 'Select and execute a recently saved script', :select_recent_script, false, val_as_bool],
529
+ ['tab-completions', nil, nil, nil, 'List tab completions', :tab_completions, false, val_as_bool],
513
530
  ['user-must-approve', nil, 'MDE_USER_MUST_APPROVE', 'BOOL', 'Pause for user to approve script', :user_must_approve, true, val_as_bool]
514
531
  ]
515
532
  # rubocop:enable Layout/LineLength
@@ -520,7 +537,7 @@ module MarkdownExec
520
537
  nil, nil, ->(_) { options_finalize options; fout sorted_keys(options).to_yaml }],
521
538
  ['help', 'h', nil, nil, 'App help',
522
539
  nil, nil, ->(_) { fout menu_help; exit }],
523
- ['version', 'v', nil, nil, 'App version',
540
+ ['version', 'v', nil, nil, "Print the gem's version",
524
541
  nil, nil, ->(_) { fout MarkdownExec::VERSION; exit }],
525
542
  ['exit', 'x', nil, nil, 'Exit app',
526
543
  nil, nil, ->(_) { exit }]
@@ -529,18 +546,20 @@ module MarkdownExec
529
546
 
530
547
  env_vars = [
531
548
  [nil, nil, 'MDE_BLOCK_NAME_EXCLUDED_MATCH', nil, 'Pattern for blocks to hide from user-selection',
532
- :block_name_excluded_match, '^\(.+\)$', nil],
533
- [nil, nil, 'MDE_BLOCK_NAME_MATCH', nil, '', :block_name_match, ':(?<title>\S+)( |$)', nil],
534
- [nil, nil, 'MDE_BLOCK_REQUIRED_SCAN', nil, '', :block_required_scan, '\+\S+', nil],
535
- [nil, nil, 'MDE_FENCED_START_AND_END_MATCH', nil, '', :fenced_start_and_end_match, '^`{3,}', nil],
549
+ :block_name_excluded_match, '^\(.*\)$', val_as_str],
550
+ [nil, nil, 'MDE_BLOCK_NAME_MATCH', nil, '', :block_name_match, ':(?<title>\S+)( |$)', val_as_str],
551
+ [nil, nil, 'MDE_BLOCK_REQUIRED_SCAN', nil, '', :block_required_scan, '\+\S+', val_as_str],
552
+ [nil, nil, 'MDE_FENCED_START_AND_END_MATCH', nil, '', :fenced_start_and_end_match, '^`{3,}', val_as_str],
536
553
  [nil, nil, 'MDE_FENCED_START_EX_MATCH', nil, '', :fenced_start_ex_match,
537
- '^`{3,}(?<shell>[^`\s]*) *(?<name>.*)$', nil],
538
- [nil, nil, 'MDE_HEADING1_MATCH', nil, '', :heading1_match, '^# *(?<name>[^#]*?) *$', nil],
539
- [nil, nil, 'MDE_HEADING2_MATCH', nil, '', :heading2_match, '^## *(?<name>[^#]*?) *$', nil],
540
- [nil, nil, 'MDE_HEADING3_MATCH', nil, '', :heading3_match, '^### *(?<name>.+?) *$', nil],
541
- [nil, nil, 'MDE_MD_FILENAME_GLOB', nil, '', :md_filename_glob, '*.[Mm][Dd]', nil],
542
- [nil, nil, 'MDE_MD_FILENAME_MATCH', nil, '', :md_filename_match, '.+\\.md', nil],
543
- [nil, nil, 'MDE_SELECT_PAGE_HEIGHT', nil, '', :select_page_height, 12, nil]
554
+ '^`{3,}(?<shell>[^`\s]*) *(?<name>.*)$', val_as_str],
555
+ [nil, nil, 'MDE_HEADING1_MATCH', nil, '', :heading1_match, '^# *(?<name>[^#]*?) *$', val_as_str],
556
+ [nil, nil, 'MDE_HEADING2_MATCH', nil, '', :heading2_match, '^## *(?<name>[^#]*?) *$', val_as_str],
557
+ [nil, nil, 'MDE_HEADING3_MATCH', nil, '', :heading3_match, '^### *(?<name>.+?) *$', val_as_str],
558
+ [nil, nil, 'MDE_MD_FILENAME_GLOB', nil, '', :md_filename_glob, '*.[Mm][Dd]', val_as_str],
559
+ [nil, nil, 'MDE_MD_FILENAME_MATCH', nil, '', :md_filename_match, '.+\\.md', val_as_str],
560
+ [nil, nil, 'MDE_OUTPUT_VIEWER_OPTIONS', nil, 'Options for viewing saved output file', :output_viewer_options,
561
+ '', val_as_str],
562
+ [nil, nil, 'MDE_SELECT_PAGE_HEIGHT', nil, '', :select_page_height, 12, val_as_int]
544
563
  # [nil, nil, 'MDE_', nil, '', nil, '', nil],
545
564
  ]
546
565
 
@@ -577,7 +596,8 @@ module MarkdownExec
577
596
 
578
597
  ## position 1: block name (optional)
579
598
  #
580
- @options[:block_name] = rest.fetch(1, nil)
599
+ block_name = rest.fetch(1, nil)
600
+ @options[:block_name] = block_name if block_name.present?
581
601
  end
582
602
 
583
603
  def optsmerge(call_options = {}, options_block = nil)
@@ -652,7 +672,7 @@ module MarkdownExec
652
672
  opts.banner = [
653
673
  "#{MarkdownExec::APP_NAME}" \
654
674
  " - #{MarkdownExec::APP_DESC} (#{MarkdownExec::VERSION})",
655
- "Usage: #{executable_name} [path] [filename] [options]"
675
+ "Usage: #{executable_name} [(path | filename [block_name])] [options]"
656
676
  ].join("\n")
657
677
 
658
678
  menu_data
@@ -681,24 +701,39 @@ module MarkdownExec
681
701
  exec_block options, options[:block_name]
682
702
  end
683
703
 
704
+ FNR11 = '/'
705
+ FNR12 = ',;'
706
+
707
+ def saved_name_make(opts)
708
+ fne = opts[:filename].gsub(FNR11, FNR12)
709
+ "#{[opts[:saved_script_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
710
+ ',', opts[:block_name]].join('_')}.sh"
711
+ end
712
+
713
+ def saved_name_split(name)
714
+ mf = name.match(/#{@options[:saved_script_filename_prefix]}_(?<time>[0-9\-]+)_(?<file>.+)_,_(?<block>.+)\.sh/)
715
+ return unless mf
716
+
717
+ @options[:block_name] = mf[:block].tap_inspect name: :options_block_name
718
+ @options[:filename] = mf[:file].gsub(FNR12, FNR11).tap_inspect name: :options_filename
719
+ end
720
+
684
721
  def run_last_script
685
- filename = Dir.glob(File.join(@options[:saved_script_folder],
686
- @options[:saved_script_glob])).sort[0..(options[:list_count] - 1)].last
687
- filename.tap_inspect name: filename
688
- mf = filename.match(/#{@options[:saved_script_filename_prefix]}_(?<time>[0-9\-]+)_(?<file>.+)_(?<block>.+)\.sh/)
722
+ filename = most_recent Dir.glob(File.join(@options[:saved_script_folder],
723
+ @options[:saved_script_glob]))
724
+ return unless filename
689
725
 
690
- @options[:block_name] = mf[:block]
691
- @options[:filename] = "#{mf[:file]}.md" ### other extensions
726
+ filename.tap_inspect name: filename
727
+ saved_name_split filename
692
728
  @options[:save_executed_script] = false
693
729
  select_and_approve_block
694
- save_execution_output
695
- output_execution_summary
696
730
  end
697
731
 
698
732
  def save_execution_output
699
733
  return unless @options[:save_execution_output]
700
734
 
701
735
  fne = File.basename(@options[:filename], '.*')
736
+
702
737
  @options[:logged_stdout_filename] =
703
738
  "#{[@options[:logged_stdout_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
704
739
  @options[:block_name]].join('_')}.out.txt"
@@ -707,12 +742,6 @@ module MarkdownExec
707
742
  dirname = File.dirname(@options[:logged_stdout_filespec])
708
743
  Dir.mkdir dirname unless File.exist?(dirname)
709
744
  File.write(@options[:logged_stdout_filespec], @execute_files&.fetch(0, ''))
710
- # @options[:logged_stderr_filename] =
711
- # "#{[@options[:logged_stdout_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
712
- # @options[:block_name]].join('_')}.err.txt"
713
- # @options[:logged_stderr_filespec] = File.join @options[:saved_stdout_folder], @options[:logged_stderr_filename]
714
- # @logged_stderr_filespec = @options[:logged_stderr_filespec]
715
- # File.write(@options[:logged_stderr_filespec], @execute_files&.fetch(1, ''))
716
745
  end
717
746
 
718
747
  def select_and_approve_block(call_options = {}, &options_block)
@@ -746,22 +775,25 @@ module MarkdownExec
746
775
  end
747
776
  end
748
777
 
778
+ def select_recent_output
779
+ filename = prompt_with_quit @options[:prompt_select_output].to_s, list_recent_output,
780
+ per_page: @options[:select_page_height]
781
+ return unless filename.present?
782
+
783
+ `open #{filename} #{options[:output_viewer_options]}`
784
+ end
785
+
749
786
  def select_recent_script
750
787
  filename = prompt_with_quit @options[:prompt_select_md].to_s, list_recent_scripts,
751
788
  per_page: @options[:select_page_height]
752
789
  return if filename.nil?
753
790
 
754
- mf = filename.match(/#{@options[:saved_script_filename_prefix]}_(?<time>[0-9\-]+)_(?<file>.+)_(?<block>.+)\.sh/)
755
-
756
- @options[:block_name] = mf[:block]
757
- @options[:filename] = "#{mf[:file]}.md" ### other extensions
791
+ saved_name_split filename
758
792
  select_and_approve_block(
759
793
  bash: true,
760
794
  save_executed_script: false,
761
795
  struct: true
762
796
  )
763
- save_execution_output
764
- output_execution_summary
765
797
  end
766
798
 
767
799
  def sorted_keys(hash1)
@@ -772,6 +804,12 @@ module MarkdownExec
772
804
  { headings: headings, name: title, title: title }
773
805
  end
774
806
 
807
+ def tab_completions(data = menu_data)
808
+ data.map do |item|
809
+ "--#{item[0]}" if item[0]
810
+ end.compact
811
+ end
812
+
775
813
  def update_options(opts = {}, over: true)
776
814
  if over
777
815
  @options = @options.merge opts
@@ -825,12 +863,13 @@ module MarkdownExec
825
863
  end
826
864
 
827
865
  def write_command_file(opts, required_blocks)
828
- fne = File.basename(opts[:filename], '.*')
829
- opts[:saved_script_filename] =
830
- "#{[opts[:saved_script_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
831
- opts[:block_name]].join('_')}.sh"
832
- @options[:saved_filespec] = File.join opts[:saved_script_folder], opts[:saved_script_filename]
833
- @execute_script_filespec = @options[:saved_filespec]
866
+ return unless opts[:save_executed_script]
867
+
868
+ opts[:saved_script_filename] = saved_name_make(opts)
869
+ @execute_script_filespec =
870
+ @options[:saved_filespec] =
871
+ File.join opts[:saved_script_folder], opts[:saved_script_filename]
872
+
834
873
  dirname = File.dirname(@options[:saved_filespec])
835
874
  Dir.mkdir dirname unless File.exist?(dirname)
836
875
  File.write(@options[:saved_filespec], "#!/usr/bin/env bash\n" \
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fareed Stevenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-07 00:00:00.000000000 Z
11
+ date: 2022-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: open3
@@ -73,6 +73,7 @@ email:
73
73
  - fareed@phomento.com
74
74
  executables:
75
75
  - mde
76
+ - tab_completion.sh
76
77
  extensions: []
77
78
  extra_rdoc_files: []
78
79
  files:
@@ -92,6 +93,7 @@ files:
92
93
  - bin/console
93
94
  - bin/mde
94
95
  - bin/setup
96
+ - bin/tab_completion.sh
95
97
  - fixtures/bash1.md
96
98
  - fixtures/bash2.md
97
99
  - fixtures/exclude1.md