以前のだと拡張子のないファイルが候補に表示されていなかったので修正。

let s:save_cpo = &cpo
set cpo&vim

let s:True = 1
let s:False = 0

let s:is_cache_invalid = s:True
let s:output_filenames = []


if !exists( "g:project_unite_source_filter_extentions" )
	let g:project_unite_source_filter_extentions = []
endif

if !exists( "g:project_unite_source_dirnames" )
	let g:project_unite_source_dirnames = []
endif

function! unite#sources#project#define()"{{{
  return s:source
endfunction"}}}

let s:source = {
\   'name': 'project',
\ 	'max_candidates' : 30,
\ }

function! s:format_for_word( index, max_digit, path )
	let format = '%' . a:max_digit . 'd: %s'
	return printf(format, a:index + 1, matchstr(a:path, '[^\\]*$'))
endfunction

function! s:source.gather_candidates(args, context)
	let l:extentions = g:project_unite_source_filter_extentions
	let l:dirnames = g:project_unite_source_dirnames

	for l:arg in a:args
		if l:arg == "invalid"
			echo "invalid"
			let s:is_cache_invalid = s:True
		endif
	endfor

	if s:is_cache_invalid == s:True
		let s:output_filenames = []
		echo "no cache"

		" don't use cache
		for l:dir in l:dirnames
			let l:filenames = split( glob( l:dir . "**/*" ), "\n" )
			for l:ext in l:extentions
				let l:file_filter_pattern = '.*' . l:ext . "$"
				let l:outputs = filter( copy(l:filenames), 'matchstr( v:val, l:file_filter_pattern ) != ""' )
				let s:output_filenames = extend( s:output_filenames, l:outputs )
			endfor
		endfor

		let format = '%' . strlen(len(s:output_filenames)) . 'd: %s'
		let s:is_cache_invalid = s:False
		let s:output_filenames = map( s:output_filenames, '{
					\ "word": s:format_for_word( v:key, strlen(len(s:output_filenames)), v:val ),
					\ "kind": "file",
					\ "action__path": v:val,
					\ }')
		return s:output_filenames
	else
		" use cache
		return s:output_filenames
	endif
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo

これで、とりあえず、普段使いには問題なさそう。
次の記事のネタを探そう...