mirror of
https://github.com/amix/vimrc
synced 2025-07-10 11:44:59 +08:00
add cocoa.vim & swift.vim
This commit is contained in:
215
sources_non_forked/cocoa.vim/autoload/objc/cocoacomplete.vim
Normal file
215
sources_non_forked/cocoa.vim/autoload/objc/cocoacomplete.vim
Normal file
@ -0,0 +1,215 @@
|
||||
" File: cocoacomplete.vim (part of the cocoa.vim plugin)
|
||||
" Author: Michael Sanders (msanders42 [at] gmail [dot] com)
|
||||
" Last Updated: June 30, 2009
|
||||
" Description: An omni-completion plugin for Cocoa/Objective-C.
|
||||
|
||||
let s:lib_dir = fnameescape(expand('<sfile>:p:h:h:h').'/lib/')
|
||||
let s:cocoa_indexes = s:lib_dir.'cocoa_indexes/'
|
||||
|
||||
if !isdirectory(s:cocoa_indexes)
|
||||
echom 'Error in cocoacomplete.vim: could not find ~/.vim/lib/cocoa_indexes directory'
|
||||
endif
|
||||
|
||||
fun! objc#cocoacomplete#Complete(findstart, base)
|
||||
if a:findstart
|
||||
" Column where completion starts:
|
||||
return match(getline('.'), '\k\+\%'.col('.').'c')
|
||||
else
|
||||
let matches = []
|
||||
let complete_type = s:GetCompleteType(line('.'), col('.') - 1)
|
||||
|
||||
if complete_type == 'methods'
|
||||
call s:Complete(a:base, ['alloc', 'init', 'retain', 'release',
|
||||
\ 'autorelease', 'retainCount',
|
||||
\ 'description', 'class', 'superclass',
|
||||
\ 'self', 'zone', 'isProxy', 'hash'])
|
||||
let obj_pos = s:GetObjPos(line('.'), col('.'))
|
||||
call extend(matches, s:CompleteMethod(line('.'), obj_pos, a:base))
|
||||
elseif complete_type == 'types' || complete_type == 'returntypes'
|
||||
let opt_types = complete_type == 'returntypes' ? ['IBAction'] : []
|
||||
call s:Complete(a:base, opt_types + ['void', 'id', 'BOOL', 'int',
|
||||
\ 'double', 'float', 'char'])
|
||||
call extend(matches, s:CompleteCocoa(a:base, 'classes', 'types',
|
||||
\ 'notifications'))
|
||||
elseif complete_type != ''
|
||||
if complete_type =~ 'function_params$'
|
||||
let complete_type = substitute(complete_type, 'function_params$', '', '')
|
||||
let functions = s:CompleteFunction(a:base)
|
||||
endif
|
||||
|
||||
" Mimic vim's dot syntax for other complete types (see :h ft).
|
||||
let word = a:base == '' ? 'NS' : a:base
|
||||
let args = [word] + split(complete_type, '\.')
|
||||
call extend(matches, call('s:CompleteCocoa', args))
|
||||
|
||||
" List functions after the other items in the menu.
|
||||
if exists('functions') | call extend(matches, functions) | endif
|
||||
endif
|
||||
return matches
|
||||
endif
|
||||
endf
|
||||
|
||||
fun s:GetCompleteType(lnum, col)
|
||||
let scopelist = map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")')
|
||||
if empty(scopelist) | return 'types' | endif
|
||||
|
||||
let current_scope = scopelist[-1]
|
||||
let beforeCursor = strpart(getline(a:lnum), 0, a:col)
|
||||
|
||||
" Completing a function name:
|
||||
if getline(a:lnum) =~ '\%'.(a:col + 1).'c\s*('
|
||||
return 'functions'
|
||||
elseif current_scope == 'objcSuperclass'
|
||||
return 'classes'
|
||||
" Inside brackets "[ ... ]":
|
||||
elseif index(scopelist, 'objcMethodCall') != -1
|
||||
return beforeCursor =~ '\[\k*$' ? 'classes' : 'methods'
|
||||
" Inside parentheses "( ... )":
|
||||
elseif current_scope == 'cParen'
|
||||
" Inside parentheses for method definition:
|
||||
if beforeCursor =~ '^\s*[-+]\s*([^{;]*'
|
||||
return beforeCursor =~ '^\s*[-+]\s*([^)]*$' ? 'returntypes' : 'types'
|
||||
" Inside function, loop, or conditional:
|
||||
else
|
||||
return 'classes.types.constants.function_params'
|
||||
endif
|
||||
" Inside braces "{ ... }" or after equals "=":
|
||||
elseif current_scope == 'cBlock' || current_scope == 'objcAssign' || current_scope == ''
|
||||
let type = current_scope == 'cBlock' ? 'types.constants.' : ''
|
||||
let type = 'classes.'.type.'function_params'
|
||||
|
||||
if beforeCursor =~ 'IBOutlet' | return 'classes' | endif
|
||||
return beforeCursor =~ '\v(^|[{};=\])]|return)\s*\k*$'? type : 'methods'
|
||||
" Directly inside "@implementation ... @end" or "@interface ... @end"
|
||||
elseif current_scope == 'objcImp' || current_scope == 'objcHeader'
|
||||
" TODO: Complete delegate/subclass methods
|
||||
endif
|
||||
return ''
|
||||
endf
|
||||
|
||||
" Adds item to the completion menu if they match the base.
|
||||
fun s:Complete(base, items)
|
||||
for item in a:items
|
||||
if item =~ '^'.a:base | call complete_add(item) | endif
|
||||
endfor
|
||||
endf
|
||||
|
||||
" Returns position of "foo" in "[foo bar]" or "[baz bar: [foo bar]]".
|
||||
fun s:GetObjPos(lnum, col)
|
||||
let beforeCursor = strpart(getline(a:lnum), 0, a:col)
|
||||
return match(beforeCursor, '\v.*(^|[\[=;])\s*\[*\zs[A-Za-z0-9_@]+') + 1
|
||||
endf
|
||||
|
||||
" Completes a method given the position of the object and the method
|
||||
" being completed.
|
||||
fun s:CompleteMethod(lnum, col, method)
|
||||
let class = s:GetCocoaClass(a:lnum, a:col)
|
||||
if class == ''
|
||||
let object = matchstr(getline(a:lnum), '\%'.a:col.'c\k\+')
|
||||
let class = s:GetDeclWord(object)
|
||||
if class == '' | return [] | endif
|
||||
endif
|
||||
let method = s:GetMethodName(a:lnum, a:col, a:method)
|
||||
let matches = split(system(s:lib_dir.'get_methods.sh '.class.
|
||||
\ '|grep "^'.method.'"'), "\n")
|
||||
if exists('g:loaded_snips') " Use snipMate if it's installed
|
||||
call objc#pum_snippet#Map()
|
||||
else " Otherwise, only complete the method name.
|
||||
call map(matches, 'substitute(v:val, ''\v:\zs.{-}\ze(\w+:|$)'', " ", "g")')
|
||||
endif
|
||||
|
||||
" If dealing with a partial method name, only complete past it. E.g., in
|
||||
" "[NSString stringWithCharacters:baz l|]" (where | is the cursor),
|
||||
" only return "length", not "stringWithCharacters:length:".
|
||||
if stridx(method, ':') != -1
|
||||
let method = substitute(method, a:method.'$', '\\\\zs&', '')
|
||||
call map(matches, 'matchstr(v:val, "'.method.'.*")')
|
||||
endif
|
||||
return matches
|
||||
endf
|
||||
|
||||
" Returns the Cocoa class at a given position if it exists, or
|
||||
" an empty string "" if it doesn't.
|
||||
fun s:GetCocoaClass(lnum, col)
|
||||
let class = matchstr(getline(a:lnum), '\%'.a:col.'c[A-Za-z0-9_"@]\+')
|
||||
if class =~ '^@"' | return 'NSString' | endif " Treat @"..." as an NSString
|
||||
let v:errmsg = ''
|
||||
sil! hi cocoaClass
|
||||
if v:errmsg == '' && synIDattr(synID(a:lnum, a:col, 0), 'name') == 'cocoaClass'
|
||||
return class " If cocoaClass is defined, try using that.
|
||||
endif
|
||||
return system('grep ^'.class.' '.s:cocoa_indexes.'classes.txt') != ''
|
||||
\ ? class : '' " Use grep as a fallback.
|
||||
endf
|
||||
|
||||
" Returns the word before a variable declaration.
|
||||
fun s:GetDeclWord(var)
|
||||
let startpos = [line('.'), col('.')]
|
||||
let line_found = searchdecl(a:var) != 0 ? 0 : line('.')
|
||||
call cursor(startpos)
|
||||
let matchstr = '\v(IBOutlet\s+)=\zs\k+\s*\ze\**\s*'
|
||||
|
||||
" If the declaration was not found in the implementation file, check
|
||||
" the header.
|
||||
if !line_found && expand('%:e') == 'm'
|
||||
let header_path = expand('%:p:r').'.h'
|
||||
if filereadable(header_path)
|
||||
for line in readfile(header_path)
|
||||
if line =~ '^\s*\(IBOutlet\)\=\s*\k*\s*\ze\**\s*'.a:var.'\s*'
|
||||
return matchstr(line, matchstr)
|
||||
endif
|
||||
endfor
|
||||
return ''
|
||||
endif
|
||||
endif
|
||||
|
||||
return matchstr(getline(line_found), matchstr.a:var)
|
||||
endf
|
||||
|
||||
fun s:SearchList(list, regex)
|
||||
for line in a:list
|
||||
if line =~ a:regex
|
||||
return line
|
||||
endif
|
||||
endfor
|
||||
return ''
|
||||
endf
|
||||
|
||||
" Returns the method name, ready to be searched by grep.
|
||||
" The "base" word needs to be passed in separately, because
|
||||
" Vim apparently removes it from the line during completions.
|
||||
fun s:GetMethodName(lnum, col, base)
|
||||
let line = getline(a:lnum)
|
||||
let col = matchend(line, '\%'.a:col.'c\S\+\s\+') + 1 " Skip past class name.
|
||||
if line =~ '\%'.col.'c\k\+:'
|
||||
let base = a:base == '' ? '' : ' '.a:base
|
||||
let method = matchstr(line, '\%'.col.'c.\{-}\ze]').base
|
||||
return substitute(method, '\v\k+:\zs.{-}\ze(\s*\k+:|'.base.'$)', '[^:]*', 'g')
|
||||
else
|
||||
return a:base
|
||||
endif
|
||||
endf
|
||||
|
||||
" Completes Cocoa functions, using snippets for the parameters if possible.
|
||||
fun s:CompleteFunction(word)
|
||||
let files = s:cocoa_indexes.'functions.txt' " TODO: Add C functions.
|
||||
let matches = split(system('zgrep -h "^'.a:word.'" '.files), "\n")
|
||||
if exists('g:loaded_snips') " Use snipMate if it's installed
|
||||
call objc#pum_snippet#Map()
|
||||
else " Otherwise, just complete the function name
|
||||
call map(matches, "{'word':matchstr(v:val, '^\\k\\+'), 'abbr':v:val}")
|
||||
endif
|
||||
return matches
|
||||
endf
|
||||
|
||||
" Completes word for Cocoa "classes", "types", "notifications", or "constants".
|
||||
" (supplied as the optional parameters).
|
||||
fun s:CompleteCocoa(word, file, ...)
|
||||
let files = ''
|
||||
for file in [a:file] + a:000
|
||||
let files .= ' '.s:cocoa_indexes.file.'.txt'
|
||||
endfor
|
||||
|
||||
return split(system('grep -ho "^'.a:word.'[A-Za-z0-9_]*" '.files), "\n")
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
185
sources_non_forked/cocoa.vim/autoload/objc/man.vim
Normal file
185
sources_non_forked/cocoa.vim/autoload/objc/man.vim
Normal file
@ -0,0 +1,185 @@
|
||||
" File: objc#man.vim (part of the cocoa.vim plugin)
|
||||
" Author: Michael Sanders (msanders42 [at] gmail [dot] com)
|
||||
" Description: Allows you to look up Cocoa API docs in Vim.
|
||||
" Last Updated: December 26, 2009
|
||||
" NOTE: See http://tinyurl.com/remove-annoying-alert
|
||||
" for removing the annoying security alert in Leopard.
|
||||
|
||||
" Return all matches in for ":CocoaDoc <tab>" sorted by length.
|
||||
fun objc#man#Completion(ArgLead, CmdLine, CursorPos)
|
||||
return system('grep -ho "^'.a:ArgLead.'\w*" ~/.vim/lib/cocoa_indexes/*.txt'.
|
||||
\ "| perl -e 'print sort {length $a <=> length $b} <>'")
|
||||
endf
|
||||
|
||||
let s:docsets = []
|
||||
let locations = [
|
||||
\ {'path': '/Developer/Documentation/DocSets/com.apple.ADC_Reference_Library.CoreReference.docset',
|
||||
\ 'alias': 'Leopard'},
|
||||
\ {'path': '/Developer/Documentation/DocSets/com.apple.adc.documentation.AppleSnowLeopard.CoreReference.docset',
|
||||
\ 'alias': 'Snow Leopard'},
|
||||
\ {'path': '/Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets/com.apple.adc.documentation.AppleiPhone3_0.iPhoneLibrary.docset',
|
||||
\ 'alias': 'iPhone 3.0'}
|
||||
\ ]
|
||||
for location in locations
|
||||
if isdirectory(location.path)
|
||||
call add(s:docsets, location)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let s:docset_cmd = '/Developer/usr/bin/docsetutil search -skip-text -query '
|
||||
|
||||
fun s:OpenFile(file)
|
||||
if a:file =~ '/.*/man/'
|
||||
exe ':!'.substitute(&kp, '^man -s', 'man', '').' '.a:file
|
||||
else
|
||||
" Sometimes Xcode doesn't download a bundle fully, and docsetutil is
|
||||
" inaccurate.
|
||||
if !filereadable(matchstr(a:file, '^.*\ze#.*$'))
|
||||
echoh ErrorMsg
|
||||
echom 'File "'.a:file.'" is not readable.'
|
||||
echom 'Check that Xcode has fully downloaded the DocSet.'
|
||||
echoh None
|
||||
else
|
||||
" /usr/bin/open strips the #fragments in file:// URLs, which we need,
|
||||
" so I'm using applescript instead.
|
||||
call system('osascript -e ''open location "file://'.a:file.'"'' &')
|
||||
endif
|
||||
endif
|
||||
endf
|
||||
|
||||
fun objc#man#ShowDoc(...)
|
||||
let word = a:0 ? a:1 : matchstr(getline('.'), '\<\w*\%'.col('.').'c\w\+:\=')
|
||||
|
||||
" Look up the whole method if it takes multiple arguments.
|
||||
if !a:0 && word[len(word) - 1] == ':'
|
||||
let word = s:GetMethodName()
|
||||
endif
|
||||
|
||||
if word == ''
|
||||
if !a:0 " Mimic K if using it as such
|
||||
echoh ErrorMsg
|
||||
echo 'E349: No identifier under cursor'
|
||||
echoh None
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
let references = {}
|
||||
|
||||
" First check Cocoa docs for word using docsetutil
|
||||
for location in s:docsets
|
||||
let docset = location.path
|
||||
let response = split(system(s:docset_cmd.word.' '.docset), "\n")
|
||||
let docset .= '/Contents/Resources/Documents/' " Actual path of files
|
||||
for line in response
|
||||
" Format string is: " Language/type/class/word path"
|
||||
let path = matchstr(line, '\S*$')
|
||||
if path[0] != '/' | let path = docset.path | endif
|
||||
|
||||
" Ignore duplicate entries
|
||||
if has_key(references, path) | continue | endif
|
||||
|
||||
let attrs = split(matchstr(line, '^ \zs*\S*'), '/')[:2]
|
||||
|
||||
" Ignore unrecognized entries.
|
||||
if len(attrs) != 3 | continue | endif
|
||||
|
||||
" If no class is given use type instead
|
||||
let [lang, type, class] = attrs
|
||||
if class == '-' | let class = type | endif
|
||||
let references[path] = {'lang': lang, 'class': class,
|
||||
\ 'location': location}
|
||||
endfor
|
||||
endfor
|
||||
|
||||
" Then try man
|
||||
let man = system('man -S2:3 -aW '.word)
|
||||
if man !~ '^No manual entry'
|
||||
for path in split(man, "\n")
|
||||
if !has_key(references, path)
|
||||
let references[path] = {'lang': 'C', 'class': 'man'}
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if len(references) == 1
|
||||
return s:OpenFile(keys(references)[0])
|
||||
elseif !empty(references)
|
||||
echoh ModeMsg | echo word | echoh None
|
||||
return s:ChooseFrom(references)
|
||||
else
|
||||
echoh WarningMsg
|
||||
echo "Can't find documentation for ".word
|
||||
echoh None
|
||||
endif
|
||||
endf
|
||||
|
||||
fun s:ChooseFrom(references)
|
||||
let type_abbr = {'cl' : 'Class', 'intf' : 'Protocol', 'cat' : 'Category',
|
||||
\ 'intfm' : 'Method', 'instm' : 'Method', 'econst' : 'Enum',
|
||||
\ 'tdef' : 'Typedef', 'macro' : 'Macro', 'data' : 'Data',
|
||||
\ 'func' : 'Function'}
|
||||
let inputlist = []
|
||||
" Don't display "Objective-C" if all items are objc
|
||||
let show_lang = !AllKeysEqual(values(a:references), 'lang', 'Objective-C')
|
||||
let i = 1
|
||||
for ref in values(a:references)
|
||||
let class = ref.class
|
||||
if has_key(type_abbr, class) | let class = type_abbr[class] | endif
|
||||
call add(inputlist, i.'. '.(show_lang ? ref['lang'].' ' : '').class.' ('.ref.location.alias.')')
|
||||
let i += 1
|
||||
endfor
|
||||
let num = inputlist(inputlist)
|
||||
return num ? s:OpenFile(keys(a:references)[num - 1]) : -1
|
||||
endf
|
||||
|
||||
fun AllKeysEqual(list, key, item)
|
||||
for item in a:list
|
||||
if item[a:key] != a:item
|
||||
return 0
|
||||
endif
|
||||
endfor
|
||||
return 1
|
||||
endf
|
||||
|
||||
fun s:GetMethodName()
|
||||
let pos = [line('.'), col('.')]
|
||||
let startpos = searchpos('\v^\s*-.{-}\w+:|\[\s*\w+\s+\w+:|\]\s*\w+:', 'cbW')
|
||||
|
||||
" Method declaration (- (foo) bar:)
|
||||
if getline(startpos[0]) =~ '^\s*-.\{-}\w\+:'
|
||||
let endpos = searchpos('{', 'W')
|
||||
" Message inside brackets ([foo bar: baz])
|
||||
else
|
||||
let endpos = searchpairpos('\[', '', '\]', 'W')
|
||||
endif
|
||||
call cursor(pos)
|
||||
|
||||
if startpos[0] == 0 || endpos[0] == 0 | return '' | endif
|
||||
let lines = getline(startpos[0], endpos[0])
|
||||
|
||||
let lines[0] = strpart(lines[0], startpos[1] - 1)
|
||||
let lines[-1] = strpart(lines[-1], 0, endpos[1])
|
||||
|
||||
" Ignore outer brackets
|
||||
let message = substitute(join(lines), '^\[\|\]$', '', '')
|
||||
" Ignore nested messages [...]
|
||||
let message = substitute(message, '\[.\{-}\]', '', 'g')
|
||||
" Ignore strings (could contain colons)
|
||||
let message = substitute(message, '".\{-}"', '', 'g')
|
||||
" Ignore @selector(...)
|
||||
let message = substitute(message, '@selector(.\{-})', '', 'g')
|
||||
|
||||
return s:MatchAll(message, '\w\+:')
|
||||
endf
|
||||
|
||||
fun s:MatchAll(haystack, needle)
|
||||
let matches = matchstr(a:haystack, a:needle)
|
||||
let index = matchend(a:haystack, a:needle)
|
||||
while index != -1
|
||||
let matches .= matchstr(a:haystack, a:needle, index + 1)
|
||||
let index = matchend(a:haystack, a:needle, index + 1)
|
||||
endw
|
||||
return matches
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
124
sources_non_forked/cocoa.vim/autoload/objc/method_builder.vim
Normal file
124
sources_non_forked/cocoa.vim/autoload/objc/method_builder.vim
Normal file
@ -0,0 +1,124 @@
|
||||
" File: objc#method_builder.vim (part of the cocoa.vim plugin)
|
||||
" Author: Michael Sanders (msanders42 [at] gmail [dot] com)
|
||||
" Description: Builds an empty implementation (*.m) file given a header (*.h)
|
||||
" file. When called with no arguments (simply ":BuildMethods"),
|
||||
" it looks for the corresponding header file of the current *.m
|
||||
" file (e.g. "foo.m" -> "foo.h").
|
||||
" Last Updated: June 03, 2009
|
||||
" - make sure you're not in a comment
|
||||
|
||||
" TODO: Relative pathnames
|
||||
fun objc#method_builder#Completion(ArgLead, CmdLine, CursorPos)
|
||||
let dir = stridx(a:ArgLead, '/') == -1 ? getcwd() : fnamemodify(a:ArgLead, ':h')
|
||||
let search = fnamemodify(a:ArgLead, ':t')
|
||||
let files = split(glob(dir.'/'.search.'*.h')
|
||||
\ ."\n".glob(dir.'/'.search.'*/'), "\n")
|
||||
call map(files, 'fnameescape(fnamemodify(v:val, ":."))')
|
||||
return files
|
||||
endf
|
||||
|
||||
fun s:Error(msg)
|
||||
echoh ErrorMsg | echo a:msg | echoh None
|
||||
return -1
|
||||
endf
|
||||
|
||||
fun s:GetDeclarations(file)
|
||||
let header = readfile(a:file)
|
||||
let template = []
|
||||
let in_comment = 0
|
||||
let in_header = 0
|
||||
let looking_for_semi = 0
|
||||
|
||||
for line in header
|
||||
if in_comment
|
||||
if stridx(line, '*/') != -1 | let in_comment = 0 | endif
|
||||
continue " Ignore declarations inside multi-line comments
|
||||
elseif stridx(line, '/*') != -1
|
||||
let in_comment = 1 | continue
|
||||
endif
|
||||
|
||||
if stridx(line, '@interface') != -1
|
||||
let in_header = 1
|
||||
let template += ['@implementation'.matchstr(line, '@interface\zs\s\+\w\+'), '']
|
||||
continue
|
||||
elseif in_header && stridx(line, '@end') != -1
|
||||
let in_header = 0
|
||||
call add(template, '@end')
|
||||
break " Only process one @interface at a time, for now.
|
||||
endif
|
||||
if !in_header | continue | endif
|
||||
|
||||
let first_char = strpart(line, 0, 1)
|
||||
if first_char == '-' || first_char == '+' || looking_for_semi
|
||||
let semi_pos = stridx(line, ';')
|
||||
let looking_for_semi = semi_pos == -1
|
||||
if looking_for_semi
|
||||
call add(template, line)
|
||||
else
|
||||
call add(template, strpart(line, 0, semi_pos))
|
||||
let template += ['{', "\t", '}', '']
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return template
|
||||
endf
|
||||
|
||||
fun objc#method_builder#Build(header)
|
||||
let headerfile = a:header == '' ? expand('%:p:r').'.h' : a:header
|
||||
if expand('%:e') != 'm'
|
||||
return s:Error('Not in an implementation file.')
|
||||
elseif !filereadable(headerfile)
|
||||
return s:Error('Could not read header file.')
|
||||
endif
|
||||
|
||||
let declarations = s:GetDeclarations(headerfile)
|
||||
|
||||
if empty(declarations)
|
||||
return s:Error('Header file has no method declarations!')
|
||||
endif
|
||||
|
||||
let len = len(declarations)
|
||||
let last_change = line('.')
|
||||
|
||||
if search('\V'.substitute(declarations[0], '\s\+', '\\s\\+', ''))
|
||||
if !searchpair('@implementation', '', '@end', 'W')
|
||||
return s:Error('Missing @end declaration.')
|
||||
endif
|
||||
let i = 2 " Skip past the @implementation line & blank line
|
||||
let len -= 1 " Skip past @end declaration
|
||||
let lnum = line('.') - 1
|
||||
else
|
||||
let i = 0
|
||||
let lnum = line('.')
|
||||
endif
|
||||
let start_line = lnum
|
||||
|
||||
while i < len
|
||||
let is_method = declarations[i][0] =~ '@\|+\|-'
|
||||
if !is_method || !search('\V'.substitute(escape(declarations[i], '\'),
|
||||
\ 'void\|IBAction', '\\(void\\|IBAction\\)', 'g'), 'n')
|
||||
call append(lnum, declarations[i])
|
||||
let lnum += 1
|
||||
if is_method | let last_change = lnum | endif
|
||||
else " Skip method declaration if it is already declared.
|
||||
if declarations[i][0] == '@'
|
||||
let i += 1
|
||||
else
|
||||
while declarations[i] != '}' && i < len
|
||||
let i += 1
|
||||
endw
|
||||
let i += 1
|
||||
endif
|
||||
endif
|
||||
let i += 1
|
||||
endw
|
||||
call cursor(last_change, 1)
|
||||
|
||||
if lnum == start_line
|
||||
echoh WarningMsg
|
||||
let class = matchstr(declarations[0], '@implementation\s\+\zs.*')
|
||||
echo 'The methods for the "'.class.'" class have already been declared.'
|
||||
echoh None
|
||||
endif
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
115
sources_non_forked/cocoa.vim/autoload/objc/method_list.vim
Normal file
115
sources_non_forked/cocoa.vim/autoload/objc/method_list.vim
Normal file
@ -0,0 +1,115 @@
|
||||
" File: objc#method_list.vim (part of the cocoa.vim plugin)
|
||||
" Author: Michael Sanders (msanders42 [at] gmail [dot] com)
|
||||
" Description: Opens a split window containing the methods of the current file.
|
||||
" Last Updated: July 13, 2009
|
||||
|
||||
au WinLeave Method\ List call<SID>LeaveMethodList()
|
||||
au WinEnter Method\ List call objc#method_list#Activate(0)
|
||||
|
||||
fun objc#method_list#Activate(update)
|
||||
let s:opt = {'is':&is, 'hls': &hls} " Save current options.
|
||||
let s:last_search = @/
|
||||
set is nohls
|
||||
" If methodlist has already been opened, reactivate it.
|
||||
if exists('s:mlist_buffer') && bufexists(s:mlist_buffer)
|
||||
let mlist_win = bufwinnr(s:mlist_buffer)
|
||||
if mlist_win == -1
|
||||
sil exe 'belowright sbuf '.s:mlist_buffer
|
||||
if a:update | call s:UpdateMethodList() | endif
|
||||
elseif winbufnr(2) == -1
|
||||
quit " If no other windows are open, close the method list automatically.
|
||||
else " If method list is out of focus, bring it back into focus.
|
||||
exe mlist_win.'winc w'
|
||||
endif
|
||||
else " Otherwise, create the method list.
|
||||
call s:CreateMethodList()
|
||||
call s:UpdateMethodList()
|
||||
endif
|
||||
endf
|
||||
|
||||
fun s:CreateMethodList()
|
||||
botright new
|
||||
|
||||
let s:sortPref = 0
|
||||
let s:mlist_buffer = bufnr('%')
|
||||
|
||||
sil file Method\ List
|
||||
setl bt=nofile bh=wipe noswf nobl nonu nowrap syn=objc
|
||||
syn match objcPragmark '^[^-+@].*$'
|
||||
hi objcPragmark gui=italic term=underline
|
||||
|
||||
nn <silent> <buffer> <cr> :cal<SID>SelectMethod()<cr>
|
||||
nn <buffer> q <c-w>q
|
||||
nn <buffer> p <c-w>p
|
||||
nm <buffer> l p
|
||||
nm <buffer> <2-leftmouse> <cr>
|
||||
endf
|
||||
|
||||
" Returns the lines of all the matches in a dictionary
|
||||
fun s:GetAllMatches(needle)
|
||||
let startpos = [line('.'), col('.')]
|
||||
call cursor(1, 1)
|
||||
|
||||
let results = {}
|
||||
let line = search(a:needle, 'Wc')
|
||||
let key = matchstr(getline(line), a:needle)
|
||||
if !s:InComment(line, 1) && key != ''
|
||||
let results[key] = line
|
||||
endif
|
||||
|
||||
while 1
|
||||
let line = search(a:needle, 'W')
|
||||
if !line | break | endif
|
||||
let key = matchstr(getline(line), a:needle)
|
||||
if !s:InComment(line, 1) && key != ''
|
||||
let results[key] = line
|
||||
endif
|
||||
endw
|
||||
|
||||
call cursor(startpos)
|
||||
return results
|
||||
endf
|
||||
|
||||
fun s:InComment(line, col)
|
||||
return stridx(synIDattr(synID(a:line, a:col, 0), 'name'), 'omment') != -1
|
||||
endf
|
||||
|
||||
fun s:UpdateMethodList()
|
||||
winc p " Go to source file window
|
||||
let s:methods = s:GetAllMatches('^\v(\@(implementation|interface) \w+|'.
|
||||
\ '\s*(\+|-).*|#pragma\s+mark\s+\zs.+)')
|
||||
winc p " Go to method window
|
||||
|
||||
if empty(s:methods)
|
||||
winc q
|
||||
echoh WarningMsg
|
||||
echo 'There are no methods in this file!'
|
||||
echoh None
|
||||
return
|
||||
endif
|
||||
|
||||
call setline(1, sort(keys(s:methods), 's:SortByLineNum'))
|
||||
exe "norm! \<c-w>".line('$').'_'
|
||||
endf
|
||||
|
||||
fun s:SortByLineNum(i1, i2)
|
||||
let line1 = s:methods[a:i1]
|
||||
let line2 = s:methods[a:i2]
|
||||
return line1 == line2 ? 0 : line1 > line2 ? 1 : -1
|
||||
endf
|
||||
|
||||
fun s:SelectMethod()
|
||||
let number = s:methods[getline('.')]
|
||||
winc q
|
||||
winc p
|
||||
call cursor(number, 1)
|
||||
endf
|
||||
|
||||
fun s:LeaveMethodList()
|
||||
for [option, value] in items(s:opt)
|
||||
exe 'let &'.option.'='.value
|
||||
endfor
|
||||
let @/ = s:last_search == '' ? '' : s:last_search
|
||||
unl s:opt s:last_search
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
87
sources_non_forked/cocoa.vim/autoload/objc/pum_snippet.vim
Normal file
87
sources_non_forked/cocoa.vim/autoload/objc/pum_snippet.vim
Normal file
@ -0,0 +1,87 @@
|
||||
" File: pum_snippet.vim
|
||||
" Author: Michael Sanders (msanders42 [at] gmail [dot] com)
|
||||
" Last Updated: June 12, 2009
|
||||
" Description: Uses snipMate to jump through function or method objc
|
||||
" parameters when autocompleting. Used in cocoacomplete.vim.
|
||||
|
||||
" This function is invoked whenever pum_snippet is to be used; the keys are
|
||||
" only mapped when used as the trigger, and then immediately unmapped to avoid
|
||||
" breaking abbreviations, as well as other things.
|
||||
fun! objc#pum_snippet#Map()
|
||||
ino <silent> <buffer> <space> <c-r>=objc#pum_snippet#Trigger(' ')<cr>
|
||||
if !exists('g:SuperTabMappingForward') " Only map tab if not using supertab.
|
||||
\ || (g:SuperTabMappingForward != '<tab>' && g:SuperTabMappingForward != '<tab>')
|
||||
ino <silent> <buffer> <tab> <c-r>=objc#pum_snippet#Trigger("\t")<cr>
|
||||
endif
|
||||
ino <silent> <buffer> <return> <c-r>=objc#pum_snippet#Trigger("\n")<cr>
|
||||
let s:start = col('.')
|
||||
" Completion menu can only be detected when the popup menu is visible, so
|
||||
" 'menuone' needs to be temporarily set:
|
||||
let s:cot = &cot
|
||||
set cot+=menuone
|
||||
endf
|
||||
|
||||
fun! objc#pum_snippet#Unmap()
|
||||
call s:UnmapKey('<space>')
|
||||
call s:UnmapKey('<tab>')
|
||||
call s:UnmapKey('<return>')
|
||||
endf
|
||||
|
||||
fun s:UnmapKey(key)
|
||||
if maparg(a:key, 'i') =~? '^<C-R>=objc#pum_snippet#Trigger('
|
||||
sil exe 'iunmap <buffer> '.a:key
|
||||
endif
|
||||
endf
|
||||
|
||||
fun! objc#pum_snippet#Trigger(key)
|
||||
call objc#pum_snippet#Unmap()
|
||||
if pumvisible()
|
||||
let line = getline('.')
|
||||
let col = col('.')
|
||||
let word = matchstr(line, '\%'.s:start.'c\k\+(.\{-})\%'.col.'c')
|
||||
if word != ''
|
||||
let ConvertWord = function('s:ConvertFunction')
|
||||
elseif match(line, '\%'.s:start.'c\k\+[^()]*:[^()]*\%'.col.'c') != -1
|
||||
let word = matchstr(line, '\%'.s:start.'c\k\+[^()]*\%'.col.'c')
|
||||
let ConvertWord = function('s:ConvertMethod')
|
||||
endif
|
||||
if word != ''
|
||||
call s:ResetOptions()
|
||||
let col -= len(word)
|
||||
sil exe 's/\V'.escape(word, '\/').'\%#//'
|
||||
return snipMate#expandSnip(ConvertWord(word), col)
|
||||
endif
|
||||
endif
|
||||
call s:ResetOptions()
|
||||
return a:key
|
||||
endf
|
||||
|
||||
fun s:ResetOptions()
|
||||
let &cot = s:cot
|
||||
unl s:start s:cot
|
||||
endf
|
||||
|
||||
fun s:ConvertFunction(function)
|
||||
let name = matchstr(a:function, '^\k\+')
|
||||
let params = matchstr(a:function, '^\k\+(\zs.*')
|
||||
let snippet = name.'('.substitute(params, '\v(.{-1})(, |\))', '${0:\1}\2', 'g').'${0}'
|
||||
return s:OrderSnippet(snippet)
|
||||
endf
|
||||
|
||||
fun s:ConvertMethod(method)
|
||||
if stridx(a:method, ':') == -1 | return a:method | endif
|
||||
let snippet = substitute(a:method, '\v\k+:\zs.{-}\ze(\s*\k+:|$)', '${0:&}', 'g')
|
||||
return s:OrderSnippet(snippet)
|
||||
endf
|
||||
|
||||
" Converts "${0} foo ${0} bar ..." to "${1} foo ${2} bar", etc.
|
||||
fun s:OrderSnippet(snippet)
|
||||
let snippet = a:snippet
|
||||
let i = 1
|
||||
while stridx(snippet, '${0') != -1
|
||||
let snippet = substitute(snippet, '${0', '${'.i, '')
|
||||
let i += 1
|
||||
endw
|
||||
return snippet
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
Reference in New Issue
Block a user