Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dgutov/robe

Code navigation, documentation lookup and completion for Ruby
https://github.com/dgutov/robe

code-assist-tool code-completion emacs emacs-lisp ruby

Last synced: 2 months ago
JSON representation

Code navigation, documentation lookup and completion for Ruby

Awesome Lists containing this project

README

        

# Robe [![Build Status](https://github.com/dgutov/robe/actions/workflows/ci.yml/badge.svg)](https://github.com/dgutov/robe/actions/workflows/ci.yml) [![MELPA](http://melpa.org/packages/robe-badge.svg)](http://melpa.org/#/robe)

Robe is a code assistance tool that uses a Ruby REPL subprocess with
your application or gem code loaded, to provide information about
loaded classes and modules, and where each method is defined.

Generally, you'll want to start with `M-x inf-ruby-console-auto` or
with `M-x robe-start` (which will offer to call the former function as
well if there is no Ruby console running). Some interactive commands
provided by Robe will also offer to launch it first.

The exceptions are code completion and eldoc, which only work if the
server is already running. To launch it, type `M-x robe-start`.

As you change the code in your project, you'll want to update the
running process. To load the current file, type C-c C-l
(`ruby-load-file`), see [inf-ruby](https://github.com/nonsequitur/inf-ruby/)
for more commands. When you're working on a Rails project, you can
type C-c C-k instead to reload the whole environment at once.

## Features

* Jump to method definition
* Jump to `super` or a constructor called at point
* Jump to a module/class/constant definition
* Display method documentation
* Display information about method called at point using ElDoc
* Method and constant name completion
* Jumping and completion for instance and local variable names, using
simple regexp search in the current file

To see the available commands, type M-x describe-package RET robe RET.

## Details

When performing one of the commands defined here, we either need to
narrow the method name at point down to a specific method in a specific
module, or enumerate the possible method names or constants allowed at
point (for code completion).

To do that, we look at the contents of the buffer, and the context at
point: in which method it is, of which class, and if it's in singleton
class context. Then we look at the method call at point.

If the method call target is implicit (there's no target or the method
is `super`), or the call target is obvious (`Foo.new`, `self.foo`),
then we first try to look for the definition in the inheritance
hierarchy of the target class. Otherwise, or if the initial search
yields no result, scan all defined classes and modules.

Depending on the command, if the result is ambiguous, you're either
prompted to resolve the ambiguity manually, or the results are merged
together.

## Install

Set up [MELPA](https://melpa.org/#/getting-started) if you haven't already,
then type M-x package-install RET robe RET.

In the init file:

```emacs
(add-hook 'ruby-mode-hook 'robe-mode)
(add-hook 'ruby-ts-mode-hook 'robe-mode)
```

or

```emacs
(global-robe-mode)
```

## Dependencies

* `pry` >= 0.10
* `pry-doc` >= 0.6.0 (for stdlib docs on MRI; optional)
* Ruby [must be](https://github.com/dgutov/robe/issues/148) compiled
with Readline support ([how to
check](https://github.com/dgutov/robe/wiki/How-to-check-that-Ruby-is-built-with-Readline-support)).
* With Ruby 3.3, the gem `readline-ext` is [also
needed](https://github.com/dgutov/robe/issues/147).

The alternative to the last two items is to configure the app not to
use the Pry shell (at least when inside Emacs) while still keeping
`pry` available for loading.

Note that if your project is using `Bundler`, all dependencies have to be in the `Gemfile`.

## Completion

### [company-mode](https://company-mode.github.io/) ([screenshot](screenshots/company-robe.png)):

```emacs
(eval-after-load 'company
'(push 'company-robe company-backends))
```

Built-in completion (triggered with C-M-i) is also supported,
no extra setup required.

Both of the above work only when the connection to the Ruby subprocess has
been established. To do that, either use one of the core Robe commands, or
type M-x robe-start.

## Integration with rvm.el

[rvm.el](https://github.com/senny/rvm.el) may not have activated the
correct project Ruby before `robe-start` runs.

Either manually run M-x rvm-activate-corresponding-ruby
before starting Robe, or advise `inf-ruby-console-auto` to activate
rvm automatically.

```emacs
(advice-add 'inf-ruby-console-auto :before #'rvm-activate-corresponding-ruby)
```

## Compatibility

* Tested in Emacs 24.4+, with Ruby 2.3-3.3, on GNU/Linux.
* But see the section [Dependencies](#dependencies) above.
* Essential features work with JRuby, though the startup is longer.
* Mostly works on MS Windows, with minor glitches.
* Built-in `ruby-mode` or `ruby-ts-mode` (Emacs 29+) work best,
`enh-ruby-mode` is not recommended (it breaks the detection of the
current context, see [#47](https://github.com/dgutov/robe/issues/47)
and
[enhanced-ruby-mode#96](https://github.com/zenspider/enhanced-ruby-mode/issues/96)).

## Notes

* We can't jump to methods defined in C (such as most of the core classes).
To read their docs, install `pry-doc` or add it to your Gemfile.
* We can't jump to lazily defined methods, such as `model.column` or `find_by_`
`ActiveRecord` methods, before they've been called. This is treatable, but low
priority.
* Jumping to methods defined with `Module#delegate` just brings us to the place
where `delegate` is called, which is accurate, but often less than useful.
* To work on several projects in the same Emacs session, you'll have
to create the Ruby console for each project after the first one
manually with `M-x inf-ruby-console-auto`. Otherwise, the first one
will be used for all Ruby files, with suboptimal results.
* We may get the context wrong for code inside a block if the method
it's passed to uses `instance_eval` or `instance_exec`.

## TODO

* Handle `delegate` and `send`, `Class.new.method` and `self.class.method`.
* For methods defined through macros, optionally jump to where the macro was
called, instead of its definition?
* Apropos search for classes and methods.
* Better type inference.

## Copying

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.