editor_opener 0.1.0 → 0.1.1

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: 6d7652583a50398a131c7f55eb47307dc5aec0a521d3663462e37345afc3e206
4
+ data.tar.gz: 2428aeee0b984176fddfd3c1307039be50d38296725990384f8465a18a578d6a
5
5
  SHA512:
6
- metadata.gz: '039d8837645d9a93163a08693939eabeebc8179176ead4bc8e113906bc80a1b219e57a7c47cdab904e8571bbd005fac2cdd91ecb87d7529d154c2ed59cd99e76'
7
- data.tar.gz: 2598ff96c36081386a3d8ec4692c9aff666d322a268e11ec47cfe92c625816d9516baaaea8b866779ab7130a4aa9c8f6723c1a8d6c09d1a6e445995a32e07ccf
6
+ metadata.gz: 59d2f5d010666fe3b600e87fbb044d14850abd6b7a71673ff8672398040e389f90d9c844022f41683fa2fca18303823e346dc478d9a48ad20416589419efe709
7
+ data.tar.gz: 29be85c61c83125543cb25c3a2348c6ae94597118e5f3cb97244c0e91ecff11b7d1659df7f125fb4c2d4fb80a42e3a36506b3057b57e994b81c8257266d54f97
data/README.md CHANGED
@@ -1,28 +1,191 @@
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
+ - 🔗 **Clickable file links** in Rails error pages
10
+ - 📝 **Multiple editor support** - Works with 13+ popular editors
11
+ - 🎯 **Precise line targeting** - Opens files at the exact error line
12
+ - 🔧 **Easy configuration** - Set via initializer or environment variable
13
+ - 🚀 **Zero configuration** - Works out of the box with `EDITOR` environment variable
14
+ - 📱 **Custom URL schemes** - Uses editor-specific protocols for seamless integration
6
15
 
7
16
  ## Installation
17
+
8
18
  Add this line to your application's Gemfile:
9
19
 
10
20
  ```ruby
11
- gem "editor_opener"
21
+ group :development do
22
+ gem "editor_opener"
23
+ end
12
24
  ```
13
25
 
14
26
  And then execute:
15
27
  ```bash
16
- $ bundle
28
+ $ bundle install
29
+ ```
30
+
31
+ ## Configuration
32
+
33
+ ### Option 1: Generate and configure initializer (Recommended)
34
+
35
+ ```bash
36
+ $ rails generate editor_opener:install
37
+ ```
38
+
39
+ This creates `config/initializers/editor_opener.rb` with all supported editors listed as comments.
40
+
41
+ Edit the initializer to set your preferred editor:
42
+
43
+ ```ruby
44
+ EditorOpener.setup do |config|
45
+ config.editor = :cursor # or any other supported editor
46
+ end
17
47
  ```
18
48
 
19
- Or install it yourself as:
49
+ ### Option 2: Environment variable
50
+
51
+ Set the `EDITOR` environment variable:
52
+
20
53
  ```bash
21
- $ gem install editor_opener
54
+ export EDITOR=cursor # for Cursor
55
+ export EDITOR=atom # for Atom
56
+ export EDITOR=subl # for Sublime Text
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ 1. **Install and configure** the gem (see above)
62
+ 2. **Restart your Rails server**
63
+ 3. **Trigger an error** in your Rails application
64
+ 4. **Click the edit icons** (✏️) or line numbers in the error page to open files in your editor
65
+
66
+ The gem automatically detects error traces from:
67
+ - Application code
68
+ - Gem files
69
+ - Direct file paths
70
+
71
+ ## Supported Editors
72
+
73
+ The gem supports the following editors with their respective symbols:
74
+
75
+ | Editor | Symbols | Protocol |
76
+ |--------|---------|----------|
77
+ | **Atom** | `:atom` | `atom://` |
78
+ | **Cursor** | `:cursor` | `cursor://` |
79
+ | **Emacs** | `:emacs`, `:emacsclient` | `emacs://` |
80
+ | **IntelliJ IDEA** | `:idea` | `idea://` |
81
+ | **MacVim** | `:macvim`, `:mvim` | `mvim://` |
82
+ | **Nova** | `:nova` | `nova://` |
83
+ | **RubyMine** | `:rubymine` | `x-mine://` |
84
+ | **Sublime Text** | `:sublime`, `:subl`, `:st` | `subl://` |
85
+ | **TextMate** | `:textmate`, `:txmt`, `:tm` | `txmt://` |
86
+ | **Visual Studio Code** | `:vscode`, `:code` | `vscode://` |
87
+ | **VSCodium** | `:vscodium`, `:codium` | `vscodium://` |
88
+ | **Windsurf** | `:windsurf` | `windsurf://` |
89
+ | **Zed** | `:zed` | `zed://` |
90
+
91
+ ## Examples
92
+
93
+ ### Basic Configuration
94
+
95
+ ```ruby
96
+ # config/initializers/editor_opener.rb
97
+ EditorOpener.setup do |config|
98
+ config.editor = :cursor
99
+ end
100
+ ```
101
+
102
+ ### Environment Variable
103
+
104
+ ```bash
105
+ # In your shell profile (~/.bashrc, ~/.zshrc, etc.)
106
+ export EDITOR=cursor
107
+
108
+ # Or in your .env file (if using dotenv)
109
+ EDITOR=cursor
110
+ ```
111
+
112
+ ### Multiple Environments
113
+
114
+ ```ruby
115
+ # config/initializers/editor_opener.rb
116
+ EditorOpener.setup do |config|
117
+ config.editor = Rails.env.development? ? :cursor : nil
118
+ end
119
+ ```
120
+
121
+ ## How It Works
122
+
123
+ 1. **Error Detection**: The gem overrides Rails error pages
124
+ 2. **Trace Parsing**: Extracts file paths and line numbers from stack traces
125
+ 3. **Editor Detection**: Matches configured editor with supported protocols
126
+ 4. **URL Generation**: Creates editor-specific URLs for file opening
127
+ 5. **Link Enhancement**: Adds clickable links to error page templates
128
+
129
+ ## Troubleshooting
130
+
131
+ ### Editor doesn't open files
132
+
133
+ 1. **Check editor configuration**: Ensure your editor symbol is correct
134
+ 2. **Verify protocol support**: Make sure your editor supports URL protocols
135
+ 3. **Test environment variable**: Try setting `EDITOR` environment variable
136
+ 4. **Restart Rails server**: Configuration changes require server restart
137
+
138
+ ### Links don't appear
139
+
140
+ 1. **Check gem is loaded**: Ensure gem is in development group
141
+ 2. **Verify Rails environment**: Gem typically only works in development
142
+ 3. **Test with simple error**: Create a basic error to test functionality
143
+
144
+ ## Development
145
+
146
+ After checking out the repo, run:
147
+
148
+ ```bash
149
+ $ bin/setup
150
+ $ bin/test
151
+ ```
152
+
153
+ To run tests:
154
+
155
+ ```bash
156
+ $ bin/test
157
+ $ bin/rubocop
22
158
  ```
23
159
 
24
160
  ## Contributing
25
- Contribution directions go here.
161
+
162
+ Bug reports and pull requests are welcome on GitHub at https://github.com/igorkasyanchuk/editor_opener.
163
+
164
+ 1. Fork the project
165
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
166
+ 3. Make your changes
167
+ 4. Add tests for your changes
168
+ 5. Ensure all tests pass (`bin/test`)
169
+ 6. Commit your changes (`git commit -am 'Add some feature'`)
170
+ 7. Push to the branch (`git push origin my-new-feature`)
171
+ 8. Create a new Pull Request
172
+
173
+ ## TODO
174
+
175
+ - verify it works with old Rails versions
176
+ - more tests
177
+ - support for more error pages?
178
+ - support for more editors
26
179
 
27
180
  ## License
181
+
28
182
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
183
+
184
+ ## Credits
185
+
186
+ Created by [Igor Kasyanchuk](https://github.com/igorkasyanchuk).
187
+
188
+ ## Related Projects
189
+
190
+ - [better_errors](https://github.com/BetterErrors/better_errors) - Better error pages for Rails
191
+ - [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.1"
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 = :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
metadata CHANGED
@@ -1,7 +1,7 @@
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.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
@@ -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