markdown_exec 2.8.2 → 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 +52 -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 +20 -0
- 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-preconditions.bats +8 -0
- data/bats/block-type-ux-readonly.bats +10 -0
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/block-type-vars.bats +3 -3
- data/bats/indented-block-type-vars.bats +9 -0
- data/bats/indented-multi-line-output.bats +9 -0
- data/bats/line-decor-dynamic.bats +8 -0
- data/bats/test_helper.bash +19 -2
- data/bats/variable-expansion-multiline.bats +8 -0
- data/bats/variable-expansion.bats +1 -1
- data/bin/tab_completion.sh +0 -5
- data/bin/tab_completion.sh.erb +0 -5
- 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-echo.md +21 -0
- data/docs/dev/block-type-ux-hidden.md +21 -0
- data/docs/dev/block-type-ux-invalid.md +5 -0
- data/docs/dev/block-type-ux-preconditions.md +9 -0
- data/docs/dev/block-type-ux-readonly.md +7 -0
- data/docs/dev/block-type-ux-require.md +8 -4
- data/docs/dev/indented-block-type-vars.md +6 -0
- data/docs/dev/indented-multi-line-output.md +11 -0
- data/docs/dev/line-decor-dynamic.md +10 -0
- data/docs/dev/variable-expansion-multiline.md +31 -0
- data/lib/ansi_formatter.rb +0 -1
- data/lib/ansi_string.rb +10 -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 +51 -8
- data/lib/filter.rb +4 -4
- data/lib/format_table.rb +1 -0
- data/lib/fout.rb +1 -1
- data/lib/hash.rb +0 -1
- data/lib/hash_delegator.rb +403 -200
- 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 +33 -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
|
@@ -395,10 +387,17 @@ module HashDelegatorSelf
|
|
395
387
|
# @param [String] line The line to be processed.
|
396
388
|
# @param [Array<Symbol>] selected_types A list of message types to check.
|
397
389
|
# @param [Proc] block The block to be called with the line data.
|
398
|
-
def yield_line_if_selected(line, selected_types,
|
390
|
+
def yield_line_if_selected(line, selected_types, all_fcbs: nil,
|
391
|
+
source_id: '', &block)
|
399
392
|
return unless block && block_type_selected?(selected_types, :line)
|
400
393
|
|
401
|
-
block.call(:line,
|
394
|
+
block.call(:line, persist_fcb_self(all_fcbs, body: [line], id: source_id))
|
395
|
+
end
|
396
|
+
|
397
|
+
def persist_fcb_self(all_fcbs, options)
|
398
|
+
fcb = MarkdownExec::FCB.new(options)
|
399
|
+
all_fcbs << fcb if all_fcbs
|
400
|
+
fcb
|
402
401
|
end
|
403
402
|
end
|
404
403
|
|
@@ -609,6 +608,7 @@ module MarkdownExec
|
|
609
608
|
@dml_link_state = Struct.new(:document_filename, :inherited_lines)
|
610
609
|
.new(@delegate_object[:filename], [])
|
611
610
|
@dml_menu_blocks = []
|
611
|
+
@fcb_store = [] # all fcbs created
|
612
612
|
|
613
613
|
@p_all_arguments = []
|
614
614
|
@p_options_parsed = []
|
@@ -737,7 +737,7 @@ module MarkdownExec
|
|
737
737
|
|
738
738
|
formatted_name = format(@delegate_object[:menu_link_format],
|
739
739
|
HashDelegator.safeval(option_name))
|
740
|
-
chrome_block =
|
740
|
+
chrome_block = persist_fcb(
|
741
741
|
chrome: true,
|
742
742
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
743
743
|
formatted_name, :menu_chrome_color
|
@@ -781,7 +781,7 @@ module MarkdownExec
|
|
781
781
|
chrome_blocks = link_state.inherited_lines_map do |line|
|
782
782
|
formatted = format(@delegate_object[:menu_inherited_lines_format],
|
783
783
|
{ line: line })
|
784
|
-
|
784
|
+
persist_fcb(
|
785
785
|
chrome: true,
|
786
786
|
disabled: TtyMenu::DISABLE,
|
787
787
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
@@ -840,25 +840,6 @@ module MarkdownExec
|
|
840
840
|
end
|
841
841
|
end
|
842
842
|
|
843
|
-
# private
|
844
|
-
|
845
|
-
def expand_references!(fcb, link_state)
|
846
|
-
expand_variable_references!(
|
847
|
-
blocks: [fcb],
|
848
|
-
initial_code_required: false,
|
849
|
-
link_state: link_state
|
850
|
-
)
|
851
|
-
expand_variable_references!(
|
852
|
-
blocks: [fcb],
|
853
|
-
echo_format: '%s',
|
854
|
-
group_name: :command,
|
855
|
-
initial_code_required: false,
|
856
|
-
key_format: '$(%s)',
|
857
|
-
link_state: link_state,
|
858
|
-
pattern: options_command_substitution_regexp
|
859
|
-
)
|
860
|
-
end
|
861
|
-
|
862
843
|
# Iterates through nested files to collect various types
|
863
844
|
# of blocks, including dividers, tasks, and others.
|
864
845
|
# The method categorizes blocks based on their type and processes them accordingly.
|
@@ -873,12 +854,15 @@ module MarkdownExec
|
|
873
854
|
|
874
855
|
count = 0
|
875
856
|
blocks = []
|
857
|
+
results = {}
|
876
858
|
iter_blocks_from_nested_files do |btype, fcb|
|
877
859
|
count += 1
|
878
860
|
case btype
|
879
861
|
when :blocks
|
862
|
+
result = SuccessResult.instance
|
880
863
|
if @delegate_object[:bash]
|
881
|
-
|
864
|
+
# prepare block for menu, may fail and call HashDelegator.error_handler
|
865
|
+
result = fcb.for_menu!(
|
882
866
|
block_calls_scan: @delegate_object[:block_calls_scan],
|
883
867
|
block_name_match: @delegate_object[:block_name_match],
|
884
868
|
block_name_nick_match: @delegate_object[:block_name_nick_match],
|
@@ -889,10 +873,11 @@ module MarkdownExec
|
|
889
873
|
) do |oname, color|
|
890
874
|
apply_block_type_color_option(oname, color)
|
891
875
|
end
|
876
|
+
results[fcb.id] = result if result.failure?
|
892
877
|
else
|
893
878
|
expand_references!(fcb, link_state)
|
894
879
|
end
|
895
|
-
blocks << fcb
|
880
|
+
blocks << fcb unless result.failure?
|
896
881
|
when :filter # types accepted
|
897
882
|
%i[blocks line]
|
898
883
|
when :line
|
@@ -907,36 +892,12 @@ module MarkdownExec
|
|
907
892
|
end
|
908
893
|
end
|
909
894
|
end
|
910
|
-
|
911
|
-
blocks
|
895
|
+
OpenStruct.new(blocks: blocks, results: results)
|
912
896
|
rescue StandardError
|
897
|
+
# ww $@, $!,
|
913
898
|
HashDelegator.error_handler('blocks_from_nested_files')
|
914
899
|
end
|
915
900
|
|
916
|
-
# find a block by its original (undecorated) name or nickname (not visible in menu)
|
917
|
-
# if matched, the block returned has properties that it is from cli and not ui
|
918
|
-
def block_state_for_name_from_cli(block_name)
|
919
|
-
SelectedBlockMenuState.new(
|
920
|
-
blocks_find_by_block_name(@dml_blocks_in_file, block_name),
|
921
|
-
OpenStruct.new(
|
922
|
-
block_name_from_cli: true,
|
923
|
-
block_name_from_ui: false
|
924
|
-
),
|
925
|
-
MenuState::CONTINUE
|
926
|
-
)
|
927
|
-
end
|
928
|
-
|
929
|
-
def blocks_find_by_block_name(blocks, block_name)
|
930
|
-
@dml_blocks_in_file.find do |item|
|
931
|
-
# 2024-08-04 match oname for long block names
|
932
|
-
# 2024-08-04 match nickname for long block names
|
933
|
-
block_name == item.pub_name || block_name == item.nickname || block_name == item.oname
|
934
|
-
end || @dml_menu_blocks.find do |item|
|
935
|
-
# 2024-08-22 search in menu blocks to allow matching of automatic chrome with nickname
|
936
|
-
block_name == item.pub_name || block_name == item.nickname || block_name == item.oname
|
937
|
-
end
|
938
|
-
end
|
939
|
-
|
940
901
|
def build_menu_options(exit_option, display_mode_option,
|
941
902
|
menu_entries, display_format)
|
942
903
|
[exit_option,
|
@@ -949,7 +910,8 @@ module MarkdownExec
|
|
949
910
|
initial_code_required: false, key_format:
|
950
911
|
)
|
951
912
|
evaluate_shell_expressions(
|
952
|
-
(link_state&.inherited_lines_block || ''),
|
913
|
+
(link_state&.inherited_lines_block || ''),
|
914
|
+
commands,
|
953
915
|
initial_code_required: initial_code_required,
|
954
916
|
key_format: key_format
|
955
917
|
)
|
@@ -1025,6 +987,21 @@ module MarkdownExec
|
|
1025
987
|
]
|
1026
988
|
end
|
1027
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
|
+
|
1028
1005
|
# parse YAML body defining the UX for a single variable
|
1029
1006
|
# set ENV value for the variable and return code lines for the same
|
1030
1007
|
def code_from_ux_block_to_set_environment_variables(
|
@@ -1058,82 +1035,30 @@ module MarkdownExec
|
|
1058
1035
|
code_lines.push "[[ -z $#{precondition} ]] && exit 1"
|
1059
1036
|
end
|
1060
1037
|
|
1061
|
-
exportable = true
|
1062
1038
|
if only_default
|
1063
|
-
value
|
1064
|
-
|
1065
|
-
when :exec
|
1066
|
-
raise unless export.exec.present?
|
1067
|
-
|
1068
|
-
output = export_exec_with_code(
|
1069
|
-
export, inherited_code, code_lines, required
|
1070
|
-
)
|
1071
|
-
if output == :invalidated
|
1072
|
-
return :ux_exec_prohibited
|
1073
|
-
end
|
1074
|
-
|
1075
|
-
transform_export_value(output, export)
|
1076
|
-
# default
|
1077
|
-
else
|
1078
|
-
export.default.to_s
|
1079
|
-
end
|
1080
|
-
else
|
1081
|
-
value = nil
|
1082
|
-
|
1083
|
-
# exec > allowed
|
1084
|
-
if export.exec
|
1085
|
-
value = export_exec_with_code(
|
1039
|
+
value, exportable, transformable =
|
1040
|
+
ux_block_export_automatic(
|
1086
1041
|
export, inherited_code, code_lines, required
|
1087
1042
|
)
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
[exit_prompt] + export.allowed,
|
1096
|
-
string: export.prompt,
|
1097
|
-
color_sym: :prompt_color_after_script_execution
|
1098
|
-
))
|
1099
|
-
when exit_prompt
|
1100
|
-
exportable = false
|
1101
|
-
else
|
1102
|
-
value = choice
|
1103
|
-
end
|
1104
|
-
|
1105
|
-
# prompt > default
|
1106
|
-
elsif export.prompt.present?
|
1107
|
-
begin
|
1108
|
-
loop do
|
1109
|
-
print "#{export.prompt} [#{export.default}]: "
|
1110
|
-
value = gets.chomp
|
1111
|
-
value = export.default.to_s if value.empty?
|
1112
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1113
|
-
export.validate)
|
1114
|
-
break if caps
|
1115
|
-
|
1116
|
-
# invalid input, retry
|
1117
|
-
end
|
1118
|
-
rescue Interrupt
|
1119
|
-
exportable = false
|
1120
|
-
end
|
1043
|
+
else
|
1044
|
+
value, exportable, transformable =
|
1045
|
+
ux_block_export_activated(
|
1046
|
+
export, inherited_code, code_lines, required, exit_prompt
|
1047
|
+
)
|
1048
|
+
end
|
1049
|
+
return :ux_exec_prohibited if value == :ux_exec_prohibited
|
1121
1050
|
|
1122
|
-
|
1123
|
-
|
1124
|
-
value = export
|
1051
|
+
if SelectResponse.continue?(value)
|
1052
|
+
if transformable
|
1053
|
+
value = transform_export_value(value, export)
|
1125
1054
|
end
|
1126
1055
|
|
1127
1056
|
if exportable
|
1128
|
-
|
1057
|
+
ENV[export.name] = value.to_s
|
1058
|
+
code_lines.push code_line_safe_assign(export.name, value,
|
1059
|
+
force: force)
|
1129
1060
|
end
|
1130
1061
|
end
|
1131
|
-
|
1132
|
-
if exportable
|
1133
|
-
ENV[export.name] = value.to_s
|
1134
|
-
code_lines.push code_line_safe_assign(export.name, value,
|
1135
|
-
force: force)
|
1136
|
-
end
|
1137
1062
|
else
|
1138
1063
|
raise "Invalid data type: #{data.inspect}"
|
1139
1064
|
end
|
@@ -1382,7 +1307,7 @@ module MarkdownExec
|
|
1382
1307
|
next if exclude_types.include?(block.type)
|
1383
1308
|
|
1384
1309
|
# Scan each block name for matches of the pattern
|
1385
|
-
(
|
1310
|
+
count_named_group_occurrences_block_body_fix_indent(block).scan(pattern) do |(_, _variable_name)|
|
1386
1311
|
pattern.match($LAST_MATCH_INFO.to_s) # Reapply match for named groups
|
1387
1312
|
occurrence_count[$LAST_MATCH_INFO[group_name]] += 1
|
1388
1313
|
end
|
@@ -1391,6 +1316,11 @@ module MarkdownExec
|
|
1391
1316
|
occurrence_count
|
1392
1317
|
end
|
1393
1318
|
|
1319
|
+
def count_named_group_occurrences_block_body_fix_indent(block)
|
1320
|
+
### actually double the entries, but not a problem since it's used as a boolean
|
1321
|
+
([block.oname || ''] + block.body).join("\n")
|
1322
|
+
end
|
1323
|
+
|
1394
1324
|
##
|
1395
1325
|
# Creates and adds a formatted block to the blocks array
|
1396
1326
|
# based on the provided match and format options.
|
@@ -1432,10 +1362,30 @@ module MarkdownExec
|
|
1432
1362
|
line_cap[:line] ||= ''
|
1433
1363
|
|
1434
1364
|
line_caps = [line_cap]
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
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
|
1439
1389
|
end
|
1440
1390
|
end
|
1441
1391
|
|
@@ -1492,7 +1442,7 @@ module MarkdownExec
|
|
1492
1442
|
fcb.type = type
|
1493
1443
|
use_fcb = false # next line is new record
|
1494
1444
|
else
|
1495
|
-
fcb =
|
1445
|
+
fcb = persist_fcb(
|
1496
1446
|
center: center,
|
1497
1447
|
chrome: true,
|
1498
1448
|
collapse: collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse,
|
@@ -1534,7 +1484,9 @@ module MarkdownExec
|
|
1534
1484
|
if block_given?
|
1535
1485
|
# expand references only if block is recognized (not a comment)
|
1536
1486
|
yield if block_given?
|
1537
|
-
|
1487
|
+
|
1488
|
+
# parse multiline to capture output of variable expansion
|
1489
|
+
mbody = fcb.body[0].match Regexp.new(@delegate_object[criteria[:match]], Regexp::MULTILINE)
|
1538
1490
|
end
|
1539
1491
|
|
1540
1492
|
create_and_add_chrome_block(
|
@@ -1579,7 +1531,7 @@ module MarkdownExec
|
|
1579
1531
|
oname = format(@delegate_object[:menu_divider_format],
|
1580
1532
|
HashDelegator.safeval(@delegate_object[divider_key]))
|
1581
1533
|
|
1582
|
-
|
1534
|
+
persist_fcb(
|
1583
1535
|
chrome: true,
|
1584
1536
|
disabled: TtyMenu::DISABLE,
|
1585
1537
|
dname: string_send_color(oname, :menu_divider_color),
|
@@ -1989,7 +1941,7 @@ module MarkdownExec
|
|
1989
1941
|
end
|
1990
1942
|
|
1991
1943
|
def execute_block_in_state(block_name)
|
1992
|
-
@dml_block_state =
|
1944
|
+
@dml_block_state = find_block_state_by_name(block_name)
|
1993
1945
|
dump_and_warn_block_state(name: block_name,
|
1994
1946
|
selected: @dml_block_state.block)
|
1995
1947
|
next_block_state =
|
@@ -2439,7 +2391,8 @@ module MarkdownExec
|
|
2439
2391
|
# update blocks
|
2440
2392
|
#
|
2441
2393
|
Regexp.union(replacements.keys.map do |word|
|
2442
|
-
|
2394
|
+
# match multiline text from variable expansion
|
2395
|
+
Regexp.new(Regexp.escape(word), Regexp::MULTILINE)
|
2443
2396
|
end).tap do |pattern|
|
2444
2397
|
menu_blocks.each do |block|
|
2445
2398
|
next if exclude_types.include?(block.type)
|
@@ -2449,9 +2402,26 @@ module MarkdownExec
|
|
2449
2402
|
end
|
2450
2403
|
end
|
2451
2404
|
|
2405
|
+
def expand_references!(fcb, link_state)
|
2406
|
+
expand_variable_references!(
|
2407
|
+
blocks: [fcb],
|
2408
|
+
initial_code_required: false,
|
2409
|
+
link_state: link_state
|
2410
|
+
)
|
2411
|
+
expand_variable_references!(
|
2412
|
+
blocks: [fcb],
|
2413
|
+
echo_format: '%s',
|
2414
|
+
group_name: :command,
|
2415
|
+
initial_code_required: false,
|
2416
|
+
key_format: '$(%s)',
|
2417
|
+
link_state: link_state,
|
2418
|
+
pattern: options_command_substitution_regexp
|
2419
|
+
)
|
2420
|
+
end
|
2421
|
+
|
2452
2422
|
def expand_variable_references!(
|
2453
2423
|
blocks:,
|
2454
|
-
echo_format: 'echo $%s',
|
2424
|
+
echo_format: 'echo "$%s"',
|
2455
2425
|
group_name: :variable,
|
2456
2426
|
initial_code_required: false,
|
2457
2427
|
key_format: '${%s}',
|
@@ -2479,6 +2449,40 @@ module MarkdownExec
|
|
2479
2449
|
expand_blocks_with_replacements(blocks, replacements)
|
2480
2450
|
end
|
2481
2451
|
|
2452
|
+
def export_echo_with_code_single(export_echo, inherited_code, code_lines,
|
2453
|
+
required)
|
2454
|
+
code = %(printf '%s' "#{export_echo}")
|
2455
|
+
value = execute_temporary_script(
|
2456
|
+
code,
|
2457
|
+
(inherited_code || []) +
|
2458
|
+
code_lines + required[:code]
|
2459
|
+
)
|
2460
|
+
if value == :invalidated
|
2461
|
+
warn "A value must exist for: #{export.preconditions.join(', ')}"
|
2462
|
+
end
|
2463
|
+
value
|
2464
|
+
end
|
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
|
+
|
2482
2486
|
def export_exec_with_code(export, inherited_code, code_lines, required)
|
2483
2487
|
value = execute_temporary_script(
|
2484
2488
|
export.exec,
|
@@ -2524,6 +2528,31 @@ module MarkdownExec
|
|
2524
2528
|
{ size: file_size, lines: line_count }
|
2525
2529
|
end
|
2526
2530
|
|
2531
|
+
# Search in @dml_blocks_in_file first,
|
2532
|
+
# fallback to @dml_menu_blocks if not found.
|
2533
|
+
def find_block_by_name(blocks, block_name)
|
2534
|
+
match_block = ->(item) do
|
2535
|
+
[item.pub_name, item.nickname,
|
2536
|
+
item.oname, item.s2title].include?(block_name)
|
2537
|
+
end
|
2538
|
+
|
2539
|
+
@dml_blocks_in_file.find(&match_block) ||
|
2540
|
+
@dml_menu_blocks.find(&match_block)
|
2541
|
+
end
|
2542
|
+
|
2543
|
+
# find a block by its original (undecorated) name or nickname (not visible in menu)
|
2544
|
+
# if matched, the block returned has properties that it is from cli and not ui
|
2545
|
+
def find_block_state_by_name(block_name)
|
2546
|
+
SelectedBlockMenuState.new(
|
2547
|
+
find_block_by_name(@dml_blocks_in_file, block_name),
|
2548
|
+
OpenStruct.new(
|
2549
|
+
block_name_from_cli: true,
|
2550
|
+
block_name_from_ui: false
|
2551
|
+
),
|
2552
|
+
MenuState::CONTINUE
|
2553
|
+
)
|
2554
|
+
end
|
2555
|
+
|
2527
2556
|
def format_and_execute_command(
|
2528
2557
|
code_lines:,
|
2529
2558
|
erls:,
|
@@ -2532,6 +2561,7 @@ module MarkdownExec
|
|
2532
2561
|
formatted_command = code_lines.flatten.join("\n")
|
2533
2562
|
@fout.fout fetch_color(data_sym: :script_execution_head,
|
2534
2563
|
color_sym: :script_execution_frame_color)
|
2564
|
+
|
2535
2565
|
command_execute(
|
2536
2566
|
formatted_command,
|
2537
2567
|
args: @pass_args,
|
@@ -2641,10 +2671,8 @@ module MarkdownExec
|
|
2641
2671
|
@process_mutex.synchronize do
|
2642
2672
|
Thread.new do
|
2643
2673
|
stream.each_line do |line|
|
2644
|
-
line.strip!
|
2645
2674
|
if @run_state.files.streams
|
2646
|
-
@run_state.files.append_stream_line(file_type,
|
2647
|
-
line)
|
2675
|
+
@run_state.files.append_stream_line(file_type, line)
|
2648
2676
|
end
|
2649
2677
|
|
2650
2678
|
puts line if @delegate_object[:output_stdout]
|
@@ -2692,7 +2720,7 @@ module MarkdownExec
|
|
2692
2720
|
Regexp.new(@delegate_object.fetch(
|
2693
2721
|
:fenced_start_and_end_regex, '^(?<indent> *)`{3,}'
|
2694
2722
|
)),
|
2695
|
-
fcb:
|
2723
|
+
fcb: persist_fcb(id: 'INIT'),
|
2696
2724
|
in_fenced_block: false,
|
2697
2725
|
headings: []
|
2698
2726
|
}
|
@@ -2717,7 +2745,7 @@ module MarkdownExec
|
|
2717
2745
|
menu_entries, current_display_format
|
2718
2746
|
)
|
2719
2747
|
|
2720
|
-
selection =
|
2748
|
+
selection = prompt_select_from_list(
|
2721
2749
|
menu_options,
|
2722
2750
|
string: menu_title,
|
2723
2751
|
color_sym: :prompt_color_after_script_execution
|
@@ -2773,7 +2801,7 @@ module MarkdownExec
|
|
2773
2801
|
def iter_source_blocks(source, source_id: nil, &block)
|
2774
2802
|
case source
|
2775
2803
|
when 1
|
2776
|
-
blocks_from_nested_files(source_id: source_id).each(&block)
|
2804
|
+
blocks_from_nested_files(source_id: source_id).blocks.each(&block)
|
2777
2805
|
when 2
|
2778
2806
|
@dml_blocks_in_file.each(&block)
|
2779
2807
|
when 3
|
@@ -2816,7 +2844,8 @@ module MarkdownExec
|
|
2816
2844
|
nil),
|
2817
2845
|
end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
|
2818
2846
|
scan1: @delegate_object.fetch(:output_assignment_match, nil),
|
2819
|
-
format1: @delegate_object.fetch(:output_assignment_format, nil)
|
2847
|
+
format1: @delegate_object.fetch(:output_assignment_format, nil),
|
2848
|
+
name: ''
|
2820
2849
|
)
|
2821
2850
|
|
2822
2851
|
else
|
@@ -3077,7 +3106,7 @@ module MarkdownExec
|
|
3077
3106
|
else
|
3078
3107
|
## user selects from existing files or other
|
3079
3108
|
#
|
3080
|
-
case (name =
|
3109
|
+
case (name = prompt_select_from_list(
|
3081
3110
|
[@delegate_object[:prompt_filespec_back]] + files,
|
3082
3111
|
string: @delegate_object[:prompt_select_code_file],
|
3083
3112
|
color_sym: :prompt_color_after_script_execution
|
@@ -3108,11 +3137,19 @@ module MarkdownExec
|
|
3108
3137
|
end
|
3109
3138
|
|
3110
3139
|
def mdoc_and_blocks_from_nested_files(source_id: nil)
|
3111
|
-
|
3112
|
-
|
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|
|
3113
3149
|
@delegate_object.merge!(nopts)
|
3114
3150
|
end
|
3115
|
-
|
3151
|
+
|
3152
|
+
[blocks_results.blocks, mdoc]
|
3116
3153
|
end
|
3117
3154
|
|
3118
3155
|
## Handles the file loading and returns the blocks
|
@@ -3180,7 +3217,7 @@ module MarkdownExec
|
|
3180
3217
|
#
|
3181
3218
|
menu_blocks.each do |fcb|
|
3182
3219
|
fcb.body = fcb.raw_body || fcb.body || []
|
3183
|
-
fcb.
|
3220
|
+
fcb.name_in_menu!(fcb.raw_dname || fcb.dname)
|
3184
3221
|
fcb.s0printable = fcb.raw_s0printable || fcb.s0printable
|
3185
3222
|
fcb.s1decorated = fcb.raw_s1decorated || fcb.s1decorated
|
3186
3223
|
expand_references!(fcb, link_state)
|
@@ -3212,7 +3249,7 @@ module MarkdownExec
|
|
3212
3249
|
#
|
3213
3250
|
return unless block.nil?
|
3214
3251
|
|
3215
|
-
chrome_block =
|
3252
|
+
chrome_block = persist_fcb(
|
3216
3253
|
chrome: true,
|
3217
3254
|
disabled: TtyMenu::DISABLE,
|
3218
3255
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
@@ -3259,6 +3296,19 @@ module MarkdownExec
|
|
3259
3296
|
end
|
3260
3297
|
end
|
3261
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
|
+
|
3262
3312
|
def menu_toggle_collapsible_block(selected)
|
3263
3313
|
# return true if @compress_ids.key?(fcb.id) && !!@compress_ids[fcb.id]
|
3264
3314
|
# return false if @expand_ids.key?(fcb.id) && !!@expand_ids[fcb.id]
|
@@ -3371,6 +3421,12 @@ module MarkdownExec
|
|
3371
3421
|
prompt_select_continue == MenuState::EXIT
|
3372
3422
|
end
|
3373
3423
|
|
3424
|
+
def persist_fcb(options)
|
3425
|
+
MarkdownExec::FCB.new(options).tap do |fcb|
|
3426
|
+
@fcb_store << fcb
|
3427
|
+
end
|
3428
|
+
end
|
3429
|
+
|
3374
3430
|
def pop_add_current_code_to_head_and_trigger_load(
|
3375
3431
|
link_state, block_names, code_lines,
|
3376
3432
|
dependencies, selected, next_block_name: nil
|
@@ -3486,7 +3542,7 @@ module MarkdownExec
|
|
3486
3542
|
# private
|
3487
3543
|
|
3488
3544
|
def process_string_array(arr, begin_pattern: nil, end_pattern: nil, scan1: nil,
|
3489
|
-
format1: nil)
|
3545
|
+
format1: nil, name: '')
|
3490
3546
|
in_block = !begin_pattern.present?
|
3491
3547
|
collected_lines = []
|
3492
3548
|
|
@@ -3508,6 +3564,9 @@ module MarkdownExec
|
|
3508
3564
|
collected_lines << formatted
|
3509
3565
|
end
|
3510
3566
|
end
|
3567
|
+
elsif format1.present?
|
3568
|
+
formatted = format(format1, { value: line })
|
3569
|
+
collected_lines << formatted
|
3511
3570
|
else
|
3512
3571
|
collected_lines << line
|
3513
3572
|
end
|
@@ -3633,9 +3692,22 @@ module MarkdownExec
|
|
3633
3692
|
0
|
3634
3693
|
end
|
3635
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
|
+
|
3636
3708
|
# public
|
3637
3709
|
|
3638
|
-
def
|
3710
|
+
def prompt_select_from_list(
|
3639
3711
|
filenames,
|
3640
3712
|
color_sym: :prompt_color_after_script_execution,
|
3641
3713
|
cycle: true,
|
@@ -3661,19 +3733,6 @@ module MarkdownExec
|
|
3661
3733
|
end
|
3662
3734
|
end
|
3663
3735
|
|
3664
|
-
def prompt_select_continue(filter: true, quiet: true)
|
3665
|
-
sel = @prompt.select(
|
3666
|
-
string_send_color(@delegate_object[:prompt_after_script_execution],
|
3667
|
-
:prompt_color_after_script_execution),
|
3668
|
-
filter: filter,
|
3669
|
-
quiet: quiet
|
3670
|
-
) do |menu|
|
3671
|
-
menu.choice @delegate_object[:prompt_yes]
|
3672
|
-
menu.choice @delegate_object[:prompt_exit]
|
3673
|
-
end
|
3674
|
-
sel == @delegate_object[:prompt_exit] ? MenuState::EXIT : MenuState::CONTINUE
|
3675
|
-
end
|
3676
|
-
|
3677
3736
|
# user prompt to exit if the menu will be displayed again
|
3678
3737
|
#
|
3679
3738
|
def prompt_user_exit(block_name_from_cli:, selected:)
|
@@ -3747,27 +3806,6 @@ module MarkdownExec
|
|
3747
3806
|
end&.compact
|
3748
3807
|
end
|
3749
3808
|
|
3750
|
-
def saved_asset_for_history(
|
3751
|
-
file:, form:, match_info:
|
3752
|
-
)
|
3753
|
-
OpenStruct.new(
|
3754
|
-
file: file[(Dir.pwd.length + 1)..-1],
|
3755
|
-
full: file,
|
3756
|
-
row: format(
|
3757
|
-
form,
|
3758
|
-
# default '*' so unknown parameters are given a wildcard
|
3759
|
-
match_info.names.each_with_object(Hash.new('*')) do |name, hash|
|
3760
|
-
hash[name.to_sym] = match_info[name]
|
3761
|
-
end
|
3762
|
-
)
|
3763
|
-
)
|
3764
|
-
rescue KeyError
|
3765
|
-
# pp $!, $@
|
3766
|
-
warn "Cannot format with: #{@delegate_object[:saved_history_format]}"
|
3767
|
-
error_handler('saved_history_format')
|
3768
|
-
:break
|
3769
|
-
end
|
3770
|
-
|
3771
3809
|
# Processes YAML data from the selected menu item, updating delegate
|
3772
3810
|
# objects and optionally printing formatted output.
|
3773
3811
|
# @param selected [Hash] Selected item from the menu containing a YAML body.
|
@@ -3822,8 +3860,8 @@ module MarkdownExec
|
|
3822
3860
|
# console [height, width]. If not provided or if the terminal
|
3823
3861
|
# is resized, it will be set to the current console dimensions.
|
3824
3862
|
# - :select_page_height [Integer, nil] The height of the page for
|
3825
|
-
# selection. If not provided or if not positive, it
|
3826
|
-
# 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.
|
3827
3865
|
# - :per_page [Integer, nil] The number of items per page. If
|
3828
3866
|
# :select_page_height is not provided or if not positive, it
|
3829
3867
|
# will be set to the maximum of (console height - 3) or 4.
|
@@ -3950,7 +3988,7 @@ module MarkdownExec
|
|
3950
3988
|
## user selects from existing files or other
|
3951
3989
|
# input into path with wildcard for easy entry
|
3952
3990
|
#
|
3953
|
-
case (name =
|
3991
|
+
case (name = prompt_select_from_list(
|
3954
3992
|
[@delegate_object[:prompt_filespec_back],
|
3955
3993
|
@delegate_object[:prompt_filespec_other]] + files,
|
3956
3994
|
string: @delegate_object[:prompt_select_code_file],
|
@@ -3987,6 +4025,27 @@ module MarkdownExec
|
|
3987
4025
|
).generate_name
|
3988
4026
|
end
|
3989
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
|
+
|
3990
4049
|
def screen_width
|
3991
4050
|
width = @delegate_object[:screen_width]
|
3992
4051
|
if width&.positive?
|
@@ -4195,7 +4254,7 @@ module MarkdownExec
|
|
4195
4254
|
TtyMenu::ENABLE
|
4196
4255
|
end
|
4197
4256
|
|
4198
|
-
|
4257
|
+
persist_fcb(
|
4199
4258
|
body: [],
|
4200
4259
|
call: rest.match(
|
4201
4260
|
Regexp.new(@delegate_object[:block_calls_scan])
|
@@ -4320,7 +4379,9 @@ module MarkdownExec
|
|
4320
4379
|
# add line if it is depth 0 or option allows it
|
4321
4380
|
#
|
4322
4381
|
HashDelegator.yield_line_if_selected(
|
4323
|
-
line, selected_types,
|
4382
|
+
line, selected_types,
|
4383
|
+
all_fcbs: @fcb_store,
|
4384
|
+
source_id: source_id, &block
|
4324
4385
|
)
|
4325
4386
|
end
|
4326
4387
|
end
|
@@ -4333,6 +4394,147 @@ module MarkdownExec
|
|
4333
4394
|
@delegate_object.merge!(options)
|
4334
4395
|
end
|
4335
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
|
+
|
4336
4538
|
def vux_await_user_selection(prior_answer: @dml_block_selection)
|
4337
4539
|
@dml_block_state = load_cli_or_user_selected_block(
|
4338
4540
|
all_blocks: @dml_blocks_in_file,
|
@@ -4359,7 +4561,7 @@ module MarkdownExec
|
|
4359
4561
|
end
|
4360
4562
|
|
4361
4563
|
def vux_execute_and_prompt(block_name)
|
4362
|
-
@dml_block_state =
|
4564
|
+
@dml_block_state = find_block_state_by_name(block_name)
|
4363
4565
|
if @dml_block_state.block &&
|
4364
4566
|
@dml_block_state.block.type == BlockType::OPTS
|
4365
4567
|
debounce_reset
|
@@ -4532,7 +4734,8 @@ module MarkdownExec
|
|
4532
4734
|
|
4533
4735
|
inherited_block_names = []
|
4534
4736
|
inherited_dependencies = {}
|
4535
|
-
selected =
|
4737
|
+
selected = persist_fcb(oname: 'load_code')
|
4738
|
+
|
4536
4739
|
pop_add_current_code_to_head_and_trigger_load(
|
4537
4740
|
@dml_link_state, inherited_block_names,
|
4538
4741
|
code_lines, inherited_dependencies, selected
|
@@ -4800,7 +5003,7 @@ module MarkdownExec
|
|
4800
5003
|
def vux_user_selected_block_name
|
4801
5004
|
if @dml_link_state.block_name.present?
|
4802
5005
|
# @prior_block_was_link = true
|
4803
|
-
@dml_block_state.block =
|
5006
|
+
@dml_block_state.block = find_block_by_name(
|
4804
5007
|
@dml_blocks_in_file,
|
4805
5008
|
@dml_link_state.block_name
|
4806
5009
|
)
|
@@ -5269,7 +5472,7 @@ module MarkdownExec
|
|
5269
5472
|
end
|
5270
5473
|
|
5271
5474
|
def test_blocks_from_nested_files
|
5272
|
-
result = @hd.blocks_from_nested_files
|
5475
|
+
result = @hd.blocks_from_nested_files.blocks
|
5273
5476
|
assert_kind_of Array, result
|
5274
5477
|
assert_kind_of FCB, result.first
|
5275
5478
|
end
|
@@ -5278,7 +5481,7 @@ module MarkdownExec
|
|
5278
5481
|
@hd = HashDelegator.new(no_chrome: true)
|
5279
5482
|
@hd.expects(:create_and_add_chrome_blocks).never
|
5280
5483
|
|
5281
|
-
result = @hd.blocks_from_nested_files
|
5484
|
+
result = @hd.blocks_from_nested_files.blocks
|
5282
5485
|
|
5283
5486
|
assert_kind_of Array, result
|
5284
5487
|
end
|
@@ -5724,7 +5927,7 @@ module MarkdownExec
|
|
5724
5927
|
Thread.new { @hd.handle_stream(stream: stream, file_type: file_type) }
|
5725
5928
|
|
5726
5929
|
@hd.wait_for_stream_processing
|
5727
|
-
assert_equal [
|
5930
|
+
assert_equal ["line 1\n", "line 2\n"],
|
5728
5931
|
@hd.instance_variable_get(:@run_state)
|
5729
5932
|
.files.stream_lines(ExecutionStreams::STD_OUT)
|
5730
5933
|
end
|