Class: Onlylogs::FilePathParser
- Inherits:
-
Object
- Object
- Onlylogs::FilePathParser
- Defined in:
- app/models/onlylogs/file_path_parser.rb
Constant Summary collapse
- KNOWN_EDITORS =
[ { symbols: [ :atom ], sniff: /atom/i, url: "atom://core/open/file?filename=%{file}&line=%{line}" }, { symbols: [ :emacs, :emacsclient ], sniff: /emacs/i, url: "emacs://open?url=file://%{file}&line=%{line}" }, { symbols: [ :idea ], sniff: /idea/i, url: "idea://open?file=%{file}&line=%{line}" }, { symbols: [ :macvim, :mvim ], sniff: /vim/i, url: "mvim://open?url=file://%{file_unencoded}&line=%{line}" }, { symbols: [ :rubymine ], sniff: /mine/i, url: "x-mine://open?file=%{file}&line=%{line}" }, { symbols: [ :sublime, :subl, :st ], sniff: /subl/i, url: "subl://open?url=file://%{file}&line=%{line}" }, { symbols: [ :textmate, :txmt, :tm ], sniff: /mate/i, url: "txmt://open?url=file://%{file}&line=%{line}" }, { symbols: [ :vscode, :code ], sniff: /code/i, url: "vscode://file/%{file}:%{line}" }, { symbols: [ :vscodium, :codium ], sniff: /codium/i, url: "vscodium://file/%{file}:%{line}" } ].freeze
- FILE_PATH_PATTERN =
Pre-compiled regex for better performance
%r{ (?<![a-zA-Z0-9_/]) # Negative lookbehind - not preceded by word chars or / (?:\./)? # Optional relative path indicator (?:/[a-zA-Z0-9_\-\.\s]+)+ # File path with allowed characters (?:\.rb|\.js|\.ts|\.tsx|\.jsx|\.py|\.java|\.go|\.rs|\.php|\.html|\.erb|\.haml|\.slim|\.css|\.scss|\.sass|\.less|\.xml|\.json|\.yml|\.yaml|\.md|\.txt|\.log) # File extensions (?::\d+)? # Optional line number (?![a-zA-Z0-9_/]) # Negative lookahead - not followed by word chars or / }x.freeze
- HTML_TEMPLATE =
Pre-built HTML template to avoid string interpolation
'<a href="%{url}" class="file-link">%{match}</a>'.freeze
Class Method Summary collapse
- .cached_editor_instance ⇒ Object
- .editor_from_symbol(symbol) ⇒ Object
- .extract_file_path(match) ⇒ Object
- .extract_line_number(match) ⇒ Object
- .for_formatting_string(formatting_string) ⇒ Object
- .for_proc(url_proc) ⇒ Object
- .parse(string) ⇒ Object
Instance Method Summary collapse
-
#initialize(url_proc) ⇒ FilePathParser
constructor
A new instance of FilePathParser.
- #scheme ⇒ Object
- #url(raw_path, line) ⇒ Object
Constructor Details
#initialize(url_proc) ⇒ FilePathParser
Returns a new instance of FilePathParser.
73 74 75 |
# File 'app/models/onlylogs/file_path_parser.rb', line 73 def initialize(url_proc) @url_proc = url_proc end |
Class Method Details
.cached_editor_instance ⇒ Object
60 61 62 63 |
# File 'app/models/onlylogs/file_path_parser.rb', line 60 def self.cached_editor_instance return @cached_editor_instance if @cached_editor_instance @cached_editor_instance = editor_from_symbol(Onlylogs.editor) end |
.editor_from_symbol(symbol) ⇒ Object
66 67 68 69 70 71 |
# File 'app/models/onlylogs/file_path_parser.rb', line 66 def self.editor_from_symbol(symbol) KNOWN_EDITORS.each do |preset| return for_formatting_string(preset[:url]) if preset[:symbols].include?(symbol) end editor_from_symbol(:vscode) end |
.extract_file_path(match) ⇒ Object
107 108 109 110 |
# File 'app/models/onlylogs/file_path_parser.rb', line 107 def self.extract_file_path(match) # Remove line number if present match.sub(/:\d+$/, "") end |
.extract_line_number(match) ⇒ Object
112 113 114 115 116 |
# File 'app/models/onlylogs/file_path_parser.rb', line 112 def self.extract_line_number(match) # Extract line number or default to 1 line_match = match.match(/:(\d+)$/) line_match ? line_match[1].to_i : 1 end |
.for_formatting_string(formatting_string) ⇒ Object
47 48 49 50 51 |
# File 'app/models/onlylogs/file_path_parser.rb', line 47 def self.for_formatting_string(formatting_string) new proc { |file, line| formatting_string % { file: URI.encode_www_form_component(file), file_unencoded: file, line: line } } end |
.for_proc(url_proc) ⇒ Object
53 54 55 |
# File 'app/models/onlylogs/file_path_parser.rb', line 53 def self.for_proc(url_proc) new url_proc end |
.parse(string) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/models/onlylogs/file_path_parser.rb', line 33 def self.parse(string) return string if string.blank? # Early return if no file paths present return string unless string.match?(FILE_PATH_PATTERN) string.gsub(FILE_PATH_PATTERN) do |match| file_path = extract_file_path(match) line_number = extract_line_number(match) url = cached_editor_instance.url(file_path, line_number) HTML_TEMPLATE % { url: url, match: match } end end |
Instance Method Details
#scheme ⇒ Object
91 92 93 |
# File 'app/models/onlylogs/file_path_parser.rb', line 91 def scheme url("/fake", 42).sub(/:.*/, ":") end |
#url(raw_path, line) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/models/onlylogs/file_path_parser.rb', line 77 def url(raw_path, line) if virtual_path && raw_path.start_with?(virtual_path) if host_path file = raw_path.sub(%r{\A#{virtual_path}}, host_path) else file = raw_path.sub(%r{\A#{virtual_path}/}, "") end else file = raw_path end url_proc.call(file, line) end |