ruby icon indicating copy to clipboard operation
ruby copied to clipboard

Feature request: switch between a Ruby file and its test (spec) file

Open vittorius opened this issue 11 months ago • 9 comments

Basically, the subject. It's a pretty common piece of functionality for a Ruby extension IMHO.

Also, there can be a config to map custom relations between files and their specs (e.g. from app/controllers/{file}.rb to spec/requests/api/v1/{file}_spec.rb.

A good example of it could be https://marketplace.visualstudio.com/items?itemName=malt03.rails-rspec-file-toggle. We can replicate its functionality.

WDYT? I'm willing to contribute BTW.

vittorius avatar Feb 16 '25 15:02 vittorius

Hi, this would be amazing, but unfortunately, the Zed Extension API is limited, and there is no way to implement this currently.

vitallium avatar Feb 18 '25 08:02 vitallium

For anyone looking for some kind of a solution for this I'm able to employ tasks to achieve this. Basically I have this in my tasks.json:

  {
    "label": "open_alternative_file",
    "command": "zed \"$ZED_WORKTREE_ROOT\"/$(spec-alternative-file $ZED_RELATIVE_FILE)",
    "hide": "on_success",
    "allow_concurrent_runs": false,
    "use_new_terminal": false,
    "reveal": "never",
    "shell": {
      "with_arguments": {
        "program": "sh",
        "args": ["--noediting", "--norc", "--noprofile"]
      }
    }
  },

and such script in my PATH:

#!/bin/sh

# Check if a filename is provided
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

# Get the provided filename
filename=$1

# Determine the alternative file
if [[ "$filename" =~ _spec\.rb$ ]]; then
    # If the file is a spec file, convert it to the corresponding regular Ruby file
    alternative_file=$(echo "$filename" | sed 's|^spec/|app/|; s|_spec\.rb$|.rb|')
else
    # If the file is a regular Ruby file, convert it to the corresponding spec file
    alternative_file=$(echo "$filename" | sed 's|^app/|spec/|; s|\.rb$|_spec.rb|')
fi

echo "$alternative_file"

asok avatar Feb 28 '25 14:02 asok

This feature was added to Ruby LSP in https://github.com/Shopify/ruby-lsp/pull/2985 and uses a custom LSP request along with integration with VS Code.

The PR description also shows how it can be used with NeoVim, and I imagine something similar would be possible for Zed once scripting is supported (there's a long discussion here).

@asok's approach of shelling out to zed is interesting, but I can't think how that would be hooked into the language server.

cc @jenny-codes

andyw8 avatar Mar 24 '25 01:03 andyw8

I got this working using a task that I assigned to a keyboard shortcut. You just need an executable that can take a file as input and then launch zed to another file by shelling out. If it’s possible to include a task and have it point to an executable in the extension, it could be doable.

joeldrapper avatar Apr 16 '25 21:04 joeldrapper

I suspect it wouldn't be viable since the extension compiles down to WebAssembly, but you could perhaps have the extension auto-install a tiny gem?

andyw8 avatar Apr 16 '25 21:04 andyw8

I just started writing that gem yesterday. It works locally, I just need a little time to package it.

MoskitoHero avatar Apr 17 '25 10:04 MoskitoHero

Here you go, it’s quite rough for now, but it does the job (on my projects). Feel free to make PRs to match more settings / frameworks.

https://github.com/MoskitoHero/zed-test-toggle

MoskitoHero avatar Apr 17 '25 12:04 MoskitoHero

Nice! Had to make a small fix to the README example:

https://github.com/MoskitoHero/zed-test-toggle/pull/1

andyw8 avatar Apr 17 '25 13:04 andyw8

I made a rails helper in a similar vain to the zed-test-toggle. It allows jumping between a controller method and the related view if it exists and also a view and the respective controller + action. It takes into account inheritance and what not. It was a major bottleneck for me switching off of vs code forks so hopefully this helps others too until scripting is supported

https://github.com/Tonksthebear/zed-rails-jumper

Tonksthebear avatar Jun 30 '25 22:06 Tonksthebear