1# Ruby
2
3Ruby support is available through the [Ruby extension](https://github.com/zed-extensions/ruby).
4
5- Tree-sitters:
6 - [tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby)
7 - [tree-sitter-embedded-template](https://github.com/tree-sitter/tree-sitter-embedded-template)
8- Language Servers:
9 - [ruby-lsp](https://github.com/Shopify/ruby-lsp)
10 - [solargraph](https://github.com/castwide/solargraph)
11 - [rubocop](https://github.com/rubocop/rubocop)
12
13The Ruby extension also provides support for ERB files.
14
15## Language Servers
16
17There are multiple language servers available for Ruby. Zed supports the two following:
18
19- [solargraph](https://github.com/castwide/solargraph)
20- [ruby-lsp](https://github.com/Shopify/ruby-lsp)
21
22They both have an overlapping feature set of autocomplete, diagnostics, code actions, etc. and it's up to you to decide which one you want to use. Note that you can't use both at the same time.
23
24In addition to these two language servers, Zed also supports [rubocop](https://github.com/rubocop/rubocop) which is a static code analyzer and linter for Ruby. Under the hood, it's also used by Zed as a language server, but its functionality is complimentary to that of solargraph and ruby-lsp.
25
26## Configuring a language server
27
28The [Ruby extension](https://github.com/zed-extensions/ruby) offers both `solargraph` and `ruby-lsp` language server support.
29
30### Using `solargraph`
31
32`solargraph` is enabled by default in the Ruby extension.
33
34### Using `ruby-lsp`
35
36To switch to `ruby-lsp`, add the following to your `settings.json`:
37
38```json
39{
40 "languages": {
41 "Ruby": {
42 "language_servers": ["ruby-lsp", "!solargraph", "!rubocop", "..."]
43 }
44 }
45}
46```
47
48That disables `solargraph` and `rubocop` and enables `ruby-lsp`.
49
50### Using `rubocop`
51
52The Ruby extension also provides support for `rubocop` language server for offense detection and autocorrection.
53
54To enable it, add the following to your `settings.json`:
55
56```json
57{
58 "languages": {
59 "Ruby": {
60 "language_servers": ["ruby-lsp", "rubocop", "!solargraph", "..."]
61 }
62 }
63}
64```
65
66Or, conversely, you can disable `ruby-lsp` and enable `solargraph` and `rubocop` by adding the following to your `settings.json`:
67
68```json
69{
70 "languages": {
71 "Ruby": {
72 "language_servers": ["solargraph", "rubocop", "!ruby-lsp", "..."]
73 }
74 }
75}
76```
77
78## Setting up `solargraph`
79
80Zed currently doesn't install Solargraph automatically. To use Solargraph, you need to install the gem. Zed just looks for an executable called `solargraph` on your `PATH`.
81
82You can install the gem manually with the following command:
83
84```sh
85gem install solargraph
86```
87
88Alternatively, if your project uses Bundler, you can add the Solargraph gem to your `Gemfile`:
89
90```rb
91gem 'solargraph', group: :development
92```
93
94Solargraph has formatting and diagnostics disabled by default. We can tell Zed to enable them by adding the following to your `settings.json`:
95
96```json
97{
98 "lsp": {
99 "solargraph": {
100 "initialization_options": {
101 "diagnostics": true,
102 "formatting": true
103 }
104 }
105 }
106}
107```
108
109To use Solargraph in the context of the bundle, you can use [folder-specific settings](../configuring-zed.md#settings-files) and specify the absolute path to the [`binstub`](https://bundler.io/v2.5/man/bundle-binstubs.1.html) of Solargraph:
110
111```json
112{
113 "lsp": {
114 "solargraph": {
115 "binary": {
116 "path": "<path_to_your_project>/bin/solargraph"
117 }
118 }
119 }
120}
121```
122
123### Configuration
124
125Solargraph reads its configuration from a file called `.solargraph.yml` in the root of your project. For more information about this file, see the [Solargraph configuration documentation](https://solargraph.org/guides/configuration).
126
127## Setting up `ruby-lsp`
128
129Zed currently doesn't install Ruby LSP automatically. To use Ruby LSP, you need to install the gem. Zed just looks for an executable called `ruby-lsp` on your `PATH`.
130
131You can install the gem manually with the following command:
132
133```sh
134gem install ruby-lsp
135```
136
137Ruby LSP uses pull-based diagnostics which Zed doesn't support yet. We can tell Zed to disable it by adding the following to your `settings.json`:
138
139```json
140{
141 "languages": {
142 "Ruby": {
143 "language_servers": ["ruby-lsp", "!solargraph", "..."]
144 }
145 },
146 "lsp": {
147 "ruby-lsp": {
148 "initialization_options": {
149 "enabledFeatures": {
150 // This disables diagnostics
151 "diagnostics": false
152 }
153 }
154 }
155 }
156}
157```
158
159## Setting up `rubocop` LSP
160
161Zed currently doesn't install `rubocop` automatically. To use `rubocop`, you need to install the gem. Zed just looks for an executable called `rubocop` on your `PATH`.
162
163You can install the gem manually with the following command:
164
165```sh
166gem install rubocop
167```
168
169Rubocop has unsafe autocorrection disabled by default. We can tell Zed to enable it by adding the following to your `settings.json`:
170
171```json
172{
173 "languages": {
174 "Ruby": {
175 // Use ruby-lsp as the primary language server and rubocop as the secondary.
176 "language_servers": ["ruby-lsp", "rubocop", "!solargraph", "..."]
177 }
178 },
179 "lsp": {
180 "rubocop": {
181 "initialization_options": {
182 "safeAutocorrect": false
183 }
184 },
185 "ruby-lsp": {
186 "initialization_options": {
187 "enabledFeatures": {
188 "diagnostics": false
189 }
190 }
191 }
192 }
193}
194```
195
196To use Rubocop in the context of the bundle, you can use [folder-specific settings](../configuring-zed.md#settings-files) and specify the absolute path to the [`binstub`](https://bundler.io/v2.5/man/bundle-binstubs.1.html) of Rubocop:
197
198```json
199{
200 "lsp": {
201 "rubocop": {
202 "binary": {
203 "path": "<path_to_your_project>/bin/rubocop"
204 }
205 }
206 }
207}
208```
209
210## Using the Tailwind CSS Language Server with Ruby
211
212It's possible to use the [Tailwind CSS Language Server](https://github.com/tailwindlabs/tailwindcss-intellisense/tree/HEAD/packages/tailwindcss-language-server#readme) in Ruby and ERB files.
213
214In order to do that, you need to configure the language server so that it knows about where to look for CSS classes in Ruby/ERB files by adding the following to your `settings.json`:
215
216```json
217{
218 "languages": {
219 "Ruby": {
220 "language_servers": ["tailwindcss-language-server", "..."]
221 }
222 },
223 "lsp": {
224 "tailwindcss-language-server": {
225 "settings": {
226 "includeLanguages": {
227 "erb": "html",
228 "ruby": "html"
229 },
230 "experimental": {
231 "classRegex": ["\\bclass:\\s*['\"]([^'\"]*)['\"]"]
232 }
233 }
234 }
235 }
236}
237```
238
239With these settings you will get completions for Tailwind CSS classes in HTML attributes inside ERB files and inside Ruby/ERB strings that are coming after a `class:` key. Examples:
240
241```rb
242# Ruby file:
243def method
244 div(class: "pl-2 <completion here>") do
245 p(class: "mt-2 <completion here>") { "Hello World" }
246 end
247end
248
249# ERB file:
250<%= link_to "Hello", "/hello", class: "pl-2 <completion here>" %>
251<a href="/hello" class="pl-2 <completion here>">Hello</a>
252```
253
254## Running tests
255
256To run tests in your Ruby project, you can set up custom tasks in your local `.zed/tasks.json` configuration file. These tasks can be defined to work with different test frameworks like Minitest, RSpec, quickdraw, and tldr. Below are some examples of how to set up these tasks to run your tests from within your editor.
257
258### Minitest
259
260```json
261[
262 {
263 "label": "test $ZED_RELATIVE_FILE:$ZED_ROW",
264 "command": "bundle exec rails",
265 "args": ["test", "\"$ZED_RELATIVE_FILE:$ZED_ROW\""],
266 "tags": ["ruby-test"]
267 }
268]
269```
270
271### RSpec
272
273```json
274[
275 {
276 "label": "test $ZED_RELATIVE_FILE:$ZED_ROW",
277 "command": "bundle exec rspec",
278 "args": ["\"$ZED_RELATIVE_FILE:$ZED_ROW\""],
279 "tags": ["ruby-test"]
280 }
281]
282```
283
284### quickdraw
285
286```json
287[
288 {
289 "label": "test $ZED_RELATIVE_FILE:$ZED_ROW",
290 "command": "bundle exec qt",
291 "args": ["\"$ZED_RELATIVE_FILE:$ZED_ROW\""],
292 "tags": ["ruby-test"]
293 }
294]
295```
296
297### tldr
298
299```json
300[
301 {
302 "label": "test $ZED_RELATIVE_FILE:$ZED_ROW",
303 "command": "bundle exec tldr",
304 "args": ["\"$ZED_RELATIVE_FILE:$ZED_ROW\""],
305 "tags": ["ruby-test"]
306 }
307]
308```