This summer, I participated in the Google Summer of Code (GSoC) 2021. In this article, I summarize my work as a final report of GSoC. I worked on extending the functionality of the Language Server Protocol(LSP) of RBS, a language for describing the structure of Ruby programs.
LSP is one of the most widely adopted solutions to implement IDE/editor integrations with programming languages. A language server for RBS editing will be really helpful for reading/writing RBS files using IDEs. I had experience with several languages that benefited from the language server protocol. I wanted to achieve such a function in RBS to make it more user-friendly.
We decided to implement the features in Steep because it already provides LSP features for Ruby code and working on top of the code base is the shortest path for delivering the enhancement to users.
The plan was to implement these features.
- Display type information when the text is hovered in rbs
- Completion for type names.
These PRs were all merged
- Display type information when type alias is hovered in rbs
- Extend the functionality of hover in rbs files.
- Implement auto complete feature
Until now, hovering over text did not show any information.
This is difficult for the user to understand the code.
This implementation now displays information about class
, interface
, singleton
and alias
.
It also shows the comments, if any.
When a class is inherited, it was necessary to consider how to display the information of the parent class.
I needed to find out how hover
works in LSP and pass the necessary information from Steep.
In the following code, the type of text is determined from the hovered position, and the necessary information is retrieved. https://github.com/soutaro/steep/blob/76f3368df42dac9f57078e3ae51c4d46b20e75f2/lib/steep/services/hover_content.rb#L77-L105
When you typed in a character, no words suggestions were shown. With this implementation, it is now possible to type names during completion.
During development, I had the following problems with nested modules.
module Alpha
module Albatross
module Foo
end
module Hoge
end
type foo = A__ autocomplete here
↓Currently
Alpha
Alpha::Albatross
Alpha::Albatross::Foo
Alpha::Albatross::Hoge
↓Expectation
Alpha
Albatross
Foo
Hoge
end
end
In order to fix this problem, I needed to get the nesting relation of the module at the cursor position.
You can check the implementation here https://github.com/soutaro/steep/blob/49017c0f4c5c31432fb5896a6733960bd99843f4/lib/steep/server/interaction_worker.rb#L509-L518
auto.complete.mov
I was able to implement all the features that were initially planned. The final code has already been merged and received good feedback from the mentors. I hope I can continue to contribute to Steep!
I think it has dramatically improved the experience for rbs users. Even with a large code base, it is now easy to add features and get information. I think more people will use RBS because there will be less difference in user experience from other modern languages.
-
I also learned more about RBS and how it holds information about parsing code. I was able to learn about LSP specifications.
-
I was able to learn how to specify the specifications and code the implementation of a new feature.
I am grateful to my mentors Soutaro Matsumoto and Yusuke Endoh for guidance and support.
The once-a-week video calls by the mentors were a big help. Also, they were always willing to help. I am very grateful to them. Without their help, I could not have achieved them.