Specky: support rspec 2.x by default. vim-stuff
authorMahlon E. Smith <mahlon@martini.nu>
Sat, 18 Dec 2010 00:56:09 -0800
branchvim-stuff
changeset 19 763cef799c74
parent 18 bf8f3c788cad
child 20 09c4f575f627
Specky: support rspec 2.x by default.
specky/doc/specky.txt
specky/plugin/specky.vim
specky/ruby/specky_formatter.rb
specky/snippets/rspec.snippets
specky/syntax/rspec.vim
specky/syntax/specrun.vim
specky/syntax/specrun1.vim
--- a/specky/doc/specky.txt	Fri Oct 01 08:16:47 2010 -0700
+++ b/specky/doc/specky.txt	Sat Dec 18 00:56:09 2010 -0800
@@ -9,10 +9,9 @@
 ==============================================================================
 CONTENTS                                                      *SpeckyContents*
 
-
     1) Intro........................................|SpeckyIntro|
     2) Functionality................................|SpeckyFunctionality|
-    3) Enabling Specky..............................|SpeckyVimrcExample|
+    3) Enabling Specky..............................|SpeckyInstallation|
     4) Configuration................................|SpeckyOptions|
         4.1) Create text banners....................|g:speckyBannerKey|
         4.2) Cycling quote styles...................|g:speckyQuoteSwitcherKey|
@@ -22,6 +21,7 @@
         4.6) Modify the default spec command........|g:speckyRunSpecCmd|
         4.7) Modify the default rdoc command........|g:speckyRunRdocCmd|
         4.8) Alter new window behavior..............|g:speckyWindowType|
+        4.9) Running older rspec (1.x) .............|g:speckySpecVersion|
     5) Author.......................................|SpeckyAuthor|
     6) License......................................|SpeckyLicense|
 
@@ -30,19 +30,17 @@
 ==============================================================================
 1. INTRO                                                         *SpeckyIntro*
 
-
 Specky is primarily a small collection of functions to help make behavioral
-testing streamlined and easy when working with ruby and rspec.
+testing streamlined and easy when working with ruby and rspec.  Specky
+supports rspec 2.x by default, and is backwards compatible with rspec 1.x.
 
 Specky secondarily includes a couple of conveniences to make your everyday
 programming tasks smooooth and pleasurable.
 
 
-
 ==============================================================================
 2. FUNCTIONALITY                                         *SpeckyFunctionality*
 
-
 Okay then, what does it do?
 
 By default?  Nothing but syntax highlighting unless you are comfortable using
@@ -80,40 +78,63 @@
 	http://www.vim.org/scripts/script.php?script_id=2540
 
 ==============================================================================
-3. ENABLING-SPECKY                                        *SpeckyVimrcExample*
+3. ENABLING-SPECKY                                        *SpeckyInstallation*
+
+Getting Specky to work should be a fairly trivial process.  Specky now
+uses a custom rspec formatter to function reliably, and it needs to know
+where that lives on your system.
+
+If you installed Specky from Vimball, it is likely found at:
+
+	~/.vim/ruby/specky_formatter.rb ~
+
+Otherwise, you'll need to locate it, and tell rspec to use it in one of two
+ways.
+
+	1) Set the *g:speckyRunSpecCmd* variable explicitly:
+
+		let g:speckyRunRdocCmd = "rspec -r ~/.vim/ruby/specky_formatter.rb -f SpeckyFormatter" ~
+
+	2) or, leave *g:speckyRunSpecCmd* at its default value, and instead use
+	   an '.rspec' settings file in the root directory of the the project
+	   you're working in.  I find this method much more flexible -- the
+	   '.rspec' file can be carried with your project, and customized to
+	   include additional bits like custom $LOAD_PATH injections, etc.
+	   Here's what mine usually looks like: >
+
+		-r loadpath
+		-r ~/.vim/bundle/specky/ruby/specky_formatter
+		-f SpeckyFormatter
 
 
-Here's what my config looks like. >
+After that is taken care of, then just set up your keybindings in your
+.vimrc.  Here's what my config looks like. >
 
-    let g:speckyBannerKey = "<C-S>b"
+    let g:speckyBannerKey        = "<C-S>b"
     let g:speckyQuoteSwitcherKey = "<C-S>'"
-    let g:speckyRunRdocKey = "<C-S>r"
-    let g:speckySpecSwitcherKey = "<C-S>x"
-    let g:speckyRunSpecKey = "<C-S>s"
-    let g:speckyRunSpecCmd = "spec -fs -r loadpath.rb"
-    let g:speckyRunRdocCmd = "fri -L -f plain"
-    let g:speckyWindowType = 2
+    let g:speckyRunRdocKey       = "<C-S>r"
+    let g:speckySpecSwitcherKey  = "<C-S>x"
+    let g:speckyRunSpecKey       = "<C-S>s"
+    let g:speckyRunRdocCmd       = "fri -L -f plain"
+    let g:speckyWindowType       = 2
 
-
-With these bindings, all specky commands start with <ctrl-s> ("s" for
-specky!), followed by a mnemonic function to run:
+With these bindings, all Specky commands start with <ctrl-s> ("s" for
+Specky!), followed by a mnemonic function to run:
 
     b ----> Banner creation ~
     ' ----> Quote cycling ~
     r ----> run Rdoc ~
     x ----> code and spec eXchange ~
-    s ----> run Spec ~
+    s ----> run rSpec ~
 
 Of course, <ctrl-s> is a "suspend" signal for most terminals, so these
 bindings are meant for a |gui| environment, such as gvim.  Your mileage (and
 tastes) will doubtlessly vary.  Do what you will.  I won't judge you.
 
 
-
 ==============================================================================
 4. CONFIGURATION-OPTIONS                                       *SpeckyOptions*
 
-
 Here are all of the available configuration options.
 
 Please note that you must set binding variables:
@@ -124,17 +145,15 @@
     |g:speckySpecSwitcherKey|
     |g:speckyRunSpecKey|
 
-...in order to enable the respective specky functionality.  See
-|SpeckyVimrcExample| for details. Any other options are entirely optional.
+...in order to enable the respective Specky functionality.  See
+|SpeckyInstallation| for details. Any other options are entirely optional.
 Put these into your |vimrc|, or wherever else you enjoy storing this kind of
 stuff.
 
 
-
 ------------------------------------------------------------------------------
 4.1                                                        *g:speckyBannerKey*
 
-
 Setting this binding enables comment banner creation.
 
 This is purely a convenience routine, and a stylistic one at that.  I prefer
@@ -158,11 +177,9 @@
 The possibilities are staggering.
 
 
-
 ------------------------------------------------------------------------------
 4.2                                                 *g:speckyQuoteSwitcherKey*
 
-
 Setting this binding enables quote "style switching".
 
 If you aren't in ruby mode, this just changes the word under the cursor
@@ -177,21 +194,17 @@
 Note that quote cycling only works with a |word|.
 
 
-
 ------------------------------------------------------------------------------
 4.3                                                       *g:speckyRunRdocKey*
 
-
 Setting this enables the display of rdoc documentation for the current
 word under the cursor.  For lookups with multiple matches, you can continue
 using this binding to "drill down" to the desired documentation.
          
 
-
 ------------------------------------------------------------------------------
 4.4                                                  *g:speckySpecSwitcherKey*
 
-
 Setting this enables spec to code switching, and visa versa.
 
 Switching uses path searching instead of reliance on directory structure in
@@ -205,12 +218,10 @@
 as a quick toggle between code and tests.
 
 
-
 ------------------------------------------------------------------------------
 4.5                                                       *g:speckyRunSpecKey*
 
-
-Setting this variable runs "spec" on the current buffer.
+Setting this variable runs "rspec" on the current buffer.
 
 All output is sent to a syntax highlighted scratch buffer. This new window is
 re-used for each spec run.  You can quickly "jump" to assertion failures and
@@ -232,32 +243,28 @@
 
 
 Normally, you'd only want to perform this keystroke while in a spec file
-buffer.  If specky thinks you are in code, rather than a buffer (as indicated
+buffer.  If Specky thinks you are in code, rather than a buffer (as indicated
 by the lack of a "_spec.rb" file naming convention) then it will attempt to
 switch to the spec before running the command.
 
 
-
 ------------------------------------------------------------------------------
 4.6                                                       *g:speckyRunSpecCmd*
 
-
 This is the program, with flags, that the current file is sent to when
 executing the |g:speckyRunSpecKey| keybinding.
 
 A common addition is to include an "-r" flag for sucking in local libraries
-necessary for testing your project.  The spec "plain" output format is
-supported too, though less useful.
+necessary for testing your project.  In fact, this is required to use the 
+rspec formatter supplied by Specky.  See |SpeckyInstallation| for more info.
 
     Default: ~
-        spec -fs
-
+        rspec
 
 
 ------------------------------------------------------------------------------
 4.7                                                       *g:speckyRunRdocCmd*
 
-
 If you prefer an rdoc display program other than "ri", you can set it
 with this variable.  "fri -L -f plain" is always a nice choice, for example.
 
@@ -265,11 +272,9 @@
         ri
 
 
-
 ------------------------------------------------------------------------------
 4.8                                                       *g:speckyWindowType*
 
-
 For both spec and rdoc commands, this variable controls the behavior of the
 newly generated window.
 
@@ -284,6 +289,21 @@
 		Split the current window vertically
 
 
+------------------------------------------------------------------------------
+4.9                                                      *g:speckySpecVersion*
+
+Specky should work out of the box with rspec 2.x.  If you'd like to use rspec
+1.x instead, you can do so with the following Vim settings: >
+
+    let g:speckySpecVersion = 1
+	let g:speckyRunRdocCmd  = "spec -fs" 
+
+If you have both rspec 1.x and 2.x installed at the same time, you need to 
+be explicit with what version you are executing: >
+
+	let g:speckyRunRdocCmd  = "spec _1.3.0_ -fs" 
+
+
 ==============================================================================
 5. AUTHOR                                                       *SpeckyAuthor*
 
@@ -302,7 +322,7 @@
 Specky is distributed under the BSD license.
     http://www.opensource.org/licenses/bsd-license.php
 >
-    Copyright (c) 2008-2009, Mahlon E. Smith <mahlon@martini.nu>
+    Copyright (c) 2008-2010, Mahlon E. Smith <mahlon@martini.nu>
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -331,3 +351,4 @@
 
 
 vim: set noet nosta sw=4 ts=4 ft=help :
+
--- a/specky/plugin/specky.vim	Fri Oct 01 08:16:47 2010 -0700
+++ b/specky/plugin/specky.vim	Sat Dec 18 00:56:09 2010 -0800
@@ -99,7 +99,6 @@
 	endif
 
 	" Restore the original path.
-	"
 	execute 'set path=' . l:orig_path
 endfunction
 
@@ -118,28 +117,23 @@
 
 	if l:type == '"'
 		" Double quote to single
-		"
 		execute ":normal viWc'" . l:word . "'"
 
 	elseif l:type == "'"
 		if &ft == 'ruby' || &ft == 'rspec'
 			" Single quote to symbol
-			"
 			execute ':normal viWc:' . l:word
 		else
 			" Single quote to double
-			"
 			execute ':normal viWc"' . l:word . '"'
 		end
 
 	else
 		" Whatever to double quote
-		"
 		execute ':normal viWc"' . l:word . '"'
 	endif
 
 	" Move the cursor back into the cl:word
-	"
 	call cursor( 0, getpos('.')[2] - 1 )
 endfunction
 
@@ -178,9 +172,10 @@
 		silent call <SID>SpecSwitcher()
 	endif
 
-	let l:spec   = bufname('%')
-	let l:buf    = 'specky:specrun'
-	let l:bufnum = bufnr( l:buf )
+	let l:spec    = bufname('%')
+	let l:buf     = 'specky:specrun'
+	let l:bufnum  = bufnr( l:buf )
+	let l:specver = (exists( 'g:speckySpecVersion') && g:speckySpecVersion == 1) ? 1 : 2
 
 	" Squash the old buffer, if it exists.
 	"
@@ -189,8 +184,14 @@
 	endif
 
 	execute <SID>NewWindowCmd() . l:buf
-	setlocal buftype=nofile bufhidden=delete noswapfile filetype=specrun
-	set foldtext='--'.getline(v:foldstart).v:folddashes
+	setlocal buftype=nofile bufhidden=delete noswapfile
+	if ( l:specver == 1 )
+		setlocal filetype=specrun1
+		set foldtext='--'.getline(v:foldstart).v:folddashes
+	else
+		setlocal filetype=specrun
+		set foldtext=_formatFoldText()
+	endif
 
 	" Set up some convenient keybindings.
 	"
@@ -203,20 +204,19 @@
 	" Default cmd for spec
 	"
 	if !exists( 'g:speckyRunSpecCmd' )
-		let g:speckyRunSpecCmd = 'spec -fs'
+		let g:speckyRunSpecCmd = l:specver == 1 ? 'spec -fs' : 'rspec'
 	endif
 
 	" Call spec and gather up the output
 	"
-	let l:cmd    =  g:speckyRunSpecCmd . ' ' . l:spec
+	let l:cmd =  g:speckyRunSpecCmd . ' ' . l:spec
+	call append( line('$'), 'Output of: ' . l:cmd  )
+	call append( line('$'), '' )
 	let l:output = system( l:cmd )
-	call append( 0, split( l:output, "\n" ) )
-	call append( 0, '' )
-	call append( 0, 'Output of: ' . l:cmd  )
+	call append( line('$'), split( l:output, "\n" ) )
 	normal gg
 
 	" Lockdown the buffer
-	"
 	setlocal nomodifiable
 endfunction
 
@@ -263,8 +263,7 @@
 		execute 'bd! ' . l:buf
 	endif
 
-	" With multiple matches, strip the comams from the cWORD.
-	"
+	" With multiple matches, strip the commas from the cWORD.
 	let l:word = substitute( l:word, ',', '', 'eg' )
 
 	execute <SID>NewWindowCmd() . l:buf
@@ -279,19 +278,24 @@
 	execute 'normal gg'
 
 	" Lockdown the buffer
-	"
-	execute 'setlocal nomodifiable'
+	setlocal nomodifiable
 endfunction
 
 
 " }}}
 " FindSpecError( detail ) {{{
 "
+" detail:
+" 	1  -- find the next failure
+" 	-1 -- find the previous failure
+" 	0  -- expand the current failure's detail
+"
 " Convenience searches for jumping to spec failures.
 "
 function! <SID>FindSpecError( detail )
 
-	let l:err_str = '(FAILED\|ERROR - \d\+)$'
+	let l:specver = (exists( 'g:speckySpecVersion') && g:speckySpecVersion == 1) ? 1 : 2
+	let l:err_str = l:specver == 1 ? '(FAILED\|ERROR - \d\+)$' : 'FAILED - #\d\+)$'
 
 	if ( a:detail == 0 )
 		" Find the detailed failure text for the current failure line,
@@ -299,7 +303,11 @@
 		"
 		let l:orig_so = &so
 		set so=100
-		call search('^' . matchstr(getline('.'),'\d\+)$') )
+		if l:specver == 1
+			call search('^' . matchstr(getline('.'),'\d\+)$') )
+		else
+			call search('^FAILURE - #' . matchstr(getline('.'),'\d\+)$') )
+		endif
 		if has('folding')
 			silent! normal za
 		endif
@@ -318,6 +326,7 @@
 	endif
 endfunction
 
+
 " }}}
 " NewWindowCmd() {{{
 "
@@ -337,6 +346,20 @@
 	endif
 endfunction
 
+
+" }}}
+" _formatFoldText() {{{
+"
+" Make folded failure detail visually appealing when folded.
+"
+function! _formatFoldText()
+	let l:fold = tolower( getline(v:foldstart) )
+	let l:fold = substitute( l:fold, '-', 'detail', 'e' )
+	let l:fold = '--[ ' . substitute( l:fold, ')', ' ]', 'e' )
+	return l:fold
+endfunction
+
+
 " }}}
 " s:err( msg ) "{{{
 " Notify of problems in a consistent fashion.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specky/ruby/specky_formatter.rb	Sat Dec 18 00:56:09 2010 -0800
@@ -0,0 +1,147 @@
+
+require 'rspec/core/formatters/base_text_formatter'
+
+### SpeckyFormatter: A basic RSpec 2.x text formatter, to be used
+### with the 'Specky' vim plugin (or from the command line, if you
+### dig it over the default 'documentation' format!)
+###
+### rspec -r /path/to/this/specky_formatter.rb -f SpeckyFormatter specs
+###
+class SpeckyFormatter < RSpec::Core::Formatters::BaseTextFormatter
+
+	def initialize( *args )
+		super
+		@indent_level  = 0
+		@failure_index = 0
+		@failures      = []
+	end
+
+	########################################################################
+	### R S P E C  H O O K S
+	########################################################################
+
+	### Example group hook -- increase indentation, emit description
+	###
+	def example_group_started( example_group )
+		output.puts
+		self.out '+', '-' * (example_group.description.length + 2), '+'
+		self.out '| ', example_group.description, ' |'
+		self.out '+', '-' * (example_group.description.length + 2), '+'
+		@indent_level += 1
+	end
+
+
+	### Example group hook -- decrease indentation
+	###
+	def example_group_finished( example_group )
+		@indent_level -= 1
+	end
+
+
+	### Called on example success
+	###
+	def example_passed( example )
+		msg = self.format_example( example )
+		msg << ')'
+		self.out msg
+	end
+
+
+	### Called on a pending example
+	###
+	def example_pending( example )
+		msg = self.format_example( example )
+		pending_msg = example.metadata[ :execution_result ][ :pending_message ]
+		msg << ", PENDING%s)" % [ ": #{pending_msg}" || '' ]
+		self.out msg
+	end
+
+
+	### Called on example failure
+	###
+	def example_failed( example )
+		@failure_index += 1
+		msg = self.format_example( example )
+		msg << ", FAILED - #%d)" % [ @failure_index ]
+		self.out msg
+
+		@failures << example
+	end
+
+
+	### Called after all examples are run.  Emit details for each failed example,
+	### for Vim to fold.
+	###
+	def dump_failures
+		self.out "\n\n\n" unless @failures.empty?
+
+		@failures.each_with_index do |example, index|
+			desc      = example.metadata[ :full_description ]
+			exception = example.execution_result[ :exception ]
+
+			self.out "FAILURE - #%d)" % [ index + 1 ]
+
+			if RSpec::Core::PendingExampleFixedError === exception
+				self.out "%s FIXED" % [ desc ]
+				self.out "Expected pending '%s' to fail.  No error was raised." % [
+					example.metadata[ :execution_result ][ :pending_message ]
+				]
+			else
+				self.out desc
+				self.out "Failure/Error: %s" %  [ read_failed_line( exception, example).strip ]
+				exception.message.split("\n").each {|l| self.out l}
+
+				# logic taken from the base class
+				example.example_group.ancestors.push(example.example_group).each do |group|
+					if group.metadata[:shared_group_name]
+						self.out "Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " +
+							"#{backtrace_line(group.metadata[:example_group][:location])}"
+						break
+					end
+				end
+			end
+			self.out "\n"
+		end
+	end
+
+
+	### Emit summary data for all examples.
+	###
+	def dump_summary( duration, example_count, failure_count, pending_count )
+		succeeded = example_count - failure_count - pending_count
+		self.out '+', '-' * 49, '+'
+		self.out '|', ' ' * 18, '-- Summary --', ' ' * 18, '|'
+		self.out '+----------+-----------+--------+---------+-------+'
+		self.out '| Duration | Succeeded | Failed | Pending | Total |'
+		self.out '+----------+-----------+--------+---------+-------+'
+
+		self.out "| %7ss | %9s | %6s | %7s | %5s |" % [
+			"%0.3f" % duration, succeeded, failure_count,
+			pending_count, example_count
+		]
+
+		self.out '+----------+-----------+--------+---------+-------+'
+	end
+
+
+	#########
+	protected
+	#########
+
+	### Send a string to the output IO object, after indentation.
+	###
+	def out( *msg )
+		msg = msg.join
+		output.puts "%s%s" % [ '  ' * @indent_level, msg ]
+	end
+
+	### Format the basic example information, along with the run duration.
+	###
+	def format_example( example )
+		metadata    = example.metadata
+		duration    = metadata[ :execution_result ][ :run_time ]
+		description = metadata[ :description ]
+		return "| %s (%0.3fs" % [ description, duration ]
+	end
+end # SpeckyFormatter
+
--- a/specky/snippets/rspec.snippets	Fri Oct 01 08:16:47 2010 -0700
+++ b/specky/snippets/rspec.snippets	Sat Dec 18 00:56:09 2010 -0800
@@ -56,9 +56,14 @@
 	context "${1:context}" do
 		${2}
 	end
+# this is the 'old' mock syntax (rspec 1.x)
+# use 'double' for rspec 2.x
 snippet mock
 	${1:var} = mock( "${2:mock_name}"${3:, :null_object => true} )
 	${4}
+snippet dou
+	${1:var} = double( "${2:double_name}" )${3:.as_null_object}
+	${4}
 snippet st
 	stub!( :${1:expectation} ).with( ${2:args} ).and_return( ${3} )
 snippet bef Before each test
--- a/specky/syntax/rspec.vim	Fri Oct 01 08:16:47 2010 -0700
+++ b/specky/syntax/rspec.vim	Sat Dec 18 00:56:09 2010 -0800
@@ -1,18 +1,19 @@
 "
 " specky: syntax highlighting for rspec files.
+" This includes keywords for both rspec 1.x and rspec 2.x.
 " $Id$
 "
 
 runtime! syntax/ruby.vim
 unlet b:current_syntax
 
-syntax keyword rspecGroupMethods describe it its let it_should_behave_like pending
+syntax keyword rspecGroupMethods context describe example it its let it_should_behave_like shared_examples_for subject it_behaves_like pending specify
 highlight link rspecGroupMethods Type
 
-syntax keyword rspecBeforeAndAfter after after_suite_parts append_after append_before before before_suite_parts prepend_after prepend_before
+syntax keyword rspecBeforeAndAfter after after_suite_parts append_after append_before before before_suite_parts prepend_after prepend_before around
 highlight link rspecBeforeAndAfter Statement
 
-syntax keyword rspecMocks mock stub double
+syntax keyword rspecMocks double mock stub stub_chain
 highlight link rspecMocks Constant
 
 syntax keyword rspecMockMethods and_raise and_return and_throw and_yield build_child called_max_times expected_args invoke matches
@@ -21,10 +22,11 @@
 syntax keyword rspecKeywords should should_not should_not_receive should_receive
 highlight link rspecKeywords Constant
 
-syntax keyword rspecMatchers be_a be_a_kind_of be_an be_an_instance_of be_close be_false be_instance_of be_kind_of be_nil be_true change eql equal exist expect have have_at_least have_at_most have_exactly include match matcher raise_error raise_exception respond_to satisfy throw_symbol to to_not wrap_expectation
+syntax keyword rspecMatchers be change eql equal exist expect have have_at_least have_at_most have_exactly include match matcher raise_error raise_exception respond_to satisfy throw_symbol to to_not when wrap_expectation
+syntax match rspecMatchers /\<\(be\|have\)_\w\+\>/
 highlight link rspecMatchers Function
 
-syntax keyword rspecMessageExpectation advise any_number_of_times at_least at_most exactly expected_messages_received generate_error ignoring_args matches_at_least_count matches_at_most_count matches_exact_count matches_name_but_not_args negative_expectation_for never once ordered similar_messages times twice verify_messages_received with
+syntax keyword rspecMessageExpectation advise any_args any_number_of_times anything at_least at_most exactly expected_messages_received generate_error hash_including hash_not_including ignoring_args instance_of matches_at_least_count matches_at_most_count matches_exact_count matches_name_but_not_args negative_expectation_for never no_args once ordered similar_messages times twice verify_messages_received with 
 highlight link rspecMessageExpectation Function
 
 let b:current_syntax = "rspec"
--- a/specky/syntax/specrun.vim	Fri Oct 01 08:16:47 2010 -0700
+++ b/specky/syntax/specrun.vim	Sat Dec 18 00:56:09 2010 -0800
@@ -1,5 +1,6 @@
 "
-" specky: syntax highlighting for the 'spec' script output
+" specky: syntax highlighting for rspec test output, using the
+" custom specky formatter. (rspec 2.x)
 " $Id$
 "
 
@@ -8,68 +9,48 @@
 endif
 
 " Command line as it was called, inserted by Specky
-"
 syntax match specSpeckyCmd /^Output of: .*/
-highlight link specSpeckyCmd Question
-"syntax match WarningMsg /\.\./
-
-" Plain output block (...P..F...)
-"
-syntax region specPlain start="^[\.PF]\+" end="^$" contains=specFailedPlain,specPendingPlain
-highlight link specPlain MoreMsg
-
-" Passed specs (specdoc output)
-"
-syntax match specPassed /^- .*/ contains=specFailed,specPending
-highlight link specPassed MoreMsg
 
-" Pending specs (specdoc output)
-"
-syntax match specPending /.*PENDING: .*)$/ contained
-highlight link specPending Function
-"
-" (Plain output)
-syntax match specPendingPlain /P/ contained
-highlight link specPendingPlain Function
+" Pending specs that somehow pass
+syntax keyword specCallout FIXED
 
-" Failed specs (specdoc output)
-"
-syntax match specFailed /.*\(FAILED\|ERROR\) - \d\+)/ contained
-highlight link specFailed WarningMsg
-"
-" (Plain output)
-syntax match specFailedPlain /F/ contained
-highlight link specFailedPlain WarningMsg
-
-" Warning details
-"
-syntax region specFailedDetails start="^\d\+)" end="^$" fold
-highlight link specFailedDetails WarningMsg
+" Passed specs
+syntax match specPassed /.*(\d\+.\d\+s)/ contains=specDuration,specBoxLine
+syntax keyword specPassedKeyword Succeeded
 
 " Pending specs
-"
-syntax region specPendingDetails start="^Pending:" end="^$" fold
-highlight link specPendingDetails Function
+syntax match specPending /.*PENDING: .*)$/ contains=specDuration,specBoxLine
+syntax keyword specPendingKeyword Pending
+
+" Failed specs
+syntax match specFailed /.*FAILED - #\d\+)/ contains=specDuration,specBoxLine
+syntax keyword specFailedKeyword Failed
 
-" Timing information
-"
-syntax match specTimedRun /^Finished in.*/
-highlight link specTimedRun Question
+" Failure details
+syntax region specFailedDetails start="^FAILURE - #\d\+)" end="^$" fold contains=specCallout
+
+" Boxes
+syntax match specBox /^\(\s\+\)\?\(+[+-]\+\||.*|\)$/ contains=specFailedKeyword,specDurationKeyword,specPendingKeyword,specPassedKeyword,specBoxContent
+syntax match specBoxContent /[a-zA-Z0-9]\+/ contained
+syntax match specBoxLine /^\(\s\+\)\?|/ contained
 
-" Status summary
-"
-syntax match specExamplesTotal /^\d\+ examples, .\+/ contains=specTotalFailed,specNoFailures,specTotalPending
-highlight link specExamplesTotal Special
-"
-syntax match specTotalFailed /\d\+ failure\%[s]/ contained
-highlight link specTotalFailed WarningMsg
-"
-syntax match specTotalPending /\d pending/ contained
-highlight link specTotalPending Function
-"
-syntax match specNoFailures /0 failures/ contained
-highlight link specNoFailures MoreMsg
+" Spec timing
+" syntax match specDuration /\d\+\.\d\+s/ contained
+" syntax keyword specDurationKeyword Duration
 
+highlight def link specSpeckyCmd Question
+highlight def link specCallout Todo
+highlight def link specPassed MoreMsg
+highlight def link specPassedKeyword specPassed
+highlight def link specPending Function
+highlight def link specPendingKeyword specPending
+highlight def link specFailed WarningMsg
+highlight def link specFailedKeyword specFailed
+highlight def link specFailedDetails specFailed
+highlight def link specDuration Normal
+highlight def link specBox LineNr
+highlight def link specBoxContent Constant
+highlight def link specBoxLine LineNr
 
 let b:current_syntax = "specrun"
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specky/syntax/specrun1.vim	Sat Dec 18 00:56:09 2010 -0800
@@ -0,0 +1,75 @@
+"
+" specky: syntax highlighting for the 'spec' script output (rspec 1.x)
+" $Id$
+"
+
+if has("folding")
+  setlocal foldmethod=syntax
+endif
+
+" Command line as it was called, inserted by Specky
+"
+syntax match specSpeckyCmd /^Output of: .*/
+highlight link specSpeckyCmd Question
+"syntax match WarningMsg /\.\./
+
+" Plain output block (...P..F...)
+"
+syntax region specPlain start="^[\.PF]\+" end="^$" contains=specFailedPlain,specPendingPlain
+highlight link specPlain MoreMsg
+
+" Passed specs (specdoc output)
+"
+syntax match specPassed /^- .*/ contains=specFailed,specPending
+highlight link specPassed MoreMsg
+
+" Pending specs (specdoc output)
+"
+syntax match specPending /.*PENDING: .*)$/ contained
+highlight link specPending Function
+"
+" (Plain output)
+syntax match specPendingPlain /P/ contained
+highlight link specPendingPlain Function
+
+" Failed specs (specdoc output)
+"
+syntax match specFailed /.*\(FAILED\|ERROR\) - \d\+)/ contained
+highlight link specFailed WarningMsg
+"
+" (Plain output)
+syntax match specFailedPlain /F/ contained
+highlight link specFailedPlain WarningMsg
+
+" Warning details
+"
+syntax region specFailedDetails start="^\d\+)" end="^$" fold
+highlight link specFailedDetails WarningMsg
+
+" Pending specs
+"
+syntax region specPendingDetails start="^Pending:" end="^$" fold
+highlight link specPendingDetails Function
+
+" Timing information
+"
+syntax match specTimedRun /^Finished in.*/
+highlight link specTimedRun Question
+
+" Status summary
+"
+syntax match specExamplesTotal /^\d\+ examples, .\+/ contains=specTotalFailed,specNoFailures,specTotalPending
+highlight link specExamplesTotal Special
+"
+syntax match specTotalFailed /\d\+ failure\%[s]/ contained
+highlight link specTotalFailed WarningMsg
+"
+syntax match specTotalPending /\d pending/ contained
+highlight link specTotalPending Function
+"
+syntax match specNoFailures /0 failures/ contained
+highlight link specNoFailures MoreMsg
+
+
+let b:current_syntax = "specrun"
+