markdown_exec 2.1.0 → 2.3.0

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.
data/lib/mdoc.rb CHANGED
@@ -6,6 +6,8 @@
6
6
  require_relative 'block_types'
7
7
  require_relative 'filter'
8
8
 
9
+ $pd = false unless defined?($pd)
10
+
9
11
  module MarkdownExec
10
12
  ##
11
13
  # MDoc represents an imported markdown document.
@@ -23,11 +25,11 @@ module MarkdownExec
23
25
  #
24
26
  def initialize(table = [])
25
27
  @table = table
26
- # &bc '@table.count:',@table.count
28
+ # &bt @table.count
27
29
  end
28
30
 
29
31
  def collect_block_code_cann(fcb)
30
- body = fcb[:body].join("\n")
32
+ body = fcb.body.join("\n")
31
33
  xcall = fcb[:cann][1..-2]
32
34
  mstdin = xcall.match(/<(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
33
35
  mstdout = xcall.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
@@ -44,15 +46,6 @@ module MarkdownExec
44
46
  end
45
47
  end
46
48
 
47
- def collect_block_code_shell(fcb)
48
- # write named variables to block at top of script
49
- #
50
- fcb[:body].join(' ').split.compact.map do |key|
51
- ### format(opts[:block_type_port_set_format], { key: key, value: ENV.fetch(key, nil) })
52
- "key: #{key}, value: #{ENV.fetch(key, nil)}"
53
- end
54
- end
55
-
56
49
  # Collects and formats the shell command output to redirect script block code to a file or a variable.
57
50
  #
58
51
  # @param [Hash] fcb A hash containing information about the script block's stdout and body.
@@ -66,7 +59,7 @@ module MarkdownExec
66
59
  # If stdout[:type] is false, the command will write the body to a file.
67
60
  def collect_block_code_stdout(fcb)
68
61
  stdout = fcb[:stdout]
69
- body = fcb[:body].join("\n")
62
+ body = fcb.body.join("\n")
70
63
  if stdout[:type]
71
64
  %(export #{stdout[:name]}=$(cat <<"EOF"\n#{body}\nEOF\n))
72
65
  else
@@ -83,35 +76,40 @@ module MarkdownExec
83
76
  #
84
77
  def collect_block_dependencies(anyname:)
85
78
  name_block = get_block_by_anyname(anyname)
86
- raise "Named code block `#{anyname}` not found. (@#{__LINE__})" if name_block.nil? || name_block.keys.empty?
79
+ if name_block.nil? || name_block.keys.empty?
80
+ raise "Named code block `#{anyname}` not found. (@#{__LINE__})"
81
+ end
87
82
 
88
83
  nickname = name_block.pub_name
89
84
 
90
85
  dependencies = collect_dependencies(nickname)
91
- # &bc 'dependencies.count:',dependencies.count
86
+ # &bt dependencies.count
92
87
  all_dependency_names = collect_unique_names(dependencies).push(nickname).uniq
93
- # &bc 'all_dependency_names.count:',all_dependency_names.count
88
+ # &bt all_dependency_names.count
94
89
 
95
- # select non-chrome blocks in order of appearance in source documents
90
+ # select blocks in order of appearance in source documents
96
91
  #
97
92
  blocks = @table.select do |fcb|
98
- !fcb.fetch(:chrome, false) && all_dependency_names.include?(fcb.pub_name)
93
+ # 2024-08-04 match nickname
94
+ all_dependency_names.include?(fcb.pub_name) || all_dependency_names.include?(fcb.nickname) || all_dependency_names.include?(fcb.oname)
99
95
  end
100
- # &bc 'blocks.count:',blocks.count
96
+ # &bt blocks.count
101
97
 
102
98
  ## add cann key to blocks, calc unmet_dependencies
103
99
  #
104
100
  unmet_dependencies = all_dependency_names.dup
105
101
  blocks = blocks.map do |fcb|
106
- unmet_dependencies.delete(fcb.pub_name) # may not exist if block name is duplicated
107
- if (call = fcb[:call])
102
+ # 2024-08-04 match oname for long block names
103
+ # 2024-08-04 match nickname
104
+ unmet_dependencies.delete(fcb.pub_name) || unmet_dependencies.delete(fcb.nickname) || unmet_dependencies.delete(fcb.oname) # may not exist if block name is duplicated
105
+ if (call = fcb.call)
108
106
  [get_block_by_anyname("[#{call.match(/^%\((\S+) |\)/)[1]}]")
109
107
  .merge({ cann: call })]
110
108
  else
111
109
  []
112
110
  end + [fcb]
113
111
  end.flatten(1)
114
- # &bc 'unmet_dependencies.count:',unmet_dependencies.count
112
+ # &bt unmet_dependencies.count
115
113
 
116
114
  { all_dependency_names: all_dependency_names,
117
115
  blocks: blocks,
@@ -129,7 +127,7 @@ module MarkdownExec
129
127
  block_search = collect_block_dependencies(anyname: anyname)
130
128
  if block_search[:blocks]
131
129
  blocks = collect_wrapped_blocks(block_search[:blocks])
132
- # &bc 'blocks.count:',blocks.count
130
+ # &bt blocks.count
133
131
 
134
132
  block_search.merge(
135
133
  { block_names: blocks.map(&:pub_name),
@@ -138,20 +136,20 @@ module MarkdownExec
138
136
  collect_block_code_cann(fcb)
139
137
  elsif fcb[:stdout]
140
138
  collect_block_code_stdout(fcb)
141
- elsif [BlockType::LINK, BlockType::OPTS,
142
- BlockType::VARS].include? fcb[:shell]
139
+ elsif [BlockType::OPTS].include? fcb.shell
140
+ fcb.body # entire body is returned to requesing block
141
+ elsif [BlockType::LINK,
142
+ BlockType::VARS].include? fcb.shell
143
+ nil
144
+ elsif fcb[:chrome] # for Link blocks like History
143
145
  nil
144
- elsif fcb[:shell] == BlockType::PORT
145
- collect_block_code_shell(fcb)
146
+ elsif fcb.shell == BlockType::PORT
147
+ generate_env_variable_shell_commands(fcb)
146
148
  elsif label_body
147
- block_name_for_bash_comment = fcb.pub_name.gsub(/\s+/, '_')
148
- [label_format_above && format(label_format_above,
149
- block_source.merge({ block_name: block_name_for_bash_comment }))] +
150
- fcb[:body] +
151
- [label_format_below && format(label_format_below,
152
- block_source.merge({ block_name: block_name_for_bash_comment }))]
149
+ generate_label_body_code(fcb, block_source, label_format_above,
150
+ label_format_below)
153
151
  else # raw body
154
- fcb[:body]
152
+ fcb.body
155
153
  end
156
154
  end.compact.flatten(1).compact }
157
155
  )
@@ -222,10 +220,70 @@ module MarkdownExec
222
220
  # . empty chrome between code; edges are same as blanks
223
221
  #
224
222
  select_elements_with_neighbor_conditions(selrows) do |prev_element, current, next_element|
225
- !(current[:chrome] && !current[:oname].present?) || !(!prev_element.nil? && prev_element[:shell].present? && !next_element.nil? && next_element[:shell].present?)
223
+ !(current[:chrome] && !current.oname.present?) ||
224
+ !(!prev_element.nil? &&
225
+ prev_element.shell.present? &&
226
+ !next_element.nil? &&
227
+ next_element.shell.present?)
228
+ end
229
+ end
230
+
231
+ # Generates shell code lines to set environment variables named in the body of the given object.
232
+ # Reads a whitespace-separated list of environment variable names from `fcb.body`,
233
+ # retrieves their values from the current environment, and constructs shell commands
234
+ # to set these environment variables.
235
+ #
236
+ # @param fcb [Object] An object with a `body` method that returns an array of strings,
237
+ # where each string is a name of an environment variable.
238
+ # @return [Array<String>] An array of strings, each representing a shell command to
239
+ # set an environment variable in the format `KEY=value`.
240
+ #
241
+ # Example:
242
+ # If `fcb.body` returns ["PATH", "HOME"], and the current environment has PATH=/usr/bin
243
+ # and HOME=/home/user, this method will return:
244
+ # ["PATH=/usr/bin", "HOME=/home/user"]
245
+ #
246
+ def generate_env_variable_shell_commands(fcb)
247
+ fcb.body.join(' ').split.compact.map do |key|
248
+ "#{key}=#{Shellwords.escape ENV.fetch(key, '')}"
226
249
  end
227
250
  end
228
251
 
252
+ # Generates a formatted code block with labels above and below the main content.
253
+ # The labels and content are based on the provided format strings and the body of the given object.
254
+ #
255
+ # @param fcb [Object] An object with a `pub_name` method that returns a string, and a `body` method that returns an array of strings.
256
+ # @param block_source [Hash] A hash containing additional information to be merged into the format strings.
257
+ # @param label_format_above [String, nil] A format string for the label above the content, or nil if no label is needed.
258
+ # @param label_format_below [String, nil] A format string for the label below the content, or nil if no label is needed.
259
+ # @return [Array<String>] An array of strings representing the formatted code block, with optional labels above and below the main content.
260
+ #
261
+ # Example:
262
+ # If `fcb.pub_name` returns "Example Block", `fcb.body` returns ["line1", "line2"],
263
+ # `block_source` is { source: "source_info" }, `label_format_above` is "Start of %{block_name}",
264
+ # and `label_format_below` is "End of %{block_name}", the method will return:
265
+ # ["Start of Example_Block", "line1", "line2", "End of Example_Block"]
266
+ #
267
+ def generate_label_body_code(fcb, block_source, label_format_above,
268
+ label_format_below)
269
+ block_name_for_bash_comment = fcb.pub_name.gsub(/\s+/, '_')
270
+
271
+ label_above = if label_format_above
272
+ format(label_format_above,
273
+ block_source.merge({ block_name: block_name_for_bash_comment }))
274
+ else
275
+ nil
276
+ end
277
+ label_below = if label_format_below
278
+ format(label_format_below,
279
+ block_source.merge({ block_name: block_name_for_bash_comment }))
280
+ else
281
+ nil
282
+ end
283
+
284
+ [label_above, *fcb.body, label_below].compact
285
+ end
286
+
229
287
  # Retrieves a code block by its name.
230
288
  #
231
289
  # @param name [String] The name of the code block to retrieve.
@@ -233,10 +291,14 @@ module MarkdownExec
233
291
  # @return [Hash] The code block as a hash or the default value if not found.
234
292
  #
235
293
  def get_block_by_anyname(name, default = {})
294
+ # &bt name
236
295
  @table.select do |fcb|
237
- fcb.fetch(:nickname,
238
- '') == name || fcb.fetch(:dname, '') == name || fcb.fetch(:oname, '') == name
239
- end.fetch(0, default)
296
+ fcb.tap { |_ret| pp [__LINE__, 'get_block_by_anyname()', 'fcb', fcb] if $pd }
297
+ fcb.nickname == name ||
298
+ fcb.dname == name ||
299
+ fcb.oname == name ||
300
+ fcb.pub_name == name
301
+ end.fetch(0, default).tap { |ret| pp [__LINE__, 'get_block_by_anyname() ->', ret] if $pd }
240
302
  end
241
303
 
242
304
  # Checks if a code block should be hidden based on the given options.
@@ -250,15 +312,15 @@ module MarkdownExec
250
312
  if block.fetch(:chrome, false)
251
313
  false
252
314
  else
253
- (opts[:hide_blocks_by_name] &&
254
- ((opts[:block_name_hidden_match]&.present? &&
255
- block.oname&.match(Regexp.new(opts[:block_name_hidden_match]))) ||
256
- (opts[:block_name_include_match]&.present? &&
257
- block.oname&.match(Regexp.new(opts[:block_name_include_match]))) ||
258
- (opts[:block_name_wrapper_match]&.present? &&
259
- block.oname&.match(Regexp.new(opts[:block_name_wrapper_match])))) &&
260
- (block.oname&.present? || block[:label]&.present?)
261
- )
315
+ opts[:hide_blocks_by_name] &&
316
+ ((opts[:block_name_hidden_match]&.present? &&
317
+ block.oname&.match(Regexp.new(opts[:block_name_hidden_match]))) ||
318
+ (opts[:block_name_include_match]&.present? &&
319
+ block.oname&.match(Regexp.new(opts[:block_name_include_match]))) ||
320
+ (opts[:block_name_wrapper_match]&.present? &&
321
+ block.oname&.match(Regexp.new(opts[:block_name_wrapper_match])))) &&
322
+ (block.oname&.present? || block[:label]&.present?)
323
+
262
324
  end
263
325
  end
264
326
 
@@ -277,7 +339,7 @@ module MarkdownExec
277
339
  next if memo.include? req
278
340
 
279
341
  memo += [req]
280
- get_block_by_anyname(req).fetch(:reqs, [])
342
+ get_block_by_anyname(req).reqs
281
343
  end
282
344
  .compact
283
345
  .flatten(1)
@@ -295,9 +357,11 @@ module MarkdownExec
295
357
  return memo if memo.keys.include? source
296
358
 
297
359
  block = get_block_by_anyname(source)
298
- raise "Named code block `#{source}` not found. (@#{__LINE__})" if block.nil? || block.keys.empty?
360
+ if block.nil? || block.keys.empty?
361
+ raise "Named code block `#{source}` not found. (@#{__LINE__})"
362
+ end
299
363
 
300
- memo[source] = block[:reqs]
364
+ memo[source] = block.reqs
301
365
  return memo unless memo[source]&.count&.positive?
302
366
 
303
367
  memo[source].each do |req|
@@ -322,11 +386,13 @@ module MarkdownExec
322
386
 
323
387
  end
324
388
 
325
- return memo unless block[:reqs]
389
+ return memo unless block.reqs
326
390
 
327
- memo[source] = block[:reqs]
391
+ memo[source] = block.reqs
328
392
 
329
- block[:reqs].each { |req| collect_dependencies(req, memo) unless memo.key?(req) }
393
+ block.reqs.each do |req|
394
+ collect_dependencies(req, memo) unless memo.key?(req)
395
+ end
330
396
  memo
331
397
  end
332
398
 
@@ -364,7 +430,7 @@ module MarkdownExec
364
430
  # next_element = array[index + 1]
365
431
 
366
432
  # # Check the conditions for property A on the current element and property B on adjacent elements
367
- # unless element[:chrome] && !element[:oname].present? && prev_element[:shell].present? && next_element[:shell].present?
433
+ # unless element[:chrome] && !element[:oname].present? && prev_element.shell.present? && next_element.shell.present?
368
434
  # selected_elements << element
369
435
  # # else
370
436
  # # pp 'SKIPPING', element
@@ -395,7 +461,9 @@ if $PROGRAM_NAME == __FILE__
395
461
 
396
462
  if false # must raise error
397
463
  def test_collect_dependencies_with_nonexistent_source
398
- assert_raises(RuntimeError) { @mdoc.collect_dependencies('nonexistent') }
464
+ assert_raises(RuntimeError) do
465
+ @mdoc.collect_dependencies('nonexistent')
466
+ end
399
467
  end
400
468
  end
401
469
 
@@ -512,12 +580,6 @@ if $PROGRAM_NAME == __FILE__
512
580
  # Test case 1: blocks with wraps
513
581
  OpenStruct.new(oname: 'block1')
514
582
 
515
- assert_equal(%w[{wrap1} a],
516
- @mdoc.collect_wrapped_blocks(
517
- [OpenStruct.new(oname: 'a',
518
- wraps: ['{wrap1}'])]
519
- ).map(&:oname))
520
-
521
583
  assert_equal(%w[{wrap2-before} {wrap2} b {wrap2-after}],
522
584
  @mdoc.collect_wrapped_blocks(
523
585
  [OpenStruct.new(oname: 'b',
data/lib/menu.src.yml CHANGED
@@ -275,8 +275,10 @@
275
275
  :default: false
276
276
  :description: Execute script in own window
277
277
  :env_var: MDE_EXECUTE_IN_OWN_WINDOW
278
+ :long_name: execute_in_own_window
278
279
  :opt_name: execute_in_own_window
279
280
  :procname: val_as_bool
281
+ :short_name: w
280
282
 
281
283
  - :default: fg_rgbh_7f_ff_00
282
284
  :description: execution_report_preview_frame_color
@@ -303,13 +305,13 @@
303
305
 
304
306
  ## match fenced code indented by spaces
305
307
  #
306
- - :default: "^(?<indent> *)`{3,}"
308
+ - :default: "^(?<indent>[ \t]*)`{3,}"
307
309
  :description: Matches the start and end of a fenced code block
308
310
  :env_var: MDE_FENCED_START_AND_END_REGEX
309
311
  :opt_name: fenced_start_and_end_regex
310
312
  :procname: val_as_str
311
313
 
312
- - :default: "^(?<indent> *)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*) *$"
314
+ - :default: "^(?<indent>[ \t]*)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*) *$"
313
315
  :description: Match the start of a fenced block
314
316
  :env_var: MDE_FENCED_START_EXTENDED_REGEX
315
317
  :opt_name: fenced_start_extended_regex
@@ -380,7 +382,7 @@
380
382
 
381
383
  - :arg_name: HOW
382
384
  :default: ''
383
- :description: Find in YAML configuration options
385
+ :description: Find keyword in YAML configuration options
384
386
  :long_name: how
385
387
  :procname: how
386
388
  :short_name: "?"
@@ -395,6 +397,43 @@
395
397
  :opt_name: import_pattern
396
398
  :procname: val_as_str
397
399
 
400
+ - :default:
401
+ - :color_method: :bold_underline
402
+ :pattern: '\*\*_([^_]{0,64})_\*\*'
403
+
404
+ - :color_method: :bold_italic
405
+ :pattern: '\*\*~([^~]{0,64})~\*\*'
406
+
407
+ - :color_method: :bold
408
+ :pattern: '\*\*([^*]{0,64})\*\*'
409
+ - :color_method: :bold
410
+ :pattern: '__([^_]{0,64})__'
411
+
412
+ - :color_method: :underline
413
+ :pattern: '\*([^*]{0,64})\*'
414
+
415
+ - :color_method: :underline_italic
416
+ :pattern: '_~([^_]{0,64})~_'
417
+
418
+ - :color_method: strikethrough
419
+ :pattern: '~~([^~]{0,64})~~'
420
+ :description: Line-oriented text decoration (Main)
421
+ :env_var: MDE_LINE_DECOR_MAIN
422
+ :opt_name: line_decor_main
423
+ :procname: val_as_str
424
+
425
+ - :default: []
426
+ :description: Line-oriented text decoration (Post)
427
+ :env_var: MDE_LINE_DECOR_POST
428
+ :opt_name: line_decor_post
429
+ :procname: val_as_str
430
+
431
+ - :default: []
432
+ :description: Line-oriented text decoration (Pre)
433
+ :env_var: MDE_LINE_DECOR_PRE
434
+ :opt_name: line_decor_pre
435
+ :procname: val_as_str
436
+
398
437
  - :description: List blocks
399
438
  :long_name: list-blocks
400
439
  :opt_name: list_blocks
@@ -438,6 +477,7 @@
438
477
  :long_name: load-code
439
478
  :opt_name: load_code
440
479
  :procname: val_as_str
480
+ :short_name: l
441
481
 
442
482
  - :arg_name: PREFIX
443
483
  :default: mde
@@ -507,7 +547,7 @@
507
547
  :opt_name: menu_divider_format
508
548
  :procname: val_as_str
509
549
 
510
- - :default: "^:::(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
550
+ - :default: "^(?<indent>[ \t]*):::(?<line>(?<text>.*?)(?<trailing>[ \t]*))?$"
511
551
  :description: Pattern for topics/dividers in block selection menu
512
552
  :env_var: MDE_MENU_DIVIDER_MATCH
513
553
  :opt_name: menu_divider_match
@@ -651,7 +691,8 @@
651
691
  :procname: val_as_str
652
692
 
653
693
  ## lines that start with "/" are comments (hidden), not notes (visible)
654
- - :default: "^(?<line>(?!/)(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
694
+ # - :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
695
+ - :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))?$"
655
696
  :description: Pattern for notes in block selection menu
656
697
  :env_var: MDE_MENU_NOTE_MATCH
657
698
  :opt_name: menu_note_match
@@ -965,13 +1006,19 @@
965
1006
  :procname: val_as_str
966
1007
 
967
1008
  - :default: Back
968
- :description: Quit prompt
969
- :env_var: MDE_PROMPT_FILESPEC_OTHER
1009
+ :description: User wants out of menu
1010
+ :env_var: MDE_PROMPT_FILESPEC_BACK
970
1011
  :opt_name: prompt_filespec_back
971
1012
  :procname: val_as_str
972
1013
 
1014
+ - :default: Facet
1015
+ :description: User wants to tailor the menu
1016
+ :env_var: MDE_PROMPT_FILESPEC_FACET
1017
+ :opt_name: prompt_filespec_facet
1018
+ :procname: val_as_str
1019
+
973
1020
  - :default: Other
974
- :description: Prompt for a custom file name
1021
+ :description: User wants a custom file name
975
1022
  :env_var: MDE_PROMPT_FILESPEC_OTHER
976
1023
  :opt_name: prompt_filespec_other
977
1024
  :procname: val_as_str
@@ -1042,7 +1089,7 @@
1042
1089
  :opt_name: prompt_yes
1043
1090
  :procname: val_as_str
1044
1091
 
1045
- - :description: Gem home folder
1092
+ - :description: Print the gem's home directory
1046
1093
  :long_name: pwd
1047
1094
  :opt_name: pwd
1048
1095
  :procname: val_as_bool
@@ -1059,13 +1106,13 @@
1059
1106
  :procname: val_as_int
1060
1107
 
1061
1108
  - :default: '%{prefix}%{join}%{time}%{join}%{filename}%{join}%{mark}%{join}%{blockname}%{join}%{exts}'
1062
- :description: saved_asset_format
1109
+ :description: Format for script and log file names
1063
1110
  :env_var: MDE_SAVED_ASSET_FORMAT
1064
1111
  :opt_name: saved_asset_format
1065
1112
  :procname: val_as_str
1066
1113
 
1067
1114
  - :default: "^(?<prefix>.+)(?<join>_)(?<time>[0-9\\-]+)\\g'join'(?<filename>.+)\\g'join'(?<mark>~)\\g'join'(?<blockname>.+)\\g'join'(?<exts>\\..+)$"
1068
- :description: saved_asset_match
1115
+ :description: Regexp for script and log file names
1069
1116
  :env_var: MDE_SAVED_ASSET_MATCH
1070
1117
  :opt_name: saved_asset_match
1071
1118
  :procname: val_as_str
@@ -1096,6 +1143,12 @@
1096
1143
  :opt_name: saved_filename_replacement
1097
1144
  :procname: val_as_str
1098
1145
 
1146
+ - :default: '%{time} %{blockname} %{exts}'
1147
+ :description: Format for each row displayed in history
1148
+ :env_var: MDE_SAVED_HISTORY_FORMAT
1149
+ :opt_name: saved_history_format
1150
+ :procname: val_as_str
1151
+
1099
1152
  - :arg_name: INT
1100
1153
  :default: 493
1101
1154
  :description: chmod for saved scripts
@@ -1194,16 +1247,6 @@
1194
1247
  :opt_name: select_page_height
1195
1248
  :procname: val_as_int
1196
1249
 
1197
- - :description: Select and execute a recently saved output
1198
- :long_name: select-recent-output
1199
- :opt_name: select_recent_output
1200
- :procname: val_as_bool
1201
-
1202
- - :description: Select and execute a recently saved script
1203
- :long_name: select-recent-script
1204
- :opt_name: select_recent_script
1205
- :procname: val_as_bool
1206
-
1207
1250
  - :default: "#!/usr/bin/env"
1208
1251
  :description: Shebang for saved scripts
1209
1252
  :env_var: MDE_SHEBANG
@@ -1234,6 +1277,13 @@
1234
1277
  :opt_name: shell_code_label_time_format
1235
1278
  :procname: val_as_str
1236
1279
 
1280
+ - :arg_name: BOOL
1281
+ :default: true
1282
+ :description: Whether saved file names include shell parameter expansion
1283
+ :env_var: MDE_SHELL_PARAMETER_EXPANSION
1284
+ :opt_name: shell_parameter_expansion
1285
+ :procname: val_as_bool
1286
+
1237
1287
  - :description: List tab completions
1238
1288
  :long_name: tab-completions
1239
1289
  :opt_name: tab_completions