editor_opener 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97e3fda047f6c339f6b1e5c85ac7a6e7442438adf1be5698cc74509dc277cab2
4
- data.tar.gz: 86a624869961333ebb914c16f5c8e4a9aa27d2fd11959a4c43ca04eebeeb1782
3
+ metadata.gz: 6c8b8e6b943f3a78a43389bf47f24c2bc6b9880ad791e7344035ecc6d0057d84
4
+ data.tar.gz: 136ce7ea6b21b4b181f69e6a1a32f3ed7427a8963b132194fc5df8367020e23f
5
5
  SHA512:
6
- metadata.gz: '039d8837645d9a93163a08693939eabeebc8179176ead4bc8e113906bc80a1b219e57a7c47cdab904e8571bbd005fac2cdd91ecb87d7529d154c2ed59cd99e76'
7
- data.tar.gz: 2598ff96c36081386a3d8ec4692c9aff666d322a268e11ec47cfe92c625816d9516baaaea8b866779ab7130a4aa9c8f6723c1a8d6c09d1a6e445995a32e07ccf
6
+ metadata.gz: e3fbaa4c31d6b2a1492caa43f36a1587381b0e4b5377fcb5c57349140cf1c84969fcf7c1153d642a8918f5b3085b4dedb264fd015ccdbf5ef72159c1a759f486
7
+ data.tar.gz: 1fcdb2135fa17421f3472118575a509f3ab5c7a3c8a033726dcd626e230c4ad25937fb592829d237adb5264705f3b0b210f391ba4ffcb901d118075603830ea8
data/README.md CHANGED
@@ -1,28 +1,211 @@
1
- # EditorOpener
2
- Short description and motivation.
1
+ # editor_opener
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ Open source files in your editor directly from Rails error pages. This gem adds clickable links to file paths in Rails error pages, allowing you to instantly open files at the exact line where errors occur.
4
+
5
+ ![editor_opener](docs/editor_opener.gif)
6
+
7
+ ## Features
8
+
9
+ - 🔥 **Works with Rails 7.1+**
10
+ - 🔗 **Clickable file links** in Rails error pages
11
+ - 📝 **Multiple editor support** - Works with 13+ popular editors
12
+ - 🎯 **Precise line targeting** - Opens files at the exact error line
13
+ - 🔧 **Easy configuration** - Set via initializer or environment variable
14
+ - 🚀 **Zero configuration** - Works out of the box with `EDITOR` environment variable
15
+ - 📱 **Custom URL schemes** - Uses editor-specific protocols for seamless integration
6
16
 
7
17
  ## Installation
18
+
8
19
  Add this line to your application's Gemfile:
9
20
 
10
21
  ```ruby
11
- gem "editor_opener"
22
+ group :development do
23
+ gem "editor_opener"
24
+ end
12
25
  ```
13
26
 
14
27
  And then execute:
15
28
  ```bash
16
- $ bundle
29
+ $ bundle install
17
30
  ```
18
31
 
19
- Or install it yourself as:
32
+ ## Configuration
33
+
34
+ ### Option 1: Generate and configure initializer (Recommended)
35
+
36
+ ```bash
37
+ $ rails generate editor_opener:install
38
+ ```
39
+
40
+ This creates `config/initializers/editor_opener.rb` with all supported editors listed as comments.
41
+
42
+ Edit the initializer to set your preferred editor:
43
+
44
+ ```ruby
45
+ EditorOpener.setup do |config|
46
+ config.editor = :cursor # or any other supported editor
47
+ end
48
+ ```
49
+
50
+ ### Option 2: Environment variable
51
+
52
+ Set the `EDITOR` environment variable:
53
+
20
54
  ```bash
21
- $ gem install editor_opener
55
+ export EDITOR=cursor # for Cursor
56
+ export EDITOR=atom # for Atom
57
+ export EDITOR=subl # for Sublime Text
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ 1. **Install and configure** the gem (see above)
63
+ 2. **Restart your Rails server**
64
+ 3. **Trigger an error** in your Rails application
65
+ 4. **Click the edit icons** (✏️) or line numbers in the error page to open files in your editor
66
+
67
+ The gem automatically detects error traces from:
68
+ - Application code
69
+ - Gem files
70
+ - Direct file paths
71
+
72
+ ## Supported Editors
73
+
74
+ The gem supports the following editors with their respective symbols:
75
+
76
+ | Editor | Symbols | Protocol |
77
+ |--------|---------|----------|
78
+ | **Atom** | `:atom` | `atom://` |
79
+ | **Cursor** | `:cursor` | `cursor://` |
80
+ | **Emacs** | `:emacs`, `:emacsclient` | `emacs://` |
81
+ | **IntelliJ IDEA** | `:idea` | `idea://` |
82
+ | **MacVim** | `:macvim`, `:mvim` | `mvim://` |
83
+ | **Nova** | `:nova` | `nova://` |
84
+ | **RubyMine** | `:rubymine` | `x-mine://` |
85
+ | **Sublime Text** | `:sublime`, `:subl`, `:st` | `subl://` |
86
+ | **TextMate** | `:textmate`, `:txmt`, `:tm` | `txmt://` |
87
+ | **Visual Studio Code** | `:vscode`, `:code` | `vscode://` |
88
+ | **VSCodium** | `:vscodium`, `:codium` | `vscodium://` |
89
+ | **Windsurf** | `:windsurf` | `windsurf://` |
90
+ | **Zed** | `:zed` | `zed://` |
91
+
92
+ ## Examples
93
+
94
+ ### Basic Configuration
95
+
96
+ ```ruby
97
+ # config/initializers/editor_opener.rb
98
+ EditorOpener.setup do |config|
99
+ config.editor = :cursor
100
+ end
101
+ ```
102
+
103
+ ### Environment Variable
104
+
105
+ ```bash
106
+ # In your shell profile (~/.bashrc, ~/.zshrc, etc.)
107
+ export EDITOR=cursor
108
+
109
+ # Or in your .env file (if using dotenv)
110
+ EDITOR=cursor
111
+ ```
112
+
113
+ ### Multiple Environments
114
+
115
+ ```ruby
116
+ # config/initializers/editor_opener.rb
117
+ EditorOpener.setup do |config|
118
+ config.editor = Rails.env.development? ? :cursor : nil
119
+ end
120
+ ```
121
+
122
+ ## How It Works
123
+
124
+ 1. **Error Detection**: The gem overrides Rails error pages
125
+ 2. **Trace Parsing**: Extracts file paths and line numbers from stack traces
126
+ 3. **Editor Detection**: Matches configured editor with supported protocols
127
+ 4. **URL Generation**: Creates editor-specific URLs for file opening
128
+ 5. **Link Enhancement**: Adds clickable links to error page templates
129
+
130
+ ## Troubleshooting
131
+
132
+ ### Editor doesn't open files
133
+
134
+ 1. **Check editor configuration**: Ensure your editor symbol is correct
135
+ 2. **Verify protocol support**: Make sure your editor supports URL protocols
136
+ 3. **Test environment variable**: Try setting `EDITOR` environment variable
137
+ 4. **Restart Rails server**: Configuration changes require server restart
138
+
139
+ ### Links don't appear
140
+
141
+ 1. **Check gem is loaded**: Ensure gem is in development group
142
+ 2. **Verify Rails environment**: Gem typically only works in development
143
+ 3. **Test with simple error**: Create a basic error to test functionality
144
+
145
+ ## Development
146
+
147
+ After checking out the repo, run:
148
+
149
+ ```bash
150
+ $ bin/setup
151
+ $ bin/test
152
+ ```
153
+
154
+ To run tests:
155
+
156
+ ```bash
157
+ $ bin/test
158
+ $ bin/rubocop
22
159
  ```
23
160
 
24
161
  ## Contributing
25
- Contribution directions go here.
162
+
163
+ Bug reports and pull requests are welcome on GitHub at https://github.com/igorkasyanchuk/editor_opener.
164
+
165
+ 1. Fork the project
166
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
167
+ 3. Make your changes
168
+ 4. Add tests for your changes
169
+ 5. Ensure all tests pass (`bin/test`)
170
+ 6. Commit your changes (`git commit -am 'Add some feature'`)
171
+ 7. Push to the branch (`git push origin my-new-feature`)
172
+ 8. Create a new Pull Request
173
+
174
+ ## TODO
175
+
176
+ - verify it works with old Rails versions (test with 7.1.0 and it works, for older versions it doesn't work)
177
+ possible fix:
178
+ ```ruby
179
+ # in railtie.rb
180
+ if defined?(ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS)
181
+ ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS.unshift(path)
182
+ else
183
+ module X
184
+ def initialize(assigns)
185
+ paths = [RESCUES_TEMPLATE_PATH]
186
+ lookup_context = ActionView::LookupContext.new(paths, path)
187
+ super(lookup_context, assigns, nil)
188
+ end
189
+ end
190
+
191
+ ActionDispatch::DebugView.prepend(X)
192
+ ```
193
+ But something is wrong in the views. Maybe we need to support older views, and create a new copy of them?
194
+ Also, you don't see the full exception, maybe this setting `config.action_dispatch.show_exceptions` can help, or capture exception with begin/rescue and print in the console?
195
+
196
+ - more tests
197
+ - support for more error pages?
198
+ - support for more editors
26
199
 
27
200
  ## License
201
+
28
202
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
203
+
204
+ ## Credits
205
+
206
+ Created by [Igor Kasyanchuk](https://github.com/igorkasyanchuk).
207
+
208
+ ## Related Projects
209
+
210
+ - [better_errors](https://github.com/BetterErrors/better_errors) - Better error pages for Rails
211
+ - [web-console](https://github.com/rails/web-console) - Rails console in your browser
@@ -0,0 +1,34 @@
1
+ <% error_index = local_assigns[:error_index] || 0 %>
2
+
3
+ <% source_extracts.each_with_index do |source_extract, index| %>
4
+ <% if source_extract[:code] %>
5
+ <div class="source <%= "hidden" if show_source_idx != index %>" id="frame-source-<%= error_index %>-<%= index %>">
6
+ <div class="info">
7
+ Extracted source (around line <strong>#<%= source_extract[:line_number] %></strong>):
8
+ </div>
9
+ <div class="data">
10
+ <table cellpadding="0" cellspacing="0" class="lines">
11
+ <tr>
12
+ <td>
13
+ <pre class="line_numbers">
14
+ <% source_extract[:code].each_key do |line_number| %>
15
+ <% file_url = ActionDispatch::TraceToFileExtractor.open_in_editor? && ActionDispatch::TraceToFileExtractor.new(source_extract[:trace], line_number:).call %>
16
+ <span><%= file_url ? raw("<a class=\"edit-line-link\" href=\"#{file_url}\">#{line_number}</a>") : line_number -%></span>
17
+ <% end %>
18
+ </pre>
19
+ </td>
20
+ <td width="100%">
21
+ <pre>
22
+ <% source_extract[:code].each do |line, source| -%>
23
+ <div class="line<%= " active" if line == source_extract[:line_number] -%>"><% if source.is_a?(Array) -%><%= source[0] -%><span class="error_highlight"><%= source[1] -%></span><%= source[2] -%>
24
+ <% else -%>
25
+ <%= source -%>
26
+ <% end -%></div><% end -%>
27
+ </pre>
28
+ </td>
29
+ </tr>
30
+ </table>
31
+ </div>
32
+ </div>
33
+ <% end %>
34
+ <% end %>
@@ -70,7 +70,11 @@
70
70
  display: flex;
71
71
  align-items: center;
72
72
  justify-content: center;
73
- color: #B0B0B0;
73
+ color: #A0A0A0;
74
+ }
75
+
76
+ .edit-line-link {
77
+ color: #A0A0A0;
74
78
  }
75
79
 
76
80
  .response-heading, .request-heading {
@@ -0,0 +1,9 @@
1
+ module ActionDispatch
2
+ module ExceptionWrapperOverrides
3
+ def source_extracts
4
+ backtrace.map do |trace|
5
+ extract_source(trace).merge(trace: trace)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -27,12 +27,19 @@ module ActionDispatch
27
27
  end
28
28
 
29
29
  def editor
30
- @editor ||= ENV["EDITOR"].present? && KNOWN_EDITORS.find { |editor| editor[:symbols].include?(ENV["EDITOR"].to_sym) }
30
+ @editor ||= potential_editor.present? && KNOWN_EDITORS.find { |editor| editor[:symbols].include?(potential_editor.to_sym) }
31
+ end
32
+
33
+ private
34
+
35
+ def potential_editor
36
+ EditorOpener.editor || ENV["EDITOR"]
31
37
  end
32
38
  end
33
39
 
34
- def initialize(trace)
40
+ def initialize(trace, line_number: nil)
35
41
  @trace = trace.to_s.strip
42
+ @line_number = line_number
36
43
  end
37
44
 
38
45
  def call
@@ -55,14 +62,14 @@ module ActionDispatch
55
62
  if file_name
56
63
  file, line = file_name.split(":")
57
64
 
58
- self.class.editor[:url] % { file: file, line: line }
65
+ self.class.editor[:url] % { file: file, line: line_number || line }
59
66
  else
60
67
  raise @trace
61
68
  end
62
69
  end
63
70
 
64
71
  private
65
- attr_reader :trace
72
+ attr_reader :trace, :line_number
66
73
 
67
74
  def detect_trace_type
68
75
  if trace[0] == "/" || trace.match?(/^[A-Z]:/)
@@ -1,4 +1,5 @@
1
1
  require_relative "action_dispatch/trace_to_file_extractor"
2
+ require_relative "action_dispatch/exception_wrapper_overrides"
2
3
 
3
4
  module EditorOpener
4
5
  class Railtie < ::Rails::Railtie
@@ -9,6 +10,8 @@ module EditorOpener
9
10
  # DebugView has custom templates path, that cannot be overridden by prepend_view_path
10
11
  ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS.unshift(path)
11
12
  end
13
+
14
+ ActionDispatch::ExceptionWrapper.prepend(ActionDispatch::ExceptionWrapperOverrides)
12
15
  end
13
16
  end
14
17
  end
@@ -1,3 +1,3 @@
1
1
  module EditorOpener
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/editor_opener.rb CHANGED
@@ -2,4 +2,10 @@ require "editor_opener/version"
2
2
  require "editor_opener/railtie"
3
3
 
4
4
  module EditorOpener
5
+ mattr_accessor :editor
6
+ @@editor = nil
7
+
8
+ def self.setup
9
+ yield self
10
+ end
5
11
  end
@@ -0,0 +1,19 @@
1
+ require "rails/generators/base"
2
+
3
+ module EditorOpener
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Create an initializer file for EditorOpener configuration"
9
+
10
+ def create_initializer_file
11
+ template "initializer.rb", "config/initializers/editor_opener.rb"
12
+ end
13
+
14
+ def show_readme
15
+ readme "README"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ ===============================================================================
2
+
3
+ editor_opener initializer has been created!
4
+
5
+ The initializer has been created at:
6
+ config/initializers/editor_opener.rb
7
+
8
+ To get started:
9
+ 1. Edit the initializer file to set your preferred editor
10
+ 2. Uncomment the line with your editor (e.g., config.editor = :cursor)
11
+ 3. Restart your Rails server
12
+ 4. Trigger an error in your Rails app to see the editor links
13
+
14
+ Supported editors include:
15
+ - Visual Studio Code (:vscode)
16
+ - Cursor (:cursor)
17
+ - Atom (:atom)
18
+ - Sublime Text (:sublime, :subl, or :st)
19
+ - RubyMine (:rubymine)
20
+ - Zed (:zed)
21
+ - And many more!
22
+
23
+ For more information, visit:
24
+ https://github.com/igorkasyanchuk/editor_opener
25
+
26
+ ===============================================================================
@@ -0,0 +1,43 @@
1
+ # Configuration
2
+ # This gem allows you to open files in your editor directly from Rails error pages.
3
+ # Configure your preferred editor by setting the editor symbol below.
4
+
5
+ EditorOpener.setup do |config|
6
+ # Set your preferred editor
7
+ # You can use any of the supported editors listed below:
8
+ # config.editor = ENV["EDITOR"] || :cursor
9
+
10
+ # Alternatively, you can set the EDITOR environment variable
11
+ # export EDITOR=cursor
12
+
13
+ # Supported editors:
14
+ # :atom - Atom editor
15
+ # :cursor - Cursor editor
16
+ # :emacs - Emacs editor
17
+ # :emacsclient - Emacs client
18
+ # :idea - IntelliJ IDEA
19
+ # :macvim - MacVim
20
+ # :mvim - MacVim (alternative)
21
+ # :nova - Nova editor
22
+ # :rubymine - RubyMine
23
+ # :sublime - Sublime Text
24
+ # :subl - Sublime Text (alternative)
25
+ # :st - Sublime Text (alternative)
26
+ # :textmate - TextMate
27
+ # :txmt - TextMate (alternative)
28
+ # :tm - TextMate (alternative)
29
+ # :vscode - Visual Studio Code
30
+ # :code - Visual Studio Code (alternative)
31
+ # :vscodium - VSCodium
32
+ # :codium - VSCodium (alternative)
33
+ # :windsurf - Windsurf editor
34
+ # :zed - Zed editor
35
+
36
+ # Examples:
37
+ # config.editor = :vscode # For Visual Studio Code
38
+ # config.editor = :atom # For Atom
39
+ # config.editor = :sublime # For Sublime Text
40
+ # config.editor = :rubymine # For RubyMine
41
+ # config.editor = :cursor # For Cursor
42
+ # config.editor = :zed # For Zed
43
+ end if defined?(EditorOpener)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: editor_opener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-03 00:00:00.000000000 Z
10
+ date: 2025-07-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -75,12 +75,17 @@ files:
75
75
  - MIT-LICENSE
76
76
  - README.md
77
77
  - Rakefile
78
+ - app/views/rescues/_source.html.erb
78
79
  - app/views/rescues/_trace.html.erb
79
80
  - app/views/rescues/layout.erb
80
81
  - lib/editor_opener.rb
82
+ - lib/editor_opener/action_dispatch/exception_wrapper_overrides.rb
81
83
  - lib/editor_opener/action_dispatch/trace_to_file_extractor.rb
82
84
  - lib/editor_opener/railtie.rb
83
85
  - lib/editor_opener/version.rb
86
+ - lib/generators/editor_opener/install_generator.rb
87
+ - lib/generators/editor_opener/templates/README
88
+ - lib/generators/editor_opener/templates/initializer.rb
84
89
  homepage: https://github.com/igorkasyanchuk/editor_opener
85
90
  licenses:
86
91
  - MIT