leksah-0.8.0.6: src/IDE/YiConfig.hs
{- 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 (
yiVimConfig
) where
import Yi.Prelude
import Prelude ()
import Yi
import Yi.Keymap.Vim
import Yi.Buffer.Indent (indentAsPreviousB)
import Yi.Keymap.Keys
import Yi.Misc (adjBlock)
import qualified Yi.UI.Pango
import Yi.Style.Library (darkBlueTheme)
import Data.List (isPrefixOf, reverse, replicate)
import Control.Monad (replicateM_)
-- 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
yiVimConfig = 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