{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeOperators     #-}
{-# LANGUAGE LambdaCase        #-}
{-# OPTIONS_HADDOCK show-extensions #-}

-- |
-- Module      :  Yi.Keymap.Emacs
-- License     :  GPL-2
-- Maintainer  :  yi-devel@googlegroups.com
-- Stability   :  experimental
-- Portability :  portable
--
-- This module aims at a mode that should be (mostly) intuitive to
-- emacs users, but mapping things into the Yi world when convenient.
-- Hence, do not go into the trouble of trying 100% emulation. For
-- example, @M-x@ gives access to Yi (Haskell) functions, with their
-- native names.

module Yi.Keymap.Emacs ( keymap
                       , mkKeymapSet
                       , defKeymap
                       , ModeMap(..)
                       , eKeymap
                       , completionCaseSensitive
                       ) where

import Control.Applicative      (Alternative ((<|>), empty, some))
import Control.Monad            (replicateM_, unless, void)
import Control.Monad.State      (gets)
import Data.Char                (digitToInt, isDigit)
import Data.Maybe               (fromMaybe)
import Data.Prototype           (Proto (Proto), extractValue)
import Data.Text                ()
import Lens.Micro.Platform      ((.=), makeLenses, (%=))
import Yi.Buffer
import Yi.Command               (shellCommandE)
import Yi.Core
import Yi.Dired                 (dired)
import Yi.Editor
import Yi.File                  (fwriteE, fwriteToE)
import Yi.Keymap                (Keymap, KeymapSet, YiAction (..), YiM, modelessKeymapSet, write)
import Yi.Keymap.Emacs.KillRing
import Yi.Keymap.Emacs.Utils
import Yi.Keymap.Keys
import Yi.MiniBuffer
import Yi.Misc                  (adjIndent, placeMark, selectAll)
import Yi.Mode.Buffers          (listBuffers)
import Yi.Rectangle
import Yi.Search                (isearchFinishWithE, resetRegexE, getRegexE)
import Yi.TextCompletion        (resetComplete, wordComplete')

data ModeMap = ModeMap { ModeMap -> Keymap
_eKeymap :: Keymap
                       , ModeMap -> Bool
_completionCaseSensitive :: Bool
                       }

$(makeLenses ''ModeMap)

keymap :: KeymapSet
keymap :: KeymapSet
keymap = Proto ModeMap -> KeymapSet
mkKeymapSet Proto ModeMap
defKeymap

mkKeymapSet :: Proto ModeMap -> KeymapSet
mkKeymapSet :: Proto ModeMap -> KeymapSet
mkKeymapSet = Keymap -> KeymapSet
modelessKeymapSet (Keymap -> KeymapSet)
-> (Proto ModeMap -> Keymap) -> Proto ModeMap -> KeymapSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModeMap -> Keymap
_eKeymap (ModeMap -> Keymap)
-> (Proto ModeMap -> ModeMap) -> Proto ModeMap -> Keymap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proto ModeMap -> ModeMap
forall t. Proto t -> t
extractValue

defKeymap :: Proto ModeMap
defKeymap :: Proto ModeMap
defKeymap = (ModeMap -> ModeMap) -> Proto ModeMap
forall a. (a -> a) -> Proto a
Proto ModeMap -> ModeMap
template
  where
    template :: ModeMap -> ModeMap
template ModeMap
self = ModeMap :: Keymap -> Bool -> ModeMap
ModeMap { _eKeymap :: Keymap
_eKeymap = Keymap
emacsKeymap
                            , _completionCaseSensitive :: Bool
_completionCaseSensitive = Bool
False }
      where
        emacsKeymap :: Keymap
        emacsKeymap :: Keymap
emacsKeymap = Maybe Int -> (Char -> Bool) -> Keymap
selfInsertKeymap Maybe Int
forall a. Maybe a
Nothing Char -> Bool
isDigit Keymap -> Keymap -> Keymap
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Bool -> Keymap
completionKm (ModeMap -> Bool
_completionCaseSensitive ModeMap
self) Keymap -> Keymap -> Keymap
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
             do Maybe Int
univArg <- KeymapM (Maybe Int)
readUniversalArg
                Maybe Int -> (Char -> Bool) -> Keymap
selfInsertKeymap Maybe Int
univArg (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit) Keymap -> Keymap -> Keymap
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Int -> Keymap
emacsKeys Maybe Int
univArg

selfInsertKeymap :: Maybe Int -> (Char -> Bool) -> Keymap
selfInsertKeymap :: Maybe Int -> (Char -> Bool) -> Keymap
selfInsertKeymap Maybe Int
univArg Char -> Bool
condition = do
  Char
c <- I Event Action Char
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
m Char
printableChar
  Bool -> Keymap -> Keymap
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Char -> Bool
condition Char
c) Keymap
forall (f :: * -> *) a. Alternative f => f a
empty
  let n :: Int
n = Maybe Int -> Int
argToInt Maybe Int
univArg
  BufferM () -> Keymap
forall (m :: * -> *) ev a x.
(MonadInteract m Action ev, YiAction a x, Show x) =>
a -> m ()
write (Int -> BufferM () -> BufferM ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
n (Char -> BufferM ()
insertB Char
c))

completionKm :: Bool -> Keymap
completionKm :: Bool -> Keymap
completionKm Bool
caseSensitive = do I Event Action [()] -> Keymap
forall (f :: * -> *) a. Functor f => f a -> f ()
void (I Event Action [()] -> Keymap) -> I Event Action [()] -> Keymap
forall a b. (a -> b) -> a -> b
$ Keymap -> I Event Action [()]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some (Event -> Event
meta (Char -> Event
char Char
'/') Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Bool -> YiM ()
wordComplete' Bool
caseSensitive)
                                Keymap
forall (f :: * -> *) w e. MonadInteract f w e => f ()
deprioritize
                                EditorM () -> Keymap
forall (m :: * -> *) ev a x.
(MonadInteract m Action ev, YiAction a x, Show x) =>
a -> m ()
write EditorM ()
resetComplete
           -- 'adjustPriority' is there to lift the ambiguity between "continuing" completion
           -- and resetting it (restarting at the 1st completion).

deleteB' :: BufferM ()
deleteB' :: BufferM ()
deleteB' = Int -> BufferM ()
deleteN Int
1

-- | Wrapper around 'moveE' which also cancels incremental search. See
-- issue #499 for details.
moveE :: TextUnit -> Direction -> EditorM ()
moveE :: TextUnit -> Direction -> EditorM ()
moveE TextUnit
u Direction
d = do
  EditorM (Maybe SearchExp)
getRegexE EditorM (Maybe SearchExp)
-> (Maybe SearchExp -> EditorM ()) -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    -- let's check whether searching is in progress (issues #738, #610)
    Maybe SearchExp
Nothing -> () -> EditorM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    Maybe SearchExp
_ -> EditorM () -> EditorM ()
forall a. EditorM a -> EditorM ()
isearchFinishWithE EditorM ()
resetRegexE
  BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (TextUnit -> Direction -> BufferM ()
moveB TextUnit
u Direction
d)

emacsKeys :: Maybe Int -> Keymap
emacsKeys :: Maybe Int -> Keymap
emacsKeys Maybe Int
univArg =
  [Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice [ -- First all the special key bindings
           Key -> Event
spec Key
KTab            Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! IndentBehaviour -> BufferM ()
adjIndent IndentBehaviour
IncreaseCycle
         , Event -> Event
shift (Key -> Event
spec Key
KTab)    Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! IndentBehaviour -> BufferM ()
adjIndent IndentBehaviour
DecreaseCycle
         , Key -> Event
spec Key
KEnter          Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
newlineB
         , Key -> Event
spec Key
KDel            Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM () -> YiM ()
forall a (m :: * -> *). (Show a, YiAction (m a) a) => m a -> YiM ()
deleteRegionOr YiM ()
deleteForward
         , Key -> Event
spec Key
KBS             Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM () -> YiM ()
forall a (m :: * -> *). (Show a, YiAction (m a) a) => m a -> YiM ()
deleteRegionOr YiM ()
deleteBack
         , Key -> Event
spec Key
KHome           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
moveToSol
         , Key -> Event
spec Key
KEnd            Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
moveToEol
         , Key -> Event
spec Key
KLeft           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
Character Direction
Backward
         , Key -> Event
spec Key
KRight          Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
Character Direction
Forward
         , Key -> Event
spec Key
KUp             Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
VLine Direction
Backward
         , Key -> Event
spec Key
KDown           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
VLine Direction
Forward
         , Key -> Event
spec Key
KPageDown       Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
downScreenB
         , Key -> Event
spec Key
KPageUp         Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
upScreenB

         , Event -> Event
shift (Key -> Event
spec Key
KUp)     Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
scrollB (-Int
1))
         , Event -> Event
shift (Key -> Event
spec Key
KDown)   Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
scrollB Int
1)

         -- All the keybindings of the form 'Ctrl + special key'
         , Event -> Event
ctrl (Key -> Event
spec Key
KLeft)    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
prevWordB
         , Event -> Event
ctrl (Key -> Event
spec Key
KRight)   Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
nextWordB
         , Event -> Event
ctrl (Key -> Event
spec Key
KHome)    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
topB
         , Event -> Event
ctrl (Key -> Event
spec Key
KEnd)     Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
botB
         , Event -> Event
ctrl (Key -> Event
spec Key
KUp)      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
prevNParagraphs Int
1)
         , Event -> Event
ctrl (Key -> Event
spec Key
KDown)    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
nextNParagraphs Int
1)

         -- All the keybindings of the form "C-c" where 'c' is some character
         , Char -> Event
ctrlCh Char
'@'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
placeMark
         , Char -> Event
ctrlCh Char
' '           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
placeMark
         , Char -> Event
ctrlCh Char
'/'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
undoB
         , Char -> Event
ctrlCh Char
'_'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
undoB
         , Char -> Event
ctrlCh Char
'a'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> BufferM ()
maybeMoveB TextUnit
Line Direction
Backward)
         , Char -> Event
ctrlCh Char
'b'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
Character Direction
Backward
         , Char -> Event
ctrlCh Char
'd'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
deleteForward
         , Char -> Event
ctrlCh Char
'e'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> BufferM ()
maybeMoveB TextUnit
Line Direction
Forward)
         , Char -> Event
ctrlCh Char
'f'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ TextUnit -> Direction -> EditorM ()
moveE TextUnit
Character Direction
Forward
         , Char -> Event
ctrlCh Char
'g'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Bool -> BufferM ()
setVisibleSelection Bool
False
         , Char -> Event
ctrlCh Char
'h'           Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>> Char -> Event
char Char
'b' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
acceptedInputsOtherWindow
         , Char -> Event
ctrlCh Char
'i'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! IndentBehaviour -> BufferM ()
adjIndent IndentBehaviour
IncreaseOnly
         , Char -> Event
ctrlCh Char
'j'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
newlineAndIndentB
         , Char -> Event
ctrlCh Char
'k'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> YiM ()
killLine Maybe Int
univArg
         , Char -> Event
ctrlCh Char
'l'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (BufferM () -> YiM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM ()
scrollToCursorB YiM () -> YiM () -> YiM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> YiM ()
userForceRefresh)
         , Char -> Event
ctrlCh Char
'm'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Char -> BufferM ()
insertB Char
'\n')
         , Char -> Event
ctrlCh Char
'n'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> EditorM ()
moveE TextUnit
VLine Direction
Forward)
         , Char -> Event
ctrlCh Char
'o'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Char -> BufferM ()
insertB Char
'\n' BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM ()
leftB)
         , Char -> Event
ctrlCh Char
'p'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> EditorM ()
moveE TextUnit
VLine Direction
Backward)
         , Char -> Event
ctrlCh Char
'q'           Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>  Maybe Int -> Keymap
insertNextC Maybe Int
univArg
         , Char -> Event
ctrlCh Char
'r'           Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>  Direction -> Keymap
isearchKeymap Direction
Backward
         , Char -> Event
ctrlCh Char
's'           Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>  Direction -> Keymap
isearchKeymap Direction
Forward
         , Char -> Event
ctrlCh Char
't'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
swapB
         , Char -> Event
ctrlCh Char
'v'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> BufferM ()
scrollDownE Maybe Int
univArg
         , Char -> Event
ctrlCh Char
'w'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
killRegion
         , Char -> Event
ctrlCh Char
'y'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
yank
         , Char -> Event
ctrlCh Char
'z'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
suspendEditor
         , Char -> Event
ctrlCh Char
'+'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
increaseFontSize Int
1)
         , Char -> Event
ctrlCh Char
'-'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
decreaseFontSize Int
1)

         -- All the keybindings of the form "C-M-c" where 'c' is some character
         , Event -> Event
ctrl (Char -> Event
metaCh Char
'w')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
appendNextKillE
         , Event -> Event
ctrl (Char -> Event
metaCh Char
' ')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
layoutManagersNextE
         , Event -> Event
ctrl (Char -> Event
metaCh Char
',')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
layoutManagerNextVariantE
         , Event -> Event
ctrl (Char -> Event
metaCh Char
'.')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
layoutManagerPreviousVariantE
         , Event -> Event
ctrl (Char -> Event
metaCh Char
'j')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
nextWinE
         , Event -> Event
ctrl (Char -> Event
metaCh Char
'k')    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
prevWinE
         , Event -> Event
ctrl (Event -> Event
meta (Event -> Event) -> Event -> Event
forall a b. (a -> b) -> a -> b
$ Key -> Event
spec Key
KEnter) Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
swapWinWithFirstE


-- All the keybindings of the form "S-C-M-c" where 'c' is some key
         , Event -> Event
shift (Event -> Event
ctrl (Event -> Event) -> Event -> Event
forall a b. (a -> b) -> a -> b
$ Char -> Event
metaCh Char
'j') Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
moveWinNextE
         , Event -> Event
shift (Event -> Event
ctrl (Event -> Event) -> Event -> Event
forall a b. (a -> b) -> a -> b
$ Char -> Event
metaCh Char
'k') Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
moveWinPrevE
         , Event -> Event
shift (Event -> Event
ctrl (Event -> Event) -> Event -> Event
forall a b. (a -> b) -> a -> b
$ Event -> Event
meta (Event -> Event) -> Event -> Event
forall a b. (a -> b) -> a -> b
$ Key -> Event
spec Key
KEnter) Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
pushWinToFirstE
         , Key -> [Modifier] -> Event
Event (Char -> Key
KASCII Char
' ') [Modifier
MShift,Modifier
MCtrl,Modifier
MMeta] Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
layoutManagersPreviousE

         -- All the key-bindings which are preceded by a 'C-x'
         , Char -> Event
ctrlCh Char
'x' Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>      Keymap
ctrlX

         , Char -> Event
ctrlCh Char
'c' Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>      Keymap
ctrlC

         -- All The key-bindings of the form M-c where 'c' is some character.
         , Char -> Event
metaCh Char
' '           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> BufferM ()
justOneSep Maybe Int
univArg
         , Char -> Event
metaCh Char
'v'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> BufferM ()
scrollUpE Maybe Int
univArg
         , Char -> Event
metaCh Char
'!'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
shellCommandE
         , Char -> Event
metaCh Char
'<'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
topB
         , Char -> Event
metaCh Char
'>'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
botB
         , Char -> Event
metaCh Char
'%'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
queryReplaceE
         , Char -> Event
metaCh Char
'^'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> BufferM ()
joinLinesE Maybe Int
univArg
         , Char -> Event
metaCh Char
';'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
commentRegion
         , Char -> Event
metaCh Char
'a'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> EditorM ()
moveE TextUnit
unitSentence Direction
Backward)
         , Char -> Event
metaCh Char
'b'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
prevWordB
         , Char -> Event
metaCh Char
'c'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
capitaliseWordB
         , Char -> Event
metaCh Char
'd'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
killWordB
         , Char -> Event
metaCh Char
'e'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> EditorM ()
moveE TextUnit
unitSentence Direction
Forward)
         , Char -> Event
metaCh Char
'f'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
nextWordB
         , Char -> Event
metaCh Char
'h'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
selectNParagraphs Int
1)
         , Char -> Event
metaCh Char
'k'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> BufferM ()
deleteB TextUnit
unitSentence Direction
Forward)
         , Char -> Event
metaCh Char
'l'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
lowercaseWordB
         , Char -> Event
metaCh Char
'm'           Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
firstNonSpaceB
         , Char -> Event
metaCh Char
'q'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (forall syntax. Mode syntax -> syntax -> BufferM ()) -> YiM ()
forall x a.
(Show x, YiAction a x) =>
(forall syntax. Mode syntax -> syntax -> a) -> YiM ()
withSyntax forall syntax. Mode syntax -> syntax -> BufferM ()
modePrettify
         , Char -> Event
metaCh Char
'r'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
moveToMTB
         , Char -> Event
metaCh Char
'u'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
uppercaseWordB
         , Char -> Event
metaCh Char
't'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (TextUnit -> Direction -> BufferM ()
transposeB TextUnit
unitWord Direction
Forward)
         , Char -> Event
metaCh Char
'w'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
killRingSave
         , Char -> Event
metaCh Char
'x'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
executeExtendedCommandE
         , Char -> Event
metaCh Char
'y'           Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
yankPopE
         , Char -> Event
metaCh Char
'.'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
promptTag
         , Char -> Event
metaCh Char
'{'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
prevNParagraphs Int
1)
         , Char -> Event
metaCh Char
'}'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (Int -> BufferM ()
nextNParagraphs Int
1)
         , Char -> Event
metaCh Char
'='           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
countWordsRegion
         , Char -> Event
metaCh Char
'\\'          Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Maybe Int -> BufferM ()
deleteHorizontalSpaceB Maybe Int
univArg
         , Char -> Event
metaCh Char
'@'           Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
markWord

         -- Other meta key-bindings
         , Event -> Event
meta (Key -> Event
spec Key
KBS)      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
bkillWordB
         , Char -> Event
metaCh Char
'g' Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>
             (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
meta (Char -> Event
char Char
'g') I Event Action Event
-> ((Int ::: LineNumber) -> BufferM Int) -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! (Int -> BufferM Int
gotoLn (Int -> BufferM Int)
-> ((Int ::: LineNumber) -> Int)
-> (Int ::: LineNumber)
-> BufferM Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int ::: LineNumber) -> Int
forall t doc. (t ::: doc) -> t
fromDoc :: Int ::: LineNumber -> BufferM Int)
         ]
  where
  -- inserting the empty string prevents the deletion from appearing in the killring
  -- which is a good thing when we are deleting individuals characters. See
  -- http://code.google.com/p/yi-editor/issues/detail?id=212
  blockKillring :: BufferM ()
blockKillring = YiString -> BufferM ()
insertN YiString
""

  withUnivArg :: YiAction (m ()) () => (Maybe Int -> m ()) -> YiM ()
  withUnivArg :: (Maybe Int -> m ()) -> YiM ()
withUnivArg Maybe Int -> m ()
cmd = Action -> YiM ()
runAction (Action -> YiM ()) -> Action -> YiM ()
forall a b. (a -> b) -> a -> b
$ m () -> Action
forall a x. (YiAction a x, Show x) => a -> Action
makeAction (Maybe Int -> m ()
cmd Maybe Int
univArg)

  repeatingArg :: (Monad m, YiAction (m ()) ()) => m () -> YiM ()
  repeatingArg :: m () -> YiM ()
repeatingArg m ()
f = (Int -> m ()) -> YiM ()
forall (m :: * -> *). YiAction (m ()) () => (Int -> m ()) -> YiM ()
withIntArg ((Int -> m ()) -> YiM ()) -> (Int -> m ()) -> YiM ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> Int -> m () -> m ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
n m ()
f

  withIntArg :: YiAction (m ()) () => (Int -> m ()) -> YiM ()
  withIntArg :: (Int -> m ()) -> YiM ()
withIntArg Int -> m ()
cmd = (Maybe Int -> m ()) -> YiM ()
forall (m :: * -> *).
YiAction (m ()) () =>
(Maybe Int -> m ()) -> YiM ()
withUnivArg ((Maybe Int -> m ()) -> YiM ()) -> (Maybe Int -> m ()) -> YiM ()
forall a b. (a -> b) -> a -> b
$ \Maybe Int
arg -> Int -> m ()
cmd (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 Maybe Int
arg)

  deleteBack :: YiM ()
  deleteBack :: YiM ()
deleteBack = BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (BufferM () -> YiM ()) -> BufferM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ BufferM ()
blockKillring BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM ()
bdeleteB

  deleteForward :: YiM ()
  deleteForward :: YiM ()
deleteForward = BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg (BufferM () -> YiM ()) -> BufferM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ BufferM ()
blockKillring BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM ()
deleteB'

  -- Deletes current region if any, otherwise executes the given
  -- action.
  deleteRegionOr :: (Show a, YiAction (m a) a) => m a -> YiM ()
  deleteRegionOr :: m a -> YiM ()
deleteRegionOr m a
f = do
    BufferRef
b <- (Editor -> BufferRef) -> YiM BufferRef
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets Editor -> BufferRef
currentBuffer
    Region
r <- BufferRef -> BufferM Region -> YiM Region
forall (m :: * -> *) a.
MonadEditor m =>
BufferRef -> BufferM a -> m a
withGivenBuffer BufferRef
b BufferM Region
getSelectRegionB
    if Region -> Size
regionSize Region
r Size -> Size -> Bool
forall a. Eq a => a -> a -> Bool
== Size
0
      then Action -> YiM ()
runAction (Action -> YiM ()) -> Action -> YiM ()
forall a b. (a -> b) -> a -> b
$ m a -> Action
forall a x. (YiAction a x, Show x) => a -> Action
makeAction m a
f
      else BufferRef -> BufferM () -> YiM ()
forall (m :: * -> *) a.
MonadEditor m =>
BufferRef -> BufferM a -> m a
withGivenBuffer BufferRef
b (BufferM () -> YiM ()) -> BufferM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ Region -> BufferM ()
deleteRegionB Region
r

  ctrlC :: Keymap
ctrlC = [Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice [ Char -> Event
ctrlCh Char
'c' Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
commentRegion ]


  rectangleFunctions :: Keymap
rectangleFunctions = [Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice [ Char -> Event
char Char
'o' Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
openRectangle
                              , Char -> Event
char Char
't' Event -> (YiString -> BufferM ()) -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiString -> BufferM ()
stringRectangle
                              , Char -> Event
char Char
'k' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
killRectangle
                              , Char -> Event
char Char
'y' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
yankRectangle
                              ]

  tabFunctions :: Keymap
  tabFunctions :: Keymap
tabFunctions = [Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice [ (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
'n') I Event Action Event -> EditorM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! EditorM ()
nextTabE
                        , (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
'p') I Event Action Event -> EditorM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! EditorM ()
previousTabE
                        , (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
't') I Event Action Event -> EditorM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! EditorM ()
newTabE
                        , (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
'e') I Event Action Event -> YiM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! YiM ()
findFileNewTab
                        , (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
'd') I Event Action Event -> EditorM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! EditorM ()
deleteTabE
                        , (Event -> Event) -> Char -> Char -> I Event Action Char
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Char -> Char -> m Char
charOf Event -> Event
forall a. a -> a
id Char
'0' Char
'9' I Event Action Char -> (Char -> EditorM ()) -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> (b -> a) -> m ()
>>=! Maybe Int -> EditorM ()
moveTabE (Maybe Int -> EditorM ())
-> (Char -> Maybe Int) -> Char -> EditorM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> (Char -> Int) -> Char -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
digitToInt
                        ]
  -- These keybindings are all preceded by a 'C-x' so for example to
  -- quit the editor we do a 'C-x C-c'
  ctrlX :: Keymap
ctrlX = [Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice [ Char -> Event
ctrlCh Char
'o'    Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
deleteBlankLinesB
                 , Char -> Event
char Char
'0'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
closeWindowEmacs
                 , Char -> Event
char Char
'1'      Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
closeOtherE
                 , Char -> Event
char Char
'2'      Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
splitE
                 , Char -> Event
char Char
'h'      Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
selectAll
                 , Char -> Event
char Char
's'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
askSaveEditor
                 , Char -> Event
ctrlCh Char
'b'    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
listBuffers
                 , Char -> Event
ctrlCh Char
'c'    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
askQuitEditor
                 , Char -> Event
ctrlCh Char
'f'    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
findFile
                 , Char -> Event
ctrlCh Char
'r'    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
findFileReadOnly
                 , Char -> Event
ctrlCh Char
'q'    Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>!
                     ((BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer ((Bool -> Identity Bool) -> FBuffer -> Identity FBuffer
forall c. HasAttributes c => Lens' c Bool
readOnlyA ((Bool -> Identity Bool) -> FBuffer -> Identity FBuffer)
-> (Bool -> Bool) -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= Bool -> Bool
not)) :: EditorM ())
                 , Char -> Event
ctrlCh Char
's'    Event -> YiM Bool -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM Bool
fwriteE
                 , Char -> Event
ctrlCh Char
'w'    Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Text -> (Text -> YiM ()) -> YiM ()
promptFile Text
"Write file:" (YiM Bool -> YiM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (YiM Bool -> YiM ()) -> (Text -> YiM Bool) -> Text -> YiM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> YiM Bool
fwriteToE)
                 , Char -> Event
ctrlCh Char
'x'    Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (BufferM ()
exchangePointAndMarkB BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                                       (Bool -> Identity Bool) -> FBuffer -> Identity FBuffer
Lens' FBuffer Bool
highlightSelectionA ((Bool -> Identity Bool) -> FBuffer -> Identity FBuffer)
-> Bool -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
True)
                 , Char -> Event
char Char
'b'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
switchBufferE
                 , Char -> Event
char Char
'd'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
dired
                 , Char -> Event
char Char
'e' Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>
                   Char -> Event
char Char
'e'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
evalRegionE
                 , Char -> Event
char Char
'o'      Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
nextWinE
                 , Char -> Event
char Char
'k'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
killBufferE
                 , Char -> Event
char Char
'r'      Event -> Keymap -> Keymap
forall (m :: * -> *) action a.
MonadInteract m action Event =>
Event -> m a -> m a
?>>  Keymap
rectangleFunctions
                 , Char -> Event
char Char
'u'      Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> YiM ()
forall (m :: * -> *).
(Monad m, YiAction (m ()) ()) =>
m () -> YiM ()
repeatingArg BufferM ()
undoB
                 , (Event -> Event) -> Event -> I Event Action Event
forall (m :: * -> *) w.
(MonadFail m, MonadInteract m w Event) =>
(Event -> Event) -> Event -> m Event
optMod Event -> Event
ctrl (Char -> Event
char Char
't') I Event Action Event -> Keymap -> Keymap
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Keymap
tabFunctions
                 ]