markdown_exec 2.8.3 → 2.8.4
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 +26 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +33 -23
- data/bats/{block-types.bats → block-type-bash.bats} +0 -25
- data/bats/block-type-link.bats +9 -0
- data/bats/block-type-port.bats +16 -0
- data/bats/block-type-ux-allowed.bats +29 -0
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-chained.bats +9 -0
- data/bats/block-type-ux-echo-hash.bats +14 -0
- data/bats/block-type-ux-echo.bats +2 -2
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-hidden.bats +9 -0
- data/bats/block-type-ux-invalid.bats +8 -0
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/indented-block-type-vars.bats +9 -0
- data/bats/line-decor-dynamic.bats +1 -1
- data/bats/test_helper.bash +9 -2
- data/bats/variable-expansion-multiline.bats +8 -0
- data/bats/variable-expansion.bats +1 -1
- data/docs/dev/block-type-ux-allowed.md +80 -0
- data/docs/dev/block-type-ux-chained.md +21 -0
- data/docs/dev/block-type-ux-echo-hash.md +72 -0
- data/docs/dev/block-type-ux-hidden.md +21 -0
- data/docs/dev/block-type-ux-invalid.md +5 -0
- data/docs/dev/indented-block-type-vars.md +6 -0
- data/docs/dev/line-decor-dynamic.md +2 -1
- data/docs/dev/variable-expansion-multiline.md +31 -0
- data/lib/ansi_formatter.rb +0 -1
- data/lib/ansi_string.rb +1 -1
- data/lib/array.rb +0 -1
- data/lib/array_util.rb +0 -1
- data/lib/block_label.rb +1 -1
- data/lib/cached_nested_file_reader.rb +1 -1
- data/lib/constants.rb +18 -0
- data/lib/directory_searcher.rb +1 -1
- data/lib/exceptions.rb +0 -1
- data/lib/fcb.rb +36 -5
- data/lib/filter.rb +1 -2
- data/lib/format_table.rb +1 -0
- data/lib/fout.rb +1 -1
- data/lib/hash.rb +0 -1
- data/lib/hash_delegator.rb +310 -162
- data/lib/link_history.rb +17 -17
- data/lib/logged_struct.rb +429 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +3 -3
- data/lib/mdoc.rb +5 -17
- data/lib/menu.src.yml +3 -1
- data/lib/menu.yml +1 -1
- data/lib/namer.rb +4 -5
- data/lib/null_result.rb +131 -0
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +1 -1
- data/lib/resize_terminal.rb +1 -2
- data/lib/saved_assets.rb +1 -1
- data/lib/saved_files_matcher.rb +1 -1
- data/lib/shell_session.rb +439 -0
- data/lib/streams_out.rb +0 -1
- data/lib/string_util.rb +11 -1
- data/lib/success_result.rb +112 -0
- data/lib/text_analyzer.rb +1 -0
- data/lib/ww.rb +9 -7
- metadata +23 -3
data/lib/hash_delegator.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/env bundle exec ruby
|
1
|
+
#!/usr/bin/env -S bundle exec ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# encoding=utf-8
|
@@ -45,14 +45,6 @@ require_relative 'text_analyzer'
|
|
45
45
|
$pd = false unless defined?($pd)
|
46
46
|
$table_cell_truncate = true
|
47
47
|
|
48
|
-
class String
|
49
|
-
# Checks if the string is not empty.
|
50
|
-
# @return [Boolean] Returns true if the string is not empty, false otherwise.
|
51
|
-
def non_empty?
|
52
|
-
!empty?
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
48
|
module HashDelegatorSelf
|
57
49
|
# Applies an ANSI color method to a string using a specified color key.
|
58
50
|
# The method retrieves the color method from the provided hash. If the
|
@@ -166,7 +158,7 @@ module HashDelegatorSelf
|
|
166
158
|
# (default is an empty string).
|
167
159
|
# @return [String] A single string with each line indented as specified.
|
168
160
|
def indent_all_lines(body, indent = nil)
|
169
|
-
return body unless indent&.
|
161
|
+
return body unless indent&.present?
|
170
162
|
|
171
163
|
body.lines.map { |line| indent + line.chomp }.join("\n")
|
172
164
|
end
|
@@ -862,12 +854,15 @@ module MarkdownExec
|
|
862
854
|
|
863
855
|
count = 0
|
864
856
|
blocks = []
|
857
|
+
results = {}
|
865
858
|
iter_blocks_from_nested_files do |btype, fcb|
|
866
859
|
count += 1
|
867
860
|
case btype
|
868
861
|
when :blocks
|
862
|
+
result = SuccessResult.instance
|
869
863
|
if @delegate_object[:bash]
|
870
|
-
|
864
|
+
# prepare block for menu, may fail and call HashDelegator.error_handler
|
865
|
+
result = fcb.for_menu!(
|
871
866
|
block_calls_scan: @delegate_object[:block_calls_scan],
|
872
867
|
block_name_match: @delegate_object[:block_name_match],
|
873
868
|
block_name_nick_match: @delegate_object[:block_name_nick_match],
|
@@ -878,10 +873,11 @@ module MarkdownExec
|
|
878
873
|
) do |oname, color|
|
879
874
|
apply_block_type_color_option(oname, color)
|
880
875
|
end
|
876
|
+
results[fcb.id] = result if result.failure?
|
881
877
|
else
|
882
878
|
expand_references!(fcb, link_state)
|
883
879
|
end
|
884
|
-
blocks << fcb
|
880
|
+
blocks << fcb unless result.failure?
|
885
881
|
when :filter # types accepted
|
886
882
|
%i[blocks line]
|
887
883
|
when :line
|
@@ -896,9 +892,9 @@ module MarkdownExec
|
|
896
892
|
end
|
897
893
|
end
|
898
894
|
end
|
899
|
-
|
900
|
-
blocks
|
895
|
+
OpenStruct.new(blocks: blocks, results: results)
|
901
896
|
rescue StandardError
|
897
|
+
# ww $@, $!,
|
902
898
|
HashDelegator.error_handler('blocks_from_nested_files')
|
903
899
|
end
|
904
900
|
|
@@ -914,7 +910,8 @@ module MarkdownExec
|
|
914
910
|
initial_code_required: false, key_format:
|
915
911
|
)
|
916
912
|
evaluate_shell_expressions(
|
917
|
-
(link_state&.inherited_lines_block || ''),
|
913
|
+
(link_state&.inherited_lines_block || ''),
|
914
|
+
commands,
|
918
915
|
initial_code_required: initial_code_required,
|
919
916
|
key_format: key_format
|
920
917
|
)
|
@@ -990,6 +987,21 @@ module MarkdownExec
|
|
990
987
|
]
|
991
988
|
end
|
992
989
|
|
990
|
+
# Executes the allowed exec command and processes the output
|
991
|
+
# @param export [Object] The export configuration object
|
992
|
+
# @param inherited_code [Array] The inherited code lines
|
993
|
+
# @param code_lines [Array] The code lines to append to
|
994
|
+
# @param required [Hash] Required code information
|
995
|
+
# @return [String, Symbol] The command output or :ux_exec_prohibited if execution failed
|
996
|
+
def process_allowed_exec(export, inherited_code, code_lines, required)
|
997
|
+
output = export_exec_with_code(
|
998
|
+
export, inherited_code, code_lines, required
|
999
|
+
)
|
1000
|
+
return :ux_exec_prohibited if output == :invalidated
|
1001
|
+
|
1002
|
+
output.split("\n")
|
1003
|
+
end
|
1004
|
+
|
993
1005
|
# parse YAML body defining the UX for a single variable
|
994
1006
|
# set ENV value for the variable and return code lines for the same
|
995
1007
|
def code_from_ux_block_to_set_environment_variables(
|
@@ -1023,105 +1035,30 @@ module MarkdownExec
|
|
1023
1035
|
code_lines.push "[[ -z $#{precondition} ]] && exit 1"
|
1024
1036
|
end
|
1025
1037
|
|
1026
|
-
exportable = true
|
1027
1038
|
if only_default
|
1028
|
-
value
|
1029
|
-
|
1030
|
-
when :echo
|
1031
|
-
raise unless export.echo.present?
|
1032
|
-
|
1033
|
-
output = export_echo_with_code(
|
1034
|
-
export, inherited_code, code_lines, required
|
1035
|
-
)
|
1036
|
-
if output == :invalidated
|
1037
|
-
return :ux_exec_prohibited
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
transform_export_value(output, export)
|
1041
|
-
|
1042
|
-
# exec > default
|
1043
|
-
when :exec
|
1044
|
-
raise unless export.exec.present?
|
1045
|
-
|
1046
|
-
output = export_exec_with_code(
|
1047
|
-
export, inherited_code, code_lines, required
|
1048
|
-
)
|
1049
|
-
if output == :invalidated
|
1050
|
-
return :ux_exec_prohibited
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
transform_export_value(output, export)
|
1054
|
-
|
1055
|
-
# default
|
1056
|
-
else
|
1057
|
-
export.default.to_s
|
1058
|
-
end
|
1059
|
-
else
|
1060
|
-
value = nil
|
1061
|
-
|
1062
|
-
# echo > exec
|
1063
|
-
if export.echo
|
1064
|
-
value = export_echo_with_code(
|
1039
|
+
value, exportable, transformable =
|
1040
|
+
ux_block_export_automatic(
|
1065
1041
|
export, inherited_code, code_lines, required
|
1066
1042
|
)
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
# exec > allowed
|
1072
|
-
elsif export.exec
|
1073
|
-
value = export_exec_with_code(
|
1074
|
-
export, inherited_code, code_lines, required
|
1043
|
+
else
|
1044
|
+
value, exportable, transformable =
|
1045
|
+
ux_block_export_activated(
|
1046
|
+
export, inherited_code, code_lines, required, exit_prompt
|
1075
1047
|
)
|
1076
|
-
|
1077
|
-
|
1078
|
-
end
|
1079
|
-
|
1080
|
-
# allowed > prompt
|
1081
|
-
elsif export.allowed && export.allowed.count.positive?
|
1082
|
-
case (choice = prompt_select_code_filename(
|
1083
|
-
[exit_prompt] + export.allowed,
|
1084
|
-
string: export.prompt,
|
1085
|
-
color_sym: :prompt_color_after_script_execution
|
1086
|
-
))
|
1087
|
-
when exit_prompt
|
1088
|
-
exportable = false
|
1089
|
-
else
|
1090
|
-
value = choice
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
# prompt > default
|
1094
|
-
elsif export.prompt.present?
|
1095
|
-
begin
|
1096
|
-
loop do
|
1097
|
-
print "#{export.prompt} [#{export.default}]: "
|
1098
|
-
value = gets.chomp
|
1099
|
-
value = export.default.to_s if value.empty?
|
1100
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1101
|
-
export.validate)
|
1102
|
-
break if caps
|
1103
|
-
|
1104
|
-
# invalid input, retry
|
1105
|
-
end
|
1106
|
-
rescue Interrupt
|
1107
|
-
exportable = false
|
1108
|
-
end
|
1048
|
+
end
|
1049
|
+
return :ux_exec_prohibited if value == :ux_exec_prohibited
|
1109
1050
|
|
1110
|
-
|
1111
|
-
|
1112
|
-
value = export
|
1051
|
+
if SelectResponse.continue?(value)
|
1052
|
+
if transformable
|
1053
|
+
value = transform_export_value(value, export)
|
1113
1054
|
end
|
1114
1055
|
|
1115
1056
|
if exportable
|
1116
|
-
|
1057
|
+
ENV[export.name] = value.to_s
|
1058
|
+
code_lines.push code_line_safe_assign(export.name, value,
|
1059
|
+
force: force)
|
1117
1060
|
end
|
1118
1061
|
end
|
1119
|
-
|
1120
|
-
if exportable
|
1121
|
-
ENV[export.name] = value.to_s
|
1122
|
-
code_lines.push code_line_safe_assign(export.name, value,
|
1123
|
-
force: force)
|
1124
|
-
end
|
1125
1062
|
else
|
1126
1063
|
raise "Invalid data type: #{data.inspect}"
|
1127
1064
|
end
|
@@ -1425,10 +1362,30 @@ module MarkdownExec
|
|
1425
1362
|
line_cap[:line] ||= ''
|
1426
1363
|
|
1427
1364
|
line_caps = [line_cap]
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1365
|
+
|
1366
|
+
# split text with newlines, from variable expansion
|
1367
|
+
if line_cap[:text].include?("\n")
|
1368
|
+
lines = line_cap[:text].split("\n")
|
1369
|
+
line_caps = (lines.map do |line|
|
1370
|
+
line_cap.dup.merge(text: line)
|
1371
|
+
end.to_a)
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
# wrap text on multiple lines to screen width, replacing line_caps
|
1375
|
+
if wrap
|
1376
|
+
line_caps = line_caps.flat_map do |line_cap|
|
1377
|
+
text = line_cap[:text]
|
1378
|
+
wrapper = StringWrapper.new(width: screen_width_for_wrapping - line_cap[:indent].length)
|
1379
|
+
|
1380
|
+
if text.length > screen_width_for_wrapping
|
1381
|
+
# Wrap this text and create line_cap objects for each part
|
1382
|
+
wrapper.wrap(text).map do |wrapped_text|
|
1383
|
+
line_cap.dup.merge(text: wrapped_text)
|
1384
|
+
end
|
1385
|
+
else
|
1386
|
+
# No change needed for this line
|
1387
|
+
line_cap
|
1388
|
+
end
|
1432
1389
|
end
|
1433
1390
|
end
|
1434
1391
|
|
@@ -1527,7 +1484,9 @@ module MarkdownExec
|
|
1527
1484
|
if block_given?
|
1528
1485
|
# expand references only if block is recognized (not a comment)
|
1529
1486
|
yield if block_given?
|
1530
|
-
|
1487
|
+
|
1488
|
+
# parse multiline to capture output of variable expansion
|
1489
|
+
mbody = fcb.body[0].match Regexp.new(@delegate_object[criteria[:match]], Regexp::MULTILINE)
|
1531
1490
|
end
|
1532
1491
|
|
1533
1492
|
create_and_add_chrome_block(
|
@@ -2432,7 +2391,8 @@ module MarkdownExec
|
|
2432
2391
|
# update blocks
|
2433
2392
|
#
|
2434
2393
|
Regexp.union(replacements.keys.map do |word|
|
2435
|
-
|
2394
|
+
# match multiline text from variable expansion
|
2395
|
+
Regexp.new(Regexp.escape(word), Regexp::MULTILINE)
|
2436
2396
|
end).tap do |pattern|
|
2437
2397
|
menu_blocks.each do |block|
|
2438
2398
|
next if exclude_types.include?(block.type)
|
@@ -2461,7 +2421,7 @@ module MarkdownExec
|
|
2461
2421
|
|
2462
2422
|
def expand_variable_references!(
|
2463
2423
|
blocks:,
|
2464
|
-
echo_format: 'echo $%s',
|
2424
|
+
echo_format: 'echo "$%s"',
|
2465
2425
|
group_name: :variable,
|
2466
2426
|
initial_code_required: false,
|
2467
2427
|
key_format: '${%s}',
|
@@ -2489,9 +2449,11 @@ module MarkdownExec
|
|
2489
2449
|
expand_blocks_with_replacements(blocks, replacements)
|
2490
2450
|
end
|
2491
2451
|
|
2492
|
-
def
|
2452
|
+
def export_echo_with_code_single(export_echo, inherited_code, code_lines,
|
2453
|
+
required)
|
2454
|
+
code = %(printf '%s' "#{export_echo}")
|
2493
2455
|
value = execute_temporary_script(
|
2494
|
-
|
2456
|
+
code,
|
2495
2457
|
(inherited_code || []) +
|
2496
2458
|
code_lines + required[:code]
|
2497
2459
|
)
|
@@ -2501,6 +2463,26 @@ module MarkdownExec
|
|
2501
2463
|
value
|
2502
2464
|
end
|
2503
2465
|
|
2466
|
+
def export_echo_with_code(export, inherited_code, code_lines, required,
|
2467
|
+
force:)
|
2468
|
+
exportable = true
|
2469
|
+
case export.echo
|
2470
|
+
when String
|
2471
|
+
value = export_echo_with_code_single(export.echo, inherited_code,
|
2472
|
+
code_lines, required)
|
2473
|
+
when Hash
|
2474
|
+
# each item in the hash is a variable name and value
|
2475
|
+
export.echo.each do |name, expression|
|
2476
|
+
value = export_echo_with_code_single(expression, inherited_code,
|
2477
|
+
code_lines, required)
|
2478
|
+
ENV[name] = value.to_s
|
2479
|
+
code_lines.push code_line_safe_assign(name, value, force: force)
|
2480
|
+
end
|
2481
|
+
exportable = false
|
2482
|
+
end
|
2483
|
+
[value, exportable]
|
2484
|
+
end
|
2485
|
+
|
2504
2486
|
def export_exec_with_code(export, inherited_code, code_lines, required)
|
2505
2487
|
value = execute_temporary_script(
|
2506
2488
|
export.exec,
|
@@ -2555,7 +2537,7 @@ module MarkdownExec
|
|
2555
2537
|
end
|
2556
2538
|
|
2557
2539
|
@dml_blocks_in_file.find(&match_block) ||
|
2558
|
-
|
2540
|
+
@dml_menu_blocks.find(&match_block)
|
2559
2541
|
end
|
2560
2542
|
|
2561
2543
|
# find a block by its original (undecorated) name or nickname (not visible in menu)
|
@@ -2763,7 +2745,7 @@ module MarkdownExec
|
|
2763
2745
|
menu_entries, current_display_format
|
2764
2746
|
)
|
2765
2747
|
|
2766
|
-
selection =
|
2748
|
+
selection = prompt_select_from_list(
|
2767
2749
|
menu_options,
|
2768
2750
|
string: menu_title,
|
2769
2751
|
color_sym: :prompt_color_after_script_execution
|
@@ -2819,7 +2801,7 @@ module MarkdownExec
|
|
2819
2801
|
def iter_source_blocks(source, source_id: nil, &block)
|
2820
2802
|
case source
|
2821
2803
|
when 1
|
2822
|
-
blocks_from_nested_files(source_id: source_id).each(&block)
|
2804
|
+
blocks_from_nested_files(source_id: source_id).blocks.each(&block)
|
2823
2805
|
when 2
|
2824
2806
|
@dml_blocks_in_file.each(&block)
|
2825
2807
|
when 3
|
@@ -2862,7 +2844,8 @@ module MarkdownExec
|
|
2862
2844
|
nil),
|
2863
2845
|
end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
|
2864
2846
|
scan1: @delegate_object.fetch(:output_assignment_match, nil),
|
2865
|
-
format1: @delegate_object.fetch(:output_assignment_format, nil)
|
2847
|
+
format1: @delegate_object.fetch(:output_assignment_format, nil),
|
2848
|
+
name: ''
|
2866
2849
|
)
|
2867
2850
|
|
2868
2851
|
else
|
@@ -3123,7 +3106,7 @@ module MarkdownExec
|
|
3123
3106
|
else
|
3124
3107
|
## user selects from existing files or other
|
3125
3108
|
#
|
3126
|
-
case (name =
|
3109
|
+
case (name = prompt_select_from_list(
|
3127
3110
|
[@delegate_object[:prompt_filespec_back]] + files,
|
3128
3111
|
string: @delegate_object[:prompt_select_code_file],
|
3129
3112
|
color_sym: :prompt_color_after_script_execution
|
@@ -3154,11 +3137,19 @@ module MarkdownExec
|
|
3154
3137
|
end
|
3155
3138
|
|
3156
3139
|
def mdoc_and_blocks_from_nested_files(source_id: nil)
|
3157
|
-
|
3158
|
-
|
3140
|
+
blocks_results = blocks_from_nested_files(source_id: source_id)
|
3141
|
+
|
3142
|
+
blocks_results.results.select do |_id, result|
|
3143
|
+
result.failure?
|
3144
|
+
end.each do |id, result|
|
3145
|
+
HashDelegator.error_handler("#{id} - #{result.to_yaml}")
|
3146
|
+
end
|
3147
|
+
|
3148
|
+
mdoc = MDoc.new(blocks_results.blocks) do |nopts|
|
3159
3149
|
@delegate_object.merge!(nopts)
|
3160
3150
|
end
|
3161
|
-
|
3151
|
+
|
3152
|
+
[blocks_results.blocks, mdoc]
|
3162
3153
|
end
|
3163
3154
|
|
3164
3155
|
## Handles the file loading and returns the blocks
|
@@ -3305,6 +3296,19 @@ module MarkdownExec
|
|
3305
3296
|
end
|
3306
3297
|
end
|
3307
3298
|
|
3299
|
+
def menu_from_list_with_back(list)
|
3300
|
+
case (name = prompt_select_from_list(
|
3301
|
+
[@delegate_object[:prompt_filespec_back]] + list,
|
3302
|
+
string: @delegate_object[:prompt_select_code_file],
|
3303
|
+
color_sym: :prompt_color_after_script_execution
|
3304
|
+
))
|
3305
|
+
when @delegate_object[:prompt_filespec_back]
|
3306
|
+
SelectResponse::BACK
|
3307
|
+
else
|
3308
|
+
name
|
3309
|
+
end
|
3310
|
+
end
|
3311
|
+
|
3308
3312
|
def menu_toggle_collapsible_block(selected)
|
3309
3313
|
# return true if @compress_ids.key?(fcb.id) && !!@compress_ids[fcb.id]
|
3310
3314
|
# return false if @expand_ids.key?(fcb.id) && !!@expand_ids[fcb.id]
|
@@ -3538,7 +3542,7 @@ module MarkdownExec
|
|
3538
3542
|
# private
|
3539
3543
|
|
3540
3544
|
def process_string_array(arr, begin_pattern: nil, end_pattern: nil, scan1: nil,
|
3541
|
-
format1: nil)
|
3545
|
+
format1: nil, name: '')
|
3542
3546
|
in_block = !begin_pattern.present?
|
3543
3547
|
collected_lines = []
|
3544
3548
|
|
@@ -3560,6 +3564,9 @@ module MarkdownExec
|
|
3560
3564
|
collected_lines << formatted
|
3561
3565
|
end
|
3562
3566
|
end
|
3567
|
+
elsif format1.present?
|
3568
|
+
formatted = format(format1, { value: line })
|
3569
|
+
collected_lines << formatted
|
3563
3570
|
else
|
3564
3571
|
collected_lines << line
|
3565
3572
|
end
|
@@ -3685,9 +3692,22 @@ module MarkdownExec
|
|
3685
3692
|
0
|
3686
3693
|
end
|
3687
3694
|
|
3695
|
+
def prompt_select_continue(filter: true, quiet: true)
|
3696
|
+
sel = @prompt.select(
|
3697
|
+
string_send_color(@delegate_object[:prompt_after_script_execution],
|
3698
|
+
:prompt_color_after_script_execution),
|
3699
|
+
filter: filter,
|
3700
|
+
quiet: quiet
|
3701
|
+
) do |menu|
|
3702
|
+
menu.choice @delegate_object[:prompt_yes]
|
3703
|
+
menu.choice @delegate_object[:prompt_exit]
|
3704
|
+
end
|
3705
|
+
sel == @delegate_object[:prompt_exit] ? MenuState::EXIT : MenuState::CONTINUE
|
3706
|
+
end
|
3707
|
+
|
3688
3708
|
# public
|
3689
3709
|
|
3690
|
-
def
|
3710
|
+
def prompt_select_from_list(
|
3691
3711
|
filenames,
|
3692
3712
|
color_sym: :prompt_color_after_script_execution,
|
3693
3713
|
cycle: true,
|
@@ -3713,19 +3733,6 @@ module MarkdownExec
|
|
3713
3733
|
end
|
3714
3734
|
end
|
3715
3735
|
|
3716
|
-
def prompt_select_continue(filter: true, quiet: true)
|
3717
|
-
sel = @prompt.select(
|
3718
|
-
string_send_color(@delegate_object[:prompt_after_script_execution],
|
3719
|
-
:prompt_color_after_script_execution),
|
3720
|
-
filter: filter,
|
3721
|
-
quiet: quiet
|
3722
|
-
) do |menu|
|
3723
|
-
menu.choice @delegate_object[:prompt_yes]
|
3724
|
-
menu.choice @delegate_object[:prompt_exit]
|
3725
|
-
end
|
3726
|
-
sel == @delegate_object[:prompt_exit] ? MenuState::EXIT : MenuState::CONTINUE
|
3727
|
-
end
|
3728
|
-
|
3729
3736
|
# user prompt to exit if the menu will be displayed again
|
3730
3737
|
#
|
3731
3738
|
def prompt_user_exit(block_name_from_cli:, selected:)
|
@@ -3799,27 +3806,6 @@ module MarkdownExec
|
|
3799
3806
|
end&.compact
|
3800
3807
|
end
|
3801
3808
|
|
3802
|
-
def saved_asset_for_history(
|
3803
|
-
file:, form:, match_info:
|
3804
|
-
)
|
3805
|
-
OpenStruct.new(
|
3806
|
-
file: file[(Dir.pwd.length + 1)..-1],
|
3807
|
-
full: file,
|
3808
|
-
row: format(
|
3809
|
-
form,
|
3810
|
-
# default '*' so unknown parameters are given a wildcard
|
3811
|
-
match_info.names.each_with_object(Hash.new('*')) do |name, hash|
|
3812
|
-
hash[name.to_sym] = match_info[name]
|
3813
|
-
end
|
3814
|
-
)
|
3815
|
-
)
|
3816
|
-
rescue KeyError
|
3817
|
-
# pp $!, $@
|
3818
|
-
warn "Cannot format with: #{@delegate_object[:saved_history_format]}"
|
3819
|
-
error_handler('saved_history_format')
|
3820
|
-
:break
|
3821
|
-
end
|
3822
|
-
|
3823
3809
|
# Processes YAML data from the selected menu item, updating delegate
|
3824
3810
|
# objects and optionally printing formatted output.
|
3825
3811
|
# @param selected [Hash] Selected item from the menu containing a YAML body.
|
@@ -3874,8 +3860,8 @@ module MarkdownExec
|
|
3874
3860
|
# console [height, width]. If not provided or if the terminal
|
3875
3861
|
# is resized, it will be set to the current console dimensions.
|
3876
3862
|
# - :select_page_height [Integer, nil] The height of the page for
|
3877
|
-
# selection. If not provided or if not positive, it
|
3878
|
-
# to the maximum of (console height - 3) or 4.
|
3863
|
+
# selection. If not provided or if not positive, it
|
3864
|
+
# will be set to the maximum of (console height - 3) or 4.
|
3879
3865
|
# - :per_page [Integer, nil] The number of items per page. If
|
3880
3866
|
# :select_page_height is not provided or if not positive, it
|
3881
3867
|
# will be set to the maximum of (console height - 3) or 4.
|
@@ -4002,7 +3988,7 @@ module MarkdownExec
|
|
4002
3988
|
## user selects from existing files or other
|
4003
3989
|
# input into path with wildcard for easy entry
|
4004
3990
|
#
|
4005
|
-
case (name =
|
3991
|
+
case (name = prompt_select_from_list(
|
4006
3992
|
[@delegate_object[:prompt_filespec_back],
|
4007
3993
|
@delegate_object[:prompt_filespec_other]] + files,
|
4008
3994
|
string: @delegate_object[:prompt_select_code_file],
|
@@ -4039,6 +4025,27 @@ module MarkdownExec
|
|
4039
4025
|
).generate_name
|
4040
4026
|
end
|
4041
4027
|
|
4028
|
+
def saved_asset_for_history(
|
4029
|
+
file:, form:, match_info:
|
4030
|
+
)
|
4031
|
+
OpenStruct.new(
|
4032
|
+
file: file[(Dir.pwd.length + 1)..-1],
|
4033
|
+
full: file,
|
4034
|
+
row: format(
|
4035
|
+
form,
|
4036
|
+
# default '*' so unknown parameters are given a wildcard
|
4037
|
+
match_info.names.each_with_object(Hash.new('*')) do |name, hash|
|
4038
|
+
hash[name.to_sym] = match_info[name]
|
4039
|
+
end
|
4040
|
+
)
|
4041
|
+
)
|
4042
|
+
rescue KeyError
|
4043
|
+
# pp $!, $@
|
4044
|
+
warn "Cannot format with: #{@delegate_object[:saved_history_format]}"
|
4045
|
+
error_handler('saved_history_format')
|
4046
|
+
:break
|
4047
|
+
end
|
4048
|
+
|
4042
4049
|
def screen_width
|
4043
4050
|
width = @delegate_object[:screen_width]
|
4044
4051
|
if width&.positive?
|
@@ -4387,6 +4394,147 @@ module MarkdownExec
|
|
4387
4394
|
@delegate_object.merge!(options)
|
4388
4395
|
end
|
4389
4396
|
|
4397
|
+
def ux_block_export_activated(export, inherited_code, code_lines, required,
|
4398
|
+
exit_prompt)
|
4399
|
+
exportable = true
|
4400
|
+
transformable = true
|
4401
|
+
[if export.allowed.present?
|
4402
|
+
if export.allowed == :echo
|
4403
|
+
output, exportable = export_echo_with_code(
|
4404
|
+
export, inherited_code, code_lines, required, force: true
|
4405
|
+
)
|
4406
|
+
return :ux_exec_prohibited if output == :invalidated
|
4407
|
+
|
4408
|
+
menu_from_list_with_back(output.split("\n"))
|
4409
|
+
|
4410
|
+
elsif export.allowed == :exec
|
4411
|
+
output = process_allowed_exec(export, inherited_code,
|
4412
|
+
code_lines, required)
|
4413
|
+
return :ux_exec_prohibited if output == :ux_exec_prohibited
|
4414
|
+
|
4415
|
+
menu_from_list_with_back(output)
|
4416
|
+
|
4417
|
+
else
|
4418
|
+
menu_from_list_with_back(export.allowed)
|
4419
|
+
end
|
4420
|
+
|
4421
|
+
# echo > exec
|
4422
|
+
elsif export.echo
|
4423
|
+
output, exportable = export_echo_with_code(
|
4424
|
+
export, inherited_code, code_lines, required, force: true
|
4425
|
+
)
|
4426
|
+
return :ux_exec_prohibited if output == :invalidated
|
4427
|
+
|
4428
|
+
output
|
4429
|
+
|
4430
|
+
# exec > allowed
|
4431
|
+
elsif export.exec
|
4432
|
+
output = export_exec_with_code(
|
4433
|
+
export, inherited_code, code_lines, required
|
4434
|
+
)
|
4435
|
+
return :ux_exec_prohibited if output == :invalidated
|
4436
|
+
|
4437
|
+
output
|
4438
|
+
|
4439
|
+
# allowed > prompt
|
4440
|
+
elsif export.allowed && export.allowed.count.positive?
|
4441
|
+
case (choice = prompt_select_from_list(
|
4442
|
+
[exit_prompt] + export.allowed,
|
4443
|
+
string: export.prompt,
|
4444
|
+
color_sym: :prompt_color_after_script_execution
|
4445
|
+
))
|
4446
|
+
when exit_prompt
|
4447
|
+
exportable = false
|
4448
|
+
transformable = false
|
4449
|
+
nil
|
4450
|
+
else
|
4451
|
+
choice
|
4452
|
+
end
|
4453
|
+
|
4454
|
+
# prompt > default
|
4455
|
+
elsif export.prompt.present?
|
4456
|
+
begin
|
4457
|
+
loop do
|
4458
|
+
print "#{export.prompt} [#{export.default}]: "
|
4459
|
+
output = gets.chomp
|
4460
|
+
output = export.default.to_s if output.empty?
|
4461
|
+
caps = NamedCaptureExtractor.extract_named_groups(output,
|
4462
|
+
export.validate)
|
4463
|
+
break if caps
|
4464
|
+
|
4465
|
+
# invalid input, retry
|
4466
|
+
end
|
4467
|
+
rescue Interrupt
|
4468
|
+
exportable = false
|
4469
|
+
transformable = false
|
4470
|
+
end
|
4471
|
+
|
4472
|
+
output
|
4473
|
+
|
4474
|
+
# default
|
4475
|
+
else
|
4476
|
+
transformable = false
|
4477
|
+
export.default
|
4478
|
+
end, exportable, transformable]
|
4479
|
+
end
|
4480
|
+
|
4481
|
+
def ux_block_export_automatic(export, inherited_code, code_lines, required)
|
4482
|
+
transformable = true
|
4483
|
+
exportable = true
|
4484
|
+
[case export.default
|
4485
|
+
when :allowed
|
4486
|
+
raise unless export.allowed.present?
|
4487
|
+
|
4488
|
+
if export.allowed == :echo
|
4489
|
+
output, exportable = export_echo_with_code(
|
4490
|
+
export, inherited_code, code_lines, required, force: false
|
4491
|
+
)
|
4492
|
+
return :ux_exec_prohibited if output == :invalidated
|
4493
|
+
|
4494
|
+
exportable && output.split("\n").first
|
4495
|
+
|
4496
|
+
elsif export.allowed == :exec
|
4497
|
+
output = process_allowed_exec(export, inherited_code,
|
4498
|
+
code_lines, required)
|
4499
|
+
return :ux_exec_prohibited if output == :ux_exec_prohibited
|
4500
|
+
|
4501
|
+
output.first
|
4502
|
+
|
4503
|
+
else
|
4504
|
+
export.allowed.first
|
4505
|
+
end
|
4506
|
+
|
4507
|
+
# echo > default
|
4508
|
+
when :echo
|
4509
|
+
raise unless export.echo.present?
|
4510
|
+
|
4511
|
+
output, exportable = export_echo_with_code(
|
4512
|
+
export, inherited_code, code_lines, required, force: false
|
4513
|
+
)
|
4514
|
+
return :ux_exec_prohibited if output == :invalidated
|
4515
|
+
|
4516
|
+
output
|
4517
|
+
|
4518
|
+
# exec > default
|
4519
|
+
when :exec
|
4520
|
+
raise unless export.exec.present?
|
4521
|
+
|
4522
|
+
output = export_exec_with_code(
|
4523
|
+
export, inherited_code, code_lines, required
|
4524
|
+
)
|
4525
|
+
return :ux_exec_prohibited if output == :invalidated
|
4526
|
+
|
4527
|
+
output
|
4528
|
+
|
4529
|
+
# default
|
4530
|
+
else
|
4531
|
+
transformable = false
|
4532
|
+
export.default.to_s
|
4533
|
+
end,
|
4534
|
+
exportable,
|
4535
|
+
transformable]
|
4536
|
+
end
|
4537
|
+
|
4390
4538
|
def vux_await_user_selection(prior_answer: @dml_block_selection)
|
4391
4539
|
@dml_block_state = load_cli_or_user_selected_block(
|
4392
4540
|
all_blocks: @dml_blocks_in_file,
|
@@ -5324,7 +5472,7 @@ module MarkdownExec
|
|
5324
5472
|
end
|
5325
5473
|
|
5326
5474
|
def test_blocks_from_nested_files
|
5327
|
-
result = @hd.blocks_from_nested_files
|
5475
|
+
result = @hd.blocks_from_nested_files.blocks
|
5328
5476
|
assert_kind_of Array, result
|
5329
5477
|
assert_kind_of FCB, result.first
|
5330
5478
|
end
|
@@ -5333,7 +5481,7 @@ module MarkdownExec
|
|
5333
5481
|
@hd = HashDelegator.new(no_chrome: true)
|
5334
5482
|
@hd.expects(:create_and_add_chrome_blocks).never
|
5335
5483
|
|
5336
|
-
result = @hd.blocks_from_nested_files
|
5484
|
+
result = @hd.blocks_from_nested_files.blocks
|
5337
5485
|
|
5338
5486
|
assert_kind_of Array, result
|
5339
5487
|
end
|