Browse Source

added .vim; now on xubuntu

master
James Wheaton 8 years ago
parent
commit
c691d48294

+ 36
- 55
.Xdefaults View File

@@ -1,56 +1,37 @@
URxvt*termName: rxvt-unicode
URxvt.buffered: true
URxvt.scrollBar: false
URxvt.visualBell: true
URxvt.cursorColor: gray
URxvt.underlineColor: gray
URxvt*keysym.Del: \033[3~
URxvt*keysym.Home: \033[1~
URxvt*keysym.End: \033[4~
URxvt*keysym.Prior: \033[5~
URxvt*keysym.Next: \033[6~
URxvt.font:xft:Bitstream Vera Sans Mono:pixelsize=12:antialias=true
URxvt.perl-ext-common: default,matcher
URxvt.urlLauncher: /usr/bin/uzbl-browser
URxvt*keysym.End: \033[4~
URxvt*keysym.Next: \033[6~
URxvt*keysym.Home: \033[1~
URxvt*keysym.Prior: \033[5~
URxvt*keysym.Del: \033[3~
URxvt.matcher.button: 1

urxvt*foreground: #f2f2f2
urxvt*background: #101010

! Normal
! color0    black
! color1    red
! color2    green
! color3    yellow
! color4    blue
! color5    purple
! color6    cyan
! color7    white

urxvt*color0: #6c6c6c
urxvt*color1: #e9897c
urxvt*color2: #b6e77d
urxvt*color3: #ecebbe
urxvt*color4: #a9cdeb
urxvt*color5: #ea96eb
urxvt*color6: #c9caec
urxvt*color7: #f2f2f2

! Light
! color8 black
! color9 red
! color10 green
! color11 yellow
! color12 blue
! color13 purple
! color14 cyan
! color15 white

urxvt*color8: #747474
urxvt*color9: #f99286
urxvt*color10: #c3f786
urxvt*color11: #fcfbcc
urxvt*color12: #b6defb
urxvt*color13: #fba1fb
urxvt*color14: #d7d9fc
urxvt*color15: #e2e2e2
URxvt.scrollBar: false
URxvt.underlineColor: gray
URxvt.visualBell: true
URxvt.perl-ext-common: default,matcher
URxvt.font: xft:Bitstream Vera Sans Mono:pixelsize=12:antialias=true
URxvt*termName: rxvt-unicode
URxvt.urlLauncher: /usr/bin/google-chrome
URxvt.cursorColor: gray
URxvt.buffered: true
urxvt*color9: #f99286
urxvt*color12: #b6defb
urxvt*color13: #fba1fb
urxvt*background: #101010
urxvt*color1: #e9897c
urxvt*color3: #ecebbe
urxvt*color5: #ea96eb
urxvt*color7: #f2f2f2
urxvt*color0: #6c6c6c
urxvt*color11: #fcfbcc
urxvt*color14: #d7d9fc
urxvt*foreground: #f2f2f2
urxvt*color15: #e2e2e2
urxvt*color2: #b6e77d
urxvt*color4: #a9cdeb
urxvt*color10: #c3f786
urxvt*color8: #747474
urxvt*color6: #c9caec
xrenoise.use_xcursors: 1
xrenoise.display: :0
xrenoise.display_resource: 0x00,0x39,0x42,0x7C,0x49,0x98,0x94,0x26
xrenoise.executable_path: /usr/local/bin/renoise-2.7.2

+ 1
- 0
.vim/.VimballRecord View File

@@ -0,0 +1 @@
haskellmode-20100622.vba: call delete('/home/james/.vim/compiler/ghc.vim')|call delete('/home/james/.vim/ftplugin/haskell.vim')|call delete('/home/james/.vim/ftplugin/haskell_doc.vim')|call delete('/home/james/.vim/ftplugin/haskell_hpaste.vim')|call delete('/home/james/.vim/autoload/haskellmode.vim')|call delete('/home/james/.vim/doc/haskellmode.txt')

+ 10
- 0
.vim/.netrwhist View File

@@ -0,0 +1,10 @@
let g:netrw_dirhistmax =10
let g:netrw_dirhist_cnt =8
let g:netrw_dirhist_1='/home/james/.config/xfce4/xfconf'
let g:netrw_dirhist_2='/home/james/.config/xfce4'
let g:netrw_dirhist_3='/home/james/.config/xfce4/panel'
let g:netrw_dirhist_4='/home/james/.config/xfce4'
let g:netrw_dirhist_5='/home/james/.config/xfce4/desktop'
let g:netrw_dirhist_6='/home/james/.config/xfce4'
let g:netrw_dirhist_7='/home/james/.xmonad'
let g:netrw_dirhist_8='/etc/apache2/sites-enabled'

+ 191
- 0
.vim/autoload/haskellmode.vim View File

@@ -0,0 +1,191 @@
"
" utility functions for haskellmode plugins
"
" (Claus Reinke; last modified: 22/06/2010)
"
" 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*\%({-#\s*SOURCE\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

" TODO: we could have buffer-local settings, at the expense of
" reconfiguring for every new buffer.. do we want to?
function! haskellmode#GHC()
if (!exists("g:ghc") || !executable(g:ghc))
if !executable('ghc')
echoerr s:scriptname.": can't find ghc. please set g:ghc, or extend $PATH"
return 0
else
let g:ghc = 'ghc'
endif
endif
return 1
endfunction

function! haskellmode#GHC_Version()
if !exists("g:ghc_version")
let g:ghc_version = substitute(system(g:ghc . ' --numeric-version'),'\n','','')
endif
return g:ghc_version
endfunction

function! haskellmode#GHC_VersionGE(target)
let current = split(haskellmode#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


+ 76
- 0
.vim/autoload/indent/css.vim View File

@@ -0,0 +1,76 @@
" Vim indent file
" Language: CSS
" Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2010-12-22

if exists("b:did_indent")
finish
endif
let b:did_indent = 1

setlocal indentexpr=GetCSSIndent()
setlocal indentkeys=0{,0},!^F,o,O
setlocal nosmartindent

if exists("*GetCSSIndent")
finish
endif

function s:prevnonblanknoncomment(lnum)
let lnum = a:lnum
while lnum > 1
let lnum = prevnonblank(lnum)
let line = getline(lnum)
if line =~ '\*/'
while lnum > 1 && line !~ '/\*'
let lnum -= 1
endwhile
if line =~ '^\s*/\*'
let lnum -= 1
else
break
endif
else
break
endif
endwhile
return lnum
endfunction

function s:count_braces(lnum, count_open)
let n_open = 0
let n_close = 0
let line = getline(a:lnum)
let pattern = '[{}]'
let i = match(line, pattern)
while i != -1
if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'css\%(Comment\|StringQ\{1,2}\)'
if line[i] == '{'
let n_open += 1
elseif line[i] == '}'
if n_open > 0
let n_open -= 1
else
let n_close += 1
endif
endif
endif
let i = match(line, pattern, i + 1)
endwhile
return a:count_open ? n_open : n_close
endfunction

function GetCSSIndent()
let line = getline(v:lnum)
if line =~ '^\s*\*'
return cindent(v:lnum)
endif

let pnum = s:prevnonblanknoncomment(v:lnum - 1)
if pnum == 0
return 0
endif

return indent(pnum) + s:count_braces(pnum, 1) * &sw
\ - s:count_braces(v:lnum, 0) * &sw
endfunction

+ 536
- 0
.vim/compiler/ghc.vim View File

@@ -0,0 +1,536 @@

" Vim Compiler File
" Compiler: GHC
" Maintainer: Claus Reinke <claus.reinke@talk21.com>
" Last Change: 22/06/2010
"
" 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 !haskellmode#GHC() | finish | endif
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
" TODO: it isn't a good idea to tie potentially time-consuming tasks
" (querying GHCi for the types) to cursor movements (#14). Currently,
" we ask the user to call :GHCReload explicitly. Should there be an
" option to reenable the old implicit querying?
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 )
if b:ghc_types == {}
redraw
echo "no type information (try :GHGReload)"
elseif (b:my_changedtick != b:changedtick)
redraw
echo "type information may be out of date (try :GHGReload)"
endif
" silent call GHC_HaveTypes()
if b:ghc_types!={}
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
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 b:my_changedtick = b:changedtick
let imports = {} " no need for them at the moment
let current = GHC_NameCurrent()
let module = current==[] ? 'Main' : current[0]
if haskellmode#GHC_VersionGE([6,8,1])
return GHC_BrowseBangStar(module)
else
return GHC_BrowseMultiple(imports,['*'.module])
endif
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("%"), ":info ". 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

" no need to ask GHC about its supported languages and
" options with every editing session. cache the info in
" ~/.vim/haskellmode.config
" TODO: should we store more info (see haskell_doc.vim)?
" move to autoload?
" should we keep a history of GHC versions encountered?
function! GHC_SaveConfig()
let vimdir = expand('~').'/'.'.vim'
let config = vimdir.'/haskellmode.config'
if !isdirectory(vimdir)
call mkdir(vimdir)
endif
let entries = ['-- '.g:ghc_version]
for l in s:ghc_supported_languages
let entries += [l]
endfor
let entries += ['--']
for l in s:opts
let entries += [l]
endfor
call writefile(entries,config)
endfunction

" reuse cached GHC configuration info, if using the same
" GHC version.
function! GHC_LoadConfig()
let vimdir = expand('~').'/'.'.vim'
let config = vimdir.'/haskellmode.config'
if filereadable(config)
let lines = readfile(config)
if lines[0]=='-- '.g:ghc_version
let i=1
let s:ghc_supported_languages = []
while i<len(lines) && lines[i]!='--'
let s:ghc_supported_languages += [lines[i]]
let i+=1
endwhile
let i+=1
let s:opts = []
while i<len(lines)
let s:opts += [lines[i]]
let i+=1
endwhile
return 1
else
return 0
endif
else
return 0
endif
endfunction

let s:GHC_CachedConfig = haskellmode#GHC_VersionGE([6,8]) && GHC_LoadConfig()

if haskellmode#GHC_VersionGE([6,8,2])
if !s:GHC_CachedConfig
let s:opts = filter(split(substitute(system(g:ghc . ' -v0 --interactive', ':set'), ' ', '','g'), '\n'), 'v:val =~ "-f"')
endif
else
let s:opts = ["-fglasgow-exts","-fallow-undecidable-instances","-fallow-overlapping-instances","-fno-monomorphism-restriction","-fno-mono-pat-binds","-fno-cse","-fbang-patterns","-funbox-strict-fields"]
endif
let s:opts = sort(s:opts)

amenu ]OPTIONS_GHC.- :echo '-'<cr>
aunmenu ]OPTIONS_GHC
for o in s: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 haskellmode#GHC_VersionGE([6,8])
if !s:GHC_CachedConfig
let s:ghc_supported_languages = sort(split(system(g:ghc . ' --supported-languages'),'\n'))
endif
for l in s: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

if !s:GHC_CachedConfig
call GHC_SaveConfig()
endif


+ 465
- 0
.vim/doc/haskellmode.txt View File

@@ -0,0 +1,465 @@
*haskellmode.txt* Haskell Mode Plugins 02/05/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 (more generally, options
that cannot be set by in-file OPTIONS_GHC pragmas)
for the current buffer. Useful for adding hidden
packages (-package ghc), or additional import paths
(-isrc; you will then also want to augment |path|).
If you have static options you want to set as
defaults, you could use b:ghc_staticoptions, eg:
>
au FileType haskell let b:ghc_staticoptions = '-isrc'
au FileType haskell setlocal path += src
<

*:GHCi*
:GHCi {command/expr} Run GHCi commands/expressions in the current module.

*_ct*
_ct Create |tags| file for the current Haskell source
file. This uses GHCi's :ctags command, so it will work
recursively, but will only list tags for exported
entities.

*_opt*
_opt Shows a menu of frequently used GHC compiler options
(selecting an entry adds the option as a pragma to the
start of the file). Uses popup menu (GUI) or :emenu
and command-line completion (CLI).

*_lang*
_lang Shows a menu of the LANGUAGE options supported by GHC
(selecting an entry adds the language as a pragma to
the start of the file). Uses popup menu (GUI) or
:emenu and command-line completion (CLI).

*_si*
_si Show extended information for the name under the
cursor. Uses GHCi's :info command. Output appears in
|preview-window| (when done, close with |:pclose|).

*_t*
_t Show type for the name under the cursor. Uses cached
info from GHCi's :browse command.

*_T*
_T Insert type declaration for the name under the cursor.
Uses cached info from GHCi's :browse command.

*haskellmode-XO* *haskellmode-omni-completion*
CTRL-X CTRL-O Standard insert-mode omni-completion based on the
cached type info from GHCi browsing current and
imported modules. Only names from the current and from
imported modules are included (the completion menu
also show the type of each identifier).

==============================================================================
*haskellmode-haddock* *haddock*
4. Haddock Integration ~

Haskell mode integrates with Haddock-generated HTML documentation,
providing features such as navigating to the Haddock entry for the
identifier under the cursor (|_?|), completion for the identifier under
the cursor (|i_CTRL-X_CTRL-U|), and adding import statements (|_i| |_im|
|_iq| |_iqm|) or module qualifier (|_.|) for the identifier under the
cursor.

These commands operate on an internal Haddock index built from the
platform's installed Haddock documentation for GHC's libraries. Since
populating this index takes several seconds, it should be stored as a
file called 'haddock_index.vim' in the directory specified by
|g:haddock_indexfiledir|.

Some commands present a different interface (popup menu or command-line
completion) according to whether the current Vim instance is graphical or
console-based (actually: whether or not the GUI is running). Such
differences are marked below with the annotations (GUI) and (CLI),
respectively.

|:DocSettings| shows the settings for this plugin. If you are happy with
them, you can call |:ExportDocIndex| to populate and write out the
documentation index (should be called once for every new version of GHC).

*:DocSettings*
:DocSettings Show current Haddock-files-related plugin settings.


*haskellmode-indexing*
4.1 Indexing ~

*:DocIndex*
:DocIndex Populate the Haddock index from the GHC library
documentation.

*:ExportDocIndex*
:ExportDocIndex Cache the current Haddock index to a file (populate
index first, if empty).


*haskellmode-lookup*
4.2 Lookup ~

*_?*
_? Open the Haddock entry (in |haddock_browser|) for an
identifier under the cursor, selecting full
qualifications from a popup menu (GUI) or via
command-line completion (CLI), if the identifier is
not qualified.

*_?1*
_?1 Search Hoogle (using |haddock_browser|) for an
identifier under the cursor.


*_?2*
_?2 Search Hayoo! (using |haddock_browser|) for an
identifier under the cursor.

*:IDoc*
:IDoc {identifier} Open the Haddock entry for the unqualified
{identifier} in |haddock_browser|, suggesting possible
full qualifications.

*:MDoc*
:MDoc {module} Open the Haddock entry for {module} in
|haddock_browser| (with command-line completion for
the fully qualified module name).

*:FlagReference*
:FlagReference {s} Browse Users Guide Flag Reference for section {s}
(with command-line completion for section headers).


*haskellmode-editing*
4.3 Editing ~

*_.*
_. Fully qualify the unqualified name under the cursor
selecting full qualifications from a popup menu (GUI)
or via command-line completion (CLI).

*_iq* *_i*
_i _iq Add 'import [qualified] <module>(<identifier>)'
statement for the identifier under the cursor,
selecting fully qualified modules from a popup menu
(GUI) or via command-line completion (CLI), if the
identifier is not qualified. This currently adds one
import statement per call instead of merging into
existing import statements.

*_iqm* *_im*
_im Add 'import [qualified] <module>' statement for the
identifier under the cursor, selecting fully qualified
modules from a popup menu (GUI) or via command-line
completion (CLI), if the identifier is not qualified.
This currently adds one import statement per call
instead of merging into existing import statements.

*_ie*
_ie On an 'import <module>' line, in a correctly loadable
module, temporarily comment out import and use :make
'not in scope' errors to explicitly list imported
identifiers.

*haskellmode-XU* *haskellmode-user-completion*
CTRL-X CTRL-U User-defined insert mode name completion based on all
names known to the Haddock index, including package
names. Completions are presented in a popup menu which
also displays the fully qualified module from which
each entry may be imported.

CamelCode shortcuts are supported, meaning that
lower-case letters can be elided, using only
upper-case letters and module qualifier separators (.)
for disambiguation:

pSL -> putStrLn
C.E.t -> Control.Exception.t
C.M.MP -> Control.Monad.MonadPlus

To reduce unwanted matches, the first letter of such
shortcuts and the first letter after each '.' have to
match directly.

==============================================================================
*haskellmode-hpaste* *hpaste*
5. Hpaste Integration ~

This experimental feature allows browsing and posting to
http://hpaste.org, a Web-based pastebin tailored for Haskell code.


*:HpasteIndex*
:HpasteIndex Read the most recent entries from hpaste.org. Show an
index of the entries in a new buffer, where ',r' will
open the current highlighted entry [and ',p' will
annotate it with the current buffer].

*:HpastePostNew*
:HpastePostNew Submit current buffer as a new hpaste entry.
[This, and ',p' above, are temporarily disabled,
needs update to new hpaste.org layout]

==============================================================================
*haskellmode-resources*
6. Additional Resources ~

An quick screencast tour through of these plugins is available at:

http://projects.haskell.org/haskellmode-vim/screencasts.html

Other Haskell-related Vim plugins can be found here:

http://www.haskell.org/haskellwiki/Libraries_and_tools/Program_development#Vim

Make sure to read about Vim's other program-editing features in its online
|user-manual|. Also have a look at Vim tips and plugins at www.vim.org -
two other plugins I tend to use when editing Haskell are AlignPlugin.vim
(to line up regexps for definitions, keywords, comments, etc. in
consecutive lines) and surround.vim (to surround text with quotes,
brackets, parentheses, comments, etc.).

==============================================================================
vim:tw=78:ts=8:ft=help:

+ 56
- 0
.vim/doc/tags View File

@@ -0,0 +1,56 @@
:DocIndex haskellmode.txt /*:DocIndex*
:DocSettings haskellmode.txt /*:DocSettings*
:ExportDocIndex haskellmode.txt /*:ExportDocIndex*
:FlagReference haskellmode.txt /*:FlagReference*
:GHCReload haskellmode.txt /*:GHCReload*
:GHCStaticOptions haskellmode.txt /*:GHCStaticOptions*
:GHCi haskellmode.txt /*:GHCi*
:HpasteIndex haskellmode.txt /*:HpasteIndex*
:HpastePostNew haskellmode.txt /*:HpastePostNew*
:IDoc haskellmode.txt /*:IDoc*
:MDoc haskellmode.txt /*:MDoc*
_. haskellmode.txt /*_.*
_? haskellmode.txt /*_?*
_?1 haskellmode.txt /*_?1*
_?2 haskellmode.txt /*_?2*
_T haskellmode.txt /*_T*
_ct haskellmode.txt /*_ct*
_i haskellmode.txt /*_i*
_ie haskellmode.txt /*_ie*
_im haskellmode.txt /*_im*
_iq haskellmode.txt /*_iq*
_iqm haskellmode.txt /*_iqm*
_lang haskellmode.txt /*_lang*
_opt haskellmode.txt /*_opt*
_si haskellmode.txt /*_si*
_t haskellmode.txt /*_t*
compiler-ghc haskellmode.txt /*compiler-ghc*
g:ghc haskellmode.txt /*g:ghc*
g:haddock_browser haskellmode.txt /*g:haddock_browser*
g:haddock_browser_callformat haskellmode.txt /*g:haddock_browser_callformat*
g:haddock_docdir haskellmode.txt /*g:haddock_docdir*
g:haddock_indexfiledir haskellmode.txt /*g:haddock_indexfiledir*
g:wget haskellmode.txt /*g:wget*
ghc haskellmode.txt /*ghc*
ghc-compiler haskellmode.txt /*ghc-compiler*
haddock haskellmode.txt /*haddock*
haskellmode haskellmode.txt /*haskellmode*
haskellmode-XO haskellmode.txt /*haskellmode-XO*
haskellmode-XU haskellmode.txt /*haskellmode-XU*
haskellmode-compiler haskellmode.txt /*haskellmode-compiler*
haskellmode-editing haskellmode.txt /*haskellmode-editing*
haskellmode-haddock haskellmode.txt /*haskellmode-haddock*
haskellmode-hpaste haskellmode.txt /*haskellmode-hpaste*
haskellmode-indexing haskellmode.txt /*haskellmode-indexing*
haskellmode-lookup haskellmode.txt /*haskellmode-lookup*
haskellmode-omni-completion haskellmode.txt /*haskellmode-omni-completion*
haskellmode-overview haskellmode.txt /*haskellmode-overview*
haskellmode-quickref haskellmode.txt /*haskellmode-quickref*
haskellmode-requirements haskellmode.txt /*haskellmode-requirements*
haskellmode-resources haskellmode.txt /*haskellmode-resources*
haskellmode-settings haskellmode.txt /*haskellmode-settings*
haskellmode-settings-fine haskellmode.txt /*haskellmode-settings-fine*
haskellmode-settings-main haskellmode.txt /*haskellmode-settings-main*
haskellmode-user-completion haskellmode.txt /*haskellmode-user-completion*
haskellmode.txt haskellmode.txt /*haskellmode.txt*
hpaste haskellmode.txt /*hpaste*

+ 2
- 0
.vim/ftdetect/uzbl.vim View File

@@ -0,0 +1,2 @@
au BufRead,BufNewFile .config/uzbl/* set filetype=uzbl
au BufRead,BufNewFile */uzbl/config set filetype=uzbl

+ 14
- 0
.vim/ftplugin/haskell.vim View File

@@ -0,0 +1,14 @@
"
" general Haskell source settings
" (shared functions are in autoload/haskellmode.vim)
"
" (Claus Reinke, last modified: 28/04/2009)
"
" part of haskell plugins: http://projects.haskell.org/haskellmode-vim
" please send patches to <claus.reinke@talk21.com>

" try gf on import line, or ctrl-x ctrl-i, or [I, [i, ..
setlocal include=^import\\s*\\(qualified\\)\\?\\s*
setlocal includeexpr=substitute(v:fname,'\\.','/','g').'.'
setlocal suffixesadd=hs,lhs,hsc


+ 816
- 0
.vim/ftplugin/haskell_doc.vim View File

@@ -0,0 +1,816 @@
"
" use haddock docs and index files
" show documentation, complete & qualify identifiers
"
" (Claus Reinke; last modified: 17/06/2009)
"
" part of haskell plugins: http://projects.haskell.org/haskellmode-vim
" please send patches to <claus.reinke@talk21.com>

" :Doc <name> and :IDoc <name> open haddocks for <name> in opera
"
" :Doc needs qualified name (default Prelude) and package (default base)
" :IDoc needs unqualified name, looks up possible links in g:haddock_index
"
" :DocIndex populates g:haddock_index from haddock's index files
" :ExportDocIndex saves g:haddock_index to cache file
" :ImportDocIndex reloads g:haddock_index from cache file
"
" all the following use the haddock index (g:haddock_index)
"
" _? opens haddocks for unqualified name under cursor,
" suggesting alternative full qualifications in popup menu
"
" _. fully qualifies unqualified name under cursor,
" suggesting alternative full qualifications in popup menu
"
" _i add import <module>(<name>) statement for unqualified <name> under cursor,
" _im add import <module> statement for unqualified <name> under cursor,
" suggesting alternative full qualifications in popup menu
" (this currently adds one statement per call, instead of
" merging into existing import statements, but it's a start;-)
"
" CTRL-X CTRL-U (user-defined insert mode completion)
" suggests completions of unqualified names in popup menu

let s:scriptname = "haskell_doc.vim"

" script parameters
" g:haddock_browser *mandatory* which browser to call
" g:haddock_browser_callformat [optional] how to call browser
" g:haddock_indexfiledir [optional] where to put 'haddock_index.vim'
" g:haddock_docdir [optional] where to find html docs
" g:ghc [optional] which ghc to call
" g:ghc_pkg [optional] which ghc_pkg to call

" been here before?
if exists("g:haddock_index")
finish
endif

" initialise nested dictionary, to be populated
" - from haddock index files via :DocIndex
" - from previous cached version via :ImportDocIndex
let g:haddock_index = {}

" initialise dictionary, mapping modules with haddocks to their packages,
" populated via MkHaddockModuleIndex() or HaveModuleIndex()
let g:haddock_moduleindex = {}

" program to open urls, please set this in your vimrc
"examples (for windows):
"let g:haddock_browser = "C:/Program Files/Opera/Opera.exe"
"let g:haddock_browser = "C:/Program Files/Mozilla Firefox/firefox.exe"
"let g:haddock_browser = "C:/Program Files/Internet Explorer/IEXPLORE.exe"
if !exists("g:haddock_browser")
echoerr s:scriptname." WARNING: please set g:haddock_browser!"
endif

if !haskellmode#GHC() | finish | endif

if (!exists("g:ghc_pkg") || !executable(g:ghc_pkg))
let g:ghc_pkg = substitute(g:ghc,'\(.*\)ghc','\1ghc-pkg','')
endif

if exists("g:haddock_docdir") && isdirectory(g:haddock_docdir)
let s:docdir = g:haddock_docdir
elseif executable(g:ghc_pkg)
" try to figure out location of html docs
" first choice: where the base docs are (from the first base listed)
let [field;x] = split(system(g:ghc_pkg . ' field base haddock-html'),'\n')
" path changes in ghc-6.12.*
" let field = substitute(field,'haddock-html: \(.*\)libraries.base','\1','')
let field = substitute(field,'haddock-html: \(.*\)lib\(raries\)\?.base.*$','\1','')
let field = substitute(field,'\\','/','g')
" let alternate = substitute(field,'html','doc/html','')
" changes for ghc-6.12.*: check for doc/html/ first
let alternate = field.'doc/html/'
if isdirectory(alternate)
let s:docdir = alternate
elseif isdirectory(field)
let s:docdir = field
endif
else
echoerr s:scriptname." can't find ghc-pkg (set g:ghc_pkg ?)."
endif

" second choice: try some known suspects for windows/unix
if !exists('s:docdir') || !isdirectory(s:docdir)
let s:ghc_libdir = substitute(system(g:ghc . ' --print-libdir'),'\n','','')
let location1a = s:ghc_libdir . '/doc/html/'
let location1b = s:ghc_libdir . '/doc/'
let location2 = '/usr/share/doc/ghc-' . haskellmode#GHC_Version() . '/html/'
if isdirectory(location1a)
let s:docdir = location1a
elseif isdirectory(location1b)
let s:docdir = location1b
elseif isdirectory(location2)
let s:docdir = location2
else " give up
echoerr s:scriptname." can't find locaton of html documentation (set g:haddock_docdir)."
finish
endif
endif

" todo: can we turn s:docdir into a list of paths, and
" include docs for third-party libs as well?

let s:libraries = s:docdir . 'libraries/'
let s:guide = s:docdir . 'users_guide/'
let s:index = 'index.html'
if exists("g:haddock_indexfiledir") && filewritable(g:haddock_indexfiledir)
let s:haddock_indexfiledir = g:haddock_indexfiledir
elseif filewritable(s:libraries)
let s:haddock_indexfiledir = s:libraries
elseif filewritable($HOME)
let s:haddock_indexfiledir = $HOME.'/'
else "give up
echoerr s:scriptname." can't locate index file. please set g:haddock_indexfiledir"
finish
endif
let s:haddock_indexfile = s:haddock_indexfiledir . 'haddock_index.vim'

" different browser setups require different call formats;
" you might want to call the browser synchronously or
" asynchronously, and the latter is os-dependent;
"
" by default, the browser is started in the background when on
" windows or if running in a gui, and in the foreground otherwise
" (eg, console-mode for remote sessions, with text-mode browsers).
"
" you can override these defaults in your vimrc, via a format
" string including 2 %s parameters (the first being the browser
" to call, the second being the url).
if !exists("g:haddock_browser_callformat")
if has("win32") || has("win64")
let g:haddock_browser_callformat = 'start %s "%s"'
else
if has("gui_running")
let g:haddock_browser_callformat = '%s %s '.printf(&shellredir,'/dev/null').' &'
else
let g:haddock_browser_callformat = '%s %s'
endif
endif
endif

" allow map leader override
if !exists("maplocalleader")
let maplocalleader='_'
endif

command! DocSettings call DocSettings()
function! DocSettings()
for v in ["g:haddock_browser","g:haddock_browser_callformat","g:haddock_docdir","g:haddock_indexfiledir","s:ghc_libdir","g:ghc_version","s:docdir","s:libraries","s:guide","s:haddock_indexfile"]
if exists(v)
echo v '=' eval(v)
else
echo v '='
endif
endfor
endfunction

function! DocBrowser(url)
"echomsg "DocBrowser(".url.")"
if (!exists("g:haddock_browser") || !executable(g:haddock_browser))
echoerr s:scriptname." can't find documentation browser. please set g:haddock_browser"
return
endif
" start browser to open url, according to specified format
let url = a:url=~'^\(file://\|http://\)' ? a:url : 'file://'.a:url
silent exe '!'.printf(g:haddock_browser_callformat,g:haddock_browser,escape(url,'#%'))
endfunction

"Doc/Doct are an old interface for documentation lookup
"(that is the reason they are not documented!-)
"
"These uses are still fine at the moment, and are the reason
"that this command still exists at all
"
" :Doc -top
" :Doc -libs
" :Doc -guide
"
"These uses may or may not work, and shouldn't be relied on anymore
"(usually, you want _?/_?1/_?2 or :MDoc; there is also :IDoc)
"
" :Doc length
" :Doc Control.Monad.when
" :Doc Data.List.
" :Doc Control.Monad.State.runState mtl
command! -nargs=+ Doc call Doc('v',<f-args>)
command! -nargs=+ Doct call Doc('t',<f-args>)

function! Doc(kind,qualname,...)
let suffix = '.html'
let relative = '#'.a:kind.'%3A'

if a:qualname=="-top"
call DocBrowser(s:docdir . s:index)
return
elseif a:qualname=="-libs"
call DocBrowser(s:libraries . s:index)
return
elseif a:qualname=="-guide"
call DocBrowser(s:guide . s:index)
return
endif

if a:0==0 " no package specified
let package = 'base/'
else
let package = a:1 . '/'
endif

if match(a:qualname,'\.')==-1 " unqualified name
let [qual,name] = [['Prelude'],a:qualname]
let file = join(qual,'-') . suffix . relative . name
elseif a:qualname[-1:]=='.' " module qualifier only
let parts = split(a:qualname,'\.')
let quallen = len(parts)-1
let [qual,name] = [parts[0:quallen],parts[-1]]
let file = join(qual,'-') . suffix
else " qualified name
let parts = split(a:qualname,'\.')
let quallen = len(parts)-2
let [qual,name] = [parts[0:quallen],parts[-1]]
let file = join(qual,'-') . suffix . relative . name
endif

let path = s:libraries . package . file
call DocBrowser(path)
endfunction

" TODO: add commandline completion for :IDoc
" switch to :emenu instead of inputlist?
" indexed variant of Doc, looking up links in g:haddock_index
" usage:
" 1. :IDoc length
" 2. click on one of the choices, or select by number (starting from 0)
command! -nargs=+ IDoc call IDoc(<f-args>)
function! IDoc(name,...)
let choices = HaddockIndexLookup(a:name)
if choices=={} | return | endif
if a:0==0
let keylist = map(deepcopy(keys(choices)),'substitute(v:val,"\\[.\\]","","")')
let choice = inputlist(keylist)
else
let choice = a:1
endif
let path = values(choices)[choice] " assumes same order for keys/values..
call DocBrowser(path)
endfunction

let s:flagref = s:guide . 'flag-reference.html'
if filereadable(s:flagref)
" extract the generated fragment ids for the
" flag reference sections
let s:headerPat = '.\{-}<h3 class="title"><a name="\([^"]*\)"><\/a>\([^<]*\)<\/h3>\(.*\)'
let s:flagheaders = []
let s:flagheaderids = {}
let s:contents = join(readfile(s:flagref))
let s:ml = matchlist(s:contents,s:headerPat)
while s:ml!=[]
let [_,s:id,s:title,s:r;s:x] = s:ml
let s:flagheaders = add(s:flagheaders, s:title)
let s:flagheaderids[s:title] = s:id
let s:ml = matchlist(s:r,s:headerPat)
endwhile
command! -nargs=1 -complete=customlist,CompleteFlagHeaders FlagReference call FlagReference(<f-args>)
function! FlagReference(section)
let relativeUrl = a:section==""||!exists("s:flagheaderids['".a:section."']") ?
\ "" : "#".s:flagheaderids[a:section]
call DocBrowser(s:flagref.relativeUrl)
endfunction
function! CompleteFlagHeaders(al,cl,cp)
let s:choices = s:flagheaders
return CompleteAux(a:al,a:cl,a:cp)
endfunction
endif

command! -nargs=1 -complete=customlist,CompleteHaddockModules MDoc call MDoc(<f-args>)
function! MDoc(module)
let suffix = '.html'
call HaveModuleIndex()
if !has_key(g:haddock_moduleindex,a:module)
echoerr a:module 'not found in haddock module index'
return
endif
let package = g:haddock_moduleindex[a:module]['package']
let file = substitute(a:module,'\.','-','g') . suffix
" let path = s:libraries . package . '/' . file
let path = g:haddock_moduleindex[a:module]['html']
call DocBrowser(path)
endfunction

function! CompleteHaddockModules(al,cl,cp)
call HaveModuleIndex()
let s:choices = keys(g:haddock_moduleindex)
return CompleteAux(a:al,a:cl,a:cp)
endfunction

" create a dictionary g:haddock_index, containing the haddoc index
command! DocIndex call DocIndex()
function! DocIndex()
let files = split(globpath(s:libraries,'doc-index*.html'),'\n')
let g:haddock_index = {}
call ProcessHaddockIndexes2(s:libraries,files)
if haskellmode#GHC_VersionGE([6,8,2])
if &shell =~ 'sh' " unix-type shell
let s:addon_libraries = split(system(g:ghc_pkg . ' field \* haddock-html'),'\n')
else " windows cmd.exe and the like
let s:addon_libraries = split(system(g:ghc_pkg . ' field * haddock-html'),'\n')
endif
for addon in s:addon_libraries
let ml = matchlist(addon,'haddock-html: \("\)\?\(file:///\)\?\([^"]*\)\("\)\?')
if ml!=[]
let [_,quote,file,addon_path;x] = ml
let addon_path = substitute(addon_path,'\(\\\\\|\\\)','/','g')
let addon_files = split(globpath(addon_path,'doc-index*.html'),'\n')
call ProcessHaddockIndexes2(addon_path,addon_files)
endif
endfor
endif
return 1
endfunction

function! ProcessHaddockIndexes(location,files)
let entryPat= '.\{-}"indexentry"[^>]*>\([^<]*\)<\(\%([^=]\{-}TD CLASS="\%(indexentry\)\@!.\{-}</TD\)*\)[^=]\{-}\(\%(="indexentry\|TABLE\).*\)'
let linkPat = '.\{-}HREF="\([^"]*\)".>\([^<]*\)<\(.*\)'

redraw
echo 'populating g:haddock_index from haddock index files in ' a:location
for f in a:files
echo f[len(a:location):]
let contents = join(readfile(f))
let ml = matchlist(contents,entryPat)
while ml!=[]
let [_,entry,links,r;x] = ml
"echo entry links
let ml2 = matchlist(links,linkPat)
let link = {}
while ml2!=[]
let [_,l,m,links;x] = ml2
"echo l m
let link[m] = a:location . '/' . l
let ml2 = matchlist(links,linkPat)
endwhile
let g:haddock_index[DeHTML(entry)] = deepcopy(link)
"echo entry g:haddock_index[entry]
let ml = matchlist(r,entryPat)
endwhile
endfor
endfunction

" concatenating all lines is too slow for a big file, process lines directly
function! ProcessHaddockIndexes2(location,files)
let entryPat= '^>\([^<]*\)</'
let linkPat = '.\{-}A HREF="\([^"]*\)"'
let kindPat = '#\(.\)'

" redraw
echo 'populating g:haddock_index from haddock index files in ' a:location
for f in a:files
echo f[len(a:location):]
let isEntry = 0
let isLink = ''
let link = {}
let entry = ''
for line in readfile(f)
if line=~'CLASS="indexentry'
if (link!={}) && (entry!='')
if has_key(g:haddock_index,DeHTML(entry))
let dict = extend(g:haddock_index[DeHTML(entry)],deepcopy(link))
else
let dict = deepcopy(link)
endif
let g:haddock_index[DeHTML(entry)] = dict
let link = {}
let entry = ''
endif
let isEntry=1
continue
endif
if isEntry==1
let ml = matchlist(line,entryPat)
if ml!=[] | let [_,entry;x] = ml | let isEntry=0 | continue | endif
endif
if entry!=''
let ml = matchlist(line,linkPat)
if ml!=[] | let [_,isLink;x]=ml | continue | endif
endif
if isLink!=''
let ml = matchlist(line,entryPat)
if ml!=[]
let [_,module;x] = ml
let [_,kind;x] = matchlist(isLink,kindPat)
let last = a:location[strlen(a:location)-1]
let link[module."[".kind."]"] = a:location . (last=='/'?'':'/') . isLink
let isLink=''
continue
endif
endif
endfor
if link!={}
if has_key(g:haddock_index,DeHTML(entry))
let dict = extend(g:haddock_index[DeHTML(entry)],deepcopy(link))
else
let dict = deepcopy(link)
endif
let g:haddock_index[DeHTML(entry)] = dict
endif
endfor
endfunction

command! ExportDocIndex call ExportDocIndex()
function! ExportDocIndex()
call HaveIndex()
let entries = []
for key in keys(g:haddock_index)
let entries += [key,string(g:haddock_index[key])]
endfor
call writefile(entries,s:haddock_indexfile)
redir end
endfunction

command! ImportDocIndex call ImportDocIndex()
function! ImportDocIndex()
if filereadable(s:haddock_indexfile)
let lines = readfile(s:haddock_indexfile)
let i=0
while i<len(lines)
let [key,dict] = [lines[i],lines[i+1]]
sandbox let g:haddock_index[key] = eval(dict)
let i+=2
endwhile
return 1
else
return 0
endif
endfunction

function! HaveIndex()
return (g:haddock_index!={} || ImportDocIndex() || DocIndex() )
endfunction

function! MkHaddockModuleIndex()
let g:haddock_moduleindex = {}
call HaveIndex()
for key in keys(g:haddock_index)
let dict = g:haddock_index[key]
for module in keys(dict)
let html = dict[module]
let html = substitute(html ,'#.*$','','')
let module = substitute(module,'\[.\]','','')
let ml = matchlist(html,'libraries/\([^\/]*\)[\/]')
if ml!=[]
let [_,package;x] = ml
let g:haddock_moduleindex[module] = {'package':package,'html':html}
endif
let ml = matchlist(html,'/\([^\/]*\)\/html/[A-Z]')
if ml!=[]
let [_,package;x] = ml
let g:haddock_moduleindex[module] = {'package':package,'html':html}
endif
endfor
endfor
endfunction

function! HaveModuleIndex()
return (g:haddock_moduleindex!={} || MkHaddockModuleIndex() )
endfunction

" decode HTML symbol encodings (are these all we need?)
function! DeHTML(entry)
let res = a:entry
let decode = { '&lt;': '<', '&gt;': '>', '&amp;': '\\&' }
for enc in keys(decode)
exe 'let res = substitute(res,"'.enc.'","'.decode[enc].'","g")'
endfor
return res
endfunction

" find haddocks for word under cursor
" also lists possible definition sites
" - needs to work for both qualified and unqualified items
" - for 'import qualified M as A', consider M.item as source of A.item
" - offer sources from both type [t] and value [v] namespaces
" - for unqualified items, list all possible sites
" - for qualified items, list imported sites only
" keep track of keys with and without namespace tags:
" the former are needed for lookup, the latter for matching against source
map <LocalLeader>? :call Haddock()<cr>
function! Haddock()
amenu ]Popup.- :echo '-'<cr>
aunmenu ]Popup
let namsym = haskellmode#GetNameSymbol(getline('.'),col('.'),0)
if namsym==[]
redraw
echo 'no name/symbol under cursor!'
return 0
endif
let [start,symb,qual,unqual] = namsym
let imports = haskellmode#GatherImports()
let asm = has_key(imports[1],qual) ? imports[1][qual]['modules'] : []
let name = unqual
let dict = HaddockIndexLookup(name)
if dict=={} | return | endif
" for qualified items, narrow results to possible imports that provide qualifier
let filteredKeys = filter(copy(keys(dict))
\ ,'match(asm,substitute(v:val,''\[.\]'','''',''''))!=-1')
let keys = (qual!='') ? filteredKeys : keys(dict)
if (keys==[]) && (qual!='')
echoerr qual.'.'.unqual.' not found in imports'
return 0
endif
" use 'setlocal completeopt+=menuone' if you always want to see menus before
" anything happens (I do, but many users don't..)
if len(keys)==1 && (&completeopt!~'menuone')
call DocBrowser(dict[keys[0]])
elseif has("gui_running")
for key in keys
exe 'amenu ]Popup.'.escape(key,'\.').' :call DocBrowser('''.dict[key].''')<cr>'
endfor
popup ]Popup
else
let s:choices = keys
let key = input('browse docs for '.name.' in: ','','customlist,CompleteAux')
if key!=''
call DocBrowser(dict[key])
endif
endif
endfunction

if !exists("g:haskell_search_engines")
let g:haskell_search_engines =
\ {'hoogle':'http://www.haskell.org/hoogle/?hoogle=%s'
\ ,'hayoo!':'http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s'
\ }
endif

map <LocalLeader>?? :let es=g:haskell_search_engines
\ \|echo "g:haskell_search_engines"
\ \|for e in keys(es)
\ \|echo e.' : '.es[e]
\ \|endfor<cr>
map <LocalLeader>?1 :call HaskellSearchEngine('hoogle')<cr>
map <LocalLeader>?2 :call HaskellSearchEngine('hayoo!')<cr>

" query one of the Haskell search engines for the thing under cursor
" - unqualified symbols need to be url-escaped
" - qualified ids need to be fed as separate qualifier and id for
" both hoogle (doesn't handle qualified symbols) and hayoo! (no qualified
" ids at all)
" - qualified ids referring to import-qualified-as qualifiers need to be
" translated to the multi-module searches over the list of original modules
function! HaskellSearchEngine(engine)
amenu ]Popup.- :echo '-'<cr>
aunmenu ]Popup
let namsym = haskellmode#GetNameSymbol(getline('.'),col('.'),0)
if namsym==[]
redraw
echo 'no name/symbol under cursor!'
return 0
endif
let [start,symb,qual,unqual] = namsym
let imports = haskellmode#GatherImports()
let asm = has_key(imports[1],qual) ? imports[1][qual]['modules'] : []
let unqual = haskellmode#UrlEncode(unqual)
if a:engine=='hoogle'
let name = asm!=[] ? unqual.'+'.join(map(copy(asm),'"%2B".v:val'),'+')
\ : qual!='' ? unqual.'+'.haskellmode#UrlEncode('+').qual
\ : unqual
elseif a:engine=='hayoo!'
let name = asm!=[] ? unqual.'+module:('.join(copy(asm),' OR ').')'
\ : qual!='' ? unqual.'+module:'.qual
\ : unqual
else
let name = qual=="" ? unqual : qual.".".unqual
endif
if has_key(g:haskell_search_engines,a:engine)
call DocBrowser(printf(g:haskell_search_engines[a:engine],name))
else
echoerr "unknown search engine: ".a:engine
endif
endfunction

" used to pass on choices to CompleteAux
let s:choices=[]

" if there's no gui, use commandline completion instead of :popup
" completion function CompleteAux suggests completions for a:al, wrt to s:choices
function! CompleteAux(al,cl,cp)
"echomsg '|'.a:al.'|'.a:cl.'|'.a:cp.'|'
let res = []
let l = len(a:al)-1
for r in s:choices
if l==-1 || r[0 : l]==a:al
let res += [r]
endif
endfor
return res
endfunction

" CamelCase shorthand matching:
" favour upper-case letters and module qualifier separators (.) for disambiguation
function! CamelCase(shorthand,string)
let s1 = a:shorthand
let s2 = a:string
let notFirst = 0 " don't elide before first pattern letter
while ((s1!="")&&(s2!=""))
let head1 = s1[0]
let head2 = s2[0]
let elide = notFirst && ( ((head1=~'[A-Z]') && (head2!~'[A-Z.]'))
\ ||((head1=='.') && (head2!='.')) )
if elide
let s2=s2[1:]
elseif (head1==head2)
let s1=s1[1:]
let s2=s2[1:]
else
return 0
endif
let notFirst = (head1!='.')||(head2!='.') " treat separators as new beginnings
endwhile
return (s1=="")
endfunction

" use haddock name index for insert mode completion (CTRL-X CTRL-U)
function! CompleteHaddock(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
let qual = a:base =~ '^[A-Z][a-zA-Z0-9_'']*\(\.[A-Z][a-zA-Z0-9_'']*\)*\(\.[a-zA-Z0-9_'']*\)\?$'
call HaveIndex()
for key in keys(g:haddock_index)
let keylist = map(deepcopy(keys(g:haddock_index[key])),'substitute(v:val,"\\[.\\]","","")')
if (key[0 : l]==a:base)
for m in keylist
let res += [{"word":key,"menu":m,"dup":1}]
endfor
elseif qual " this tends to be slower
for m in keylist
let word = m . '.' . key
if word[0 : l]==a:base
let res += [{"word":word,"menu":m,"dup":1}]
endif
endfor
endif
endfor
if res==[] " no prefix matches, try CamelCase shortcuts
for key in keys(g:haddock_index)
let keylist = map(deepcopy(keys(g:haddock_index[key])),'substi