Top Level Namespace
Defined Under Namespace
Modules: ArrayUtil, AttributeAccess, CLI, ClassMethodWrapper, CompactionHelpers, Env, ErrorReporting, Exceptions, HashDelegatorSelf, ImwUx, InstanceMethodWrapper, MarkdownExec, MarkdownTableFormatter, PathUtils, StringUtil, Tap, TextAnalyzer Classes: AnimationToTTS, AnsiFormatter, AnsiString, AppInterrupt, ArgPro, ArgumentProcessorTest, Array, AudioSegmentGenerator, AudioStitcher, BashCommentFormatter, BashCommentFormatterTest, BlockCache, BlockLabel, BlockLabelTest, BlockMissing, BlockSelection, BlockType, CachedNestedFileReader, CachedNestedFileReaderTest, Collapser, CollapserTest, ColorScheme, CommandProcessorTest, CommandResult, CommandResultDelegator, CommandResultInstanceVars, CommandResultOpenStruct, CommandResultRefined, CommandResultStruct, DirectorySearcher, DirectorySearcherTest, DirectorySearcherTest2, DummyObject, EnvInterface, EvaluateShellExpression, ExecutionStreams, ExportValueSource, FCB, FCBTest, FOut, FalseClass, FileMissingError, Hash, HierarchyString, IndexedLine, InputSequencer, LinkKeys, LoadFile, LoadFileLinkState, LoadMode, LoggedStruct, LoggedStructTest, MDE, MenuOptions, MenuState, NamedCaptureExtractor, NestedLine, NullResult, NullResultTest, Object, OptionValueTest, ParameterExpansion, Regexp, RegexpGsubFormatTest, ResizeTerminalTest, SavedAssetTest, SavedFilesMatcherTest, SelectResponse, SelectedBlockMenuState, ShellSession, ShellSessionTest, ShellType, StreamsOut, String, StringWrapper, SuccessResult, SuccessResultTest, SystemTTSEngine, TTSEngine, TTSEngineFactory, TableExtractor, TestAnimationToTTS, TestBlockCache, TestFindFiles, TestFormatTable, TestFormatTable2, TestHierarchyString, TestMarkdownTableFormatter, TestObjectMethods, TestParameterExpansion, TestShellExpressionEvaluator, TestStringMethods, TestTableExtractor, TestTextAnalyzer, TestWwFunction, TrackedString, TtyMenu, UxActSource, ValueOrException
Constant Summary collapse
- DEPTH_ICON =
call depth icons
'›'- LOG_LEVELS =
log levels
i[debug info warn error fatal].freeze
- BT_UX_FLD_REQUIRED =
'required'- BF =
'bin'- DISPLAY_LEVEL_BASE =
display_level values
0- DISPLAY_LEVEL_ADMIN =
required output
1- DISPLAY_LEVEL_DEBUG =
monit
2- DISPLAY_LEVEL_DUMP =
3- DISPLAY_LEVEL_DEFAULT =
DISPLAY_LEVEL_ADMIN- DISPLAY_LEVEL_MAX =
DISPLAY_LEVEL_DUMP- LOCAL_YML =
'menu.yml'- MENU_YML =
"lib/#{LOCAL_YML}"- OPTIONS =
{ divider4_collapse: false, divider4_collapsible: true, heading1_collapse: false, heading1_collapsible: false, heading2_collapse: true, heading2_collapsible: true, heading3_collapse: false, heading3_collapsible: true }.freeze
- BLOCK_TYPE_COLOR_OPTIONS =
{ BlockType::EDIT => :menu_edit_color, BlockType::HISTORY => :menu_history_color, BlockType::LINK => :menu_link_color, BlockType::LOAD => :menu_load_color, BlockType::OPTS => :menu_opts_color, BlockType::SAVE => :menu_save_color, BlockType::SHELL => :menu_bash_color, BlockType::UX => { :is_allow? => :menu_ux_color_allow, :is_echo? => :menu_ux_color_echo, :is_edit? => :menu_ux_color_edit, :is_exec? => :menu_ux_color_exec, :readonly => :menu_ux_color_readonly, true => :menu_ux_color }, BlockType::VARS => :menu_vars_color, # default for remaining block types true => :menu_block_color }.freeze
- COLLAPSIBLE_SYMBOL_COLLAPSED =
‘<+>’ # ‘∆’
'⬢'- COLLAPSIBLE_SYMBOL_EXPANDED =
‘< >’ # ‘…’
'⬡'- COLLAPSIBLE_TOKEN_COLLAPSE =
in regexp (?<collapse>?)
'+'- COLLAPSIBLE_TOKEN_EXPAND =
'-'- COLLAPSIBLE_TYPES =
[BlockType::DIVIDER, BlockType::HEADING].freeze
- DEFAULT_NULL_RESULT =
A default instance for cases where no extra details are required.
NullResult.new
- SAVED_ASSET_FORMAT =
'%{prefix}%{join}%{time}%{join}%{filename}%{join}' \ '%{mark}%{join}%{blockname}%{join}%{exts}'
- ARGV_SEP =
'--'- STATUS_SUCCESS =
0- EXIT_STATUS_REQUIRED_EMPTY =
248- DEFAULT_SUCCESS_RESULT =
Default instance for ease-of-use.
SuccessResult.instance
Constants included from Tap
Tap::ALL, Tap::ALL2, Tap::CVT, Tap::DN, Tap::NONE, Tap::T1, Tap::T2, Tap::T3, Tap::T4, Tap::TB1, Tap::TB2, Tap::TB3, Tap::TD, Tap::TD0, Tap::TD1, Tap::TD2, Tap::TDD, Tap::TP, Tap::TP0, Tap::TP1, Tap::TP2
Instance Method Summary collapse
- #assert_equal_hash(expected, actual, message = nil) ⇒ Object
-
#block_type_selected?(selected_types, type) ⇒ Boolean
Determines if a given block type is selected based on a list.
- #bpp(*args) ⇒ Object
-
#display_terminal_rectangle(width, height) ⇒ Object
This function draws a rectangle of the given width and height with stars on the edges and empty space inside.
- #dp(str) ⇒ Object
- #evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash', initial_code_required: false, occurrence_expressions: nil) ⇒ Object
-
#find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs: false, use_relative_paths: true) ⇒ Object
Finds files matching a given pattern within specified directory paths while optionally excluding “.” and “..” entries and directory names from the results.
-
#format_and_highlight_dependencies(dependencies, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '', detail_sep: ' ') ⇒ String
Formats and highlights a list of dependencies.
- #format_and_highlight_hash(data, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Data:', highlight: [], line_prefix: ' ', line_postfix: '', key_has_value: ': ') ⇒ Object
-
#format_and_highlight_lines(lines, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '') ⇒ Object
warn menu_blocks.to_yaml.sub(/^(?:—n)?/, “MenuBlocks:n”).
-
#main ⇒ Object
MDE.prepend(ImwUx).
- #menu_from_yaml ⇒ Object
- #parse_yaml_of_ux_block(data, prompt: nil, validate: nil) ⇒ Object
- #process_arguments(arguments, loose_args, options_parsed) ⇒ Object
- #process_commands(options_parsed:, arguments:, enable_search:, named_procs:, rest:) ⇒ Object
- #rbi ⇒ Object
- #rbp ⇒ Object
-
#resize_terminal(show_dims: false, show_rectangle: false, require_stdout: true, debug: $debug) ⇒ Object
This function attempts to resize the terminal to its maximum supported size.
- #rpry ⇒ Object
- #sort_hash_recursively(hash) ⇒ Object
-
#spec_source(file, env_var_name = 'SPEC_DEBUG') ⇒ Object
output standard header for file load during testing.
-
#ww(*objs, **kwargs) ⇒ Object
selectively enabled, for general debugging return the last item in the list.
-
#ww0(*objs, category: $ww_category, context: nil, full_backtrace: false, level: :debug, locations: caller_locations, log_file: $ww_log_file, output: $ww_output, single_line: false, timestamp: false, location_offset: 0) ⇒ Object
output the formatted data and location.
-
#wwa(*objs, **kwargs) ⇒ Object
output the object and backtrace for the error abort.
-
#wwb ⇒ Object
break into the debugger if enabled.
-
#wwe(*objs, **kwargs) ⇒ Object
output the object and backtrace for the error raise the error for the caller to handle.
-
#wwp(*objs, **kwargs) ⇒ Object
selectively enabled, for process tracking output data and the caller’s location.
-
#wwr(*objs, **kwargs) ⇒ Object
the return value for a function.
-
#wwt(*objs, **kwargs) ⇒ Object
selectively enabled, for tagged data the first item is the tag, the rest is data exclude tags in the list of tags to skip output data and the caller’s location.
-
#wwx(expression = nil, **kwargs, &block) ⇒ Object
enhanced expression wrapper with better context usage: wwx { some_expression } or wwx(expression).
Methods included from Tap
#tap_config, #tap_inspect, #tap_print, #tap_pry, #tap_puts, #tap_yaml
Methods included from Env
#env_bool, #env_bool_false, #env_int, #env_str
Methods included from CLI
Instance Method Details
#assert_equal_hash(expected, actual, message = nil) ⇒ Object
519 520 521 522 523 |
# File 'lib/fcb.rb', line 519 def assert_equal_hash(expected, actual, = nil) sorted_expected = sort_hash_recursively(expected) sorted_actual = sort_hash_recursively(actual) assert_equal sorted_expected, sorted_actual, end |
#block_type_selected?(selected_types, type) ⇒ Boolean
Determines if a given block type is selected based on a list.
check against. If nil, all types are considered selected. selected_types is nil (indicating all types are selected).
13 14 15 |
# File 'lib/filter.rb', line 13 def block_type_selected?(selected_types, type) !selected_types || selected_types.include?(type) end |
#bpp(*args) ⇒ Object
73 74 75 76 77 |
# File 'lib/markdown_exec.rb', line 73 def bpp(*args) pp '+ bpp()' pp(*args.map.with_index { |line, ind| " - #{ind}: #{line}" }) rbi end |
#display_terminal_rectangle(width, height) ⇒ Object
This function draws a rectangle of the given width and height with stars on the edges and empty space inside.
84 85 86 87 88 |
# File 'lib/resize_terminal.rb', line 84 def display_terminal_rectangle(width, height) puts '*' * width (height - 2).times { puts "*#{' ' * (width - 2)}*" } puts '*' * width end |
#dp(str) ⇒ Object
58 59 60 |
# File 'lib/markdown_exec.rb', line 58 def dp(str) lout " => #{str}", level: DISPLAY_LEVEL_DEBUG end |
#evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash', initial_code_required: false, occurrence_expressions: nil) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/evaluate_shell_expressions.rb', line 12 def evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash', initial_code_required: false, occurrence_expressions: nil) # !!p initial_code expressions key_format shell return if (initial_code_required && (initial_code.nil? || initial_code.empty?)) || expressions.nil? || expressions.empty? # token to separate output token = "__TOKEN__#{Time.now.to_i}__" # Construct a single shell script script = initial_code.dup expressions.each_with_index do |(_key, expression), index| script << "\necho #{token}#{index}\n" script << expression << "\n" end wwt :eval, 'script:', script # Execute stdout_str, _, status = Open3.capture3(shell, '-c', script) unless status.success? return EvaluateShellExpression::StatusFail end # Extract output for expressions result_hash = {} part = stdout_str.split(/\n?#{token}\d+\n/) unless part.empty? part[1..-1].tap do |output_parts| expressions.each_with_index do |(key, _expression), index| result_hash[occurrence_expressions[key]] = output_parts[index].chomp end end end result_hash rescue StandardError ww $@, $!, caller.deref ww initial_code, expressions raise StandardError, $! end |
#find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs: false, use_relative_paths: true) ⇒ Object
Finds files matching a given pattern within specified directory paths while optionally excluding “.” and “..” entries and directory names from the results.
The function takes a pattern (filename or pattern with wildcards), an array of paths, and options to exclude directory entries and special entries “.” and “..”, and to use relative paths. It searches for files matching the pattern within each of the specified paths. Hidden files are included in the search. The search can include subdirectories depending on the path specification (e.g., ‘dir/**’ for recursive search).
Args:
pattern (String): A filename or a pattern string with wildcards.
paths (Array<String>): An array of directory paths where the search will be performed.
Paths can include wildcards for recursive search.
exclude_dirs (Boolean): If true, excludes "." and ".." and directory names from the results.
use_relative_paths (Boolean): If true, removes the app's base directory from the file names
if present.
Returns:
Array<String>: A unique list of file paths that match the given pattern in the specified paths,
excluding directories if exclude_dirs is true. Paths are relative if use_relative_paths is true.
Example:
find_files('version.rb', ['lib/**', 'spec'], true, true)
# This might return file paths like ['markdown_exec/version.rb', 'spec/version_spec.rb'].
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/find_files.rb', line 31 def find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs: false, use_relative_paths: true) matched_files = [] paths.each do |path_with_wildcard| # Combine the path with the wildcard and the pattern search_pattern = File.join(path_with_wildcard, pattern) # Use Dir.glob with the File::FNM_DOTMATCH flag to include hidden files files = Dir.glob(search_pattern, File::FNM_DOTMATCH) # Optionally exclude "." and ".." and directory names files.reject! { |file| file.end_with?('/.', '/..') || File.directory?(file) } if exclude_dirs # Optionally use relative paths files.map! { |file| file.sub(/^#{Regexp.escape(base_dir)}\//, '') } if use_relative_paths matched_files += files end matched_files.uniq end |
#format_and_highlight_dependencies(dependencies, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '', detail_sep: ' ') ⇒ String
Formats and highlights a list of dependencies. Dependencies are presented with indentation, and specific items can be highlighted in a specified color, while others are shown in a plain color.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/directory_searcher.rb', line 50 def format_and_highlight_dependencies( dependencies, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '', detail_sep: ' ' ) formatted_deps = dependencies&.map do |dep_name, sub_items| formatted_sub_items = sub_items.map do |item| color_sym = highlight.include?(item) ? highlight_color_sym : plain_color_sym string_send_color(item, color_sym) end.join(detail_sep) "#{line_prefix}- #{string_send_color(dep_name, highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{formatted_sub_items}#{line_postfix}" end || [] "#{line_prefix}#{string_send_color(label, highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n") end |
#format_and_highlight_hash(data, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Data:', highlight: [], line_prefix: ' ', line_postfix: '', key_has_value: ': ') ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/directory_searcher.rb', line 9 def format_and_highlight_hash( data, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Data:', highlight: [], line_prefix: ' ', line_postfix: '', key_has_value: ': ' ) formatted_deps = data&.map do |key, value| color_sym = highlight.include?(key) ? highlight_color_sym : plain_color_sym dkey = string_send_color(key, color_sym) "#{line_prefix}#{dkey}#{key_has_value}" \ "#{string_send_color(value, highlight.include?(value) ? highlight_color_sym : plain_color_sym)}: " \ "#{formatted_sub_items}#{line_postfix}" end "#{line_prefix}#{string_send_color(label, highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n") end |
#format_and_highlight_lines(lines, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '') ⇒ Object
warn menu_blocks.to_yaml.sub(/^(?:—n)?/, “MenuBlocks:n”)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/directory_searcher.rb', line 75 def format_and_highlight_lines( lines, highlight_color_sym: :exception_color_detail, plain_color_sym: :menu_chrome_color, label: 'Dependencies:', highlight: [], line_prefix: ' ', line_postfix: '' ) formatted_deps = lines&.map do |item| "#{line_prefix}- #{string_send_color(dep_name, highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{item}#{line_postfix}" end || [] "#{line_prefix}#{string_send_color(label, highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n") end |
#main ⇒ Object
MDE.prepend(ImwUx)
252 253 254 255 256 257 258 259 260 261 |
# File 'lib/input_sequencer.rb', line 252 def main if ARGV.empty? puts "Usage: #{__FILE__} document_filename [block_name...]" exit(1) end document_filename = ARGV.shift initial_blocks = ARGV mde = MDE.new(document_filename, initial_blocks) mde.do_run end |
#menu_from_yaml ⇒ Object
22 23 24 |
# File 'lib/shared.rb', line 22 def YAML.load File.open(File.join(File.(__dir__), LOCAL_YML)) end |
#parse_yaml_of_ux_block(data, prompt: nil, validate: nil) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/fcb.rb', line 8 def parse_yaml_of_ux_block( data, prompt: nil, validate: nil ) export = data if (export = data['export']).nil? # a single variable name is required to display a single value = export['format'] || export['menu_format'] name = export['name'] # if name is missing, use the last key in the echo or exec hashes if !name&.present? name = if export['echo'].is_a? Hash export['echo'].keys.last elsif export['exec'].is_a? Hash export['exec'].keys.last end end raise "Name is missing in UX block: #{data.inspect}" unless name.present? || .present? OpenStruct.new( act: export['act'], allow: export['allow'] || export['allowed'], default: export['default'], echo: export['echo'], exec: export['exec'], force: export['force'], init: export['init'], menu_format: , name: name, prompt: export['prompt'] || prompt, readonly: export['readonly'].nil? ? false : export['readonly'], required: export['require'] || export['required'] || export[BT_UX_FLD_REQUIRED], transform: export['transform'], validate: export['validate'] || validate ) end |
#process_arguments(arguments, loose_args, options_parsed) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/argument_processor.rb', line 7 def process_arguments(arguments, loose_args, ) # !!t arguments, loose_args, options_parsed # loose_args will be empty first command contains pass-through arguments while loose_args.any? if arguments.first == loose_args.first yield ArgPro::ArgIsPosition, arguments.shift loose_args.shift next end yield ArgPro::ArgIsOption, .first arguments.shift(.first[:procname].present? ? 2 : 1) .shift end end |
#process_commands(options_parsed:, arguments:, enable_search:, named_procs:, rest:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/argument_processor.rb', line 25 def process_commands(options_parsed:, arguments:, enable_search:, named_procs:, rest:) # !!t arguments,options_parsed command_processed = false block_executed = false = false position = 0 process_arguments(arguments.dup, rest.dup, .dup) do |type, item| # !!t type,item case type when ArgPro::ArgIsOption if named_procs.include?(item[:name]) command_processed = true yield ArgPro::CallProcess, item[:name] else converted = if item[:proccode] yield ArgPro::ConvertValue, [item[:proccode], item[:value]] else item[:value] end if item[:name] yield ArgPro::ActSetOption, [item[:name], converted] end end when ArgPro::ArgIsPosition case position when 0 # position 0: file, folder, or search term (optional) if Dir.exist?(item) yield ArgPro::ActSetPath, item elsif File.exist?(item) yield ArgPro::ActSetFileName, item elsif enable_search yield ArgPro::ActFind, item else yield ArgPro::ActFileIsMissing, item end else # position 1: block (optional) if item == '.' = true else block_executed = true yield ArgPro::ActSetBlockName, item end end position += 1 rest.shift else raise end end end |
#rbi ⇒ Object
62 63 64 65 |
# File 'lib/markdown_exec.rb', line 62 def rbi pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" }) binding.irb end |
#rbp ⇒ Object
67 68 69 70 71 |
# File 'lib/markdown_exec.rb', line 67 def rbp rpry pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" }) binding.pry end |
#resize_terminal(show_dims: false, show_rectangle: false, require_stdout: true, debug: $debug) ⇒ Object
This function attempts to resize the terminal to its maximum supported size. It checks if the script is running in an interactive terminal with no arguments. If so, it sends escape sequences to query the terminal size and reads the response. It then compares the current terminal size with the calculated size and adjusts if necessary. If the terminal emulator is unsupported, it prints an error message. 2024-08-23 add require_stdout to allow for testing
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/resize_terminal.rb', line 16 def resize_terminal(show_dims: false, show_rectangle: false, require_stdout: true, debug: $debug) # Check if running in an interactive terminal and no arguments are provided unless $stdin.tty? warn 'Usage: resize_terminal' return end return if require_stdout && !$stdout.tty? # Save the current state and send the escape sequence to get the cursor position print "\e7\e[r\e[999;999H\e[6n\e8" $stdout.flush # Read the response from the terminal response = String.new Timeout.timeout(5) do loop do char = $stdin.getch response << char break if response.include?('R') end end if response.empty? wwe "Error: No response received from terminal. Response: #{response.inspect}" if debug return 1 end # Match the response to extract the terminal dimensions match_data = response.match(/\[(\d+);(\d+)R/) unless match_data wwe "Error: Failed to match terminal response pattern. Response: #{response.inspect}" if debug return 1 end calculated_rows, calculated_columns = match_data.captures.map(&:to_i) if EnvInterface.get('COLUMNS', transform: lambda(&:to_i)) == calculated_columns && EnvInterface.get('LINES', transform: lambda(&:to_i)) == calculated_rows puts "#{ENV.fetch('TERM', nil)} #{calculated_columns}x#{calculated_rows}" elsif calculated_columns.positive? && calculated_rows.positive? warn "#{ENV.fetch('COLUMNS', nil)}x#{ENV.fetch('LINES', nil)} -> #{calculated_columns}x#{calculated_rows}" if show_dims system("stty cols #{calculated_columns} rows #{calculated_rows}") else wwe "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}" if debug return 1 end # Display a text rectangle if the option is enabled display_terminal_rectangle(calculated_columns, calculated_rows) if show_rectangle rescue Timeout::Error wwe 'Error: Timeout while reading terminal response. Unsupported terminal emulator.' if debug 1 rescue StandardError => err wwe "Error: #{err.message}. Unsupported terminal emulator." if debug 1 ensure EnvInterface.set('COLUMNS', @original_columns) EnvInterface.set('LINES', @original_lines) end |
#rpry ⇒ Object
79 80 81 82 |
# File 'lib/markdown_exec.rb', line 79 def rpry require 'pry-nav' require 'pry-stack_explorer' end |
#sort_hash_recursively(hash) ⇒ Object
525 526 527 528 529 |
# File 'lib/fcb.rb', line 525 def sort_hash_recursively(hash) hash.transform_values do |v| v.is_a?(Hash) ? sort_hash_recursively(v) : v end.sort.to_h end |
#spec_source(file, env_var_name = 'SPEC_DEBUG') ⇒ Object
output standard header for file load during testing
5 6 7 8 9 10 |
# File 'lib/rspec_helpers.rb', line 5 def spec_source(file, env_var_name = 'SPEC_DEBUG') if (->(val) { val.nil? ? false : !(val.empty? || val == '0') }) .call(ENV.fetch(env_var_name, nil)) puts "#{env_var_name}: #{file}" end end |
#ww(*objs, **kwargs) ⇒ Object
selectively enabled, for general debugging return the last item in the list
69 70 71 72 73 74 75 76 |
# File 'lib/ww.rb', line 69 def ww(*objs, **kwargs) # assume the final item is the significant one # allows prefixing to an existing expression and forwarding the result return objs.last unless $debug locations = kwargs[:locations] || caller_locations ww0(*objs, **kwargs.merge(locations: locations)) end |
#ww0(*objs, category: $ww_category, context: nil, full_backtrace: false, level: :debug, locations: caller_locations, log_file: $ww_log_file, output: $ww_output, single_line: false, timestamp: false, location_offset: 0) ⇒ Object
output the formatted data and location
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/ww.rb', line 169 def ww0(*objs, category: $ww_category, context: nil, full_backtrace: false, level: :debug, locations: caller_locations, log_file: $ww_log_file, output: $ww_output, single_line: false, timestamp: false, location_offset: 0) # Format caller information line caller_info_line = lambda do |caller_info, ind| [ DEPTH_ICON * (location_offset + locations.count - ind), caller_info.path.deref, caller_info.lineno, caller_info.label ].join(' : ') end # Validate log level raise ArgumentError, "Invalid log level: #{level}" unless LOG_LEVELS.include?(level) # Generate backtrace backtrace = if full_backtrace locations.map.with_index do |caller_info, ind| caller_info_line.call(caller_info, ind) end else [caller_info_line.call(locations.first, 0)] end # Add optional timestamp time_prefix = ? "[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] " : '' # Add log level, category, and context prefix level_prefix = "[#{level.to_s.upcase}]" category_prefix = category ? "[#{category}] " : '' context_prefix = context ? "[#{context}] " : '' # Combine all parts into the final message header = "#{time_prefix}#{level_prefix} #{category_prefix}#{context_prefix}" trace = backtrace + objs io = StringIO.new = if single_line PP.singleline_pp(trace, io) "#{header} #{io.string}" else PP.pp(trace, io) "#{header}\n#{io.string}" end # prefix each line in formatted_message prefix = (' ' * 8).freeze = prefix + .gsub("\n", "\n#{prefix}") # Output to $stderr or specified IO object output.puts "\033[38;2;128;191;191m#{formatted_message}\033[0m" output.flush # Optionally log to a file if log_file File.open(log_file, 'a') do |file| file.puts() end end # Always return the last item in the list, as the label is usually first objs.last end |
#wwa(*objs, **kwargs) ⇒ Object
output the object and backtrace for the error abort
80 81 82 83 84 85 86 |
# File 'lib/ww.rb', line 80 def wwa(*objs, **kwargs) ww0(*objs, **kwargs.merge(full_backtrace: true, locations: caller_locations)) exit 1 end |
#wwb ⇒ Object
break into the debugger if enabled
89 90 91 |
# File 'lib/ww.rb', line 89 def wwb binding.irb if $debug end |
#wwe(*objs, **kwargs) ⇒ Object
output the object and backtrace for the error raise the error for the caller to handle
95 96 97 98 99 100 101 102 |
# File 'lib/ww.rb', line 95 def wwe(*objs, **kwargs) ww0(*objs, **kwargs.merge(full_backtrace: true, locations: caller_locations)) # raise StandardError, objs.first.fetch(:error) || objs.first raise StandardError, objs.first end |
#wwp(*objs, **kwargs) ⇒ Object
selectively enabled, for process tracking output data and the caller’s location
106 107 108 109 110 111 112 113 114 |
# File 'lib/ww.rb', line 106 def wwp(*objs, **kwargs) return objs.last unless $debug ww0(*objs, **kwargs.merge( locations: caller_locations[0..0], location_offset: caller_locations.count )) end |
#wwr(*objs, **kwargs) ⇒ Object
the return value for a function
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/ww.rb', line 117 def wwr(*objs, **kwargs) # assume the final item is the significant one # allows prefixing to an existing expression and forwarding the result return objs.last unless $debug ww0(*objs, **kwargs.merge( locations: caller_locations[0..0], location_offset: caller_locations.count )) end |
#wwt(*objs, **kwargs) ⇒ Object
selectively enabled, for tagged data the first item is the tag, the rest is data exclude tags in the list of tags to skip output data and the caller’s location
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/ww.rb', line 133 def wwt(*objs, **kwargs) # tags to skip return objs.last if !$debug || i[blocks env fcb].include?(objs.first) formatted = ['Tagged', objs.first] + objs[1..] ww0(*formatted, **kwargs.merge( locations: caller_locations[0..0], location_offset: caller_locations.count )) end |
#wwx(expression = nil, **kwargs, &block) ⇒ Object
enhanced expression wrapper with better context usage: wwx { some_expression } or wwx(expression)
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/ww.rb', line 147 def wwx(expression = nil, **kwargs, &block) if block_given? # Block form: wwx { some_expression } result = block.call return result unless $debug # Capture the source location of the block locations = kwargs[:locations] || caller_locations ww0(result, **kwargs.merge(locations: locations, context: 'block')) elsif expression # Direct form: wwx(some_expression) return expression unless $debug locations = kwargs[:locations] || caller_locations ww0(expression, **kwargs.merge(locations: locations, context: 'direct')) else # No arguments - just return nil nil end end |