Skip to content
This repository has been archived by the owner on Mar 4, 2023. It is now read-only.

Commit

Permalink
Vim implementation update.
Browse files Browse the repository at this point in the history
LoadComponent, BackgroundTypecheckFile, ThingAtPoint all seem to work fine.
  • Loading branch information
MarcWeber authored and nominolo committed May 25, 2009
1 parent d115e99 commit 9f74693
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 53 deletions.
44 changes: 25 additions & 19 deletions server/Scion/Server/Protocol/Vim.hs
Expand Up @@ -26,7 +26,7 @@ import Scion.Configure (configureCabalProject)
import Scion.Utils ( unqualifiedForModule )
import Scion.Session (preprocessPackage, currentCabalPackage, loadComponent,
backgroundTypecheckFile, unload, setGHCVerbosity, addCmdLineFlags)
import FastString (fsLit)
import FastString (fsLit, unpackFS)

import Control.Monad (forever, liftM)
import Control.Exception.Base (Exception)
Expand Down Expand Up @@ -291,26 +291,32 @@ instance ToVimType Bool where
instance ToVimType CompilationResult where
toVim cr = toVim [
("compilationSucceeded", toVim (compilationSucceeded cr)),
("compilationWarnings", toVim ([] :: [ErrMsg])), --(compilationWarnings cr)),
("compilationErrors", toVim ([] :: [ErrMsg])), --(compilationErrors cr)),
("compilationWarnings", toVim $ concatMap errMsgToVimList ([] :: [ErrMsg])),
("compilationErrors", toVim $ concatMap errMsgToVimList ([] :: [ErrMsg])),
("compilationTime", toVim ( "TODO" {- (compilationTime cr-} ))
]
instance (ToVimType a) => ToVimType (Bag a) where
toVim = listToVim . bagToList
instance ToVimType ErrMsg where
toVim em = toVim [
("errMsgSpans", toVim (errMsgSpans em)),
("errMsgContext", toVim (errMsgSpans em)),
("errMsgShortDoc", toVim (errMsgSpans em)),
("errMsgExtraInfo", toVim (errMsgSpans em))
]
instance ToVimType SrcSpan where
toVim ss = let start = srcSpanStart ss in toVim $ [
("file", (toVim . show) ( srcLocFile start)),
("line", toVim ( srcLocLine start)),
("col", toVim ( srcLocCol start))
]
-- TODO, what about span end ? do we need it
-- return list which can be passed to setqflist
errMsgToVimList :: ErrMsg -> [VimType]
errMsgToVimList em =
let (fst:moreLocations) = errMsgSpans em
loc :: SrcSpan -> [(VimType, VimType)]
loc em =
[ (toVim "filename", (toVim . unpackFS) ( (srcLocFile . srcSpanStart) em))
, (toVim "lnum", toVim ( srcLocLine . srcSpanStart $ em))
, (toVim "col", toVim ( srcLocCol . srcSpanStart $ em))
]

-- ghc does print multiline messages. So add a text qf item for all
-- trailing lines to keep them readable
addText :: VimType -> [String] -> [VimType]
addText (VDict map') [msg] = [VDict $ M.insert (toVim "text") (toVim msg) map']
addText (VDict map') (msg:msgs) = addText (VDict map') [msg] ++ map (\m -> toVim [(toVim "text", toVim m)]) msgs
-- addText _ _ = error "never executed"
in
-- first location and message
(addText (toVim $ loc fst) $ lines $ (O.showSDoc (errMsgShortDoc em)) ++ ("\n" ++ O.showSDoc (errMsgExtraInfo em)))
-- more error locations - when do they occur?
++ map (toVim . loc) moreLocations

instance ToVimType O.SDoc where
toVim = toVim . O.showSDoc
Expand Down
17 changes: 11 additions & 6 deletions vim_runtime_path/autoload/haskellcomplete.vim
@@ -1,6 +1,10 @@
" haskellcomplete.vim - Omni Completion for haskell
" This file contains the code necessary to talk to the scion server
" -> haskellcomplete#EvalScion )
"
" This implementation requires has('python') support
"
" You can look up some use cases in the ftplugin file.
"
" This file talks to the scion server. You need python support
" This code is based on the initial implementation found in shim by Benedikt Schmidt
" The server side code can be found in src-scion-server/Scion/Server/ProtocolVim.hs

Expand Down Expand Up @@ -81,14 +85,15 @@ class ScionServerConnectionStdinOut(ScionServerConnection):
self.scion_o = p.stdout
self.scion_i = p.stdin
def receive(self):
let s = super.receive()
s = ScionServerConnection.receive(self)
if s[:6] == "scion:":
# ghc doesn't always use the ghc API to print statements.. so ignore all
# lines not marked by "scion:" at the beginning
# see README.markdown
return s[6:]
else:
self.receive()
# throw away non "scion:" line and try again
return self.receive()

class ScionServerConnectionSocket(ScionServerConnection):
"""connects to the scion server by either TCP/IP or socketfile"""
Expand All @@ -114,7 +119,7 @@ def connectscion():
global told_user_about_missing_configuration
if 0 == told_user_about_missing_configuration:
try:
print scionConnectionSetting
print "connecting to scion %s"%scionConnectionSetting.__str__()
except NameError:
vim.command("sp")
b = vim.current.buffer
Expand Down Expand Up @@ -143,7 +148,7 @@ def evalscion(str):
try:
server_connection.send(str)
except:
vim.command('echoe "%s"'% ("(re) connecting to scion"))
vim.command('echom "%s"'% ("(re)connecting to scion"))
connectscion()
server_connection.send(str)
return server_connection.receive()
Expand Down
104 changes: 76 additions & 28 deletions vim_runtime_path/ftplugin/haskell.vim
@@ -1,35 +1,83 @@
finish
" old shim stuff :
setlocal omnifunc=haskellcomplete#CompleteIdentifier
setlocal completefunc=haskellcomplete#CompleteModule
command! -nargs=1 GrepScope call haskellcomplete#GrepScope(<f-args>)
command! -nargs=1 FindModulesExporting echo haskellcomplete#FindModulesExporting(<f-args>)
if exists('g:dont_load_haskell_scion_interface_simple')
finish
endif

let g:haskellModuleImportBehaviour = 'interactive' " one of interactive, automatic
" r = scion result with error locations
" func : either setqflist or setloclist
fun! ScionResultToErrorList(action, func, r)
let compilationResult = has_key(a:r, 'compilationResult') ? a:r['compilationResult'] : a:r
let g:foo = compilationResult
let qflist = compilationResult['compilationErrors'] + compilationResult['compilationWarnings']

if !exists('g:modulePreferenceCacheFile')
let g:modulePreferenceCacheFile = expand('$HOME').'/.vim/modulePreferenceCacheFile'
endif
" for debugging
let g:scion_qf_list = qflist
if has_key(a:r, 'inProject')
let inProj = "inProject : ". a:r['inProject']
else
let inProj = ""
endif
if (has_key(a:r,'compilationSucceeded') && a:r['compilationSucceeded'])
\ || (!has_key(a:r, 'compilationSucceeded') && len(qflist) == 0)
return printf(a:action." success. ".inProj." compilationTime: %s", compilationResult['compilationTime'])
else
call call(a:func, [qflist])
return printf(a:action." there are errors, ".inProj." compilationTime: %s", compilationResult['compilationTime'])
endif
endfun

if filereadable(g:modulePreferenceCacheFile)
let g:modulePreferences = eval(readfile(g:modulePreferences, 'b'))
else
let g:modulePreferences = {
\ 'Data.Map' : { 'q' : 'M' }
\ , 'Control.Monad' : { 'fitness' : 10 }
" very simple user interface to expose scion functionality
" I'll implement a better interface in tovl.
" (http://github.com/MarcWeber/theonevimlib)

\ }
endif
fun! s:BackgroundTypecheckFile(...)
" no file given defaults to current buffer
let file = a:0 > 0 ? a:1 : expand('%:p')
let r = haskellcomplete#EvalScion({'request' : 'cmdBackgroundTypecheckFile', 'file' : file})
echo ScionResultToErrorList('file check', 'setqflist', r)
endf

fun! s:OpenCabalProject(...)
let builddir = a:0 > 0 ? a:1 : "dist"
echo haskellcomplete#EvalScion(
\ {'request' : 'cmdOpenCabalProject', 'root_dir' : getcwd(),
\ 'dist_dir' : builddir, 'extra_args' : a:000[1:] }
\)
endf

" ===== you don't need any project for these: =============
command! -buffer ConnectionInfo
\ echo haskellcomplete#EvalScion({'request' : 'cmdConnectionInfo'})

" list supported languages
command! -buffer ListSupportedLanguages
\ echo haskellcomplete#EvalScion({'request' : 'cmdListSupportedLanguages'})

" list supported pragmas
command! -buffer ListSupportedPragmas
\ echo haskellcomplete#EvalScion({'request' : 'cmdListSupportedPragmas'})

" list supported flags
command! -buffer ListSupportedFlags
\ echo haskellcomplete#EvalScion({'request' : 'cmdListSupportedFlags'})

" ===== loading a cabal project: ============================

" assuming pwd is current cabal directory containing the .cabal file
" optional argument specifies the cabal build (dist) directory
command! -buffer -nargs=* -complete=file OpenCabalProject
\ call s:OpenCabalProject(<f-args>)

" returns 0 (= not importet)
" or { 'q' : <opitonal qualifier name>
" , 'functions' : [ list of explicit imported functions ] }
function! ImportInfo(module)
let pos =
endfunction
" arg either "library" or "executable:name"
command! -buffer -nargs=1 LoadComponent
\ echo ScionResultToErrorList('load component finished: ','setqflist',haskellcomplete#EvalScion({'request' : 'cmdLoadComponent', 'component' : <q-args>}))

" list exposed
command! -buffer ListExposedModules
\ echo haskellcomplete#EvalScion({'request' : 'cmdListExposedModules'})
command! -buffer -nargs=* -complete=file BackgroundTypecheckFile
\ call s:BackgroundTypecheckFile(<f-args>)
command! -buffer ThingAtPoint
\ echo haskellcomplete#EvalScion({'request' : 'cmdThingAtPoint', 'file' : expand('%:p'), 'line' : line('.').'', 'col' : col('.').''})

" needs g:modulePreferences, g:haskellModuleImportBehaviour
function! HaskellImportIdentifier(id)
let modules = haskellcomplete#FindModulesExporting(a:id)
endfunction
command! -buffer ListRdrNamesInScope
\ echo haskellcomplete#EvalScion({'request' : 'cmdListRdrNamesInScope'})

0 comments on commit 9f74693

Please sign in to comment.