Top Level Namespace
Defined Under Namespace
Modules: ArrayUtil, CLI, ClassMethodWrapper, CompactionHelpers, Env, Exceptions, HashDelegatorSelf, ImwUx, InstanceMethodWrapper, MarkdownExec, MarkdownTableFormatter, PathUtils, StringUtil, Tap, TextAnalyzer Classes: AnsiFormatter, AnsiString, AppInterrupt, ArgPro, ArgumentProcessorTest, Array, BashCommentFormatter, BashCommentFormatterTest, BlockLabel, BlockLabelTest, BlockMissing, BlockType, CachedNestedFileReader, CachedNestedFileReaderTest, ColorScheme, CommandProcessorTest, DOH, DirectorySearcher, DirectorySearcherTest, DirectorySearcherTest2, ExecutionStreams, FCBTest, FOut, FalseClass, FileMissingError, Hash, HierarchyString, IndexedLine, InputSequencer, LayeredHash, LinkKeys, LoadFile, LoadFileLinkState, MDE, MenuOptions, MenuState, NamedCaptureExtractor, NestedLine, Object, OptionValueTest, Poly, Regexp, RegexpGsubFormatTest, ResizeTerminalTest, SavedAssetTest, SavedFilesMatcherTest, SelectedBlockMenuState, ShellType, StreamsOut, String, StringWrapper, TableExtractor, TestFindFiles, TestFormatTable, TestFormatTable2, TestHierarchyString, TestMarkdownTableFormatter, TestObjectMethods, TestShellExpressionEvaluator, TestStringMethods, TestTableExtractor, TestTextAnalyzer, TtyMenu
Constant Summary collapse
- 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}"
- 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::VARS => :menu_vars_color }.freeze
- SAVED_ASSET_FORMAT =
'%{prefix}%{join}%{time}%{join}%{filename}%{join}' \ '%{mark}%{join}%{blockname}%{join}%{exts}'
- ARGV_SEP =
'--'
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
- #append_to_bash_history(line) ⇒ Object
- #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
- #cil(caller_info) ⇒ 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', key_format: "%%<%s>") ⇒ 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
- #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) ⇒ 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, full_backtrace: false, single_line: false, locations: caller_locations) ⇒ Object
def wtr(*objs, full_backtrace: false, single_line: false) ww( + objs, locations: caller_locations, full_backtrace: full_backtrace, single_line: single_line) end.
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
#append_to_bash_history(line) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/append_to_bash_history.rb', line 6 def append_to_bash_history(line) # Get the bash history file from the HISTFILE environment variable or default to ~/.bash_history histfile = ENV['HISTFILE'] || File.("~/.bash_history") if File.exist?(histfile) # Open the file in append mode and write the line File.open(histfile, 'a') do |file| file.puts line end puts "Appended to bash history: #{line}" else puts "Bash history file does not exist." end end |
#assert_equal_hash(expected, actual, message = nil) ⇒ Object
189 190 191 192 193 |
# File 'lib/fcb.rb', line 189 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
71 72 73 74 75 |
# File 'lib/markdown_exec.rb', line 71 def bpp(*args) pp '+ bpp()' pp(*args.map.with_index { |line, ind| " - #{ind}: #{line}" }) rbi end |
#cil(caller_info) ⇒ Object
25 26 27 28 |
# File 'lib/ww.rb', line 25 def cil(caller_info) "#{caller_info.lineno} : #{File.basename(caller_info.path)} : " \ "#{caller_info.label}" 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.
77 78 79 80 81 |
# File 'lib/resize_terminal.rb', line 77 def display_terminal_rectangle(width, height) puts '*' * width (height - 2).times { puts "*#{' ' * (width - 2)}*" } puts '*' * width end |
#dp(str) ⇒ Object
56 57 58 |
# File 'lib/markdown_exec.rb', line 56 def dp(str) lout " => #{str}", level: DISPLAY_LEVEL_DEBUG end |
#evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash', key_format: "%%<%s>") ⇒ 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/evaluate_shell_expressions.rb', line 8 def evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash', key_format: "%%<%s>") # !!p initial_code expressions key_format shell return if initial_code.nil? || initial_code.empty? || expressions.nil? || expressions.empty? || key_format.nil? || key_format.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 # !!v script # Execute stdout_str, stderr_str, status = Open3.capture3(shell, "-c", script) # !!v stdout_str, stderr_str, status unless status.success? raise "Shell script execution failed: #{stderr_str}" end # Extract output for expressions result_hash = {} stdout_str.split(/\n?#{token}\d+\n/)[1..-1].tap do |output_parts| expressions.each_with_index do |(key, _expression), index| result_hash[sprintf(key_format, key)] = output_parts[index].chomp end end # !!v result_hash result_hash 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 |
#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
60 61 62 63 |
# File 'lib/markdown_exec.rb', line 60 def rbi pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" }) binding.irb end |
#rbp ⇒ Object
65 66 67 68 69 |
# File 'lib/markdown_exec.rb', line 65 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) ⇒ 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-8-23 add require_stdout to allow for testing
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/resize_terminal.rb', line 14 def resize_terminal(show_dims: false, show_rectangle: false, require_stdout: true) # 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? warn "Error: No response received from terminal. Response: #{response.inspect}" return 1 end # Match the response to extract the terminal dimensions match_data = response.match(/\[(\d+);(\d+)R/) unless match_data warn "Error: Failed to match terminal response pattern. Response: #{response.inspect}" return 1 end calculated_rows, calculated_columns = match_data.captures.map(&:to_i) if ENV['COLUMNS'].to_i == calculated_columns && ENV['LINES'].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 warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}" 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 warn 'Error: Timeout while reading terminal response. Unsupported terminal emulator.' 1 rescue StandardError => err warn "Error: #{err.}. Unsupported terminal emulator." 1 end |
#rpry ⇒ Object
77 78 79 80 |
# File 'lib/markdown_exec.rb', line 77 def rpry require 'pry-nav' require 'pry-stack_explorer' end |
#sort_hash_recursively(hash) ⇒ Object
195 196 197 198 199 |
# File 'lib/fcb.rb', line 195 def sort_hash_recursively(hash) hash.each_with_object({}) do |(k, v), new_hash| new_hash[k] = 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, full_backtrace: false, single_line: false, locations: caller_locations) ⇒ Object
def wtr(*objs, full_backtrace: false, single_line: false)
ww(['->'] + objs,
locations: caller_locations[2..-1],
full_backtrace: full_backtrace,
single_line: single_line)
end
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ww.rb', line 21 def ww(*objs, full_backtrace: false, single_line: false, locations: caller_locations) return unless $debug def cil(caller_info) "#{caller_info.lineno} : #{File.basename(caller_info.path)} : " \ "#{caller_info.label}" end backtrace = if full_backtrace locations.map do |caller_info| cil(caller_info) end else [cil(locations[0, 1].first)] end trace = backtrace + objs if single_line PP.singleline_pp(trace, $stderr) else PP.pp(trace, $stderr) end end |