yi-0.4: Yi/Mode/Shim.hs
{-# LANGUAGE DeriveDataTypeable #-}
module Yi.Mode.Shim where
import Data.List
import Yi
import Shim.Hsinfo as Hsinfo
import Yi.Buffer
import Yi.Modes
import Control.Monad.State
import qualified Shim.Hsinfo as Hsinfo
import SrcLoc
import FastString
import Control.Monad.State
import Yi.WindowSet as Robin
import Outputable hiding (char)
import Yi.Accessor
import Yi.Prelude
import Prelude ()
import Data.Char
import Yi.GHC
import qualified Yi.Lexer.Alex
import Yi.Syntax
import Yi.Syntax.Linear as Linear
import Yi.Lexer.Haskell
modeTable :: ReaderT String Maybe AnyMode
modeTable = ReaderT $ \fname -> case () of
_ | ".hs" `isSuffixOf` fname -> Just (AnyMode mode)
_ -> Nothing
jumpToSrcLoc :: SrcLoc -> YiM ()
jumpToSrcLoc locn =
if isGoodSrcLoc locn
then jumpToE (unpackFS $ srcLocFile locn) (srcLocLine locn) (srcLocCol locn)
else msgEditor $ show (ppr locn defaultUserStyle)
jumpToNextNote :: YiM ()
jumpToNextNote = do
note <- withEditor $ do
modifyA notesA (fmap forward)
getsA notesA (fmap current)
case note of
Nothing -> msgEditor "No note!"
Just n -> jumpToSrcLoc $ srcSpanStart $ srcSpan $ n
-- | Position of the cursor
cursorPos :: BufferM (Maybe String, Int, Int)
cursorPos = (,,) <$> gets file <*> curLn <*> curCol
-- | Type of the symbol at current position
typeAtPos :: YiM String
typeAtPos = do
(Just filename,line,col) <- withBuffer cursorPos
withShim $ do
Hsinfo.findTypeOfPos filename line col Nothing
-- | Annotate the current function with its type
annotType :: YiM ()
annotType = do
t <- typeAtPos
withBuffer $ do
moveToSol
insertN $ t ++ "\n"
-- | Update a line of the form "-- expr = value" with the new value of expr
annotValue :: YiM ()
annotValue = do
lnReg <- withBuffer $ regionOfB Yi.Line
Just sourcefile <- withBuffer $ gets file
ln <- withBuffer $ readRegionB lnReg
let lhs = takeWhile (/= '=') $ dropWhile (== '-') $ dropWhile isSpace $ ln
newVal <- withShim $ do
ses <- getSessionFor sourcefile
evaluate ses lhs
withBuffer $ replaceRegionB lnReg ("--" ++ lhs ++ "= " ++ newVal)
jumpToDefinition :: YiM ()
jumpToDefinition = do
(Just filename,line,col) <- withBuffer cursorPos
locn <- withShim $ Hsinfo.findDefinition filename line col Nothing
jumpToSrcLoc locn
-- NOTE: source argument to Hsinfo functions can be used to provide
-- source text, apparently.
mode :: Mode (Linear.Result (Yi.Lexer.Alex.Tok Token))
mode = haskellMode
{
modeKeymap = (<||)
(((ctrl $ char 'c') ?>> choice
[ctrl (char 't') ?>>! typeAtPos,
char '!' ?>> char 't' ?>>! annotType,
char '!' ?>> char '=' ?>>! annotType,
ctrl (char 'd') ?>>! jumpToDefinition,
ctrl (char 'l') ?>>! do
withEditor $ do
withOtherWindow $ do
switchToBufferWithNameE "*messages*"
msgEditor "Loading..."
Just filename <- withBuffer $ gets file
runShimThread (Hsinfo.load filename True Nothing >> return ())
return ()
]
) <|> (ctrl (char 'x') ?>> char '`' ?>>! jumpToNextNote))
}