├── Support ├── GriffonMate │ ├── clean.rb │ ├── test_app.rb │ ├── help.rb │ ├── list_plugins.rb │ ├── war.rb │ ├── run_app.rb │ ├── run_applet.rb │ ├── run_webstart.rb │ ├── run_griffon_task.rb │ ├── install_plugin.rb │ ├── focussed_test.rb │ ├── create.rb │ ├── create_mvc.rb │ └── GriffonMate.rb ├── bin │ ├── griffonmate_bootstrap.sh │ └── go_to_alternate_file.rb └── lib │ ├── misc.rb │ ├── buffer.rb │ ├── TextMate.rb │ └── GriffonPath.rb ├── Snippets ├── @Bindable.tmSnippet ├── def action.tmSnippet ├── button.tmSnippet └── action.tmSnippet ├── Commands ├── Create MVC.tmCommand ├── Help.tmCommand ├── Clean.tmCommand ├── ListPlugins.tmCommand ├── Run App.tmCommand ├── Test App.tmCommand ├── Run Applet.tmCommand ├── Run Webstart.tmCommand ├── Install Plugin ___.tmCommand └── Run Griffon Task ___.tmCommand ├── README.mdown └── info.plist /Support/GriffonMate/clean.rb: -------------------------------------------------------------------------------- 1 | GriffonCommand.new("clean").run -------------------------------------------------------------------------------- /Support/GriffonMate/test_app.rb: -------------------------------------------------------------------------------- 1 | GriffonCommand.new("test-app").run -------------------------------------------------------------------------------- /Support/GriffonMate/help.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("help") 2 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/list_plugins.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("list-plugins") 2 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/war.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("war") 2 | gc.colorisations['green'] << /Created WAR (.)+/ 3 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/run_app.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("run-app") 2 | gc.colorisations['red'] << /Server failed to start/ 3 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/run_applet.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("run-applet") 2 | gc.colorisations['red'] << /Server failed to start/ 3 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/run_webstart.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("run-webstart") 2 | gc.colorisations['red'] << /Server failed to start/ 3 | gc.run -------------------------------------------------------------------------------- /Support/GriffonMate/run_griffon_task.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("") do |default| 2 | TextMate::UI.request_string( 3 | :title => "Run def Griffon(args) 4 | 5 | end 6 | Task", 7 | :prompt => "Enter a command to pass to griffon", 8 | :default => default 9 | ) 10 | end 11 | 12 | gc.run -------------------------------------------------------------------------------- /Support/bin/griffonmate_bootstrap.sh: -------------------------------------------------------------------------------- 1 | source "$TM_SUPPORT_PATH/lib/bash_init.sh" 2 | export RUBYLIB="$TM_BUNDLE_SUPPORT/GriffonMate:$TM_SUPPORT_PATH/lib/${RUBYLIB:+:$RUBYLIB}" 3 | 4 | export TM_GRIFFON=`which $TM_GRIFFON` 5 | script="$1" 6 | shift 7 | 8 | ruby18 -r GriffonMate -r ui -- "$TM_BUNDLE_SUPPORT/GriffonMate/$script.rb" $@ 9 | -------------------------------------------------------------------------------- /Support/GriffonMate/install_plugin.rb: -------------------------------------------------------------------------------- 1 | gc = GriffonCommand.new("install-plugin") do |default| 2 | TextMate::UI.request_string( 3 | :title => "Install Griffon Plug-in", 4 | :prompt => "Enter the Plug-in name", 5 | :default => "" 6 | ) 7 | end 8 | 9 | gc.colorisations['green'] << /Plugin (.)+ installed/ 10 | gc.colorisations['red'] << /Plugin (.)+ was not found in repository/ 11 | gc.run -------------------------------------------------------------------------------- /Snippets/@Bindable.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | @Bindable 7 | 8 | name 9 | @Bindable 10 | scope 11 | source.groovy 12 | tabTrigger 13 | @b 14 | uuid 15 | 51BEF2CA-6260-44B3-8484-AF30A93A0496 16 | 17 | 18 | -------------------------------------------------------------------------------- /Snippets/def action.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | def ${1:action} = { evt = null -> 7 | $2 8 | } 9 | 10 | name 11 | def action 12 | scope 13 | source.groovy 14 | tabTrigger 15 | defact 16 | uuid 17 | 5ECE28ED-463A-4175-8931-E1D403B30981 18 | 19 | 20 | -------------------------------------------------------------------------------- /Snippets/button.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | button id: '${1:id}Button', text: ${2:text/bind {\}}, action: ${3:name}Action 7 | 8 | name 9 | button 10 | scope 11 | source.groovy 12 | tabTrigger 13 | button 14 | uuid 15 | A7FB47AB-8BFF-43E5-8CEC-1ADDC9A138DE 16 | 17 | 18 | -------------------------------------------------------------------------------- /Support/GriffonMate/focussed_test.rb: -------------------------------------------------------------------------------- 1 | require "#{ENV['TM_SUPPORT_PATH']}/lib/exit_codes" 2 | 3 | potential_phases = ["unit", "integration", "functional", "other"] 4 | 5 | path = ARGV[0] 6 | test = File.basename(path) 7 | test =~ /^(.+)\.(.+)$/ 8 | clazz = $1 9 | extension = $2 10 | if extension == "groovy" or extension == "java" 11 | phases = [] 12 | potential_phases.each do |potential_phase| 13 | phases << "--#{potential_phase}" if path =~ /test\/#{potential_phase}\// 14 | end 15 | clazz.sub! /Tests$/, "" 16 | GrailsCommand.new("test-app #{clazz} #{phases.join(' ')}").run 17 | else 18 | TextMate.exit_show_tool_tip "#{test} is not a test case" 19 | end 20 | -------------------------------------------------------------------------------- /Support/GriffonMate/create.rb: -------------------------------------------------------------------------------- 1 | class GriffonCreateCommand < GriffonCommand 2 | 3 | def initialize() 4 | super "create" do |default| 5 | TextMate::UI.request_string( 6 | :title => "Create Artefact", 7 | :prompt => "Enter the kind of artefact (e.g. domain-class)", 8 | :default => "" 9 | ) 10 | end 11 | self.colorisations['green'] << /Created (.)+ for (\w)+/ 12 | end 13 | 14 | def construct_command(task, option) 15 | if option.nil? or option.empty? 16 | return nil 17 | else 18 | options = Shellwords.shellwords(option) 19 | ["#{task}-#{options.shift}"] + options 20 | end 21 | end 22 | 23 | end 24 | 25 | GriffonCreateCommand.new.run -------------------------------------------------------------------------------- /Support/GriffonMate/create_mvc.rb: -------------------------------------------------------------------------------- 1 | class GriffonCreateMVCCommand < GriffonCommand 2 | 3 | def initialize() 4 | super "create-mvc" do |default| 5 | TextMate::UI.request_string( 6 | :title => "Create MVC Artefacts", 7 | :prompt => "Enter the name of MVC artefact (e.g. File)", 8 | :default => "" 9 | ) 10 | end 11 | self.colorisations['green'] << /Created (.)+ for (\w)+/ 12 | end 13 | 14 | def construct_command(task, option) 15 | if option.nil? or option.empty? 16 | return nil 17 | else 18 | options = Shellwords.shellwords(option) 19 | ["#{task} #{options.shift}"] + options 20 | end 21 | end 22 | 23 | end 24 | 25 | GriffonCreateMVCCommand.new.run -------------------------------------------------------------------------------- /Snippets/action.tmSnippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | content 6 | action(id: '${1:name}Action', 7 | name: '${2:name}', 8 | closure: controller.&${3:closure action}, 9 | mnemonic: '${4:mnemonic}', 10 | accelerator: '${5:F1}', 11 | shortDescription: '${6:shortDescription}' 12 | ) 13 | 14 | name 15 | action 16 | scope 17 | source.groovy 18 | tabTrigger 19 | act 20 | uuid 21 | 5B3B1235-FB16-46AF-AB5D-4559C56E6C7A 22 | 23 | 24 | -------------------------------------------------------------------------------- /Support/bin/go_to_alternate_file.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Copyright: 4 | # (c) 2006 syncPEOPLE, LLC. 5 | # Visit us at http://syncpeople.com/ 6 | # Author: Duane Johnson (duane.johnson@gmail.com) 7 | # Description: 8 | # Makes an intelligent decision on which file to go to based on the current line or current context. 9 | 10 | require 'GriffonPath' 11 | require 'TextMate' 12 | 13 | choice = ARGV.shift 14 | current_file = GriffonPath.new 15 | 16 | if Griffon_path = current_file.Griffon_path_for(choice.to_sym) 17 | if Griffon_path.exists? 18 | TextMate.open Griffon_path 19 | else 20 | if TextMate.message_ok_cancel "#{Griffon_path.basename} does not exist", "Would you like to create it?" 21 | Griffon_path.touch 22 | TextMate.open Griffon_path 23 | else 24 | TextMate.exit_discard 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /Commands/Create MVC.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh create_mvc 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Create MVC 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | variable 28 | TM_GRIFFON 29 | 30 | 31 | scope 32 | source.groovy 33 | uuid 34 | 2B083A1E-9890-41E7-8725-A8964B71E081 35 | 36 | 37 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | You can install this bundle in TextMate by opening the preferences and going to the bundles tab. After installation it will be automatically updated for you. 4 | 5 | # General 6 | 7 | * [Bundle Styleguide](http://kb.textmate.org/bundle_styleguide) — _before you make changes_ 8 | * [Commit Styleguide](http://kb.textmate.org/commit_styleguide) — _before you send a pull request_ 9 | * [Writing Bug Reports](http://kb.textmate.org/writing_bug_reports) — _before you report an issue_ 10 | 11 | # License 12 | 13 | If not otherwise specified (see below), files in this repository fall under the following license: 14 | 15 | Permission to copy, use, modify, sell and distribute this 16 | software is granted. This software is provided "as is" without 17 | express or implied warranty, and with no claim as to its 18 | suitability for any purpose. 19 | 20 | An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”. -------------------------------------------------------------------------------- /Commands/Help.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh help 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Help 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml 35 | uuid 36 | D6518BFC-9934-4819-907F-313EE5190DB6 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/Clean.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh clean 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Clean 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 35 | uuid 36 | DA1F072D-6D6A-4AD0-98DA-09D89CB848D0 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/ListPlugins.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh list_plugins 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | List Plugins 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml 35 | uuid 36 | 207BBD6B-1BC7-4D9E-8438-3C103C6812A5 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/Run App.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh run_app 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Run App 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 35 | uuid 36 | FBA08F8E-3C51-4AB2-B417-F88D2ECB5843 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/Test App.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh test_app 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Test App 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 35 | uuid 36 | A2B2C702-E63A-4605-A1AC-38188D17B3BA 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/Run Applet.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh run_applet 9 | 10 | input 11 | none 12 | keyEquivalent 13 | ^@G 14 | name 15 | Run Applet 16 | output 17 | showAsHTML 18 | requiredCommands 19 | 20 | 21 | command 22 | griffon 23 | locations 24 | 25 | /opt/local/bin/griffon 26 | /usr/local/bin/griffon 27 | 28 | moreInfoURL 29 | http://griffon-framework.org 30 | variable 31 | TM_GRIFFON 32 | 33 | 34 | scope 35 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 36 | uuid 37 | 164FF85D-27CE-4CC6-BF6E-1C925D1DFF71 38 | 39 | 40 | -------------------------------------------------------------------------------- /Commands/Run Webstart.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh run_webstart 9 | 10 | input 11 | none 12 | keyEquivalent 13 | ^@G 14 | name 15 | Run Webstart 16 | output 17 | showAsHTML 18 | requiredCommands 19 | 20 | 21 | command 22 | griffon 23 | locations 24 | 25 | /opt/local/bin/griffon 26 | /usr/local/bin/griffon 27 | 28 | moreInfoURL 29 | http://griffon-framework.org 30 | variable 31 | TM_GRIFFON 32 | 33 | 34 | scope 35 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 36 | uuid 37 | 35A303C5-9064-41F5-A092-EF5CD83DEF81 38 | 39 | 40 | -------------------------------------------------------------------------------- /Commands/Install Plugin ___.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh install_plugins 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Install Plugin… 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 35 | uuid 36 | A5D27A2E-F29B-481E-97B9-0D070E99EA50 37 | 38 | 39 | -------------------------------------------------------------------------------- /Commands/Run Griffon Task ___.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | griffonmate_bootstrap.sh run_griffon_task 9 | input 10 | none 11 | keyEquivalent 12 | ^@G 13 | name 14 | Run Griffon Task… 15 | output 16 | showAsHTML 17 | requiredCommands 18 | 19 | 20 | command 21 | griffon 22 | locations 23 | 24 | /opt/local/bin/griffon 25 | /usr/local/bin/griffon 26 | 27 | moreInfoURL 28 | http://griffon-framework.org 29 | variable 30 | TM_GRIFFON 31 | 32 | 33 | scope 34 | source.groovy, source.java, source.java-props, text.xml, text.html.grails 35 | uuid 36 | 43336C0D-495B-44F0-BBA9-3108A51AFC37 37 | 38 | 39 | -------------------------------------------------------------------------------- /Support/lib/misc.rb: -------------------------------------------------------------------------------- 1 | class String 2 | # Gets the line number of character +i+ (0-base index) 3 | def line_from_index(i) 4 | slice(0..i).count("\n") 5 | end 6 | 7 | # Gets the index of the beginning of line number +l+ (0-base index) 8 | def index_from_line(l) 9 | to_a.slice(0...l).join.length 10 | end 11 | 12 | # Temporarily replace "strings" with (parens) and :symbols with .notation. 13 | # Useful before a find_nearest_string_or_symbol search when method calls have 14 | # special meaning for lists of strings or symbols (e.g. javascript_include_tag) 15 | def unstringify_hash_arguments 16 | gsub(/'([^']+?)'(?=\s*=>)/, '(\1)'). 17 | gsub(/"([^"]+?)"(?=\s*=>)/, '(\1)'). 18 | gsub(/:(\w+)(?=\s*=>)/, '.\1'). 19 | gsub(/(=>\s*)'([^']+?)'/, '\1(\2)'). 20 | gsub(/(=>\s*)"([^"]+?)"/, '\1(\2)'). 21 | gsub(/(=>\s*):(\w+)/, '\1.\2') 22 | end 23 | 24 | # Finds the nearest "string" or :symbol to +column_number+ 25 | def find_nearest_string_or_symbol(column_number) 26 | re = /'([^']+?)'|"([^"]+)"|:([a-zA-Z0-9_]+)\b/ 27 | matching_tokens = scan(re).flatten.compact 28 | # Which token is nearest to column_number? 29 | nearest_token = nearest_index = distance = nil 30 | matching_tokens.each do |token| 31 | i = index(token, column_number) 32 | if i and (distance.nil? or (column_number - i).abs < distance) 33 | nearest_token = token 34 | nearest_index = i 35 | distance = (column_number - i).abs 36 | end 37 | 38 | i = rindex(token, column_number) 39 | if i and (distance.nil? or ((column_number - i).abs - token.length) < distance) 40 | nearest_token = token 41 | nearest_index = i 42 | distance = (column_number - i).abs - token.length 43 | end 44 | end 45 | (nearest_token.nil?) ? nil : [nearest_token, nearest_index] 46 | end 47 | 48 | def underscore 49 | gsub(/::/, '/'). 50 | gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 51 | gsub(/([a-z\d])([A-Z])/,'\1_\2'). 52 | tr("-", "_"). 53 | downcase 54 | end 55 | 56 | def camelize 57 | gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } 58 | end 59 | alias camelcase camelize 60 | end 61 | 62 | -------------------------------------------------------------------------------- /Support/GriffonMate/GriffonMate.rb: -------------------------------------------------------------------------------- 1 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/escape" 2 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/ui" 3 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/tm/process" 4 | require "#{ENV["TM_SUPPORT_PATH"]}/lib/tm/htmloutput" 5 | 6 | require "shellwords" 7 | require "pstore" 8 | 9 | class GriffonCommand 10 | 11 | attr_reader :colorisations 12 | 13 | def initialize(task, &option_getter) 14 | @griffon = ENV['TM_GRIFFON'] 15 | @location = ENV['TM_PROJECT_DIRECTORY'] || ENV['TM_DIRECTORY'] 16 | @task = task 17 | @option_getter = option_getter 18 | @command = nil 19 | @colorisations = { 20 | "green" => [/SUCCESS/,/Server running/, /Tests PASSED/, /Running test (\w+)...PASSED/], 21 | "red" => [/FAILURE/,/Tests FAILED/,/Compilation error/,/threw exception/, /Exception:/, /...FAILED/], 22 | "blue" => [/Environment set to/], 23 | } 24 | end 25 | 26 | def command 27 | if @command.nil? 28 | option = nil 29 | unless @option_getter.nil? 30 | prefs = PStore.new(File.expand_path( "~/Library/Preferences/com.macromates.textmate.griffonmate")) 31 | pref_key = "#{@location}::#{@task}" 32 | last_value = prefs.transaction(true) { prefs[pref_key] } 33 | option = @option_getter[last_value] 34 | prefs.transaction { prefs[pref_key] = option } 35 | end 36 | @command = construct_command(@task, option) 37 | end 38 | @command 39 | end 40 | 41 | def construct_command(task, option) 42 | command = [] 43 | command << task unless task.nil? or task.empty? 44 | unless option.nil? or option.empty? 45 | (Shellwords.shellwords(option).each { |option| command << option }) 46 | end 47 | command 48 | end 49 | 50 | def run 51 | Dir.chdir(@location) do 52 | cmd = command 53 | TextMate::HTMLOutput.show(:window_title => "GriffonMate", :page_title => "GriffonMate", :sub_title => "#{@location}") do |io| 54 | if cmd.nil? 55 | io << "Command cancelled." 56 | else 57 | io << "
"
58 |           io << "griffon " + htmlize(cmd.join(' ')) + "
" 59 | TextMate::Process.run(@griffon, cmd) do |line| 60 | line.chomp! 61 | match = false 62 | if line =~ /^(Running test )(\S+)(\.\.\.)$/ 63 | match = $1 + "#{$2}" + $3 + "
" 64 | else 65 | @colorisations.each do | color, patterns | 66 | if match == false and patterns.detect { |pattern| line =~ pattern } 67 | match = "#{htmlize line}
" 68 | end 69 | end 70 | end 71 | io << (match ? match : "#{htmlize line}
") 72 | end 73 | io << "
" 74 | end 75 | end 76 | end 77 | end 78 | 79 | end -------------------------------------------------------------------------------- /Support/lib/buffer.rb: -------------------------------------------------------------------------------- 1 | # Copyright: 2 | # (c) 2006 syncPEOPLE, LLC. 3 | # Visit us at http://syncpeople.com/ 4 | # Author: Duane Johnson (duane.johnson@gmail.com) 5 | # Description: 6 | # Makes analyzing of a Rails path + filename easier. 7 | 8 | require 'TextMate' 9 | require 'misc' 10 | 11 | # Stores lines of text 12 | class Buffer 13 | # The actual lines of the text file 14 | attr_reader :lines 15 | # State of caret positions (both 0-based indexes) 16 | attr_accessor :line_number, :column_number 17 | # Stack for remembering caret positions 18 | attr_reader :stack 19 | 20 | # Init from a String or Buffer object 21 | def initialize(buffer, line_number = nil, column_number = nil) 22 | self.text = buffer 23 | @line_number = line_number || TextMate.line_number 24 | @column_number = column_number || TextMate.column_number 25 | @stack = [] 26 | end 27 | 28 | # Init from a String (filename) or FilePath 29 | def self.new_from_file(filepath, line_number = nil, column_number = nil) 30 | # In case it's a RailsPath, get the string representing the filepath 31 | filepath = filepath.filepath if filepath.respond_to?(:filepath) 32 | new(IO.read(filepath, line_number, column_number)) 33 | end 34 | 35 | def index 36 | @lines.slice(0...line_number).join.length 37 | end 38 | 39 | def current_line 40 | lines[line_number] 41 | end 42 | 43 | def push_position 44 | @stack.push [@line_number, @column_number] 45 | end 46 | 47 | def pop_position 48 | @line_number, @column_number = @stack.pop 49 | end 50 | 51 | def to_a 52 | @lines 53 | end 54 | 55 | def text 56 | @text ||= lines.join 57 | end 58 | 59 | def text=(buffer) 60 | @text = buffer.gsub("\r\n", "\n") 61 | @lines = @text.to_a 62 | end 63 | 64 | def =~(other) 65 | text =~ other 66 | end 67 | 68 | # Searches a region of the buffer, lines :from to :to 69 | # Accepts a block which can evaluate to either true/false indication of a line match, 70 | # or a Regexp indicating that the line must match the regexp for the line to match. 71 | # An optional :direction of :backward is also accepted if the search is to be reversed. 72 | def find(options = {}, &block) 73 | options = {:direction => :forward}.update(options) 74 | 75 | # Use some sensible defaults if just a direction is given 76 | if direction = options[:direction] == :forward 77 | from = options[:from] || line_number 78 | to = options[:to] || lines.size - 1 79 | from, to = to, from if from > to 80 | direction = 1 81 | else 82 | from = options[:from] || 0 83 | to = options[:to] || line_number 84 | from, to = to, from if from < to 85 | direction = -1 86 | end 87 | 88 | from.step(to, direction) do |i| 89 | value = yield(lines[i]) 90 | value = lines[i].scan(value).flatten.compact.first if value.is_a? Regexp 91 | return [value, i] if value 92 | end 93 | return nil 94 | end 95 | 96 | # Search for the nearest "def [method]" declaration 97 | def find_method(options = {}) 98 | options = {:direction => :backwards}.update(options) 99 | find(options) { %r{def\s+(\w+)\s+=\s+\{} } 100 | end 101 | 102 | def find_nearest_string_or_symbol(current_line = current_line) 103 | current_line.find_nearest_string_or_symbol(column_number) 104 | end 105 | 106 | end 107 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | contactEmailRot13 6 | FuvatyreWvz@tznvy.pbz 7 | contactName 8 | Jim Shingler 9 | description 10 | <a href="http://griffon.codehaus.org/">Griffon</a> - A ‘code by convention’ Groovy application framework. 11 | mainMenu 12 | 13 | items 14 | 15 | 18F476CC-8BEA-46BB-9419-77EDD521F9F0 16 | 6792FF28-C46E-4E42-8211-F9C03CBEEE49 17 | 7DCC7965-9E75-4933-A953-9BD5BCBA5CF3 18 | A1E08336-31C7-4ED1-B9DE-CADEAA84E06E 19 | 20 | submenus 21 | 22 | 18F476CC-8BEA-46BB-9419-77EDD521F9F0 23 | 24 | items 25 | 26 | FBA08F8E-3C51-4AB2-B417-F88D2ECB5843 27 | A2B2C702-E63A-4605-A1AC-38188D17B3BA 28 | 164FF85D-27CE-4CC6-BF6E-1C925D1DFF71 29 | 35A303C5-9064-41F5-A092-EF5CD83DEF81 30 | 43336C0D-495B-44F0-BBA9-3108A51AFC37 31 | ------------------------------------ 32 | DA1F072D-6D6A-4AD0-98DA-09D89CB848D0 33 | ------------------------------------ 34 | D6518BFC-9934-4819-907F-313EE5190DB6 35 | ------------------------------------ 36 | 207BBD6B-1BC7-4D9E-8438-3C103C6812A5 37 | A5D27A2E-F29B-481E-97B9-0D070E99EA50 38 | ------------------------------------ 39 | 2B083A1E-9890-41E7-8725-A8964B71E081 40 | 41 | name 42 | Commands 43 | 44 | 6792FF28-C46E-4E42-8211-F9C03CBEEE49 45 | 46 | items 47 | 48 | 51BEF2CA-6260-44B3-8484-AF30A93A0496 49 | 50 | name 51 | Model 52 | 53 | 7DCC7965-9E75-4933-A953-9BD5BCBA5CF3 54 | 55 | items 56 | 57 | 5B3B1235-FB16-46AF-AB5D-4559C56E6C7A 58 | A7FB47AB-8BFF-43E5-8CEC-1ADDC9A138DE 59 | 60 | name 61 | View 62 | 63 | A1E08336-31C7-4ED1-B9DE-CADEAA84E06E 64 | 65 | items 66 | 67 | 5ECE28ED-463A-4175-8931-E1D403B30981 68 | 69 | name 70 | Controller 71 | 72 | 73 | 74 | name 75 | Groovy Griffon 76 | ordering 77 | 78 | DA1F072D-6D6A-4AD0-98DA-09D89CB848D0 79 | D6518BFC-9934-4819-907F-313EE5190DB6 80 | 207BBD6B-1BC7-4D9E-8438-3C103C6812A5 81 | A5D27A2E-F29B-481E-97B9-0D070E99EA50 82 | FBA08F8E-3C51-4AB2-B417-F88D2ECB5843 83 | 43336C0D-495B-44F0-BBA9-3108A51AFC37 84 | 164FF85D-27CE-4CC6-BF6E-1C925D1DFF71 85 | 35A303C5-9064-41F5-A092-EF5CD83DEF81 86 | A2B2C702-E63A-4605-A1AC-38188D17B3BA 87 | 2B083A1E-9890-41E7-8725-A8964B71E081 88 | 51BEF2CA-6260-44B3-8484-AF30A93A0496 89 | 5B3B1235-FB16-46AF-AB5D-4559C56E6C7A 90 | 5ECE28ED-463A-4175-8931-E1D403B30981 91 | A7FB47AB-8BFF-43E5-8CEC-1ADDC9A138DE 92 | 93 | uuid 94 | 594D848B-CA20-4AB0-8A4D-1B6F38357404 95 | 96 | 97 | -------------------------------------------------------------------------------- /Support/lib/TextMate.rb: -------------------------------------------------------------------------------- 1 | # Copyright: 2 | # (c) 2006 syncPEOPLE, LLC. 3 | # Visit us at http://syncpeople.com/ 4 | # Author: Duane Johnson (duane.johnson@gmail.com) 5 | # Description: 6 | # Helper module for accesing TextMate facilities such as environment variables. 7 | 8 | module TextMate 9 | class < "Message", :informative_text => text, :button1 => "Ok"}.update(options) 102 | return cocoa_dialog('msgbox', options)[0] == "1" 103 | end 104 | 105 | def textbox(informative_text, text, options = {}) 106 | options = {:title => "Message", :informative_text => informative_text, :text => text, :button1 => "Ok"}.update(options) 107 | return cocoa_dialog('textbox', options)[0] == "1" 108 | end 109 | 110 | def message_yes_no_cancel(text, options = {}) 111 | options = {:title => "Message", :text => text}.update(options) 112 | return cocoa_dialog('yesno-msgbox', options)[0] == "1" 113 | end 114 | 115 | def message_ok_cancel(text, informative_text = nil, options = {}) 116 | options = {:title => "Message", :text => text, :informative_text => informative_text}.update(options) 117 | return cocoa_dialog('ok-msgbox', options)[0] == "1" 118 | end 119 | 120 | def input(text, default_text = "", options = {}) 121 | options = {:title => "Input", :informative_text => text, :text => default_text}.update(options) 122 | button, text = cocoa_dialog('standard-inputbox', options) 123 | if button == '1' 124 | return text.strip 125 | else 126 | return nil 127 | end 128 | end 129 | 130 | def choose(text, choices = ["none"], options = {}) 131 | options = {:title => "Choose", :text => text, :items => choices, :button1 => 'Ok', :button2 => 'Cancel'}.update(options) 132 | button, choice = cocoa_dialog('dropdown', options) 133 | if button == '1' 134 | return choice.strip.to_i 135 | else 136 | return nil 137 | end 138 | end 139 | end 140 | end 141 | 142 | 143 | module TextMate 144 | 145 | def TextMate.call_with_progress( args, &block ) 146 | output_filepath = args[:output_filepath] # path to open after execution 147 | 148 | title = args[:title] || 'Progress' 149 | message = args[:message] || 'Frobbing the widget...' 150 | 151 | cocoa_dialog = "#{ENV['TM_SUPPORT_PATH']}/bin/CocoaDialog.app/Contents/MacOS/CocoaDialog" 152 | 153 | tempdir = "/tmp/TextMate_progress_cmd_tmp.#{$PID}" 154 | Dir.mkdir(tempdir) 155 | Dir.chdir(tempdir) 156 | pipe = IO.popen( %Q("#{cocoa_dialog}" progressbar --indeterminate --title "#{title}" --text "#{message}"), "w+") 157 | begin 158 | pipe.puts "" 159 | data = block.call 160 | puts data 161 | ensure 162 | pipe.close 163 | %x{rm -rf "#{tempdir}"} 164 | end 165 | 166 | sleep 0.1 167 | 168 | end 169 | 170 | end 171 | -------------------------------------------------------------------------------- /Support/lib/GriffonPath.rb: -------------------------------------------------------------------------------- 1 | # Copyright: 2 | # (c) 2006 syncPEOPLE, LLC. 3 | # Visit us at http://syncpeople.com/ 4 | # Author: Duane Johnson (duane.johnson@gmail.com) 5 | # Description: 6 | # Makes analyzing of a Griffon path + filename easier. 7 | # 8 | # Mercileslly ripped off from the Rails bundle by Luke Daley. 9 | 10 | require 'misc' 11 | require 'TextMate' 12 | require 'buffer' 13 | 14 | module AssociationMessages 15 | # Return associated_with_*? methods 16 | def method_missing(method, *args) 17 | case method.to_s 18 | when /^associated_with_(.+)\?$/ 19 | return associations[$1.to_sym].include?(file_type) 20 | else 21 | super(method, *args) 22 | end 23 | end 24 | 25 | @@associations = { 26 | :controller => [:view, :domain_class, :service, :taglib, :controller_test], 27 | :view => [:controller, :domain_class, :taglib], 28 | :domain_class => [:controller, :service, :domain_class_test], 29 | :service => [:controller, :domain_class, :taglib, :service_test], 30 | :taglib => [:controller, :view, :taglib_test], 31 | :controller_test => [:controller, :domain_class], 32 | :domain_class_test => [:domain_class], 33 | :service_test => [:service, :controller], 34 | :taglib_test => [:taglib] 35 | } 36 | 37 | # Make associations hash publicly available to each object 38 | def associations; self.class.class_eval("@@associations") end 39 | end 40 | 41 | class GriffonPath 42 | attr_reader :filepath 43 | 44 | include AssociationMessages 45 | 46 | def initialize(filepath = TextMate.filepath) 47 | if filepath[0..0] == '/' 48 | # Absolute file, treat as is 49 | @filepath = filepath 50 | else 51 | # Relative file, prepend griffon_root 52 | @filepath = File.join(griffon_root, filepath) 53 | end 54 | end 55 | 56 | def buffer 57 | @buffer ||= Buffer.new_from_file(self) 58 | end 59 | 60 | def exists? 61 | File.file?(@filepath) 62 | end 63 | 64 | def basename 65 | File.basename(@filepath) 66 | end 67 | 68 | def dirname 69 | File.dirname(@filepath) 70 | end 71 | 72 | def touch_directories 73 | return if dirname[0..0] != '/' 74 | dirs = dirname[1..-1].split('/') 75 | for i in 0..(dirs.size) 76 | new_dir = '/' + File.join(dirs[0..i]) 77 | Dir.mkdir(new_dir) if !File.exist?(new_dir) 78 | end 79 | end 80 | 81 | # Make sure the file exists by creating it if it doesn't 82 | def touch 83 | if !exists? 84 | touch_directories 85 | f = File.open(@filepath, "w"); f.close 86 | end 87 | end 88 | 89 | def artifact_base_name 90 | name = basename 91 | # Remove extension 92 | name.sub!(/\.\w+$/, '') 93 | # Remove extras 94 | case file_type 95 | when :controller then name.sub!(/Controller$/, '') 96 | when :view then name = dirname.split('/').pop.capitalize 97 | when :domain_class then name 98 | when :service then name.sub!(/Service$/, '') 99 | when :taglib then name.sub!(/TagLib$/, '') 100 | when :controller_test then name.sub!(/ControllerTests$/, '') 101 | when :domain_class_test then name.sub!(/Tests$/, '') 102 | when :service_test then name.sub!(/ServiceTests$/, '') 103 | when :taglib_test then name.sub!(/TagLibTests$/, '') 104 | end 105 | 106 | return name 107 | end 108 | 109 | def action_name 110 | name = 111 | case file_type 112 | when :controller 113 | buffer.find_method(:direction => :backwards).first rescue nil 114 | when :view 115 | basename 116 | # when :unit_test 117 | # buffer.find_method(:direction => :backwards).first.sub('^test_', '') 118 | else nil 119 | end 120 | 121 | return name.sub(/\.\w+$/, '') rescue nil # Remove extension 122 | end 123 | 124 | def griffon_root 125 | return TextMate.project_directory 126 | # TODO: Look for the root_indicators inside TM_PROJECT_DIRECTORY and return nil if not found 127 | 128 | #self.class.root_indicators.each do |i| 129 | # if index = @filepath.index(i) 130 | # return @filepath[0...index] 131 | # end 132 | #end 133 | end 134 | 135 | # This is used in :file_type and :griffon_path_for_view 136 | VIEW_EXTENSIONS = %w( gsp ) 137 | 138 | def file_type 139 | return @file_type if @file_type 140 | 141 | @file_type = 142 | case @filepath 143 | when %r{/griffon-app/controllers/(.+Controller\.(groovy))$} then :controller 144 | when %r{/griffon-app/views/(.+\.(#{VIEW_EXTENSIONS * '|'}))$} then :view 145 | when %r{/griffon-app/domain/(.+\.(groovy))$} then :domain_class 146 | when %r{/griffon-app/services/(.+Service\.(groovy))$} then :service 147 | when %r{/griffon-app/taglib/(.+TagLib\.(groovy))$} then :taglib 148 | when %r{/test/unit/(.+ControllerTests\.(groovy))$} then :controller_test 149 | when %r{/test/unit/(.+ServiceTests\.(groovy))$} then :service_test 150 | when %r{/test/unit/(.+TagLibTests\.(groovy))$} then :taglib_test 151 | when %r{/test/unit/(.+Tests\.(groovy))$} then :domain_class_test 152 | else nil 153 | end 154 | # Store the tail (modules + file) after the regexp 155 | # The first set of parens in each case will become the "tail" 156 | @tail = $1 157 | # Store the file extension 158 | @extension = $2 159 | return @file_type 160 | end 161 | 162 | def tail 163 | # Get the tail if it's not set yet 164 | file_type unless @tail 165 | return @tail 166 | end 167 | 168 | def extension 169 | # Get the extension if it's not set yet 170 | file_type unless @extension 171 | return @extension 172 | end 173 | 174 | # View file that does not begin with _ 175 | def partial? 176 | file_type == :view and basename !~ /^_/ 177 | end 178 | 179 | def artifact_base_name_modified_for(type) 180 | case type 181 | when :controller then artifact_base_name + 'Controller' 182 | when :service then artifact_base_name + 'Service' 183 | when :taglib then artifact_base_name + 'TagLib' 184 | when :controller_test then artifact_base_name + 'ControllerTests' 185 | when :domain_class_test then artifact_base_name + 'Tests' 186 | when :service_test then artifact_base_name + 'ServiceTests' 187 | when :taglib_test then artifact_base_name + 'TagLibTests' 188 | else artifact_base_name 189 | end 190 | end 191 | 192 | def default_extension_for(type) 193 | case type 194 | when :view then '.gsp' 195 | else '.groovy' 196 | end 197 | end 198 | 199 | def griffon_path_for(type) 200 | return griffon_path_for_view if type == :view 201 | if TextMate.project_directory 202 | GriffonPath.new(File.join(griffon_root, stubs[type], artifact_base_name_modified_for(type) + default_extension_for(type))) 203 | else 204 | puts "There needs to be a project associated with this file." 205 | end 206 | end 207 | 208 | def griffon_path_for_view 209 | return ask_for_view("index") if action_name.nil? 210 | 211 | file_exists = false 212 | VIEW_EXTENSIONS.each do |e| 213 | filename_with_extension = action_name + "." + e 214 | existing_view = File.join(griffon_root, stubs[:view], artifact_base_name.downcase, filename_with_extension) 215 | return GriffonPath.new(existing_view) if File.exist?(existing_view) 216 | end 217 | default_view = File.join(griffon_root, stubs[:view], artifact_base_name.downcase, action_name + default_extension_for(:view)) 218 | return GriffonPath.new(default_view) 219 | end 220 | 221 | def ask_for_view(default_name = action_name) 222 | if designated_name = TextMate.input("Enter the name of the new view file:", default_name + default_extension_for(:view)) 223 | view_file = File.join(griffon_root, stubs[:view], artifact_base_name.downcase, designated_name) 224 | # FIXME: For some reason the following line freezes TextMate 225 | # TextMate.refresh_project_drawer 226 | return GriffonPath.new(view_file) 227 | end 228 | return nil 229 | end 230 | 231 | def self.stubs 232 | { 233 | :controller => 'griffon-app/controllers', 234 | :view => 'griffon-app/views/', 235 | :domain_class => 'griffon-app/domain', 236 | :service => 'griffon-app/services', 237 | :taglib => 'griffon-app/taglib', 238 | :controller_test => 'test/unit', 239 | :domain_class_test => 'test/unit', 240 | :service_test => 'test/unit', 241 | :taglib_test => 'test/unit' 242 | } 243 | end 244 | 245 | def stubs; self.class.stubs end 246 | 247 | def ==(other) 248 | other = other.filepath if other.respond_to?(:filepath) 249 | @filepath == other 250 | end 251 | end --------------------------------------------------------------------------------