Stimulus.js
Leveling Up Developer Tooling For The Modern Rails & Hotwire Era

Summarized using AI

Leveling Up Developer Tooling For The Modern Rails & Hotwire Era

Marco Roth • October 07, 2024 • Boulder, CO

In this talk, Marco Roth discusses the evolution of developer experience (DX) tooling in the context of modern Ruby on Rails and the Hotwire era. He emphasizes the significance of enhancing the developer experience through advanced tools and introduces the concept of Language Server Protocols (LSP) as a way to improve productivity while working with Rails, Stimulus, and Turbo.

Key Points Discussed:
- Background and Motivation: Marco shares his journey from working with React and Rails to focusing on Ruby on Rails and Hotwire, articulating a desire for improved tooling equivalent to what exists in the JavaScript ecosystem.
- Language Server Protocol (LSP): He explains LSP as a method for providing language-specific intelligence across multiple editors without the necessity of local IDE installations. This protocol allows developers to write a single server that can communicate with different editors like VS Code using JSON RPC.
- Stimulus and Turbo Autocompletion: Marco provides an example of how LSP integration can assist developers by offering autocompletion features for Stimulus attributes and Turbo actions, enhancing the coding experience and reducing errors.
- Challenges with JavaScript Syntax: The talk highlights obstacles encountered when parsing JavaScript, especially given the complexities of different syntaxes in the language that can hinder establishing a robust LSP.
- Practical Implementations: Marco shares details about implementing a LSP server that recognizes Stimulus controllers and targets, showcasing the enhancements it brings to developer efficiency.
- Future Directions: He mentions ongoing work to incorporate diagnostics for Ruby and improvements in ERB support, along with ideas to expand capabilities for other templating languages.
- Tooling for Hotwire: The speaker further discusses a browser extension, hotit dev tools, designed to assist developers in visualizing and interacting with Turbo frames, enabling easier debugging and enhancing productivity.

In conclusion, Marco emphasizes the importance of advancing the Ruby on Rails ecosystem with modern tooling to compete with JavaScript frameworks. He encourages community feedback and collaboration to build these tools for a better developer experience, illustrating a vision for the future of Rails applications that aligns with contemporary technological expectations. The ongoing developments aim to make Rails more accessible and enjoyable for new and existing developers alike.

Ultimately, this talk serves as a call to action for the community to contribute to the evolution of Rails tooling, fueling further innovation in developer experience for Ruby applications.

Leveling Up Developer Tooling For The Modern Rails & Hotwire Era
Marco Roth • October 07, 2024 • Boulder, CO

The evolution of developer experience (DX) tooling has been a game-changer in how we build, debug, and enhance web applications.

This talk aims to illuminate the path toward enriching the Ruby on Rails ecosystem with advanced DX tools, focusing on the implementation of Language Server Protocols (LSP) for Stimulus and Turbo.

Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers, including how advanced browser extensions and tools specifically designed for the Hotwire ecosystem can level up your developer experience.

Rocky Mountain Ruby 2024

00:00:13.360 all right thank
00:00:14.599 you hi my name is Marco if you haven't
00:00:17.320 met please reach out afterwards I'm a
00:00:19.720 full developer and open source
00:00:21.240 contributor and super happy to be here
00:00:23.119 and super excited to see this conference
00:00:25.800 happening and thanks to Becky and Spike
00:00:27.599 for having us here
00:00:33.399 today I want to talk about the up
00:00:35.320 tooling and how it affects the modern
00:00:37.480 rails and hot by Era and we want to talk
00:00:40.480 about LSPs language server um we want to
00:00:44.879 understand them we want to build a
00:00:45.920 simple one and then kind of show what's
00:00:48.520 next in the tooling
00:00:50.760 space I've been on the coure team for
00:00:52.920 the simus reflex and cap ready gems for
00:00:55.039 the past five years or so and I've been
00:00:57.079 maintaining simul over the past few
00:00:58.600 years as well
00:01:00.519 I love open source and if you can tell
00:01:02.760 from this slide I have been doing a
00:01:04.280 bunch of stuff in um in the Hotwire
00:01:07.159 space in Turbo and stimulus it's kind of
00:01:09.600 a passion at this point so it's really
00:01:12.000 cool to see that's evolving and kind of
00:01:14.320 happening as we
00:01:16.040 speak I started to actively contribute
00:01:18.640 back in 2019 and at the time I was
00:01:20.840 working at a shop that was doing react
00:01:23.520 and rails API and I don't mind react I
00:01:27.720 like react but the way how people build
00:01:31.119 react apps with react is sometimes a
00:01:32.840 little bit too much and I felt like I
00:01:35.119 had enough I wanted to go back to Ruby
00:01:38.840 back to rails where I'm home and I want
00:01:40.880 to keep building rails and hold fire up
00:01:42.920 because it feels like you have a
00:01:44.920 superpower that's kind of we the most
00:01:46.759 productive with it and I person believe
00:01:49.119 it's also the future of modern rail apps
00:01:50.799 in
00:01:51.640 general I want to do full St apps again
00:01:54.320 I want to build all stuff by myself
00:01:56.680 single stack single person that's what
00:01:58.840 we kind of call it the single engineer
00:02:02.560 framework and for that to happen I want
00:02:04.759 to help build a modern tooling that's
00:02:06.360 missing for enabling that which is why I
00:02:09.239 went open source full-time for over a
00:02:11.959 little bit over a year back in
00:02:14.200 2022 to work on Hotwire and related
00:02:16.680 projects just because I had fun doing
00:02:19.080 so but I also noticed that while I was
00:02:21.959 working in reacts that their tooling and
00:02:25.080 especially the child Tooling in general
00:02:27.080 the Del experience is really awesome and
00:02:29.959 we didn't really have something like
00:02:31.319 this in the Ruby world I think or if
00:02:34.720 there was something it wasn't quite as
00:02:36.160 easy to set up and get started with we
00:02:39.159 had solra for the longest time it's a
00:02:41.040 great project is really good but I had
00:02:43.879 my trouble setting it up and it was
00:02:45.120 never really as easy to get started
00:02:47.120 with so I started to miss these tools I
00:02:50.080 knew from react and the JavaScript
00:02:51.800 worlds and I wanted to have them in my
00:02:53.360 daily work in Ruben rails
00:02:55.640 too and I'm the kind of person who
00:02:57.879 doesn't use an IDE to me me they always
00:03:00.280 felt clunky heavy rates combersome to
00:03:02.560 use and somehow made me less productive
00:03:05.000 in a way I don't know
00:03:06.480 why but in the past few years stuff
00:03:09.319 changed and we kind of got the Eder
00:03:11.440 Evolution if you will uh we got the
00:03:13.879 language service protocol LSP for
00:03:16.840 short so what is it why do we want to
00:03:19.680 use it um it's a way of providing
00:03:23.519 language intelligence without the need
00:03:25.319 for having to install an IDE
00:03:27.200 specifically for this framework or
00:03:29.080 language
00:03:30.519 and before we had LSPs if you wanted to
00:03:32.519 build for example Ruby plugin you would
00:03:34.319 have to build a plugin for all the
00:03:36.599 editors you want to support but with the
00:03:39.040 language server protocol you get to
00:03:40.560 write one server one language server and
00:03:43.239 all the editors that speak that protocol
00:03:44.799 can just use it and make use of that
00:03:46.920 intelligence for free pretty
00:03:49.080 much so how does it work you have kind
00:03:52.280 of a mapping in your editor that kind of
00:03:53.920 registers all the available servers and
00:03:56.040 whenever you open a file of that
00:03:57.680 specific kinds data will start
00:03:59.799 background process uh language server
00:04:02.319 and we'll try to respond to these
00:04:04.200 requests usually communicates over
00:04:06.560 didn't stand it out but also options to
00:04:08.239 do it over TCP IP it uses Jason RPC
00:04:11.560 under hoods if you aren't familiar with
00:04:13.799 this it's kind of like HTTP in the sense
00:04:16.560 that you also have a header up top and
00:04:19.320 you have a body in this case it's a blob
00:04:21.000 of
00:04:22.560 Json um so this lead to sim LSP and the
00:04:26.840 question is what are we trying to solve
00:04:29.000 here
00:04:30.520 so if you aren't familiar with stimulus
00:04:32.000 this is the basic example they have on
00:04:33.720 the website and what we care about here
00:04:36.320 is these attributes which are the
00:04:37.919 controls the targets the action and so
00:04:40.520 on and if you aren't familiar with the
00:04:42.919 syntax it's kind of hard to remember all
00:04:44.800 the syntax how you write it what you
00:04:46.400 have to use and where you have to
00:04:48.160 reference the right names so what we
00:04:50.560 want to do is we kind of want to provide
00:04:51.960 you help with making it right or getting
00:04:54.160 in right so you want to have a list of
00:04:56.160 all available attributes and when you
00:04:58.479 select one of those you want to get all
00:05:00.520 the values that are kind of valid or
00:05:03.039 good for this attributes and when you
00:05:05.479 kind of autocomplete this you might end
00:05:06.840 up with something like this but if you
00:05:09.280 have been using stimulus you might have
00:05:10.479 noticed that there is a typo here it
00:05:12.120 should be an underscore not a dash and
00:05:14.880 that's just super hard to miss and it
00:05:17.560 happened to me a bunch of times I've
00:05:18.880 been wasting a lot of hours with that
00:05:20.600 and it happens so easily I think if you
00:05:23.080 have been using it you probably
00:05:24.560 experience it yourself too so that was
00:05:27.160 kind of the initial thought of right
00:05:29.479 like we can do better than
00:05:31.280 that so A few years back in 2021 I was
00:05:34.160 looking up and said yeah what do we have
00:05:36.039 to do to make this work so I looked it
00:05:38.000 up I found this really good extension
00:05:39.880 guide on the vs code dos and they
00:05:43.080 reference um this repo has a bunch of
00:05:45.880 examples in it and they had one specific
00:05:48.240 one for
00:05:49.440 LSPs and this basic one had this um
00:05:53.400 simple auto complete um it just gives
00:05:56.280 you two options for text documents so
00:05:59.000 let's see how this one specifically
00:06:01.440 works so when you on an editor you have
00:06:03.759 the curs of the points it will send a
00:06:06.560 request in this case a text document
00:06:08.680 completion request it sends along some
00:06:11.680 attributes with it like the file you are
00:06:13.880 in and the position your cursor is right
00:06:16.280 now and the server can respond do
00:06:18.759 anything and respond with a Chason
00:06:20.280 response in the end it has a certain
00:06:22.240 format in this case it's just ajent blob
00:06:25.199 and it's a list and has a few attributes
00:06:27.680 in it and with getting that back to the
00:06:30.360 editor it will Rend something like this
00:06:31.960 in vs codes and you got this auto
00:06:33.960 complete um for
00:06:35.800 free so with that we kind of have the
00:06:38.479 basic idea of what we want to do but how
00:06:41.280 does it translate now to our HTML use
00:06:43.960 case stimulus doesn't have any grammar
00:06:47.080 or any like syntax specifically it's all
00:06:49.400 HTML attributes but in HTML LSP wouldn't
00:06:52.759 know about the S attributes so we
00:06:54.520 dealing with what we call embedded
00:06:57.000 languages the stos SC is not part of the
00:06:59.160 HM who doesn't know about it so we need
00:07:01.800 to have a way of kind of extending the
00:07:03.599 HTML syntax or the HTML grammar to
00:07:06.680 handle stimulus as well and we can do
00:07:09.400 this with language
00:07:11.120 Services which also leads us to the next
00:07:13.080 question what language do you write this
00:07:15.120 service in there are a few choices here
00:07:18.879 some of you might like some of these
00:07:19.960 languages some of you don't um
00:07:22.680 preferably it would be Ruby but we ended
00:07:24.759 up using typescript because of a few
00:07:27.720 reasons we have been using using or
00:07:30.160 people have been using hot Vio in
00:07:31.759 different Frameworks in different
00:07:32.840 languages and it felt always wrong to
00:07:35.000 kind of require Ruby to be set up and
00:07:36.840 available on the system even if you just
00:07:39.039 want to have Tooling in your editor so
00:07:41.960 the portability aspect the existing data
00:07:44.199 providers the existing language services
00:07:46.440 and all the integration around it kind
00:07:48.599 of made it an obvious choice for our
00:07:52.199 case and with that they provide a
00:07:54.520 language service for HTML already which
00:07:56.440 we can use and what we have to do is we
00:07:58.840 have to write
00:07:59.960 one single data provider which is a
00:08:02.360 class that we can extend from and by
00:08:04.560 implementing these methods it
00:08:06.400 automatically knows about all our syntax
00:08:07.960 automatically so let's implement
00:08:11.240 this we have a provide tax um method and
00:08:16.400 since we extending the HM gramar we can
00:08:18.080 add new attacks to it too but since
00:08:20.840 we're using stimulus we don't have extra
00:08:22.520 tags we're just using regular attributes
00:08:25.000 so for this we just return an m and are
00:08:27.800 done with that next up are the
00:08:30.639 attributes um you get pass in a attack
00:08:33.640 too but since you can put HTML simulus
00:08:37.279 controls on any tag we don't really care
00:08:38.839 about that what we want to do is kind
00:08:41.919 return this list and there are a few
00:08:45.080 static ones we can um talk about and
00:08:46.959 some Dynamic ones we look at later so
00:08:49.240 for the static ones we can just return
00:08:51.040 another array with a list of um these
00:08:54.200 attributes and for the other ones we
00:08:56.160 need to know about our application and
00:08:58.600 our controlers that we we have in our
00:09:00.000 application so we can interpolate these
00:09:02.560 values so we need to pass the JavaScript
00:09:05.040 or we need to pass our Sim controls for
00:09:07.600 us to be able to do that so let's put up
00:09:10.720 a class in JavaScript which is control
00:09:12.959 definition where we just hold a
00:09:14.519 reference to all these controls we have
00:09:16.480 in our app it has a path it has have
00:09:18.680 methods targets and everything else you
00:09:20.320 can do in
00:09:21.480 stimulus and we're using Acorn to pars
00:09:24.120 out JavaScript we write a little class a
00:09:27.959 par class has a part controller method
00:09:30.720 takes in the code the source code and
00:09:33.000 the file
00:09:34.000 name and then if you look at this
00:09:36.040 example where we have hello controller
00:09:37.600 which US generates with rails new you
00:09:40.360 get targets you get um methods and what
00:09:44.040 we care about is these parts here the
00:09:45.680 Target Center methods that we want to
00:09:47.320 parse
00:09:48.480 out so we can write a little script A
00:09:51.560 glob pattern to look for all the
00:09:52.920 controls and up Loop over them read the
00:09:56.480 file and then pass them into our
00:09:58.440 controller
00:10:00.680 um pass Control
00:10:02.839 Function in there we can par it using um
00:10:05.720 Acorn we get a abst synex tree and then
00:10:10.360 we can walk down this representation of
00:10:12.399 our source code and look for method
00:10:14.279 definitions and whenever we find one of
00:10:16.360 those we push this name into our methods
00:10:19.640 array and with that we can kind of par
00:10:22.519 all the basic um information about a
00:10:24.480 single
00:10:25.279 controller we can do something very
00:10:27.160 similar for targets and then
00:10:30.320 this controller turns into an instance
00:10:31.959 of this control definition class which
00:10:33.360 looks like this where we have the path
00:10:35.040 the methods the targets and so on and
00:10:38.240 with this information we can then go and
00:10:40.560 try to interpolate these values now
00:10:42.600 because we have the controllers we have
00:10:44.279 our targets so everything we need to
00:10:46.959 finish
00:10:48.000 that this is where we left off the
00:10:50.639 static ones and now we can add a new on
00:10:53.720 at top we Loop over all our a map over
00:10:56.079 all our controllers interpolate the
00:10:58.800 names we get a list of Target attributes
00:11:02.600 we spread them back into our array that
00:11:04.519 we return and with that we have the
00:11:07.120 basic idea of um autocomplete for
00:11:10.279 targets and when you look in our editor
00:11:12.360 now we get an experience like this where
00:11:14.000 you have the actions to controllers but
00:11:16.880 also now specifically the data hell
00:11:18.519 Target which is what we had in our
00:11:20.360 controller so this is already quite
00:11:23.880 useful now if you aut to complete for
00:11:27.200 example the controller attribute you
00:11:28.920 would want to know which values are
00:11:31.000 allowed here which are actually um valid
00:11:33.959 here that's what you get to do in our
00:11:36.160 last method which is provide values we
00:11:38.240 get a tag again which you don't care
00:11:40.120 about and we get our attributes so we
00:11:42.880 know which ones we are completing
00:11:45.120 for and here we can check if we are
00:11:47.600 dealing with the data controller
00:11:48.800 attribute and if we do we just return a
00:11:52.200 list of all the identifies we know about
00:11:54.800 if it doesn't match we can check if it
00:11:56.320 matches the target attributes and if it
00:11:59.000 does we find the right controller and
00:12:00.680 then return all the targets we know
00:12:02.800 about and with this we get into
00:12:05.040 something like this where you have the
00:12:06.279 controllers you get all the possible
00:12:08.800 values for the uh identifiers and if you
00:12:11.839 specify a Target you get all the valid
00:12:13.920 Targets in the
00:12:15.880 controller that was kind of the first
00:12:18.000 initial commit I did in like a night
00:12:20.760 worth of hacking so was kind of fun um
00:12:24.959 and then a few days later I messaged a
00:12:26.480 friend of mine to just showcase this to
00:12:29.320 him and just s the demo and he was like
00:12:32.399 pretty impressed by it and was like yeah
00:12:33.760 we should continue working on this so
00:12:36.399 that's what we did um so what else can
00:12:38.920 we
00:12:39.800 do the thing is when you might thinking
00:12:43.279 can AI do all of that now and probably
00:12:46.920 maybe but um I think there are a few
00:12:49.440 different use cases where it doesn't
00:12:50.720 make sense so I feel like AI is really
00:12:53.079 good for boiler plate for generating a
00:12:54.560 lot of markup but LSPs are really good
00:12:57.079 for making sure the stuff is accurate
00:12:58.920 and that that actually um is what you
00:13:01.680 actually want with AI you have still a
00:13:04.360 limited context window and you have a
00:13:06.160 lot of files that you have to know about
00:13:08.560 and the AI is not really good with
00:13:09.880 making the connections between these
00:13:11.079 files when you have the control Files
00:13:12.839 The View files partials it doesn't get
00:13:15.199 it right most of times but even if it
00:13:18.800 would do it get it right we still have
00:13:22.000 Diagnostics which makes it um really
00:13:24.399 useful so when the AI generates some
00:13:26.680 codes it LSP can tell you if the code
00:13:29.120 generated was right and that's still I
00:13:31.440 think a useful use case and most of this
00:13:34.279 is inspired by Ruby's um did you mean
00:13:36.880 suggestions as well when you misspell a
00:13:38.959 typo method name it will give you some
00:13:41.560 suggestions of what you could have meant
00:13:44.199 so similarly you do this now in stimulus
00:13:46.240 with LSP when you have an underscore
00:13:48.279 somewhere it will give you a suggestion
00:13:50.399 of what you could have meant it works
00:13:52.440 for controllers works for actions works
00:13:54.959 works for targets and even for the
00:13:57.839 values if you pass the wrong
00:14:00.560 type so that's already quite cool but
00:14:03.560 can we do more um so we already know
00:14:06.160 that something is wrong about the codes
00:14:07.680 you know what it could have meant so can
00:14:10.440 we provide code actions to um help you
00:14:12.800 guide in the right direction so what you
00:14:15.320 can do now as well is if you have a
00:14:17.160 wrong controller you can have the Quick
00:14:18.839 Fix actions and then replace that
00:14:20.639 suggestion in your view with the new
00:14:24.240 um uh value that they are could have
00:14:26.920 meant and with all of these features
00:14:29.399 kind of ready we kind of fast forward to
00:14:31.680 October last year where I kind of felt
00:14:34.040 confident enough to release this to the
00:14:35.519 public and that's what we did and thanks
00:14:38.079 to the language s protocol we could also
00:14:40.480 support of all of these editors out of
00:14:42.040 the box without doing any more work
00:14:43.920 which is quite
00:14:45.759 cool but then we asked the committee for
00:14:47.880 feedback to get like what they how they
00:14:49.759 are using it and how they might be
00:14:51.839 having issues with it so we got a lot of
00:14:54.240 ideas feedback and I started to notice
00:14:57.440 that a lot of the naive approach we used
00:14:59.040 using L falling short falling short yeah
00:15:02.480 so especially around the way we were
00:15:03.720 passing out JavaScript with Acorn didn't
00:15:05.720 quite work the way we wanted to because
00:15:07.880 there's lot of different syntax in
00:15:09.199 JavaScript and lot different versions
00:15:10.680 with the es versions you might have
00:15:12.759 known it's it's quite a mess but we got
00:15:15.480 it figured out um the other problem was
00:15:19.120 not all apps are using app Javascript
00:15:21.279 controllers and we kind of hardcoded
00:15:22.759 that um turns out not all apps us this
00:15:25.000 so that works out too and um the way can
00:15:29.199 register or install stimus application
00:15:31.839 is really huge there's a lot of ways to
00:15:34.360 do it and if you have been using R front
00:15:37.079 in the last few years you might have
00:15:38.519 seen some of these tools here and if you
00:15:42.079 want to provide a tool you kind of have
00:15:43.720 to support all of those to make it work
00:15:45.560 in all apps so that took quite a long of
00:15:48.160 time to make it work in all of these
00:15:50.959 scenarios and most time you just had a
00:15:53.120 situation where it technically works but
00:15:56.000 it just produce a lot of false positives
00:15:57.759 and inaccurate results
00:15:59.759 which is really annoying for you as a
00:16:01.720 user because you want it to be reliable
00:16:04.199 so we addressed all these issues we
00:16:06.639 technically rewrote the whole par you
00:16:08.839 make up for that and this is what
00:16:11.759 powered um the new release that we
00:16:14.639 released early this
00:16:16.000 may so we could extract a parcel um we
00:16:19.399 could um use that to um ship this LSP
00:16:23.800 1.0 release which add support for
00:16:26.639 controls from Mion packages for typ
00:16:28.959 files for more code actions and a lot of
00:16:31.600 more things so that was really a success
00:16:34.800 and then next up we also got recently
00:16:38.560 supportting Ruby mine a major editor in
00:16:41.160 the Ruby world to support it out of the
00:16:42.759 box which is cool and then all of these
00:16:46.759 Diagnostics we talked about earlier are
00:16:48.680 not specifically tied to the LSP
00:16:51.680 itself so you could kind of extract
00:16:53.839 those two and make them so you can use
00:16:56.040 them independently kind of like you use
00:16:58.319 ruop you can use your book up as a loan
00:17:01.399 tool but your editor might warn you
00:17:03.160 about warnings as well that's what we
00:17:05.600 kind of want to do here too we want to
00:17:06.880 provide a stimulus lint package so we
00:17:08.480 get all the errors Diagnostics best
00:17:10.679 practices and so on in like a single
00:17:13.240 handy CLI so you can run this locally or
00:17:16.319 on CI before you ship to production and
00:17:19.319 kind of test that your controls are
00:17:21.720 actually valid and do the right
00:17:23.600 thing and the other problem we have
00:17:26.880 right now is that we don't support all
00:17:28.280 the h Erb syntax so if you're
00:17:30.240 interpolating using the data hash it
00:17:33.120 doesn't quite work yet so we have to fix
00:17:35.000 that and then also provides diagnostics
00:17:37.600 code actions for ERB tooling too and
00:17:40.679 this is what leads us to the triple SSP
00:17:43.320 as
00:17:44.360 well it's already available now but it's
00:17:47.039 really super basic and it has the same
00:17:48.880 issue here because turbo makes heavy use
00:17:51.520 of all the view helpers and
00:17:53.679 Erb so for it to be actually useful we
00:17:56.320 have to provide um intellig forb we have
00:17:59.720 to understand Erb and right now there's
00:18:02.400 not really a good solution to par and
00:18:04.320 understand Erb with
00:18:06.320 HML so the LSP understands HTML and Erb
00:18:09.480 documents but it doesn't understand when
00:18:11.679 you use Ruby to Output
00:18:14.039 HTML and that was the kind of big issu
00:18:16.600 that we have here I gave a talk at ra
00:18:19.799 world last year where we had um this
00:18:23.240 kind of point up there to say that you
00:18:25.679 want to support trp if the rubp supports
00:18:28.600 it
00:18:29.880 and um this led to discussion um with
00:18:32.679 Vinnie the creator of the
00:18:34.280 rubp and we ended up trying to make it
00:18:36.880 work in rubp and last year at Rubicon
00:18:39.880 fact day we got together to work on this
00:18:42.960 and we also started to realize that if
00:18:45.760 you want to go go beyond the basics you
00:18:47.840 need to have something more
00:18:49.559 powerful so the approach we ended up
00:18:51.640 using for that was we have this document
00:18:54.240 here and what what we would do is we
00:18:56.520 strip out all the HTML around it
00:18:59.400 and when you do this you are just left
00:19:00.799 with the Ruby codes then you can use any
00:19:03.400 Ruby par to make that work and then you
00:19:05.559 can understand the file this is also
00:19:08.120 what shipped a few weeks ago with Ru P
00:19:09.960 now so this is quite cool and they have
00:19:12.559 been shipping a lot of features as well
00:19:14.679 alongside that so if you haven't been
00:19:16.720 using rubp check out this article to see
00:19:18.840 what it can do for you
00:19:20.320 today but back to this problem here um
00:19:23.919 when we kind of did this whole thing we
00:19:25.760 lost the whole HML context in the
00:19:27.559 process and it really matters where you
00:19:30.440 are interpolating in a HML document if
00:19:32.240 you are interpolating in between taxs in
00:19:34.919 values or just the top level it has a
00:19:37.520 different meaning right so we want to
00:19:41.200 kind of support HTML with Ruby as you
00:19:43.600 would use in HTML Erb files but Erb
00:19:46.760 itself is super versatile so you can use
00:19:48.559 it for pretty much anything when you're
00:19:50.080 interpolating Ruby so you could use it
00:19:52.320 for inter plating emails or for text
00:19:55.520 documents or anything else right so what
00:19:57.880 we really need is a HTML yearb parer and
00:20:01.039 that's kind of what I've been trying to
00:20:02.760 get at the last few
00:20:04.640 um months um to make that work and see
00:20:08.080 what's possible by doing
00:20:09.799 so for my big um inspiration here to
00:20:13.200 kind of P these tools that we have been
00:20:15.320 talking
00:20:16.240 about and what you have to understand is
00:20:18.799 that we want to par these scenarios
00:20:20.840 where you're using rail tax helpers if
00:20:23.360 you using content tags if you're using
00:20:26.000 Loops if you're using for each if you're
00:20:28.760 using conditionals if you're using data
00:20:30.720 controllers or data
00:20:32.679 attributes which made me think there's
00:20:34.799 something missing in the H abstraction
00:20:36.679 because in the ends what we want to see
00:20:39.360 as a output you want to kind of treat
00:20:41.840 those two things equally because in the
00:20:44.000 end it just outputs the same thing
00:20:46.679 similarly we want to treat these two um
00:20:49.360 equally um but that's not something you
00:20:51.559 can easily do today so this needs a lot
00:20:54.159 of more exploration to see where this
00:20:55.880 can go but if this is done right you
00:20:58.679 could also maybe support Hammer slim and
00:21:01.159 other languages to get this in the same
00:21:03.440 format to then provide the same tools
00:21:05.320 for all of these out of box and if this
00:21:08.720 also done right we might be able to ex
00:21:11.600 extend or provide some more language
00:21:12.960 services in general like we were using
00:21:15.520 the HML language service
00:21:18.159 earlier so if you have this and we
00:21:20.679 understand all of that and if you
00:21:22.039 understand even ra rent calls we could
00:21:24.840 provide even more Advanced
00:21:27.240 Diagnostics for for example if you have
00:21:29.640 this controller here all this
00:21:31.400 Snippets the Target in here has to be
00:21:34.159 inside the controller elements so this
00:21:37.039 target needs to be inside of this
00:21:38.600 element if this is outside it doesn't
00:21:41.400 quite work it that's just nothing it
00:21:42.919 doesn't tell you anything about
00:21:44.799 it and I guess realistically speaking
00:21:49.080 modern rails are not one file they are
00:21:51.279 split up between partials views
00:21:53.000 components and so on so you might up end
00:21:55.880 rendering this paral from another file
00:21:58.600 and then it gets really tricky to
00:21:59.919 understand how these um files relate to
00:22:01.600 each other and how we can kind of
00:22:02.799 provide
00:22:04.320 Diagnostics but if you can get the parts
00:22:06.360 to understand this and kind of build up
00:22:07.919 a tree of all your files and all your
00:22:09.799 views you might be able to just
00:22:11.679 reference these different um tools and
00:22:14.919 make um tooling on top of
00:22:17.400 that so when we kind of render the
00:22:19.679 partial outside of these elements we
00:22:21.360 could also try to annotate this and
00:22:22.880 saying this is actually not in the right
00:22:25.840 place I've lost so many hours debuging
00:22:28.520 and stuff like that it's really this
00:22:30.480 would be really helpful so that's what
00:22:32.760 I've been trying to get at just trying
00:22:35.200 to see if you can make this work and
00:22:37.799 power these tools but also by doing some
00:22:40.279 research I found a lot of other gems
00:22:41.760 that are dealing with similar situations
00:22:44.159 so maybe it could even be helpful for
00:22:45.720 them to have something like that
00:22:48.760 available maybe even I format that works
00:22:51.200 out the box for free that's just like
00:22:53.200 you installed and it works I have been
00:22:55.039 trying to get this working in my
00:22:56.159 environments could make it work
00:22:59.000 um a lintern that's kind of tries to
00:23:01.120 figure stuff out for you or possibly
00:23:03.600 even a new Erb engine that kind of
00:23:05.360 understands all of that out of the box
00:23:07.360 we'll see um the Ruby parsel the prism
00:23:11.360 that had been released like last year
00:23:14.600 had a big effect on Ruby internals and
00:23:16.720 tooling landscape it can do stuff with
00:23:18.279 Ruby it actually just shipped today in
00:23:20.880 the Ruby 34 preview to as a default
00:23:23.559 parel which is kind of cool and I feel
00:23:26.240 like something like this for HML could
00:23:28.120 also improve the landscape in general
00:23:29.960 for template
00:23:31.520 languages which is kind of the goal of
00:23:33.520 this whole um
00:23:35.600 Journey okay I have one more thing I
00:23:38.880 have been working with a friend of mine
00:23:40.960 on a hot browser extension and this came
00:23:43.720 all about from this tweet by mat wanton
00:23:46.279 a few years back he was using a CSS hack
00:23:49.440 to annotate the turbo frames so kind of
00:23:52.720 outlin them so you can see where frames
00:23:54.840 are and I was talking with my friend
00:23:56.840 Leon about this and he then just spun up
00:23:59.600 a new project as well so hotti def tools
00:24:02.720 is available today too um it works in
00:24:05.600 all major browsers and it gives you this
00:24:07.360 little panel here for the sabling all
00:24:10.240 the features it has and one cool thing I
00:24:12.760 noticed is on stack Overflow if you have
00:24:15.360 this
00:24:16.520 enabled here you can see all the
00:24:18.360 outlined um elements that are Sim
00:24:20.919 controls on the page so most of the
00:24:23.120 interactions iny overflow are powered by
00:24:24.600 stimulus which I found surprising and in
00:24:27.200 the bottom right corner you can see all
00:24:28.720 the controls that are referenced and
00:24:30.159 used on this
00:24:31.720 page I have a sneak peek here too and
00:24:35.240 while working on um this extension we
00:24:38.000 also found GitHub is using a bunch of
00:24:40.120 Turbo frames all over the place so we've
00:24:42.279 been trying to see if you can visualize
00:24:43.799 how buttons and Frames kind of relate to
00:24:46.000 each other so you have a visual
00:24:47.399 representation of that but as you can
00:24:49.640 see on this slide here it gets a little
00:24:51.679 bit messy quickly so we have to figure
00:24:53.960 out a way of how we can make this more
00:24:56.240 um readable
00:24:58.919 and then in the stimus refix ecosystem
00:25:00.960 we had this plugin that um was kind of
00:25:04.360 highlighting you which buttons are
00:25:05.960 interactive which View files it would
00:25:08.360 render which parts of the page it would
00:25:10.559 update if you click on this button and
00:25:12.440 all of the kind of with these boxes
00:25:13.840 alongside so if you can bring this to
00:25:15.919 Turbo as well which is what we're trying
00:25:17.520 to do that would be really cool to debug
00:25:20.360 um turbo
00:25:22.240 applications another thing is that um if
00:25:24.880 you have been using turbos
00:25:26.399 streams you might have noticed that they
00:25:28.640 are super quick to execute and sometimes
00:25:30.760 if there are a bunch of them at the same
00:25:32.360 time it's hard to see what's happening
00:25:34.640 so we want to kind of bring a debug bar
00:25:36.559 to that so you can stop the execution
00:25:38.919 step through them and see what's
00:25:40.240 actually going
00:25:41.200 on um a similar thing with um turbo
00:25:43.840 frames you can get this button here to
00:25:47.120 reload this current frame request the
00:25:49.440 page and then get
00:25:51.159 updates and there are a lot of more
00:25:53.080 ideas on the road map it's all a work in
00:25:56.320 progress um so if you have any on how
00:25:58.799 you could make this your life easier
00:26:00.679 with um daily Hotwire work let me know
00:26:03.919 um you can see if you can make it
00:26:06.520 work okay so to conclude I think
00:26:10.600 developer experience and developer
00:26:12.000 economics matter I think we have been
00:26:14.679 somehow missing these tools in the last
00:26:16.960 few years and Ruby and R leared and I
00:26:20.120 feel like there's so much more potential
00:26:21.360 to level up yeah just catching up now
00:26:24.520 but as I was working on these tools I
00:26:26.760 feel like you have a super exciting Fe
00:26:28.559 with them and that's kind of why I'm
00:26:30.559 doing all of that and then at the same
00:26:33.279 time I think it's also why language
00:26:35.679 stays relevant if you have tools and the
00:26:38.039 tooling around it or if you kind of put
00:26:40.640 it other way around it's kind of
00:26:42.840 expected today that Frameworks and
00:26:45.360 languages have these tools available
00:26:46.760 otherwise people are just not picking
00:26:48.200 them up especially the newcomers I kind
00:26:50.840 of hard to um to work
00:26:53.679 with they have been struggling to just
00:26:56.279 understand why Ruby doesn't provide you
00:26:58.080 any intelligent tooling so it's really I
00:27:00.880 think crucial for the new generation to
00:27:03.000 have these tools
00:27:04.679 available and yeah we have been lacking
00:27:06.720 behind and because of that I want to
00:27:09.760 keep building that and I want to keep
00:27:11.600 building R applications I want to keep
00:27:14.480 using Ruby and rails and that's why I'm
00:27:18.000 trying to help build these um tools for
00:27:19.960 the future of rail
00:27:22.360 applications um one more thing here um I
00:27:25.279 have been running a hot V Weekly
00:27:26.799 Newsletter which is a weekly Roundup of
00:27:29.399 what's happening in the world of Hotwire
00:27:31.720 so if you are interested in keeping up
00:27:33.960 what's happening you can sign up on the
00:27:36.320 SES here on hot.com it comes out every
00:27:40.360 Sunday so I am just trying to stand in
00:27:43.880 for a more productive hot ecosystem for
00:27:46.880 a more unified Hotwire ecosystem and I
00:27:49.480 want to be available to talk about that
00:27:50.919 with you so if you have any feedbacks
00:27:53.519 ideas thoughts questions come see me
00:27:55.640 after the talk and if you are stickers I
00:27:58.760 got some of these too so that's all I
00:28:01.480 have thank
00:28:11.399 you the question was how I interacting
00:28:13.760 with my LSP um I don't I've been using
00:28:18.000 it to test my LP but I'm have been
00:28:20.039 mostly using still Adam which is um what
00:28:23.000 I'm pring from to neovim but neovim I'm
00:28:25.960 using too
00:28:28.519 but it's easy to um deal with on test in
00:28:31.559 vs codes with all the debugging Tools
00:28:33.240 around it yeah question was how many
00:28:35.399 days it takes to ship EB LSP
00:28:38.200 support I don't
00:28:40.720 know um hopefully soon but I feel like
00:28:43.640 it's a bigger efforts that we have to go
00:28:45.320 through first but and I want to do it
00:28:48.120 right and I think that takes more time
00:28:49.880 now but I hope to see something the next
00:28:52.200 few months yeah no promises
00:28:55.919 though the question was if I know some
00:28:58.120 something about LSPs now that I wish I
00:29:00.120 knew
00:29:01.320 earlier um I think just that I'm not
00:29:04.240 that scary that you think it's just um
00:29:07.240 like you write a rails application you
00:29:09.000 have a client at a server and it's
00:29:11.200 really just the same interaction so if
00:29:14.640 it's anything like maybe I could show
00:29:16.399 here this talk I think it's just EAS
00:29:18.399 than you think to make it work
00:29:25.600 yeah cool thank you than
Explore all talks recorded at Rocky Mountain Ruby 2024
+22