diff options
author | René 'Necoro' Neumann <necoro@necoro.net> | 2009-12-16 20:24:26 +0100 |
---|---|---|
committer | René 'Necoro' Neumann <necoro@necoro.net> | 2009-12-16 20:34:13 +0100 |
commit | ae306613d059bbf306ccc414edfd49c8f2a0307f (patch) | |
tree | c74a8f39f321acad33f4fe88fb4829bd06eee969 | |
parent | 65d2d6655ab9b6e991412aa0681735ea46419fa2 (diff) | |
download | dotfiles-ae306613d059bbf306ccc414edfd49c8f2a0307f.tar.gz dotfiles-ae306613d059bbf306ccc414edfd49c8f2a0307f.tar.bz2 dotfiles-ae306613d059bbf306ccc414edfd49c8f2a0307f.zip |
Haskell stuff for Vim
-rw-r--r-- | .vim/.VimballRecord | 1 | ||||
-rw-r--r-- | .vim/autoload/haskellmode.vim | 155 | ||||
-rw-r--r-- | .vim/compiler/ghc.vim | 479 | ||||
-rw-r--r-- | .vim/doc/haskellmode.txt | 456 | ||||
-rw-r--r-- | .vim/doc/tags | 56 | ||||
-rw-r--r-- | .vim/ftplugin/haskell.vim | 14 | ||||
-rw-r--r-- | .vim/ftplugin/haskell_doc.vim | 837 | ||||
-rw-r--r-- | .vim/ftplugin/haskell_hpaste.vim | 79 | ||||
-rw-r--r-- | .vim/plugin/shim.vim | 273 | ||||
-rw-r--r-- | .vimrc | 8 |
10 files changed, 2358 insertions, 0 deletions
diff --git a/.vim/.VimballRecord b/.vim/.VimballRecord new file mode 100644 index 0000000..b72e3e8 --- /dev/null +++ b/.vim/.VimballRecord @@ -0,0 +1 @@ +haskellmode-20090430.vba: call delete('/home/necoro/.vim/compiler/ghc.vim')|call delete('/home/necoro/.vim/ftplugin/haskell.vim')|call delete('/home/necoro/.vim/ftplugin/haskell_doc.vim')|call delete('/home/necoro/.vim/ftplugin/haskell_hpaste.vim')|call delete('/home/necoro/.vim/autoload/haskellmode.vim')|call delete('/home/necoro/.vim/doc/haskellmode.txt') diff --git a/.vim/autoload/haskellmode.vim b/.vim/autoload/haskellmode.vim new file mode 100644 index 0000000..ce20a67 --- /dev/null +++ b/.vim/autoload/haskellmode.vim @@ -0,0 +1,155 @@ +" +" utility functions for haskellmode plugins +" +" (Claus Reinke; last modified: 23/04/2009) +" +" part of haskell plugins: http://projects.haskell.org/haskellmode-vim +" please send patches to <claus.reinke@talk21.com> + + + +" find start/extent of name/symbol under cursor; +" return start, symbolic flag, qualifier, unqualified id +" (this is used in both haskell_doc.vim and in GHC.vim) +function! haskellmode#GetNameSymbol(line,col,off) + let name = "[a-zA-Z0-9_']" + let symbol = "[-!#$%&\*\+/<=>\?@\\^|~:.]" + "let [line] = getbufline(a:buf,a:lnum) + let line = a:line + + " find the beginning of unqualified id or qualified id component + let start = (a:col - 1) + a:off + if line[start] =~ name + let pattern = name + elseif line[start] =~ symbol + let pattern = symbol + else + return [] + endif + while start > 0 && line[start - 1] =~ pattern + let start -= 1 + endwhile + let id = matchstr(line[start :],pattern.'*') + " call confirm(id) + + " expand id to left and right, to get full id + let idPos = id[0] == '.' ? start+2 : start+1 + let posA = match(line,'\<\(\([A-Z]'.name.'*\.\)\+\)\%'.idPos.'c') + let start = posA>-1 ? posA+1 : idPos + let posB = matchend(line,'\%'.idPos.'c\(\([A-Z]'.name.'*\.\)*\)\('.name.'\+\|'.symbol.'\+\)') + let end = posB>-1 ? posB : idPos + + " special case: symbolic ids starting with . + if id[0]=='.' && posA==-1 + let start = idPos-1 + let end = posB==-1 ? start : end + endif + + " classify full id and split into qualifier and unqualified id + let fullid = line[ (start>1 ? start-1 : 0) : (end-1) ] + let symbolic = fullid[-1:-1] =~ symbol " might also be incomplete qualified id ending in . + let qualPos = matchend(fullid, '\([A-Z]'.name.'*\.\)\+') + let qualifier = qualPos>-1 ? fullid[ 0 : (qualPos-2) ] : '' + let unqualId = qualPos>-1 ? fullid[ qualPos : -1 ] : fullid + " call confirm(start.'/'.end.'['.symbolic.']:'.qualifier.' '.unqualId) + + return [start,symbolic,qualifier,unqualId] +endfunction + +function! haskellmode#GatherImports() + let imports={0:{},1:{}} + let i=1 + while i<=line('$') + let res = haskellmode#GatherImport(i) + if !empty(res) + let [i,import] = res + let prefixPat = '^import\s*\(qualified\)\?\s\+' + let modulePat = '\([A-Z][a-zA-Z0-9_''.]*\)' + let asPat = '\(\s\+as\s\+'.modulePat.'\)\?' + let hidingPat = '\(\s\+hiding\s*\((.*)\)\)\?' + let listPat = '\(\s*\((.*)\)\)\?' + let importPat = prefixPat.modulePat.asPat.hidingPat.listPat ".'\s*$' + + let ml = matchlist(import,importPat) + if ml!=[] + let [_,qualified,module,_,as,_,hiding,_,explicit;x] = ml + let what = as=='' ? module : as + let hidings = split(hiding[1:-2],',') + let explicits = split(explicit[1:-2],',') + let empty = {'lines':[],'hiding':hidings,'explicit':[],'modules':[]} + let entry = has_key(imports[1],what) ? imports[1][what] : deepcopy(empty) + let imports[1][what] = haskellmode#MergeImport(deepcopy(entry),i,hidings,explicits,module) + if !(qualified=='qualified') + let imports[0][what] = haskellmode#MergeImport(deepcopy(entry),i,hidings,explicits,module) + endif + else + echoerr "haskellmode#GatherImports doesn't understand: ".import + endif + endif + let i+=1 + endwhile + if !has_key(imports[1],'Prelude') + let imports[0]['Prelude'] = {'lines':[],'hiding':[],'explicit':[],'modules':[]} + let imports[1]['Prelude'] = {'lines':[],'hiding':[],'explicit':[],'modules':[]} + endif + return imports +endfunction + +function! haskellmode#ListElem(list,elem) + for e in a:list | if e==a:elem | return 1 | endif | endfor + return 0 +endfunction + +function! haskellmode#ListIntersect(list1,list2) + let l = [] + for e in a:list1 | if index(a:list2,e)!=-1 | let l += [e] | endif | endfor + return l +endfunction + +function! haskellmode#ListUnion(list1,list2) + let l = [] + for e in a:list2 | if index(a:list1,e)==-1 | let l += [e] | endif | endfor + return a:list1 + l +endfunction + +function! haskellmode#ListWithout(list1,list2) + let l = [] + for e in a:list1 | if index(a:list2,e)==-1 | let l += [e] | endif | endfor + return l +endfunction + +function! haskellmode#MergeImport(entry,line,hiding,explicit,module) + let lines = a:entry['lines'] + [ a:line ] + let hiding = a:explicit==[] ? haskellmode#ListIntersect(a:entry['hiding'], a:hiding) + \ : haskellmode#ListWithout(a:entry['hiding'],a:explicit) + let explicit = haskellmode#ListUnion(a:entry['explicit'], a:explicit) + let modules = haskellmode#ListUnion(a:entry['modules'], [ a:module ]) + return {'lines':lines,'hiding':hiding,'explicit':explicit,'modules':modules} +endfunction + +" collect lines belonging to a single import statement; +" return number of last line and collected import statement +" (assume opening parenthesis, if any, is on the first line) +function! haskellmode#GatherImport(lineno) + let lineno = a:lineno + let import = getline(lineno) + if !(import=~'^import\s') | return [] | endif + let open = strlen(substitute(import,'[^(]','','g')) + let close = strlen(substitute(import,'[^)]','','g')) + while open!=close + let lineno += 1 + let linecont = getline(lineno) + let open += strlen(substitute(linecont,'[^(]','','g')) + let close += strlen(substitute(linecont,'[^)]','','g')) + let import .= linecont + endwhile + return [lineno,import] +endfunction + +function! haskellmode#UrlEncode(string) + let pat = '\([^[:alnum:]]\)' + let code = '\=printf("%%%02X",char2nr(submatch(1)))' + let url = substitute(a:string,pat,code,'g') + return url +endfunction + diff --git a/.vim/compiler/ghc.vim b/.vim/compiler/ghc.vim new file mode 100644 index 0000000..2760df6 --- /dev/null +++ b/.vim/compiler/ghc.vim @@ -0,0 +1,479 @@ + +" Vim Compiler File +" Compiler: GHC +" Maintainer: Claus Reinke <claus.reinke@talk21.com> +" Last Change: 30/04/2009 +" +" part of haskell plugins: http://projects.haskell.org/haskellmode-vim + +" ------------------------------ paths & quickfix settings first +" + +if exists("current_compiler") && current_compiler == "ghc" + finish +endif +let current_compiler = "ghc" + +let s:scriptname = "ghc.vim" + +if (!exists("g:ghc") || !executable(g:ghc)) + if !executable('ghc') + echoerr s:scriptname.": can't find ghc. please set g:ghc, or extend $PATH" + finish + else + let g:ghc = 'ghc' + endif +endif +let ghc_version = substitute(system(g:ghc . ' --numeric-version'),'\n','','') +if (!exists("b:ghc_staticoptions")) + let b:ghc_staticoptions = '' +endif + +" set makeprg (for quickfix mode) +execute 'setlocal makeprg=' . g:ghc . '\ ' . escape(b:ghc_staticoptions,' ') .'\ -e\ :q\ %' +"execute 'setlocal makeprg=' . g:ghc .'\ -e\ :q\ %' +"execute 'setlocal makeprg=' . g:ghc .'\ --make\ %' + +" quickfix mode: +" fetch file/line-info from error message +" TODO: how to distinguish multiline errors from warnings? +" (both have the same header, and errors have no common id-tag) +" how to get rid of first empty message in result list? +setlocal errorformat= + \%-Z\ %#, + \%W%f:%l:%c:\ Warning:\ %m, + \%E%f:%l:%c:\ %m, + \%E%>%f:%l:%c:, + \%+C\ \ %#%m, + \%W%>%f:%l:%c:, + \%+C\ \ %#%tarning:\ %m, + +" oh, wouldn't you guess it - ghc reports (partially) to stderr.. +setlocal shellpipe=2> + +" ------------------------- but ghc can do a lot more for us.. +" + +" allow map leader override +if !exists("maplocalleader") + let maplocalleader='_' +endif + +" initialize map of identifiers to their types +" associate type map updates to changedtick +if !exists("b:ghc_types") + let b:ghc_types = {} + let b:my_changedtick = b:changedtick +endif + +if exists("g:haskell_functions") + finish +endif +let g:haskell_functions = "ghc" + +" avoid hit-enter prompts +set cmdheight=3 + +" edit static GHC options +" TODO: add completion for options/packages? +command! GHCStaticOptions call GHC_StaticOptions() +function! GHC_StaticOptions() + let b:ghc_staticoptions = input('GHC static options: ',b:ghc_staticoptions) + execute 'setlocal makeprg=' . g:ghc . '\ ' . escape(b:ghc_staticoptions,' ') .'\ -e\ :q\ %' + let b:my_changedtick -=1 +endfunction + +map <LocalLeader>T :call GHC_ShowType(1)<cr> +map <LocalLeader>t :call GHC_ShowType(0)<cr> +function! GHC_ShowType(addTypeDecl) + let namsym = haskellmode#GetNameSymbol(getline('.'),col('.'),0) + if namsym==[] + redraw + echo 'no name/symbol under cursor!' + return 0 + endif + let [_,symb,qual,unqual] = namsym + let name = qual=='' ? unqual : qual.'.'.unqual + let pname = ( symb ? '('.name.')' : name ) + call GHC_HaveTypes() + if !has_key(b:ghc_types,name) + redraw + echo pname "type not known" + else + redraw + for type in split(b:ghc_types[name],' -- ') + echo pname "::" type + if a:addTypeDecl + call append( line(".")-1, pname . " :: " . type ) + endif + endfor + endif +endfunction + +" show type of identifier under mouse pointer in balloon +if has("balloon_eval") + set ballooneval + set balloondelay=600 + set balloonexpr=GHC_TypeBalloon() + function! GHC_TypeBalloon() + if exists("b:current_compiler") && b:current_compiler=="ghc" + let [line] = getbufline(v:beval_bufnr,v:beval_lnum) + let namsym = haskellmode#GetNameSymbol(line,v:beval_col,0) + if namsym==[] + return '' + endif + let [start,symb,qual,unqual] = namsym + let name = qual=='' ? unqual : qual.'.'.unqual + let pname = name " ( symb ? '('.name.')' : name ) + silent call GHC_HaveTypes() + if has("balloon_multiline") + return (has_key(b:ghc_types,pname) ? split(b:ghc_types[pname],' -- ') : '') + else + return (has_key(b:ghc_types,pname) ? b:ghc_types[pname] : '') + endif + else + return '' + endif + endfunction +endif + +map <LocalLeader>si :call GHC_ShowInfo()<cr> +function! GHC_ShowInfo() + let namsym = haskellmode#GetNameSymbol(getline('.'),col('.'),0) + if namsym==[] + redraw + echo 'no name/symbol under cursor!' + return 0 + endif + let [_,symb,qual,unqual] = namsym + let name = qual=='' ? unqual : (qual.'.'.unqual) + let output = GHC_Info(name) + pclose | new + setlocal previewwindow + setlocal buftype=nofile + setlocal noswapfile + put =output + wincmd w + "redraw + "echo output +endfunction + +" fill the type map, unless nothing has changed since the last attempt +function! GHC_HaveTypes() + if b:ghc_types == {} && (b:my_changedtick != b:changedtick) + let b:my_changedtick = b:changedtick + return GHC_BrowseAll() + endif +endfunction + +" update b:ghc_types after successful make +au QuickFixCmdPost make if GHC_CountErrors()==0 | silent call GHC_BrowseAll() | endif + +" count only error entries in quickfix list, ignoring warnings +function! GHC_CountErrors() + let c=0 + for e in getqflist() | if e.type=='E' && e.text !~ "^[ \n]*Warning:" | let c+=1 | endif | endfor + return c +endfunction + +command! GHCReload call GHC_BrowseAll() +function! GHC_BrowseAll() + " let imports = haskellmode#GatherImports() + " let modules = keys(imports[0]) + keys(imports[1]) + let imports = {} " no need for them at the moment + let current = GHC_NameCurrent() + let module = current==[] ? 'Main' : current[0] + if GHC_VersionGE([6,8,1]) + return GHC_BrowseBangStar(module) + else + return GHC_BrowseMultiple(imports,['*'.module]) + endif +endfunction + +function! GHC_VersionGE(target) + let current = split(g:ghc_version, '\.' ) + let target = a:target + for i in current + if ((target==[]) || (i>target[0])) + return 1 + elseif (i==target[0]) + let target = target[1:] + else + return 0 + endif + endfor + return 1 +endfunction + +function! GHC_NameCurrent() + let last = line("$") + let l = 1 + while l<last + let ml = matchlist( getline(l), '^module\s*\([^ (]*\)') + if ml != [] + let [_,module;x] = ml + return [module] + endif + let l += 1 + endwhile + redraw + echo "cannot find module header for file " . expand("%") + return [] +endfunction + +function! GHC_BrowseBangStar(module) + redraw + echo "browsing module " a:module + let command = ":browse! *" . a:module + let orig_shellredir = &shellredir + let &shellredir = ">" " ignore error/warning messages, only output or lack of it + let output = system(g:ghc . ' ' . b:ghc_staticoptions . ' -v0 --interactive ' . expand("%") , command ) + let &shellredir = orig_shellredir + return GHC_ProcessBang(a:module,output) +endfunction + +function! GHC_BrowseMultiple(imports,modules) + redraw + echo "browsing modules " a:modules + let command = ":browse " . join( a:modules, " \n :browse ") + let command = substitute(command,'\(:browse \(\S*\)\)','putStrLn "-- \2" \n \1','g') + let output = system(g:ghc . ' ' . b:ghc_staticoptions . ' -v0 --interactive ' . expand("%") , command ) + return GHC_Process(a:imports,output) +endfunction + +function! GHC_Info(what) + " call GHC_HaveTypes() + let output = system(g:ghc . ' ' . b:ghc_staticoptions . ' -v0 --interactive ' . expand("%"), ":i ". a:what) + return output +endfunction + +function! GHC_ProcessBang(module,output) + let module = a:module + let b = a:output + let linePat = '^\(.\{-}\)\n\(.*\)' + let contPat = '\s\+\(.\{-}\)\n\(.*\)' + let typePat = '^\(\)\(\S*\)\s*::\(.*\)' + let commentPat = '^-- \(\S*\)' + let definedPat = '^-- defined locally' + let importedPat = '^-- imported via \(.*\)' + if !(b=~commentPat) + echo s:scriptname.": GHCi reports errors (try :make?)" + return 0 + endif + let b:ghc_types = {} + let ml = matchlist( b , linePat ) + while ml != [] + let [_,l,rest;x] = ml + let mlDecl = matchlist( l, typePat ) + if mlDecl != [] + let [_,indent,id,type;x] = mlDecl + let ml2 = matchlist( rest , '^'.indent.contPat ) + while ml2 != [] + let [_,c,rest;x] = ml2 + let type .= c + let ml2 = matchlist( rest , '^'.indent.contPat ) + endwhile + let id = substitute( id, '^(\(.*\))$', '\1', '') + let type = substitute( type, '\s\+', " ", "g" ) + " using :browse! *<current>, we get both unqualified and qualified ids + let qualified = (id =~ '\.') && (id =~ '[A-Z]') + let b:ghc_types[id] = type + if !qualified + for qual in qualifiers + let b:ghc_types[qual.'.'.id] = type + endfor + endif + else + let mlImported = matchlist( l, importedPat ) + let mlDefined = matchlist( l, definedPat ) + if mlImported != [] + let [_,modules;x] = mlImported + let qualifiers = split( modules, ', ' ) + elseif mlDefined != [] + let qualifiers = [module] + endif + endif + let ml = matchlist( rest , linePat ) + endwhile + return 1 +endfunction + +function! GHC_Process(imports,output) + let b = a:output + let imports = a:imports + let linePat = '^\(.\{-}\)\n\(.*\)' + let contPat = '\s\+\(.\{-}\)\n\(.*\)' + let typePat = '^\(\s*\)\(\S*\)\s*::\(.*\)' + let modPat = '^-- \(\S*\)' + " add '-- defined locally' and '-- imported via ..' + if !(b=~modPat) + echo s:scriptname.": GHCi reports errors (try :make?)" + return 0 + endif + let b:ghc_types = {} + let ml = matchlist( b , linePat ) + while ml != [] + let [_,l,rest;x] = ml + let mlDecl = matchlist( l, typePat ) + if mlDecl != [] + let [_,indent,id,type;x] = mlDecl + let ml2 = matchlist( rest , '^'.indent.contPat ) + while ml2 != [] + let [_,c,rest;x] = ml2 + let type .= c + let ml2 = matchlist( rest , '^'.indent.contPat ) + endwhile + let id = substitute(id, '^(\(.*\))$', '\1', '') + let type = substitute( type, '\s\+', " ", "g" ) + " using :browse *<current>, we get both unqualified and qualified ids + if current_module " || has_key(imports[0],module) + if has_key(b:ghc_types,id) && !(matchstr(b:ghc_types[id],escape(type,'[].'))==type) + let b:ghc_types[id] .= ' -- '.type + else + let b:ghc_types[id] = type + endif + endif + if 0 " has_key(imports[1],module) + let qualid = module.'.'.id + let b:ghc_types[qualid] = type + endif + else + let mlMod = matchlist( l, modPat ) + if mlMod != [] + let [_,module;x] = mlMod + let current_module = module[0]=='*' + let module = current_module ? module[1:] : module + endif + endif + let ml = matchlist( rest , linePat ) + endwhile + return 1 +endfunction + +let s:ghc_templates = ["module _ () where","class _ where","class _ => _ where","instance _ where","instance _ => _ where","type family _","type instance _ = ","data _ = ","newtype _ = ","type _ = "] + +" use ghci :browse index for insert mode omnicompletion (CTRL-X CTRL-O) +function! GHC_CompleteImports(findstart, base) + if a:findstart + let namsym = haskellmode#GetNameSymbol(getline('.'),col('.'),-1) " insert-mode: we're 1 beyond the text + if namsym==[] + redraw + echo 'no name/symbol under cursor!' + return -1 + endif + let [start,symb,qual,unqual] = namsym + return (start-1) + else " find keys matching with "a:base" + let res = [] + let l = len(a:base)-1 + call GHC_HaveTypes() + for key in keys(b:ghc_types) + if key[0 : l]==a:base + let res += [{"word":key,"menu":":: ".b:ghc_types[key],"dup":1}] + endif + endfor + return res + endif +endfunction +set omnifunc=GHC_CompleteImports +" +" Vim's default completeopt is menu,preview +" you probably want at least menu, or you won't see alternatives listed +" setlocal completeopt+=menu + +" menuone is useful, but other haskellmode menus will try to follow your choice here in future +" setlocal completeopt+=menuone + +" longest sounds useful, but doesn't seem to do what it says, and interferes with CTRL-E +" setlocal completeopt-=longest + +map <LocalLeader>ct :call GHC_CreateTagfile()<cr> +function! GHC_CreateTagfile() + redraw + echo "creating tags file" + let output = system(g:ghc . ' ' . b:ghc_staticoptions . ' -e ":ctags" ' . expand("%")) + " for ghcs older than 6.6, you would need to call another program + " here, such as hasktags + echo output +endfunction + +command! -nargs=1 GHCi redraw | echo system(g:ghc. ' ' . b:ghc_staticoptions .' '.expand("%").' -e "'.escape(<f-args>,'"').'"') + +" use :make 'not in scope' errors to explicitly list imported ids +" cursor needs to be on import line, in correctly loadable module +map <LocalLeader>ie :call GHC_MkImportsExplicit()<cr> +function! GHC_MkImportsExplicit() + let save_cursor = getpos(".") + let line = getline('.') + let lineno = line('.') + let ml = matchlist(line,'^import\(\s*qualified\)\?\s*\([^( ]\+\)') + if ml!=[] + let [_,q,mod;x] = ml + silent make + if getqflist()==[] + if line=~"import[^(]*Prelude" + call setline(lineno,substitute(line,"(.*","","").'()') + else + call setline(lineno,'-- '.line) + endif + silent write + silent make + let qflist = getqflist() + call setline(lineno,line) + silent write + let ids = {} + for d in qflist + let ml = matchlist(d.text,'Not in scope: \([^`]*\)`\([^'']*\)''') + if ml!=[] + let [_,what,qid;x] = ml + let id = ( qid =~ "^[A-Z]" ? substitute(qid,'.*\.\([^.]*\)$','\1','') : qid ) + let pid = ( id =~ "[a-zA-Z0-9_']\\+" ? id : '('.id.')' ) + if what =~ "data" + call GHC_HaveTypes() + if has_key(b:ghc_types,id) + let pid = substitute(b:ghc_types[id],'^.*->\s*\(\S*\).*$','\1','').'('.pid.')' + else + let pid = '???('.pid.')' + endif + endif + let ids[pid] = 1 + endif + endfor + call setline(lineno,'import'.q.' '.mod.'('.join(keys(ids),',').')') + else + copen + endif + endif + call setpos('.', save_cursor) +endfunction + +if GHC_VersionGE([6,8,2]) + let opts = filter(split(substitute(system(g:ghc . ' -v0 --interactive', ':set'), ' ', '','g'), '\n'), 'v:val =~ "-f"') +else + let opts = ["-fglasgow-exts","-fallow-undecidable-instances","-fallow-overlapping-instances","-fno-monomorphism-restriction","-fno-mono-pat-binds","-fno-cse","-fbang-patterns","-funbox-strict-fields"] +endif + +amenu ]OPTIONS_GHC.- :echo '-'<cr> +aunmenu ]OPTIONS_GHC +for o in opts + exe 'amenu ]OPTIONS_GHC.'.o.' :call append(0,"{-# OPTIONS_GHC '.o.' #-}")<cr>' +endfor +if has("gui_running") + map <LocalLeader>opt :popup ]OPTIONS_GHC<cr> +else + map <LocalLeader>opt :emenu ]OPTIONS_GHC. +endif + +amenu ]LANGUAGES_GHC.- :echo '-'<cr> +aunmenu ]LANGUAGES_GHC +if GHC_VersionGE([6,8]) + let ghc_supported_languages = split(system(g:ghc . ' --supported-languages'),'\n') + for l in ghc_supported_languages + exe 'amenu ]LANGUAGES_GHC.'.l.' :call append(0,"{-# LANGUAGE '.l.' #-}")<cr>' + endfor + if has("gui_running") + map <LocalLeader>lang :popup ]LANGUAGES_GHC<cr> + else + map <LocalLeader>lang :emenu ]LANGUAGES_GHC. + endif +endif diff --git a/.vim/doc/haskellmode.txt b/.vim/doc/haskellmode.txt new file mode 100644 index 0000000..905349c --- /dev/null +++ b/.vim/doc/haskellmode.txt @@ -0,0 +1,456 @@ +*haskellmode.txt* Haskell Mode Plugins 23/04/2009 + +Authors: + Claus Reinke <claus.reinke@talk21.com> ~ + +Homepage: + http://projects.haskell.org/haskellmode-vim + +CONTENTS *haskellmode* + + 1. Overview |haskellmode-overview| + 1.1 Runtime Requirements |haskellmode-requirements| + 1.2 Quick Reference |haskellmode-quickref| + 2. Settings |haskellmode-settings| + 2.1 GHC and web browser |haskellmode-settings-main| + 2.2 Fine tuning - more configuration options |haskellmode-settings-fine| + 3. GHC Compiler Integration |haskellmode-compiler| + 4. Haddock Integration |haskellmode-haddock| + 4.1 Indexing |haskellmode-indexing| + 4.2 Lookup |haskellmode-lookup| + 4.3 Editing |haskellmode-editing| + 5. Hpaste Integration |haskellmode-hpaste| + 6. Additional Resources |haskellmode-resources| + +============================================================================== + *haskellmode-overview* +1. Overview ~ + + The Haskell mode plugins provide advanced support for Haskell development + using GHC/GHCi on Windows and Unix-like systems. The functionality is + based on Haddock-generated library indices, on GHCi's interactive + commands, or on simply activating (some of) Vim's built-in program editing + support in Haskell-relevant fashion. These plugins live side-by-side with + the pre-defined |syntax-highlighting| support for |haskell| sources, and + any other Haskell-related plugins you might want to install (see + |haskellmode-resources|). + + The Haskell mode plugins consist of three filetype plugins (haskell.vim, + haskell_doc.vim, haskell_hpaste.vim), which by Vim's |filetype| detection + mechanism will be auto-loaded whenever files with the extension '.hs' are + opened, and one compiler plugin (ghc.vim) which you will need to load from + your vimrc file (see |haskellmode-settings|). + + + *haskellmode-requirements* +1.1 Runtime Requirements ~ + + The plugins require a recent installation of GHC/GHCi. The functionality + derived from Haddock-generated library indices also requires a local + installation of the Haddock documentation for GHC's libraries (if there is + no documentation package for your system, you can download a tar-ball from + haskell.org), as well as an HTML browser (see |haddock_browser|). If you + want to use the experimental hpaste interface, you will also need Wget. + + * GHC/GHCi ~ + Provides core functionality. http://www.haskell.org/ghc + + * HTML library documentation files and indices generated by Haddock ~ + These usually come with your GHC installation, possibly as a separate + package. If you cannot get them this way, you can download a tar-ball + matching your GHC version from http://www.haskell.org/ghc/docs/ + + * HTML browser with basic CSS support ~ + For browsing Haddock docs. + + * Wget ~ + For interfacing with http://hpaste.org. + + Wget is widely available for modern Unix-like operating systems. Several + ports also exist for Windows, including: + + - Official GNU Wget (natively compiled for Win32) + http://www.gnu.org/software/wget/#downloading + + - UnxUtils Wget (natively compiled for Win32, bundled with other ported + Unix utilities) + http://sourceforge.net/projects/unxutils/ + + - Cygwin Wget (emulated POSIX in Win32, must be run under Cygwin) + http://cygwin.com/packages/wget/ + + *haskellmode-quickref* +1.2 Quick Reference ~ + +|:make| load into GHCi, show errors (|quickfix| |:copen|) +|_ct| create |tags| file +|_si| show info for id under cursor +|_t| show type for id under cursor +|_T| insert type declaration for id under cursor +|balloon| show type for id under mouse pointer +|_?| browse Haddock entry for id under cursor +|_?1| search Hoogle for id under cursor +|_?2| search Hayoo! for id under cursor +|:IDoc| {identifier} browse Haddock entry for unqualified {identifier} +|:MDoc| {module} browse Haddock entry for {module} +|:FlagReference| {s} browse Users Guide Flag Reference for section {s} +|_.| qualify unqualified id under cursor +|_i| add 'import <module>(<identifier>)' for id under cursor +|_im| add 'import <module>' for id under cursor +|_iq| add 'import qualified <module>(<identifier>)' for id under cursor +|_iqm| add 'import qualified <module>' for id under cursor +|_ie| make imports explit for import statement under cursor +|_opt| add OPTIONS_GHC pragma +|_lang| add LANGUAGE pragma +|i_CTRL-X_CTRL-O| insert-mode completion based on imported ids (|haskellmode-XO|) +|i_CTRL-X_CTRL-U| insert-mode completion based on documented ids (|haskellmode-XU|) +|i_CTRL-N| insert-mode completion based on imported sources +|:GHCi|{command/expr} run GHCi command/expr in current module + +|:GHCStaticOptions| edit static GHC options for this buffer +|:DocSettings| show current Haddock-files-related plugin settings +|:DocIndex| populate Haddock index +|:ExportDocIndex| cache current Haddock index to a file +|:HpasteIndex| Read index of most recent entries from hpaste.org +|:HpastePostNew| Submit current buffer as a new hpaste + + +============================================================================== + *haskellmode-settings* +2. Settings ~ + + The plugins try to find their dependencies in standard locations, so if + you're lucky, you will only need to set |compiler| to ghc, and configure + the location of your favourite web browser. You will also want to make + sure that |filetype| detection and |syntax| highlighting are on. Given the + variety of things to guess, however, some dependencies might not be found + correctly, or the defaults might not be to your liking, in which case you + can do some more fine tuning. All of this configuration should happen in + your |vimrc|. +> + " enable syntax highlighting + syntax on + + " enable filetype detection and plugin loading + filetype plugin on +< + + *haskellmode-settings-main* +2.1 GHC and web browser ~ + + *compiler-ghc* *ghc-compiler* + To use the features provided by the GHC |compiler| plugin, use the + following |autocommand| in your vimrc: +> + au BufEnter *.hs compiler ghc +< + *g:ghc* + If the compiler plugin can't locate your GHC binary, or if you have + several versions of GHC installed and have a preference as to which binary + is used, set |g:ghc|: +> + :let g:ghc="/usr/bin/ghc-6.6.1" +< + *g:haddock_browser* + The preferred HTML browser for viewing Haddock documentation can be set as + follows: +> + :let g:haddock_browser="/usr/bin/firefox" +< + + *haskellmode-settings-fine* +2.2 Fine tuning - more configuration options ~ + + Most of the fine tuning is likely to happen for the haskellmode_doc.vim + plugin, so you can check the current settings for this plugin via the + command |:DocSettings|. If all the settings reported there are to your + liking, you probably won't need to do any fine tuning. + + *g:haddock_browser_callformat* + By default, the web browser|g:haddock_browser| will be started + asynchronously (in the background) on Windows or when vim is running in a + GUI, and synchronously (in the foreground) otherwise. These settings seem + to work fine if you are using a console mode browser (eg, when editing in + a remote session), or if you are starting a GUI browser that will launch + itself in the background. But if these settings do not work for you, you + can change the default browser launching behavior. + + This is controlled by |g:haddock_browser_callformat|. It specifies a + format string which uses two '%s' parameters, the first representing the + path of the browser to launch, and the second is the documentation URL + (minus the protocol specifier, i.e. file://) passed to it by the Haddock + plugin. For instance, to launch a GUI browser on Unix-like systems and + force it to the background (see also |shellredir|): +> + :let g:haddock_browser_callformat = '%s file://%s '.printf(&shellredir,'/dev/null').' &' +< + *g:haddock_docdir* + Your system's installed Haddock documentation for GHC and its libraries + should be automatically detected. If the plugin can't locate them, you + must point |g:haddock_docdir| to the path containing the master index.html + file for the subdirectories 'libraries', 'Cabal', 'users_guide', etc.: +> + :let g:haddock_docdir="/usr/local/share/doc/ghc/html/" +< + *g:haddock_indexfiledir* + The information gathered from Haddock's index files will be stored in a + file called 'haddock_index.vim' in a directory derived from the Haddock + location, or in $HOME. To configure another directory for the index file, + use: +> + :let g:haddock_indexfiledir="~/.vim/" +< + *g:wget* + If you also want to try the experimental hpaste functionality, you might + you need to set |g:wget| before the |hpaste| plugin is loaded (unless wget + is in your PATH): +> + :let g:wget="C:\Program Files\wget\wget.exe" +< + + Finally, the mappings actually use|<LocalLeader>|behind the scenes, so if + you have to, you can redefine|maplocalleader|to something other than '_'. + Just remember that the docs still refer to mappings starting with '_', to + avoid confusing the majority of users!-) + +============================================================================== + *haskellmode-compiler* *ghc* +3. GHC Compiler Integration ~ + + The GHC |compiler| plugin sets the basic |errorformat| and |makeprg| to + enable |quickfix| mode using GHCi, and provides functionality for show + info (|_si|), show type (|_t| or mouse |balloon|), add type declaration + (|_T|), create tag file (|_ct|), and insert-mode completion + (|i_CTRL-X_CTRL-O|) based on GHCi browsing of the current and imported + modules. + + To avoid frequent calls to GHCi, type information is cached in Vim. The + cache will be populated the first time a command depends on it, and will + be refreshed every time a |:make| goes through without generating errors + (if the |:make| does not succeed, the old types will remain available in + Vim). You can also unconditionally force reloading of type info using + |:GHCReload| (if GHCi cannot load your file, the type info will be empty). + + + In addition to the standard|quickfix| commands, the GHC compiler plugin + provides: + + *:GHCReload* +:GHCReload Reload modules and unconditionally refresh cache of + type info. Usually, |:make| is prefered, as that will + refresh the cache only if GHCi reports no errors, and + show the errors otherwise. + + *:GHCStaticOptions* +:GHCStaticOptions Edit the static GHC options for the current buffer. + Useful for adding hidden packages (-package ghc). + + *:GHCi* +:GHCi {command/expr} Run GHCi commands/expressions in the current module. + + *_ct* +_ct Create |tags| file for the current Haskell source + |