{- Based on example config Yi/Users/Corey.hs that uses the Vim keymap with these additions: - Always uses the VTY UI by default. - The color style is darkBlueTheme - The insert mode of the Vim keymap has been extended with a few additions I find useful. -} module IDE.YiConfig ( defaultYiConfig , Config , Control , ControlM , YiM , start , runControl , liftYi ) where #ifdef LEKSAH_WITH_YI import Data.List (reverse, isPrefixOf) import Yi.Prelude import Prelude () import Yi import Yi.Keymap.Vim import qualified Yi.UI.Pango import Yi.UI.Pango.Control import Control.Monad (replicateM_) start yiConfig f = startControl yiConfig $ do yiControl <- getControl controlIO (f yiControl) -- Set soft tabs of 4 spaces in width. prefIndent :: Mode s -> Mode s prefIndent m = m { modeIndentSettings = IndentSettings { expandTabs = True, shiftWidth = 4, tabSize = 4 }} noHaskellAnnots m | modeName m == "haskell" = m { modeGetAnnotations = modeGetAnnotations emptyMode } | otherwise = m defaultYiConfig = defaultConfig { -- Use VTY as the default UI. startFrontEnd = Yi.UI.Pango.start, defaultKm = mkKeymap extendedVimKeymap, modeTable = fmap (onMode $ noHaskellAnnots . prefIndent) (modeTable defaultConfig), configUI = (configUI defaultConfig) { configTheme = defaultLightTheme } } extendedVimKeymap = defKeymap `override` \super self -> super { v_top_level = (deprioritize >> v_top_level super) -- On 'o' in normal mode I always want to use the indent of the previous line. -- TODO: If the line where the newline is to be inserted is inside a -- block comment then the block comment should be "continued" -- TODO: Ends up I'm trying to replicate vim's "autoindent" feature. This -- should be made a function in Yi. <|> (char 'o' ?>> beginIns self $ do moveToEol insertB '\n' indentAsPreviousB ) -- On HLX (Haskell Language Extension) I want to go into insert mode such -- that the cursor position is correctly placed to start entering the name -- of an language extension in a LANGUAGE pragma. -- A language pragma will take either the form -- {-# LANGUAGE Foo #-} -- or -- >{-# LANGUAGE Foo #-} -- The form should be chosen based on the current mode. <|> ( pString "HXL" >> startExtesnionNameInsert self ), v_ins_char = (deprioritize >> v_ins_char super) -- On enter I always want to use the indent of previous line -- TODO: If the line where the newline is to be inserted is inside a -- block comment then the block comment should be "continued" -- TODO: Ends up I'm trying to replicate vim's "autoindent" feature. This -- should be made a function in Yi. <|> ( spec KEnter ?>>! do insertB '\n' indentAsPreviousB ) -- I want softtabs to be deleted as if they are tabs. So if the -- current col is a multiple of 4 and the previous 4 characters -- are spaces then delete all 4 characters. -- TODO: Incorporate into Yi itself. <|> ( spec KBS ?>>! do c <- curCol line <- readRegionB =<< regionOfPartB Line Backward sw <- indentSettingsB >>= return . shiftWidth let indentStr = replicate sw ' ' toDel = if (c `mod` sw) /= 0 then 1 else if indentStr `isPrefixOf` reverse line then sw else 1 adjBlock (-toDel) replicateM_ toDel $ deleteB Character Backward ) -- On starting to write a block comment I want the close comment -- text inserted automatically. <|> choice [ pString open_tag >>! do insertN $ open_tag ++ " \n" indentAsPreviousB insertN $ " " ++ close_tag lineUp | (open_tag, close_tag) <- [ ("{-", "-}") -- Haskell block comments , ("/*", "*/") -- C++ block comments ] ] } startExtesnionNameInsert :: ModeMap -> I Event Action () startExtesnionNameInsert self = beginIns self $ do p_current <- pointB m_current <- getMarkB (Just "'") setMarkPointB m_current p_current moveTo $ Point 0 insertB '\n' moveTo $ Point 0 insertN "{-# LANGUAGE " p <- pointB insertN " #-}" moveTo p #else data Config = Config data Control = Control data ControlM a = ControlM data YiM a = YiM defaultYiConfig :: Config defaultYiConfig = Config start :: Config -> (Control -> IO a) -> IO a start yiConfig f = f Control runControl :: ControlM a -> Control -> IO a runControl = undefined liftYi :: YiM a -> ControlM a liftYi = undefined #endif