Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add inlay hints support to the ruby-lsp #55

Open
vinistock opened this issue Mar 29, 2022 · 4 comments
Open

Add inlay hints support to the ruby-lsp #55

vinistock opened this issue Mar 29, 2022 · 4 comments
Labels
enhancement New feature or request pinned This issue or pull request is pinned and won't be marked as stale

Comments

@vinistock
Copy link
Member

vinistock commented Mar 29, 2022

Inlay hints display "invisible" information to the user to assist with the understanding of the code. For example:

class User < ApplicationRecord
  (self.)has_many :posts
#^ inlay hint displaying the receiver (doesn't actually exist in the real code)
end

We can also display the name of positional arguments as inlay hints.

Documentation: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint

@vinistock vinistock transferred this issue from another repository Apr 8, 2022
@st0012 st0012 assigned st0012 and unassigned st0012 Jul 5, 2022
@st0012
Copy link
Member

st0012 commented Jul 5, 2022

@vinistock I want to give this a try. I'll start by listing common cases that can use the hint.

But without type information, there aren't too many features we can implement with high accuracy.

  • Implicit self

  • Implicit type information, like

    • rescue => e (Exception)
    • raise "error" (RuntimeError)
  • Method visibility

    private
    
    # 100 lines
    
    (private) def foo
    end
  • Expanded namespace

    • Not sure how practical it is without code evaluation
    module Foo
      module Rails; end
    
      (Foo::)Rails

For new developers

These may be too intrusive and distracting for experienced developers. But they could help new devs understand Ruby.

  • Expand syntactical sugar like &= or |=

    a |= b # (a = a | b)
  • Operator precedence

    1 + 2 * 5 # (1 + (2 * 5))
  • Explain % literals

    %q(foobarbaz) # String "foobarbaz"

Things that'll be helpful if possible

  • Possible super source

    class A
      def foo; end
    end
    
    class B < A
      def foo
        super # hint A
      end
    end

@RyanBrushett
Copy link
Contributor

I dug into adding a hint for indicating method visibility but I kept hitting a wall in figuring out whether or not a def node was private/protected/public.

Would that require enhancing syntax_tree a bit or is there some elegant way to determine a node's visibility that I've missed? Maybe I'm looking at it from the wrong perspective.

@vinistock
Copy link
Member Author

There's no built-in way by checking the method definition straight. We'd need to keep track of which section we're currently inside. Something like this in pseudo code

class InlayHint < BaseRequest
  def initialize(...)
    @current_visibility = :public # Maybe use a Sorbet enum?
  end

  def visit_call(node) # not sure if it's call, command, fcall...
    if this_thing_is_private_public_or_protected
      @current_visibility = the_new_visibility
    end
  end

  def visit_def(node)
    add_hint_using_current_visibility
  end
end

Two thoughts:

  • I think we shouldn't add anything for public methods, since that's the default
  • If it's possible, I think this inlay hint would look better on top of the method name (not on the left or right)

@RyanBrushett
Copy link
Contributor

Ooo neat, thanks for the pointers!

I think we shouldn't add anything for public methods, since that's the default

Completely agree. That would be really messy.

If it's possible, I think this inlay hint would look better on top of the method name (not on the left or right)

Should be entirely possible. This hint in particular really runs the risk of looking messy, I agree that above is a good place to start. If I get a chance to hack on it, I'll be sure to propose a few options with screenshots for easy evaluation.

@vinistock vinistock added enhancement New feature or request pinned This issue or pull request is pinned and won't be marked as stale labels Jul 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request pinned This issue or pull request is pinned and won't be marked as stale
Projects
None yet
Development

No branches or pull requests

3 participants