Skip to content

Instantly share code, notes, and snippets.

@kristianmandrup
Created February 27, 2010 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristianmandrup/316748 to your computer and use it in GitHub Desktop.
Save kristianmandrup/316748 to your computer and use it in GitHub Desktop.
Texer::Operate DSL examples
---------------------------
Will be changed to use Ripper2Ruby API in progress for much more flexibility and power!
include 'finder'
txt = %q{
gem 'a' do |b|
a
b
c
end
gem.call :blip
}
# DSL EXAMPLES
Texer::Operate.on txt do # txt.extend(Finder)
txt.within( :do => 'gem' ).where(:args => {:hello,'blip', :ged}) do |block|
# ...
end
end
# :do => 'gem' --> 'gem\s+#{args}\s+do |#{block_args}|
where(:args => {:hello,'blip', :ged})
# translated into regular this expr
':hello\s*,\s*\'blip\'...'
# IF ELSIF ELSE END
# within : regular expr
txt.within( :if).where(:expr => /a\s*<\s*b/) # if a < v
# substitute ' ' with \s*
# :spaces means at least 1 space, so '_' is substituted with \s+
txt.within( :if).where(:expr => 'a <_b', :spaces => '_') # if a < v NOT a <v, since must be at least one space after '<'
txt.within( :if).where(:expr => %Q{a == '1_2'}, :space => '_') # if a < v : substitute -- with \s* AND -+ with \s+
txt.within( :elsif).where(:expr => 'a--<--b') # elsif a < v
txt.within( :else) # else end
# CASE WHEN END
txt.within( :case).where(:expr => 'x') # case x when end
txt.within( :when).where(:expr => 'y') # when y when|else|end
# CLASS
# module
txt.within( :module => :finder) # module Finder
# class
txt.within( :class => 'Finder') # module Finder
# module class inheritance
txt.within( :module => :finder).within(:class => :ruby_matcher).which(:inherits_from => {:base_matcher}) # module Finder class RubyMatcher < BaseMatcher
# METHODS
txt.within( :initializer) # def initialize
# singleton method
txt.within( :method => :hello).where(:obj => 'obj', :args=> {:a, :options => '{}'}) # def obj.hello(a, options = {})
# instance method
txt.within( :method => :hello).where(:args=> {:a, :options => '{}'}) # def obj.hello(a, options = {})
# setter
txt.within( :setter => :price).where(:args => {:a}) # def price=(a)
# exclaim !
txt.within( :exclaim => :merge).where(:args => {:a}) # def merge!(a)
# ask ?
txt.within( :ask => :blue?).where(:args => {:a}) # def blue?(a)
# SCOPE
txt.within( :class_self) # def class << self ... end
# DO BLOCK
txt.within( :do => :group).where(/:test/) # group :test do OR group :test, 'dds' do
txt.within( :do => :group).where(:args => {:test} ) # group :test do OR group (:test) do NOT group :test, 'dds' do
txt.within( :do => :group).where(:block_args => {:x, :y} ) # group do |x, y |
txt.within( :do => :group).where(:args => ANY, :block_args => {:x, :y} ) # group :blip, 'blap, 7 |x, y |
txt.within( :do => /Module::#{CONST}\.abc/).where(:args => {:grip}, :block_args => {:x, :y} ) # Module::Clazz.abc :grip do |x, y | OR Module::Blip.abc :grip do |x, y |
# ===========
# BEFORE
Texer::Operate.on txt do # txt.extend(Finder)
txt.before( :do => 'gem').where(:args => {:hello,'blip', :ged}) do |block|
# returns block of text before the start of this matching line
txt.before( :class => :finder)
# returns block of text before the start of this matching line
# AFTER
Texer::Operate.on txt do # txt.extend(Finder)
txt.after( :do => 'gem').where(:args => {:hello,'blip', :ged}) do |block|
# returns block of text after the end of this matching block
txt.before( :class => :finder)
# returns block of text after the end of this matching block
# ==========
# MUTATATIONS
txt = %q{
gem 'a' do |b|
a
if x - 1=0
puts 'hello'
end
end
gem.call :blip
}
# Clipboard actions can operate in two modes, stack or overwrite
# By default it is in overwrite mode
# If a block is cut and pushed onto the stack, it can later be pop-pasted, pasting while removing the block from the clipboard stack
# if popped, the next item on the stack is available for pasting
# Also support for multiple clipboards
# Use case: Find block, cut line from block, then cut remaining block and insert it into outer text block
Texer::Operate.on txt do # txt.extend(Finder)
# within block gem 'a' do |b|
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block|
clipboard = Texer.clipboard
clipboard2 = Texer.clipboard
# cut line puts 'hello'
block.remove!(:puts).where(:string)
# cut remaining block and put onto clipboard
clipboard.cut(block, :push)
# paste block from clipboard after gem.call :blip
clipboard.paste(:pop).into(txt).after(:send => 'call').where(:args => :blip)
clipboard.paste(:pop).into(txt).after(:send => 'call').where(:args => :blip) # no text pasted, clipboard is empty
end
end
# Use case: Cut line from block, then cut remaining block and insert it into outer text block
Texer::Operate.on txt do # txt.extend(Finder)
# within block gem 'a' do |b|
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block|
# find block 'if x-1 < 0' and cut it
piece = block.cut(:if).where(:expr => 'x - 1 = 0')
block.insert(piece).in(txt).before(:send => 'call').where(:args => :blip)
end
end
# OR
Texer::Operate.on txt do # txt.extend(Finder)
# within block gem 'a' do |b|
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block|
# find block 'if x-1 < 0' and cut it (and move to clipboard)
cut_block = clipboard.cut.from(block).content(:if).where(:expr => 'x - 1 = 0')
# replace puts '..' with puts "goodbye"
cut_block.replace(:puts).where(:string).with(:puts => %Q{ "goodbye" })
# alternative syntax
cut_block.replace(:puts).where(:string).with(:puts).where(:args => "goodbye")
# paste block from clipboard before gem.call :blip
txt.insert(cut_block).before(:send => 'call').where(:args => :blip)
txt.append(clipboard.paste(:pop))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment