├── .gitignore ├── Support ├── spec │ └── easyopen │ │ ├── extension │ │ ├── spec_helper.rb │ │ ├── coffee_token_spec.rb │ │ ├── js_token_spec.rb │ │ ├── java_token_spec.rb │ │ └── rb_token_spec.rb │ │ ├── open_test_log_file_spec.rb │ │ ├── config_spec.rb │ │ ├── create_def_index_file_spec.rb │ │ ├── open_with_git_status_spec.rb │ │ ├── ui_spec.rb │ │ └── next_bookmark_spec.rb ├── lib │ └── easyopen │ │ ├── open_mdfind.rb │ │ ├── extension │ │ ├── user_conf.rb │ │ ├── coffee_token.rb │ │ ├── java_token.rb │ │ ├── js_token.rb │ │ └── rb_token.rb │ │ ├── back_open_def.rb │ │ ├── prev_bookmark.rb │ │ ├── show_bookmark.rb │ │ ├── add_remove_bookmark.rb │ │ ├── config.rb │ │ ├── open_recent.rb │ │ ├── ui.rb │ │ ├── next_bookmark.rb │ │ ├── open_test_log_file.rb │ │ ├── next_word.rb │ │ ├── open_with_git_status.rb │ │ ├── open_def.rb │ │ ├── repository.rb │ │ └── create_def_index_file.rb └── fixtures │ └── ruby_code.rb ├── Macros ├── find_current_keyword.tmMacro └── prev_find_selected_keyword.tmMacro ├── Commands ├── open_mdfind.tmCommand ├── show_bookmarks.tmCommand ├── prev_bookmark.tmCommand ├── add_remove_bookmark.tmCommand ├── open_def.tmCommand ├── next_bookmark.tmCommand ├── back_open_def.tmCommand ├── open_recent.tmCommand ├── open_with_git_status.tmCommand ├── create_def_index_file.tmCommand ├── open_test_log.tmCommand └── open_gem.tmCommand ├── Preferences └── completionCommand.tmPreferences ├── MIT-LICENSE ├── README.rdoc └── info.plist /.gitignore: -------------------------------------------------------------------------------- 1 | sandbox.html 2 | sandbox.rb -------------------------------------------------------------------------------- /Support/spec/easyopen/extension/spec_helper.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :eq_token do |expect| 2 | match do |actual| 3 | expect == actual 4 | end 5 | 6 | failure_message_for_should do |actual| 7 | "expected: #{expect.sort.to_a.flatten}\n got: #{actual.sort.to_a.flatten}" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /Support/lib/easyopen/open_mdfind.rb: -------------------------------------------------------------------------------- 1 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/ui" 2 | require "#{ENV['TM_SUPPORT_PATH']}/lib/textmate" 3 | 4 | 5 | def a_herf(url) 6 | %Q+#{url}
+ 7 | end 8 | 9 | TextMate::UI.request_string do |keyword| 10 | paths = `mdfind #{keyword}` 11 | paths.split("\n").each do|path| 12 | puts a_herf(path) 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /Support/spec/easyopen/open_test_log_file_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../lib/easyopen/open_test_log_file" 2 | 3 | set_trace_func lambda { |event, file, line ,id, binding, klass| 4 | if event == 'call' 5 | puts a_herf(file, line, "#{klass} #{id}") + "
" #+ sub_link(" #{file}:#{line}:in") 6 | end 7 | } 8 | 9 | describe "sub_link" do 10 | it "" do 11 | %w[a b c].map{|n| n.upcase }.should == %w[A B C] 12 | end 13 | end -------------------------------------------------------------------------------- /Support/fixtures/ruby_code.rb: -------------------------------------------------------------------------------- 1 | class Hooooo 2 | def hoge_hoge 3 | end 4 | def hoge 5 | end 6 | 7 | def hoge(arg1, arg2) 8 | end 9 | 10 | def open(hoge) 11 | end 12 | 13 | def self.hogefuga 14 | end 15 | end 16 | 17 | class Fuga < Object; end 18 | 19 | module Foo 20 | class Foo 21 | def hoge(param1, param2) 22 | end 23 | def foo(hoge, &block); end 24 | end 25 | end 26 | 27 | module Foo::Hogeogeoge 28 | end 29 | 30 | module Foo::Hogeo::HHHH 31 | end 32 | 33 | hogefuga 34 | 35 | # def hogeoge -------------------------------------------------------------------------------- /Support/lib/easyopen/extension/user_conf.rb: -------------------------------------------------------------------------------- 1 | 2 | module EasyOpen 3 | module Extension 4 | class UserConf 5 | @@exts = {} 6 | Dir.glob("#{File.dirname(__FILE__)}/*").each do |file_name| 7 | require file_name 8 | basename = File.basename(file_name) 9 | unless basename == "user_conf.rb" 10 | tmp = basename.sub("_token.rb", "") 11 | # puts tmp 12 | @@exts[tmp] = eval("#{tmp[0..0].upcase}#{tmp[1..-1]}Token.new") 13 | end 14 | end 15 | def self.tokens 16 | @@exts 17 | end 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/extension/coffee_token.rb: -------------------------------------------------------------------------------- 1 | module EasyOpen 2 | module Extension 3 | class CoffeeToken 4 | def tokenize(line) 5 | if m = /(^\s*)(\w*):.*$/.match(line) 6 | pre = m[1] 7 | return { 8 | :name => m[2], 9 | :column => pre.size + 1, 10 | :more_info => line } 11 | elsif m = /(^\s*class\s*)(\w*)(.*)$/.match(line) 12 | pre = m[1] 13 | return { 14 | :name => m[2], 15 | :column => pre.size + 1, 16 | :more_info => line } 17 | end 18 | end 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/back_open_def.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/repository' 3 | 4 | module EasyOpen 5 | class BackOpenDef 6 | include EasyOpen::UI 7 | def initialize(config = {}) 8 | Config.setup(config) 9 | end 10 | 11 | def run 12 | if node = pop_call_stack 13 | open_menu(node) 14 | else 15 | puts "stack is empty" 16 | end 17 | end 18 | 19 | def pop_call_stack 20 | call_stack = CallStackRepository.load 21 | node = call_stack.pop 22 | CallStackRepository.save call_stack 23 | return node 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/prev_bookmark.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/config' 3 | require File.dirname(__FILE__) + '/repository' 4 | 5 | file = ENV['TM_FILEPATH'] 6 | line = ENV['TM_LINE_NUMBER'] 7 | 8 | bookmarks = EasyOpen::BookmarkRepository.load 9 | 10 | bookmark = bookmarks.pop 11 | bookmarks.insert(0, bookmark) 12 | if (file == bookmark[:file] and line == bookmark[:line]) 13 | bookmark = bookmarks.pop 14 | bookmarks.insert(0, bookmark) 15 | end 16 | 17 | EasyOpen::BookmarkRepository.save bookmarks 18 | unless bookmark 19 | puts "bookmark is nil" 20 | exit 21 | end 22 | 23 | include EasyOpen::UI 24 | go_to(bookmark) -------------------------------------------------------------------------------- /Macros/find_current_keyword.tmMacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | commands 6 | 7 | 8 | command 9 | copySelectionToFindPboard: 10 | 11 | 12 | command 13 | findNext: 14 | 15 | 16 | keyEquivalent 17 | ^@u 18 | name 19 | find_selected_keyword 20 | uuid 21 | E065B750-38D6-45BC-A3DE-C6ABCD29225A 22 | 23 | 24 | -------------------------------------------------------------------------------- /Macros/prev_find_selected_keyword.tmMacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | commands 6 | 7 | 8 | command 9 | copySelectionToFindPboard: 10 | 11 | 12 | command 13 | findPrevious: 14 | 15 | 16 | keyEquivalent 17 | ^@i 18 | name 19 | prev_find_selected_keyword 20 | uuid 21 | EE021D5D-1400-4629-A83F-AC10D68A07A5 22 | 23 | 24 | -------------------------------------------------------------------------------- /Support/lib/easyopen/show_bookmark.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/config' 2 | require File.dirname(__FILE__) + '/repository' 3 | require File.dirname(__FILE__) + '/ui' 4 | 5 | 6 | 7 | file = ENV['TM_FILEPATH'] 8 | line = ENV['TM_LINE_NUMBER'] 9 | 10 | unless File.exist?(EasyOpen::Config[:bookmark_file]) 11 | puts "not found bookmark file" 12 | exit 13 | end 14 | 15 | bookmarks = EasyOpen::BookmarkRepository.load 16 | 17 | if bookmarks.nil? || bookmarks.empty? 18 | puts "empty bookmark" 19 | exit 20 | end 21 | 22 | bookmarks.each do |b| 23 | d = "#{File.basename(b[:file])}:#{b[:line]}" 24 | b.merge!({:display => d}) 25 | end 26 | 27 | 28 | include EasyOpen::UI 29 | open_menu bookmarks 30 | -------------------------------------------------------------------------------- /Commands/open_mdfind.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/open_mdfind" 10 | 11 | input 12 | none 13 | keyEquivalent 14 | ^@m 15 | name 16 | open_mddinf 17 | output 18 | showAsHTML 19 | uuid 20 | 96781F29-CEF5-4048-A2DF-FD169045C853 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/show_bookmarks.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/show_bookmark" 10 | input 11 | none 12 | keyEquivalent 13 | ^@B 14 | name 15 | show_bookmarks 16 | output 17 | showAsTooltip 18 | uuid 19 | 5C1F81F7-EEDC-4B6B-AF28-8CC77DD536A4 20 | 21 | 22 | -------------------------------------------------------------------------------- /Commands/prev_bookmark.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/prev_bookmark" 10 | 11 | input 12 | none 13 | keyEquivalent 14 | ^@p 15 | name 16 | prev_bookmark 17 | output 18 | showAsTooltip 19 | uuid 20 | 60415A72-E2EA-42D1-8A71-FEC60644BECD 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/add_remove_bookmark.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/add_remove_bookmark" 10 | 11 | input 12 | none 13 | keyEquivalent 14 | ^@b 15 | name 16 | add_bookmark 17 | output 18 | showAsTooltip 19 | uuid 20 | 71C114BE-105F-4BF0-AE8E-050E919711F5 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/open_def.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/open_def" 10 | EasyOpen::OpenDef.new.run 11 | input 12 | none 13 | keyEquivalent 14 | ^@j 15 | name 16 | open_def 17 | output 18 | showAsTooltip 19 | uuid 20 | F79EF9CA-6D4D-45D9-807C-F7183BE855E6 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/next_bookmark.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/next_bookmark" 10 | next_bookmark 11 | 12 | input 13 | none 14 | keyEquivalent 15 | ^@n 16 | name 17 | next_bookmark 18 | output 19 | showAsTooltip 20 | uuid 21 | 71B53E07-8F2B-4074-8CAF-B2B454AF09F7 22 | 23 | 24 | -------------------------------------------------------------------------------- /Commands/back_open_def.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/back_open_def" 10 | EasyOpen::BackOpenDef.new.run 11 | input 12 | none 13 | keyEquivalent 14 | ^@k 15 | name 16 | open_call_stack 17 | output 18 | showAsTooltip 19 | uuid 20 | 1E135F00-FE33-4BDE-AA2C-31A6C3B3943D 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/open_recent.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/open_recent" 10 | EasyOpen::OpenRecent.new.run 11 | 12 | input 13 | none 14 | keyEquivalent 15 | ^@h 16 | name 17 | open_recent 18 | output 19 | showAsTooltip 20 | uuid 21 | 5C05808F-1680-4237-9026-A2EFD0CD263F 22 | 23 | 24 | -------------------------------------------------------------------------------- /Commands/open_with_git_status.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/open_with_git_status" 10 | EasyOpen::OpenWithGitStatus.new.open 11 | input 12 | none 13 | keyEquivalent 14 | ^@g 15 | name 16 | open_with_git_status 17 | output 18 | showAsTooltip 19 | uuid 20 | BF2A3851-1F8C-4E21-8CCB-8905E94CE577 21 | 22 | 23 | -------------------------------------------------------------------------------- /Commands/create_def_index_file.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/create_def_index_file" 10 | EasyOpen::CreateDefIndexFile.new.run 11 | 12 | input 13 | none 14 | keyEquivalent 15 | ^@c 16 | name 17 | create_def_index_file 18 | output 19 | showAsTooltip 20 | uuid 21 | 301C8785-9A97-4E24-A313-2AC89FF7403F 22 | 23 | 24 | -------------------------------------------------------------------------------- /Support/lib/easyopen/add_remove_bookmark.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/config' 2 | require File.dirname(__FILE__) + '/repository' 3 | require "pp" 4 | 5 | file = ENV['TM_FILEPATH'] 6 | line = ENV['TM_LINE_NUMBER'] 7 | 8 | bookmarks = [] 9 | bookmarks = EasyOpen::BookmarkRepository.load if File.exist?(EasyOpen::Config[:bookmark_file]) 10 | 11 | selected = bookmarks.select{ |node| node[:file] == file and node[:line] == line } 12 | 13 | if (selected.empty?) 14 | bookmarks.insert(0, {:file=>file, :line=>line}) 15 | puts "add bookmark[#{File.basename(file)}:#{line}]" 16 | puts "if press again then remve bookmark" 17 | else 18 | bookmarks.delete_if { |node| 19 | node[:file] == file and node[:line] == line 20 | } 21 | puts "remove bookmark" 22 | end 23 | 24 | EasyOpen::BookmarkRepository.save bookmarks 25 | -------------------------------------------------------------------------------- /Commands/open_test_log.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | require ENV['TM_BUNDLE_SUPPORT'] + "/lib/easyopen/open_test_log_file" 10 | puts open_log("#{ENV["TM_PROJECT_DIRECTORY"]}/log/test.log") 11 | 12 | fallbackInput 13 | document 14 | input 15 | none 16 | keyEquivalent 17 | ^@l 18 | name 19 | open_test_log 20 | output 21 | showAsHTML 22 | uuid 23 | 23D19409-E767-46E8-ACA6-ED193D7EF9EA 24 | 25 | 26 | -------------------------------------------------------------------------------- /Support/lib/easyopen/config.rb: -------------------------------------------------------------------------------- 1 | module EasyOpen 2 | class Config 3 | class << self 4 | def defaults 5 | save_dir = "#{ENV["HOME"]}/.easyopen_tmbundle#{(ENV['TM_PROJECT_DIRECTORY'] || ENV['TM_DIRECTORY'] || '').sub(ENV['HOME'],'')}" 6 | 7 | @defaults ||= { 8 | :project_dir => ENV['TM_PROJECT_DIRECTORY'] || ENV['TM_DIRECTORY'], 9 | :current_word => ENV['TM_CURRENT_WORD'], 10 | :save_dir => save_dir, 11 | :def_index_file => "#{save_dir}/def_index.dump", 12 | :call_stack_file => "#{save_dir}/call_stack.dump", 13 | :bookmark_file => "#{save_dir}/bookmark.yaml", 14 | :current_file => ENV['TM_FILEPATH'] 15 | } 16 | end 17 | 18 | def setup(settings = {}) 19 | @configuration = defaults.merge(settings) 20 | end 21 | 22 | def [](key) 23 | (@configuration ||= defaults)[key] 24 | end 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/extension/java_token.rb: -------------------------------------------------------------------------------- 1 | module EasyOpen 2 | module Extension 3 | class JavaToken 4 | def tokenize(line) 5 | # interface 6 | if m = /(^.*interface\s*)(\w*)[\s|{]*/.match(line) 7 | pre = m[1] 8 | return { 9 | :name => m[2], 10 | :column => pre.size + 1, 11 | :more_info => line } 12 | # class 13 | elsif m = /(^.*class\s*)(\w*)[\s|{]*/.match(line) 14 | pre = m[1] 15 | return { 16 | :name => m[2], 17 | :column => pre.size + 1, 18 | :more_info => line } 19 | # method 20 | elsif m = /(^.*\s)(\w*)\(.*\)[^;]*$/.match(line) 21 | pre = m[1] 22 | return { 23 | :name => m[2], 24 | :column => pre.size + 1, 25 | :more_info => line } 26 | else 27 | # ignore 28 | end 29 | end 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /Commands/open_gem.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby 9 | 10 | require ENV['TM_SUPPORT_PATH']+"/lib/ui" 11 | require 'rubygems' 12 | 13 | gems = Gem.source_index.latest_specs.collect {|spec| spec.full_name}.sort 14 | 15 | TextMate::UI.request_item(:title => 'open a gem', :items => gems) do |selected_gem| 16 | gem_path = Gem.source_index.specification(selected_gem).full_gem_path 17 | %x{open -a TextMate #{gem_path}} 18 | end 19 | input 20 | none 21 | keyEquivalent 22 | ^@G 23 | name 24 | open_gem 25 | output 26 | showAsTooltip 27 | uuid 28 | B5701FBA-C60D-4216-B5E5-D22829649FB2 29 | 30 | 31 | -------------------------------------------------------------------------------- /Support/lib/easyopen/open_recent.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/config' 3 | 4 | 5 | module EasyOpen 6 | class OpenRecent 7 | include EasyOpen::UI 8 | 9 | def initialize 10 | @project_dir = Config[:project_dir] 11 | @current_file = Config[:current_file] 12 | end 13 | 14 | def run 15 | if @project_dir.nil? 16 | puts "project_dir is nil. please open project" 17 | return 18 | end 19 | open_menu(recent_infos) 20 | end 21 | 22 | def recent_infos 23 | Dir.glob("#{@project_dir}/**/*.*"). 24 | reject { |e| e == @current_file }. 25 | reject { |e| !!e.match(/.*\.log$/) }. 26 | reject { |e| !!e.match(/.*coverage.*$/) }. 27 | reject { |e| !!e.match(/.*tmp\/.*$/) }. 28 | sort_by { |f| File.mtime(f) }. 29 | reverse[0..10]. 30 | map { |e| 31 | { 32 | :file => e, 33 | :display => "#{e.sub(@project_dir, "").sub("/", "")}" 34 | } 35 | } 36 | end 37 | end 38 | end -------------------------------------------------------------------------------- /Preferences/completionCommand.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | completionCommand 7 | scope 8 | source.ruby,source.js 9 | settings 10 | 11 | completionCommand 12 | #!/usr/bin/env ruby 13 | require 'yaml' 14 | 15 | Dir.glob("#{ENV["TM_PROJECT_DIRECTORY"]}/spec/fixtures/*.yml").each { |file_name| 16 | puts "*" 17 | data = YAML.load_file(file_name) 18 | puts data.values.map { |n| n.keys }.flatten.select { |e| e.include?(ENV["TM_CURRENT_WORD"].to_s) } 19 | } 20 | 21 | open("#{ENV["HOME"]}/.easyopen_tmbundle#{ENV["TM_PROJECT_DIRECTORY"]}/def_index.dump", "r") { |io| 22 | def_index = Marshal.load(io) 23 | puts def_index[:name_locationIds].keys.select { |e| e.include?(ENV["TM_CURRENT_WORD"].to_s) } 24 | } 25 | 26 | uuid 27 | 4F261511-9691-422A-8894-088A10B99061 28 | 29 | 30 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Eiji Ienaga 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Support/spec/easyopen/config_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../lib/easyopen/config" 2 | 3 | module EasyOpen 4 | describe Config do 5 | it "should default" do 6 | Config.defaults[:project_dir].should == ENV["TM_PROJECT_DIRECTORY"] 7 | Config.defaults[:current_word].should == ENV['TM_CURRENT_WORD'] 8 | Config.defaults[:save_dir].should == "#{ENV["HOME"]}/.easyopen_tmbundle#{ENV["TM_PROJECT_DIRECTORY"]}" 9 | Config.defaults[:def_index_file].should == "#{ENV["HOME"]}/.easyopen_tmbundle#{ENV["TM_PROJECT_DIRECTORY"]}/def_index.dump" 10 | Config.defaults[:call_stack_file].should == "#{ENV["HOME"]}/.easyopen_tmbundle#{ENV["TM_PROJECT_DIRECTORY"]}/call_stack.dump" 11 | Config.defaults[:current_file].should == ENV['TM_FILEPATH'] 12 | end 13 | 14 | it "should return config value" do 15 | Config[:project_dir].should == ENV["TM_PROJECT_DIRECTORY"] 16 | end 17 | 18 | it "should setup config value" do 19 | Config.setup({:project_dir => "new_dir", :hoge => "hoge"}) 20 | Config[:project_dir].should == "new_dir" 21 | Config[:hoge].should == "hoge" 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/ui.rb: -------------------------------------------------------------------------------- 1 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/ui" 2 | require "#{ENV['TM_SUPPORT_PATH']}/lib/textmate" 3 | 4 | module EasyOpen 5 | module UI 6 | def open_menu_list infos 7 | open_menu(infos, true) 8 | end 9 | 10 | def open_menu(infos, size_one_show = false) 11 | infos = [infos].flatten 12 | if infos.size == 0 13 | puts "not found" 14 | return 15 | end 16 | 17 | if infos.size == 1 && !size_one_show 18 | go_to(infos[0]) 19 | return infos[0] 20 | end 21 | 22 | displays = infos.map { |info| info[:display] } 23 | selected = TextMate::UI.menu(displays) 24 | return unless selected 25 | go_to(infos[selected]) 26 | return infos[selected] 27 | end 28 | 29 | def go_to(options = {}) 30 | resource_identifier = "txmt://open?url=file://#{e_url options[:file]}" 31 | resource_identifier = resource_identifier + "&line=#{options[:line]}" if options[:line] 32 | resource_identifier = resource_identifier + "&column=#{options[:column]}" if options[:column] 33 | `open "#{resource_identifier}"` 34 | end 35 | end 36 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/next_bookmark.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/config' 3 | require File.dirname(__FILE__) + '/repository' 4 | 5 | def next_bookmark 6 | bookmarks = EasyOpen::BookmarkRepository.load 7 | exit_if_bookmarks_is_empty bookmarks 8 | bookmarks = rotate_bookmarks(bookmarks) 9 | exit_if_bookmarks_is_empty bookmarks 10 | include EasyOpen::UI 11 | go_to(bookmarks.last) 12 | EasyOpen::BookmarkRepository.save bookmarks 13 | end 14 | 15 | def exit_if_bookmarks_is_empty bookmarks 16 | if bookmarks.empty? 17 | puts "bookmarks is empty" 18 | exit 19 | end 20 | end 21 | 22 | def rotate_bookmarks(bookmarks, file = ENV['TM_FILEPATH'], line = ENV['TM_LINE_NUMBER']) 23 | while bookmarks.any? 24 | bookmark = bookmarks.shift 25 | if file == bookmark[:file] and line == bookmark[:line] 26 | bookmarks << bookmark 27 | bookmark = bookmarks.shift 28 | end 29 | if File.exist?(bookmark[:file]) 30 | bookmarks << bookmark 31 | if bookmarks.last[:line].to_i > open(bookmarks.last[:file]).read.count("\n") + 1 32 | bookmarks.delete bookmarks.last 33 | else 34 | break 35 | end 36 | end 37 | end 38 | return bookmarks 39 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/open_test_log_file.rb: -------------------------------------------------------------------------------- 1 | def open_log(log_file) 2 | filterd_lines = [] 3 | prev_line = nil 4 | File.open(log_file) do |file| 5 | file.each do |line| 6 | filterd_lines << sub_link(line) 7 | end 8 | end 9 | filterd_lines 10 | end 11 | 12 | def sub_link(line) 13 | regs = [/called from new at (([^:]*):(\d+))/, /^\s*(([^:]*):(\d+):in)/] 14 | regs.each do |reg| 15 | if m = reg.match(line) 16 | url = m[2].gsub(/^\.\//, "#{ENV['TM_PROJECT_DIRECTORY']}/") 17 | url = url.gsub(/^\.\.\//, "/") 18 | line = line.sub(m[1], a_herf(url, m[3], "#{url}:#{m[3]}")) + "
" 19 | end 20 | end 21 | line = line.gsub(/\n/, "
") 22 | line = line.gsub(/^\s/, " ") 23 | end 24 | 25 | def a_herf(url, line = 1, display) 26 | %Q+#{display}+ 27 | end 28 | 29 | # line ="DEPRECATION WARNING: Giving :session_key to SessionStore is deprecated, please use :key instead. (called from new at /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/middleware_stack.rb:72)" 30 | # m = /called from new at ([^:]*):(\d+)/.match(line) 31 | # puts m[1] 32 | # puts m[2] /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/middleware_stack.rb 33 | # 72 34 | -------------------------------------------------------------------------------- /Support/spec/easyopen/create_def_index_file_spec.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | require "pp" 4 | 5 | require File.dirname(__FILE__) + "/../../lib/easyopen/create_def_index_file" 6 | 7 | module EasyOpen 8 | describe "メソッドなどの位置情報のデータ構造について" do 9 | before(:all) do 10 | @parser = Parser.new 11 | @file_name = File.expand_path(File.dirname(__FILE__)) + '/../../fixtures/ruby_code.rb' 12 | # test target method 13 | @parser.parse(@file_name) 14 | @result = @parser.def_index 15 | end 16 | 17 | it "ハッシュ:filesにファイルの位置情報が含まれていること" do 18 | @result[:files].should include(@file_name) 19 | end 20 | 21 | it "ハッシュ:locationsに複数のロケーション情報が含まれていること" do 22 | @result[:locations].should have_at_least(11).items 23 | end 24 | 25 | it "ハッシュ:locationsの一要素にファイルを開くためのロケーション情報(:line, :file_id)が含まれていること" do 26 | @result[:locations][0][:file_id].should eql(0) 27 | end 28 | 29 | it "ハッシュ:name_locationIdsに名前をキーに複数のlocationsのインデックス情報が含まれていること" do 30 | @result[:name_locationIds]["hoge"].should_not eql(nil) 31 | @result[:name_locationIds]["hoge"].size.should eql(3) 32 | end 33 | 34 | it "不正文字列は置換して、正規表現が使えるようにすること" do 35 | lambda { /^/.match(@parser.convert_exp_able("abc\x81あいう\u{20bb7}\xe3")) }.should_not raise_error 36 | end 37 | end 38 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/next_word.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | 3 | word = ENV["TM_CURRENT_WORD"] 4 | filepath = ENV["TM_FILEPATH"] 5 | line_n = ENV["TM_LINE_NUMBER"].to_i 6 | column = ENV["TM_COLUMN_NUMBER"].to_i 7 | 8 | go_to_line_num = nil 9 | go_to_clumn_num = nil 10 | 11 | File.open(filepath) do |file| 12 | file.each_with_index do |line_str, index| 13 | row = index + 1 14 | start_search_column = 0 15 | if line_n <= row 16 | start_search_column = column if line_n == row 17 | if column_index = line_str.index(word, start_search_column) 18 | go_to_line_num = row 19 | go_to_clumn_num = column_index + 1 20 | break 21 | end 22 | end 23 | end 24 | end 25 | 26 | unless go_to_clumn_num 27 | File.open(filepath) do |file| 28 | # puts "from first search" 29 | file.each_with_index do |line_str, index| 30 | row = index + 1 31 | start_search_column = column 32 | if column_index = line_str.index(word, 0) 33 | go_to_line_num = row 34 | go_to_clumn_num = column_index + 1 35 | break 36 | end 37 | end 38 | end 39 | end 40 | 41 | if go_to_clumn_num and go_to_line_num 42 | params = { :file => filepath, 43 | :line => go_to_line_num, 44 | :column => go_to_clumn_num} 45 | include EasyOpen::UI 46 | go_to params 47 | end 48 | -------------------------------------------------------------------------------- /Support/spec/easyopen/open_with_git_status_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../lib/easyopen/config" 2 | require File.dirname(__FILE__) + "/../../lib/easyopen/ui" 3 | require File.dirname(__FILE__) + "/../../lib/easyopen/open_with_git_status" 4 | 5 | 6 | class TestUI 7 | include EasyOpen::UI 8 | end 9 | 10 | module EasyOpen 11 | describe "subject" do 12 | before(:each) do 13 | puts File.dirname(__FILE__) + "/../../lib/easyopen/open_with_git_status" 14 | 15 | @subject = OpenWithGitStatus.new 16 | 17 | @git_status_str =<..." to unstage) 21 | # 22 | # new file: Commands/open_with_git_status.tmCommand 23 | # modified: README 24 | # deleted: Support/spec/easyopen/open_with_git_status.rb 25 | # 26 | # Changes to be committed: 27 | # (use "git reset HEAD ..." to unstage) 28 | # 29 | # renamed: Support/fixtures/ruby_code.rb -> Support/fixtures/renamed_ruby_code.rb 30 | # 31 | # Changed but not updated: 32 | # (use "git add ..." to update what will be committed) 33 | # (use "git checkout -- ..." to discard changes in working directory) 34 | # 35 | # modified: README 36 | # 37 | # Untracked files: 38 | # (use "git add ..." to include in what will be committed) 39 | # 40 | # hoge.txt 41 | GIT 42 | end 43 | it "---- check manual" do 44 | TestUI.new.open_menu( @subject.menu_infos(@git_status_str) ) 45 | end 46 | end 47 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/open_with_git_status.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/config' 3 | require File.dirname(__FILE__) + '/repository' 4 | 5 | module EasyOpen 6 | class OpenWithGitStatus 7 | include EasyOpen::UI 8 | 9 | def open 10 | git_status_str = %x[pushd "#{ENV['TM_PROJECT_DIRECTORY']}"; git status] 11 | menu_infos = menu_infos(git_status_str) 12 | open_menu_list(menu_infos) 13 | end 14 | 15 | def menu_infos(git_status_str) 16 | git_status_str.split("\n").inject([]) do |files, line| 17 | if m = /^#\trenamed:.+\s->\s(.+)$/.match(line) 18 | files << { :file => "#{ENV['TM_PROJECT_DIRECTORY']}/#{m[1]}", 19 | :display => "renamed: #{m[1]}" } 20 | elsif m = /^#\tmodified:\s+(.+)$/.match(line) 21 | files << { :file => "#{ENV['TM_PROJECT_DIRECTORY']}/#{m[1]}", 22 | :display => "modified: #{m[1]}" } 23 | elsif m = /^#\tnew file:\s+(.+)$/.match(line) 24 | files << { :file => "#{ENV['TM_PROJECT_DIRECTORY']}/#{m[1]}", 25 | :display => "new file: #{m[1]}" } 26 | elsif m = /^#\tdeleted:\s+(.+)$/.match(line) 27 | # ignore 28 | elsif m = /^#\t([^()]+)$/.match(line) 29 | files << { :file => "#{ENV['TM_PROJECT_DIRECTORY']}/#{m[1]}", 30 | :display => "untrancked: #{m[1]}" } 31 | end 32 | files 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /Support/spec/easyopen/extension/coffee_token_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../../lib/easyopen/extension/coffee_token" 2 | require File.dirname(__FILE__) + "/spec_helper" 3 | 4 | module EasyOpen::Extension 5 | describe "CoffeeToken#tokenize" do 6 | 7 | def sbjct line 8 | CoffeeToken.new.tokenize(line) 9 | end 10 | 11 | it "token 'hoge: 8" do 12 | line = "hoge: 8" 13 | sbjct(line).should eq_token({ 14 | :name => "hoge", 15 | :column => 1, 16 | :more_info => line}) 17 | 18 | end 19 | 20 | it "token 'award_medals: (first, second, rest...) ->'" do 21 | line = "award_medals: (first, second, rest...) ->" 22 | sbjct(line).should eq_token({ 23 | :name => "award_medals", 24 | :column => 1, 25 | :more_info => line}) 26 | end 27 | 28 | it "token ' award_medals: (first, second, rest...) ->'" do 29 | line = " award_medals: (first, second, rest...) ->" 30 | sbjct(line).should eq_token({ 31 | :name => "award_medals", 32 | :column => " ".size + 1, 33 | :more_info => line}) 34 | end 35 | 36 | it "token 'class Horse extends Animal'" do 37 | line = "class Horse extends Animal" 38 | sbjct(line).should eq_token({ 39 | :name => "Horse", 40 | :column => "class ".size + 1, 41 | :more_info => line}) 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = EasyOpen TextMate Bundle 2 | 3 | Easy Open method, class etc.. support by TextMate 4 | 5 | http://dl.dropbox.com/u/497950/open_def.jpg 6 | 7 | http://dl.dropbox.com/u/497950/open_with_git_status.jpg 8 | 9 | 10 | == Support Language 11 | 12 | - Ruby 13 | - JavaScript 14 | 15 | == Feature List 16 | 17 | - open method in project 18 | - open recent change file in project 19 | - open with git status in project 20 | - open gem 21 | - code completion 22 | 23 | == Installation 24 | 25 | cd ~/Library/Application\ Support/TextMate/Bundles 26 | git clone git://github.com/haru01/easy-open-tmbundle.git EasyOpen.tmbundle 27 | 28 | === if ruby 1.9.x 29 | 30 | git clone git://github.com/kballard/osx-plist.git 31 | cd osx-plist/ext/plist 32 | ruby extconf.rb && make 33 | cp plist.bundle /Applications/TextMate.app/Contents/SharedSupport/Support/lib/osx/ 34 | 35 | see also http://rvm.beginrescueend.com/integration/textmate/ 36 | 37 | 38 | == Usage (open def) 39 | 40 | 0. run 'create_def_index_file' 41 | 1. move cursor to method name 42 | 2. run 'open_def' => move cursor to def 43 | 3. run 'back_open_def' => back cusor (1.) 44 | 45 | == Usage(completion => open_def) 46 | 47 | 1. type def name (part) 48 | 2. type (esc) current cusor => auto completion def name 49 | 3. run 'open_def' => move cursor to def 50 | 51 | == UnInstallation 52 | 53 | rm -rf ~/Library/Application\ Support/TextMate/Bundles/EasyOpen.tmbundle 54 | rm -rf ~/.easyopen_tmbundle 55 | 56 | Copyright (c) 2011 Eiji Ienaga, released under the MIT license 57 | -------------------------------------------------------------------------------- /Support/lib/easyopen/extension/js_token.rb: -------------------------------------------------------------------------------- 1 | module EasyOpen 2 | module Extension 3 | class JsToken 4 | def tokenize(line) 5 | # ex: SSpec.Executor = function 6 | # ex: to = function(matcher) { 7 | if m = /^(\s*([^\s]*))\s*=\s*function\s*(\(.*\)).*\{.*$/.match(line) 8 | name = m[2].split(".").last 9 | pre = m[1].sub(/#{Regexp.escape("#{name}")}$/, "") 10 | 11 | { :name => m[1].split(".").last.strip, 12 | :column => pre.size + 1, 13 | :more_info => line } 14 | 15 | # assert.ok = function ok 16 | elsif m = /^(\s*[^\s]*\s*=\s*function\s*)([^\s]*)\s*\(.*$/.match(line) 17 | { :name => m[2], 18 | :column => m[1].size + 1, 19 | :more_info => line } 20 | 21 | # ex: ' grep: function(filter, iterator, context) {' 22 | elsif m = /^([\s]*)(\S*)\s*:\s*function.*$/.match(line) 23 | 24 | { :name => m[2], 25 | :column => m[1].size + 1, 26 | :more_info => line } 27 | 28 | # ex: 'function makeBlock (f) {' 29 | elsif m = /^(\s*function\s*)([^\s]*)\s*\(.*$/.match(line) 30 | 31 | { :name => m[2], 32 | :column => m[1].size + 1, 33 | :more_info => line } 34 | # ex: ' be_empty: {' 35 | elsif m = /^([\s]*)(.*):\s*\{\s*$/.match(line) 36 | 37 | { :name => m[2], 38 | :column => m[1].size + 1, 39 | :more_info => line } 40 | end 41 | end 42 | end 43 | end 44 | end 45 | 46 | -------------------------------------------------------------------------------- /Support/lib/easyopen/open_def.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/ui' 2 | require File.dirname(__FILE__) + '/config' 3 | require File.dirname(__FILE__) + '/repository' 4 | 5 | module EasyOpen 6 | class OpenDef 7 | include EasyOpen::UI 8 | 9 | def initialize(config = {}) 10 | Config.setup(config) 11 | @current_location = { :file => ENV["TM_FILEPATH"], 12 | :line => ENV["TM_LINE_NUMBER"], 13 | :column => ENV["TM_COLUMN_NUMBER"] } 14 | end 15 | 16 | def run 17 | if open_menu(menu_infos) 18 | push_call_stack 19 | end 20 | end 21 | 22 | def push_call_stack 23 | call_stack = CallStackRepository.load 24 | call_stack.push @current_location 25 | CallStackRepository.save call_stack 26 | end 27 | 28 | def menu_infos 29 | def_index = DefIndexRepository.load 30 | locationids = def_index[:name_locationIds][Config[:current_word]] 31 | return [] unless locationids 32 | return locationids.map do |id| 33 | file_id = def_index[:locations][id][:file_id] 34 | filepath = def_index[:files][file_id] 35 | display = "#{filepath.gsub("#{Config[:project_dir]}/", '')}"+ 36 | ":#{def_index[:locations][id][:line]}" + 37 | ": #{def_index[:locations][id][:more_info]}" 38 | { 39 | :file => filepath, 40 | :line => def_index[:locations][id][:line], 41 | :column => def_index[:locations][id][:column], 42 | :display => display 43 | } 44 | end 45 | end 46 | end 47 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/extension/rb_token.rb: -------------------------------------------------------------------------------- 1 | module EasyOpen 2 | module Extension 3 | class RbToken 4 | def tokenize(line) 5 | # ruby class def module 6 | if m = /(^\s*(class|def|module)\s*)([\w:\.]*)(.*)$/.match(line) 7 | if mm = m[3].match(/([^\.]+)\.([^\.]+)/) # static method 8 | name = mm[2] 9 | return { :column => (m[1] + mm[1]).size + 2, 10 | :name => name, 11 | :more_info => line } 12 | else 13 | names = m[3].split("::") 14 | pre_first_str = m[1] 15 | colum = pre_first_str.size + 1 16 | 17 | return names.map do |name| 18 | current = colum 19 | colum += name.size + "::".size 20 | { :name => name, 21 | :column => current, 22 | :more_info => line } 23 | end.last 24 | end 25 | elsif m = /^(\s*)([_A-Z0-9]+)\s*=\s*.*$/.match(line) 26 | return { 27 | :column => (m[1].size) + 1, 28 | :name => m[2], 29 | :more_info => line } 30 | end 31 | #rails 32 | if m =/(^\s*(alias_attribute|belongs_to|has_many)[\s:]*)([\w]*)(.*)$/.match(line) 33 | return { 34 | :column => (m[1].size) + 1, 35 | :name => m[3], 36 | :more_info => line } 37 | end 38 | # rspec 'let(:parent_group_metadata)' 39 | if m =/(^\s*let\(:)(\w*)\).*$/.match(line) 40 | return { 41 | :column => (m[1].size) + 1, 42 | :name => m[2], 43 | :more_info => line } 44 | end 45 | end 46 | end 47 | end 48 | end -------------------------------------------------------------------------------- /Support/spec/easyopen/ui_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../lib/easyopen/ui" 2 | 3 | module EasyOpen::UI 4 | class TestTarget 5 | include EasyOpen::UI 6 | end 7 | 8 | describe "EasyOpen::UI open_menu, " do 9 | before(:each) do 10 | @target = TestTarget.new 11 | end 12 | 13 | describe "when infos size is zero" do 14 | it "should show 'not found' message" do 15 | @target.should_receive(:puts).with("not found") 16 | @target.open_menu([]).should be_nil 17 | end 18 | end 19 | 20 | describe "when infos size is one" do 21 | before(:each) do 22 | @dummy = { 23 | :file => "dummy_file", 24 | :line => "dummy_line", 25 | :column => "dummy_column", 26 | :display => "dummy_display" 27 | } 28 | @infos = [@dummy] 29 | end 30 | 31 | it "should open file" do 32 | @target.should_receive(:go_to).with(@dummy) 33 | @target.open_menu(@infos).should == @dummy 34 | end 35 | end 36 | 37 | describe "when infos size is not(zero and one)" do 38 | before(:each) do 39 | @dummy1 = { 40 | :file => "dummy_file1", 41 | :line => "dummy_line1", 42 | :column => "dummy_column1", 43 | :display => "dummy_display1" 44 | } 45 | @dummy2 = { 46 | :file => "dummy_file2", 47 | :line => "dummy_line2", 48 | :column => "dummy_column2", 49 | :display => "dummy_display2" 50 | } 51 | @infos = [@dummy1, @dummy2] 52 | end 53 | 54 | it "should open menu-> open file" do 55 | TextMate::UI.should_receive(:menu).with(["dummy_display1", "dummy_display2"]).and_return(1) 56 | @target.should_receive(:go_to).with(@dummy2) 57 | @target.open_menu(@infos).should == @dummy2 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mainMenu 6 | 7 | items 8 | 9 | 301C8785-9A97-4E24-A313-2AC89FF7403F 10 | F79EF9CA-6D4D-45D9-807C-F7183BE855E6 11 | 1E135F00-FE33-4BDE-AA2C-31A6C3B3943D 12 | ------------------------------------ 13 | E065B750-38D6-45BC-A3DE-C6ABCD29225A 14 | EE021D5D-1400-4629-A83F-AC10D68A07A5 15 | ------------------------------------ 16 | 71C114BE-105F-4BF0-AE8E-050E919711F5 17 | 60415A72-E2EA-42D1-8A71-FEC60644BECD 18 | 71B53E07-8F2B-4074-8CAF-B2B454AF09F7 19 | 5C1F81F7-EEDC-4B6B-AF28-8CC77DD536A4 20 | ------------------------------------ 21 | 5C05808F-1680-4237-9026-A2EFD0CD263F 22 | BF2A3851-1F8C-4E21-8CCB-8905E94CE577 23 | ------------------------------------ 24 | B5701FBA-C60D-4216-B5E5-D22829649FB2 25 | 96781F29-CEF5-4048-A2DF-FD169045C853 26 | 23D19409-E767-46E8-ACA6-ED193D7EF9EA 27 | 28 | submenus 29 | 30 | 31 | name 32 | EasyOpen 33 | ordering 34 | 35 | E065B750-38D6-45BC-A3DE-C6ABCD29225A 36 | EE021D5D-1400-4629-A83F-AC10D68A07A5 37 | 4F261511-9691-422A-8894-088A10B99061 38 | 301C8785-9A97-4E24-A313-2AC89FF7403F 39 | F79EF9CA-6D4D-45D9-807C-F7183BE855E6 40 | 1E135F00-FE33-4BDE-AA2C-31A6C3B3943D 41 | 5C05808F-1680-4237-9026-A2EFD0CD263F 42 | B5701FBA-C60D-4216-B5E5-D22829649FB2 43 | 71C114BE-105F-4BF0-AE8E-050E919711F5 44 | 71B53E07-8F2B-4074-8CAF-B2B454AF09F7 45 | 60415A72-E2EA-42D1-8A71-FEC60644BECD 46 | 96781F29-CEF5-4048-A2DF-FD169045C853 47 | 23D19409-E767-46E8-ACA6-ED193D7EF9EA 48 | BF2A3851-1F8C-4E21-8CCB-8905E94CE577 49 | 50 | uuid 51 | A586D61A-96C6-491D-9BD9-E2C6AB7F26FF 52 | 53 | 54 | -------------------------------------------------------------------------------- /Support/lib/easyopen/repository.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require File.dirname(__FILE__) + '/config' 3 | require "yaml" 4 | 5 | 6 | module EasyOpen 7 | class CallStackRepository 8 | class << self 9 | def init 10 | open("#{Config[:call_stack_file]}", "w") { |mio| 11 | Marshal.dump([], mio) 12 | } 13 | end 14 | 15 | def save(call_stack) 16 | FileUtils::mkdir_p("#{Config[:save_dir]}") 17 | open("#{Config[:call_stack_file]}", "w") { |mio| 18 | Marshal.dump(call_stack, mio) 19 | } 20 | end 21 | 22 | def load 23 | begin 24 | open("#{Config[:call_stack_file]}", "r") { |io| 25 | Marshal.load(io) 26 | } 27 | rescue 28 | puts "not found call_stack file." 29 | exit 1 30 | end 31 | end 32 | end 33 | end 34 | 35 | class DefIndexRepository 36 | class << self 37 | def save(def_index) 38 | FileUtils::mkdir_p("#{Config[:save_dir]}") 39 | open("#{Config[:def_index_file]}", "w") { |mio| 40 | Marshal.dump(def_index, mio) 41 | } 42 | end 43 | 44 | def load(path=nil) 45 | path ||= Config[:def_index_file] 46 | oldPath = nil 47 | while not File.exists? path and path != oldPath do 48 | oldPath = path 49 | path = path.reverse().sub(%r!/[^/]+(?=/)!,'').reverse() 50 | end 51 | 52 | begin 53 | def_index = nil 54 | open("#{path}", "r") { |io| 55 | def_index = Marshal.load(io) 56 | } 57 | return def_index 58 | rescue 59 | puts "not found def_index file. please create_def_index_file before open_def" 60 | exit 1 61 | end 62 | end 63 | end 64 | end 65 | 66 | class BookmarkRepository 67 | class << self 68 | def save(bookmarks) 69 | FileUtils::mkdir_p("#{Config[:save_dir]}") 70 | bookmark_file = EasyOpen::Config[:bookmark_file] 71 | File.open(bookmark_file, "w") {|out| 72 | YAML.dump(bookmarks, out) 73 | } 74 | end 75 | 76 | def load 77 | begin 78 | bookmark_file = EasyOpen::Config[:bookmark_file] 79 | bookmarks = File.open(bookmark_file) {|ym| 80 | YAML.load(ym) 81 | } 82 | return bookmarks 83 | rescue 84 | puts "not found bookmarks. please add bookmark" 85 | exit 86 | end 87 | end 88 | end 89 | end 90 | end -------------------------------------------------------------------------------- /Support/lib/easyopen/create_def_index_file.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require File.dirname(__FILE__) + '/config' 3 | require File.dirname(__FILE__) + '/repository' 4 | require File.dirname(__FILE__) + '/extension/user_conf' 5 | 6 | module EasyOpen 7 | class CreateDefIndexFile 8 | def initialize(config = {}) 9 | Config.setup(config) 10 | end 11 | 12 | def run 13 | if Config[:project_dir].nil? 14 | puts "TM_PROJECT_DIRECTORY is nil. can't create def_index_file" 15 | exit 16 | end 17 | parser = Parser.new 18 | extnames = EasyOpen::Extension::UserConf.tokens.keys.join(",") 19 | Dir.glob("#{Config[:project_dir]}/**/*.{#{extnames}}").each do |file_name| 20 | parser.parse(file_name) 21 | end 22 | DefIndexRepository.save parser.def_index 23 | CallStackRepository.init 24 | puts "created def index file, and cleaned call stack file" 25 | puts "save_dir=>#{Config[:save_dir]}" 26 | end 27 | end 28 | 29 | class Parser 30 | def initialize(tokens = Extension::UserConf.tokens) 31 | @locations = [] 32 | @files = [] 33 | @name_locationIds = {} 34 | @tokens = tokens 35 | end 36 | 37 | def parse(file_name) 38 | File.open(file_name) do |file| 39 | file.each_with_index do |line, index| 40 | token = @tokens[File.extname(file_name).sub(".", "")] 41 | unless token 42 | puts "not support extname=>#{File.extname(file_name)}" 43 | return 44 | end 45 | 46 | line = convert_exp_able(line) 47 | if t = token.tokenize(line) 48 | @files << file_name unless @files.include?(file_name) 49 | @name_locationIds[t[:name]] ||= [] 50 | @name_locationIds[t[:name]] << @locations.size 51 | @locations << 52 | { 53 | :file_id => @files.index(file_name), 54 | :line => index + 1, 55 | :column => t[:column], 56 | :more_info => t[:more_info], 57 | } 58 | end 59 | end 60 | end 61 | end 62 | 63 | def convert_exp_able(line) 64 | begin 65 | /^/.match(line) 66 | rescue Exception => e 67 | return line.encode("UTF-16BE", :invalid => :replace, :undef => :replace, :replace => '?').encode("UTF-8") 68 | end 69 | line 70 | end 71 | 72 | def def_index 73 | { 74 | :name_locationIds => @name_locationIds, 75 | :files => @files, 76 | :locations => @locations 77 | } 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /Support/spec/easyopen/extension/js_token_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../../lib/easyopen/extension/js_token" 2 | require File.dirname(__FILE__) + "/spec_helper" 3 | 4 | 5 | module EasyOpen::Extension 6 | describe "JsToken#tokeninze" do 7 | def sbjct line 8 | JsToken.new.tokenize(line) 9 | end 10 | 11 | it "tokinize ' color : function(string, color) {'" do 12 | line = ' color : function(string, color) {' 13 | sbjct(line).should 14 | eq_token({:name => "color", 15 | :column => 4, 16 | :more_info => line}) 17 | end 18 | 19 | it "tokenize ' be_empty: {'" do 20 | line = ' be_empty: {' 21 | sbjct(line).should 22 | eq_token({:name => "be_empty", 23 | :column => " ".size + 1, 24 | :more_info => line}) 25 | end 26 | 27 | it "tokenize ' function define(self, name, fn) {'" do 28 | line = ' function define(self, name, fn) {' 29 | sbjct(line).should 30 | eq_token({:name => "define", 31 | :column => " function ".size + 1, 32 | :more_info => line}) 33 | end 34 | 35 | it "tokenize 'function makeBlock (f) {'" do 36 | line = 'function makeBlock (f) {' 37 | sbjct(line).should 38 | eq_token({:name => "makeBlock", 39 | :column => "function ".size + 1, 40 | :more_info => line}) 41 | end 42 | 43 | it "tokeninze ' JSSpec.Executor = function(target, onSuccess, onException) {'" do 44 | line = ' JSSpec.Executor = function(target, onSuccess, onException) {' 45 | sbjct(line).should 46 | eq_token({:name => "Executor", 47 | :column => " JSSpec.".size + 1, 48 | :more_info => line}) 49 | end 50 | 51 | it "tokeninze ' to = function(matcher) {'" do 52 | line = ' to = function(matcher) {' 53 | sbjct(line).should 54 | eq_token({:name => "to", 55 | :column => " ".size + 1, 56 | :more_info => line}) 57 | end 58 | 59 | it "tokenize ' grep: function(filter, iterator, context) {'" do 60 | line = ' grep: function(filter, iterator, context) {' 61 | sbjct(line).should 62 | eq_token({:name => "grep", 63 | :column => " ".size + 1, 64 | :more_info => line}) 65 | end 66 | 67 | it "tokenize 'assert.ok = function ok(value, message) {'" do 68 | line = 'assert.ok = function ok(value, message) {' 69 | sbjct(line).should 70 | eq_token({:name => "ok", 71 | :column => "assert.ok = function ".size + 1, 72 | :more_info => line}) 73 | 74 | end 75 | end 76 | end -------------------------------------------------------------------------------- /Support/spec/easyopen/extension/java_token_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../../lib/easyopen/extension/java_token" 2 | 3 | module EasyOpen::Extension 4 | describe JavaToken do 5 | before(:each) do 6 | @token = JavaToken.new 7 | end 8 | 9 | it "should token ' public void boot(final String[] args) throws Exception'" do 10 | line = " public void boot(final String[] args) throws Exception" 11 | result = @token.tokenize(line) 12 | result[:name].should == "boot" 13 | result[:column].should == " public void ".size + 1 14 | result[:more_info].should == line 15 | end 16 | 17 | it "should ignore token ' return getDeploymentModelFactory().newEndpoint(targetBean);'" do 18 | line = ' return getDeploymentModelFactory().newEndpoint(targetBean);' 19 | result = @token.tokenize(line) 20 | result.should be_nil 21 | end 22 | 23 | it "should ignore token ' getVersionTag(); '" do 24 | line = ' getVersionTag(); ' 25 | result = @token.tokenize(line) 26 | result.should be_nil 27 | end 28 | 29 | it "should token ' public String getVersionTag() '" do 30 | line = ' public String getVersionTag() ' 31 | result = @token.tokenize(line) 32 | result[:name].should == "getVersionTag" 33 | result[:column].should == " public String ".size + 1 34 | result[:more_info].should == line 35 | end 36 | 37 | it "should token 'public class ServiceController extends JBossNotificationBroadcasterSupport'" do 38 | line = 'public class ServiceController extends JBossNotificationBroadcasterSupport' 39 | result = @token.tokenize(line) 40 | result[:column].should == "public class ".size + 1 41 | result[:name].should == "ServiceController" 42 | result[:more_info].should == line 43 | end 44 | 45 | it 'public @interface EndpointFeature {' do 46 | line = 'public @interface EndpointFeature {' 47 | result = @token.tokenize(line) 48 | result[:column].should == "public @interface ".size + 1 49 | result[:name].should == "EndpointFeature" 50 | result[:more_info].should == line 51 | end 52 | 53 | it "public interface Constants" do 54 | line = 'public interface Constants' 55 | result = @token.tokenize(line) 56 | result[:column].should == "public interface ".size + 1 57 | result[:name].should == "Constants" 58 | result[:more_info].should == line 59 | end 60 | 61 | it "should token 'public interface Constants {'" do 62 | line = 'public interface Constants {' 63 | result = @token.tokenize(line) 64 | result[:column].should == "public interface ".size + 1 65 | result[:name].should == "Constants" 66 | result[:more_info].should == line 67 | end 68 | 69 | end 70 | end -------------------------------------------------------------------------------- /Support/spec/easyopen/extension/rb_token_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../../lib/easyopen/extension/rb_token" 2 | require File.dirname(__FILE__) + "/spec_helper" 3 | 4 | module EasyOpen::Extension 5 | describe "RbToken#tokeninze" do 6 | 7 | def sbjct input_line 8 | RbToken.new.tokenize(input_line) 9 | end 10 | 11 | it "tokeinze ' HOGE2 = 2'" do 12 | line = ' HOGE_2 = 1' 13 | sbjct(line).should eq_token({ 14 | :name => "HOGE_2", 15 | :column => " ".size + 1, 16 | :more_info => line}) 17 | 18 | end 19 | 20 | it "tokeinze ' has_many :name'" do 21 | line = ' has_many :name' 22 | sbjct(line).should eq_token({ 23 | :name => "name", 24 | :column => " has_many :".size + 1, 25 | :more_info => line}) 26 | end 27 | 28 | it "tokeinze ' belongs_to :name'" do 29 | line = ' belongs_to :name' 30 | sbjct(line).should eq_token({ 31 | :name => "name", 32 | :column => " belongs_to :".size + 1, 33 | :more_info => line}) 34 | end 35 | 36 | it "tokeinze ' alias_attribute :alias_name, :collumn_name'" do 37 | line = ' alias_attribute :alias_name, :collumn_name' 38 | sbjct(line).should eq_token({ 39 | :name => "alias_name", 40 | :column => " alias_attribute :".size + 1, 41 | :more_info => line}) 42 | end 43 | 44 | it "tokenize ' def Parse.html_to_text s'" do 45 | line = ' def Parse.html_to_text s' 46 | sbjct(line).should eq_token({ 47 | :name => "html_to_text", 48 | :column => " def Parse.".size + 1, 49 | :more_info => line}) 50 | end 51 | 52 | it "tokenize ' def self.hogefuga(hoge, foo)'" do 53 | line = ' def self.hogefuga(hoge, foo)' 54 | sbjct(line).should eq_token({ 55 | :name => "hogefuga", 56 | :column => " def self.".size + 1, 57 | :more_info => line}) 58 | end 59 | 60 | it "tokenize ' def open(hoge, foo)'" do 61 | line = " def open(hoge, foo)" 62 | sbjct(line).should eq_token({ 63 | :name => "open", 64 | :column => " def ".size + 1, 65 | :more_info => line}) 66 | end 67 | 68 | it "tokenize 'module Hoge::Hogeogeoge'" do 69 | line = 'module Hoge::Hogeogeoge' 70 | sbjct(line).should eq_token({ 71 | :name => "Hogeogeoge", 72 | :column => "module Hoge::".size + 1, 73 | :more_info => line}) 74 | end 75 | 76 | it "tokenize 'let(:parent_group_metadata)'" do 77 | line = ' let(:parent_group_line_number) { parent_group_metadata[:example_group][:line_number] }' 78 | sbjct(line).should eq_token({ 79 | :name => "parent_group_line_number", 80 | :column => ' let(:)'.size, 81 | :more_info => line}) 82 | end 83 | 84 | it "return nil if not include def module class" do 85 | line = ' ' 86 | sbjct(line).should be_nil 87 | end 88 | 89 | it "return nil if comment def module class" do 90 | line = ' # def hoge' 91 | sbjct(line).should be_nil 92 | end 93 | end 94 | end -------------------------------------------------------------------------------- /Support/spec/easyopen/next_bookmark_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark" 2 | 3 | 4 | describe "rotate_bookmarks, when one file" do 5 | before(:each) do 6 | @dup_file = File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb" 7 | @dup_line = "1" 8 | @bookmarks = 9 | [ {:file => @dup_file, 10 | :line => @dup_line}, 11 | ] 12 | end 13 | 14 | it "should select 1" do 15 | expects = rotate_bookmarks(@bookmarks) 16 | expects.should have(1).items 17 | expects[0][:line].should == "1" 18 | end 19 | 20 | it "should select 1, when dup file and line" do 21 | expects = rotate_bookmarks(@bookmarks, @dup_file, @dup_line) 22 | expects.should have(1).items 23 | expects[0][:line].should == "1" 24 | end 25 | end 26 | 27 | describe "rotate_bookmarks, when valid bookmarks" do 28 | before(:each) do 29 | @dup_file = File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb" 30 | @dup_line = "1" 31 | @bookmarks = 32 | [ {:file => @dup_file, 33 | :line => @dup_line}, 34 | {:file => File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb", 35 | :line => "2"}, 36 | {:file => File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb", 37 | :line => "3"} 38 | ] 39 | end 40 | 41 | it "should one shift, when not match current file & line" do 42 | expects = rotate_bookmarks(@bookmarks) 43 | expects.last[:line].should == "1" 44 | end 45 | 46 | # Why: I want to move from current file & line to other 47 | it "should two shift, when match current file & line" do 48 | expects = rotate_bookmarks(@bookmarks, @dup_file, @dup_line) 49 | expects.last[:line].should == "2" 50 | end 51 | end 52 | 53 | describe "rotate_bookmarks, when not found line" do 54 | before(:each) do 55 | @bookmarks = 56 | [ 57 | {:file => File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb", 58 | :line => "999999"}, # not found 59 | ] 60 | end 61 | # Why: I want to remove invalid bookmark 62 | it "should remove" do 63 | expects = rotate_bookmarks(@bookmarks) 64 | expects.should have(0).items 65 | end 66 | end 67 | 68 | describe "rotate_bookmarks, when not found file" do 69 | before(:each) do 70 | @bookmarks = 71 | [ 72 | {:file => "notfound", 73 | :line => "1"}, 74 | {:file => "notfound", 75 | :line => "2"}, 76 | {:file => "notfound", 77 | :line => "3"}, 78 | {:file => File.dirname(__FILE__) + "/../../lib/easyopen/next_bookmark.rb", 79 | :line => "4"}, 80 | ] 81 | end 82 | # Why: I want to remove invalid bookmark 83 | it "should remove" do 84 | expects = rotate_bookmarks(@bookmarks) 85 | expects[0][:line].should == "4" 86 | expects.should have(1).items 87 | end 88 | end 89 | 90 | describe "rotate_bookmarks, when not found file ALL!" do 91 | before(:each) do 92 | @bookmarks = 93 | [ 94 | {:file => "notfound", 95 | :line => "1"}, 96 | {:file => "notfound", 97 | :line => "2"}, 98 | {:file => "notfound", 99 | :line => "3"}, 100 | ] 101 | end 102 | # Why: I want to remove invalid bookmark 103 | it "should remove" do 104 | expects = rotate_bookmarks(@bookmarks) 105 | expects.should have(:no).items 106 | end 107 | end 108 | 109 | --------------------------------------------------------------------------------