Commit 9c7084f6 authored by Murukesh Mohanan's avatar Murukesh Mohanan

added file lookup func, tex symbol completion, updated plugins

parent e17f7857
"
" 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
Subproject commit e2a120869ba36da5d26df74fb23ef4052d55b6f0
Subproject commit 1b8e4b965adc97af623bf71c046c7d7408aba725
Subproject commit a7758aa188a2a1979070c704ff721216bdd68bc8
Subproject commit 272fc7df3a87876eb2ebd69d29c93920ef8c57c1
" 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
a4paper
a5paper
aa
AA