DSL blocks with individual contexts? #577
Replies: 1 comment
-
| I was working on a similar problem today and determined that there is no way to do this declaratively. There is a  # @yieldself [SomePlugin]
def init(name, &block)
end
# now `self` is a SomePlugin instance in every `init` blockDepending on your appetite for Solargraph plugins and poking at instance variables, the following should do more or less what you want: # put this somewhere solargraph can require it, then add "your_plugin" to the plugins array in .solargraph.yml
module Solargraph
  class FrameworkPlugin < Convention
    def local(source_map)
      return EMPTY_ENVIRON unless source_map.filename =~ /framework_config.rb/ # or whatever you want
      new_pins = []
      # @type [Array<Pin::Block>]
      blocks = source_map.pins.select { |p| p.is_a?(Pin::Block) && p.receiver.children[0] == :init }
      blocks.each do |block|
        # turns :some_plugin into "SomePlugin", the type we want our block to be bound to.
        # if you want "SomePlugin::Config" or whatever, here's where you do that.
        binder_type = block.receiver.children[0].to_s.classify
        # here we have to get a bit nasty to prevent Solargraph from computing it's own binder        
        block.instance_variable_set(:@binder, ComplexType.parse(binder_type))
      end
      # we always need to return an Environ
      EMPTY_ENVIRON
    end
  end
  Convention.register(FrameworkPlugin)
endNote: I have not tested the above code, it's adapted from a convention I wrote to support an internal DSL, so it should work, but buyer beware 😉. If you intend to support a broad user base you probably want to be a bit safer when traversing into the child nodes of  | 
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
First off, thank you for a wonderful pillar of the Ruby ecosystem…I use Solargraph extensively everywhere!
So…I'm building a DSL for initializing various plugins within a framework, with code that looks something like this:
And this itself is within an overall configuration block.
I've gotten to the point where Solargraph recognizes
initand where that comes from, but the problem is I can't figure out a way to tell it—even with just parse or override or whatever magic comments—that the first init should pick up info foroption1andoption2in Context A, and the second should pick up info forother_option1in Context B, and presumably those definitions could come from totally different gems.Any thoughts on how this might work?
Beta Was this translation helpful? Give feedback.
All reactions