69: def self.find(filename, start_line=1, block_only=true)
70: lines, lexer = nil, nil
71: retried = 0
72: loop do
73: lines = get_lines(filename, start_line)
74: return nil if lines.nil?
75:
76: if !line_has_open?(lines.join) && start_line >= 0
77: start_line -= 1 and retried +=1 and redo
78: end
79: lexer = RubyLex.new
80: lexer.set_input(StringIO.new(lines.join))
81: break
82: end
83: stoken, etoken, nesting = nil, nil, 0
84: while token = lexer.token
85: n = token.name
86:
87: if RubyToken::TkIDENTIFIER === token
88:
89: elsif token.open_tag? || RubyToken::TkfLBRACE === token
90: nesting += 1
91: stoken = token if nesting == 1
92: elsif RubyToken::TkEND === token || RubyToken::TkRBRACE === token
93: if nesting == 1
94: etoken = token
95: break
96: end
97: nesting -= 1
98: elsif RubyToken::TkLBRACE === token
99: nesting += 1
100: elsif RubyToken::TkBITOR === token && stoken
101:
102: elsif RubyToken::TkNL === token && stoken && etoken
103: break if nesting <= 0
104: else
105:
106: end
107: end
108:
109: lines = lines[stoken.line_no-1 .. etoken.line_no-1]
110:
111:
112: if block_only
113: spaces = lines.last.match(/^\s+/)[0] rescue ''
114: lines[0] = spaces << lines[0][stoken.char_no .. -1]
115: end
116: ps = ProcString.new lines.join
117: ps.file, ps.lines = filename, start_line .. start_line+etoken.line_no-1
118:
119: ps
120: end