diff -rN -u old-haskeline/System/Console/Haskeline/Command/Completion.hs new-haskeline/System/Console/Haskeline/Command/Completion.hs
|
old
|
new
|
|
| 105 | 105 | ] |
| 106 | 106 | where |
| 107 | 107 | oneLine = clearMessage >> effect (PrintLines [w]) >> pageCompletions ws |
| 108 | | clearMessage = effect $ LineChange $ const ([],[]) |
| | 108 | clearMessage = effect $ LineChange Insert $ const ([],[]) |
| 109 | 109 | |
| 110 | 110 | printPage :: MonadReader Layout m => [String] -> CmdM m () |
| 111 | 111 | printPage ls = do |
diff -rN -u old-haskeline/System/Console/Haskeline/Command.hs new-haskeline/System/Console/Haskeline/Command.hs
|
old
|
new
|
|
| 34 | 34 | import System.Console.Haskeline.LineState |
| 35 | 35 | import System.Console.Haskeline.Key |
| 36 | 36 | |
| 37 | | data Effect = LineChange (Prefix -> LineChars) |
| | 37 | data Effect = LineChange Mode (Prefix -> LineChars) |
| 38 | 38 | | PrintLines [String] |
| 39 | 39 | | ClearScreen |
| 40 | 40 | | RingBell |
| 41 | 41 | |
| 42 | 42 | lineChange :: LineState s => s -> Effect |
| 43 | | lineChange = LineChange . flip lineChars |
| | 43 | lineChange s = LineChange (mode s) $ flip lineChars s |
| 44 | 44 | |
| 45 | 45 | data KeyMap a = KeyMap {lookupKM :: Key -> Maybe (KeyConsumed a)} |
| 46 | 46 | |
diff -rN -u old-haskeline/System/Console/Haskeline/LineState.hs new-haskeline/System/Console/Haskeline/LineState.hs
|
old
|
new
|
|
| 43 | 43 | beforeChar, |
| 44 | 44 | afterChar, |
| 45 | 45 | overChar, |
| | 46 | Mode(..), |
| 46 | 47 | -- ** CommandMode |
| 47 | 48 | CommandMode(..), |
| 48 | 49 | deleteChar, |
| … |
… |
|
| 133 | 134 | -> [Grapheme] -- ^ The text to the left of the cursor |
| 134 | 135 | -- (including the prefix). |
| 135 | 136 | afterCursor :: s -> [Grapheme] -- ^ The text under and to the right of the cursor. |
| | 137 | mode ::Â s -> Mode |
| | 138 | |
| | 139 | data Mode = Command | Insert | Arg |
| | 140 | deriving (Show) |
| 136 | 141 | |
| 137 | 142 | type Prefix = [Grapheme] |
| 138 | 143 | |
| … |
… |
|
| 172 | 177 | instance LineState InsertMode where |
| 173 | 178 | beforeCursor prefix (IMode xs _) = prefix ++ reverse xs |
| 174 | 179 | afterCursor (IMode _ ys) = ys |
| | 180 | mode _ = Insert |
| 175 | 181 | |
| 176 | 182 | instance Result InsertMode where |
| 177 | 183 | toResult (IMode xs ys) = graphemesToString $ reverse xs ++ ys |
| … |
… |
|
| 251 | 257 | beforeCursor prefix (CMode xs _ _) = prefix ++ reverse xs |
| 252 | 258 | afterCursor CEmpty = [] |
| 253 | 259 | afterCursor (CMode _ c ys) = c:ys |
| | 260 | mode _ = Command |
| 254 | 261 | |
| 255 | 262 | instance Result CommandMode where |
| 256 | 263 | toResult CEmpty = "" |
| … |
… |
|
| 328 | 335 | beforeCursor _ am = let pre = map baseGrapheme $ "(arg: " ++ show (arg am) ++ ") " |
| 329 | 336 | in beforeCursor pre (argState am) |
| 330 | 337 | afterCursor = afterCursor . argState |
| | 338 | mode _ = Arg |
| 331 | 339 | |
| 332 | 340 | instance Result s => Result (ArgMode s) where |
| 333 | 341 | toResult = toResult . argState |
diff -rN -u old-haskeline/System/Console/Haskeline/Prefs.hs new-haskeline/System/Console/Haskeline/Prefs.hs
|
old
|
new
|
|
| 6 | 6 | BellStyle(..), |
| 7 | 7 | EditMode(..), |
| 8 | 8 | HistoryDuplicates(..), |
| 9 | | lookupKeyBinding |
| | 9 | lookupKeyBinding, |
| | 10 | lookupKeyViCBinding |
| 10 | 11 | ) where |
| 11 | 12 | |
| 12 | 13 | import Data.Char(isSpace,toLower) |
| … |
… |
|
| 46 | 47 | -- will ring the bell and only display them if the user |
| 47 | 48 | -- presses @TAB@ again. |
| 48 | 49 | customBindings :: Map.Map Key [Key], |
| | 50 | |
| | 51 | customViCBindings :: Map.Map Key [Key], |
| 49 | 52 | -- (termName, keysequence, key) |
| 50 | 53 | customKeySequences :: [(Maybe String, String,Key)] |
| 51 | 54 | } |
| … |
… |
|
| 76 | 79 | listCompletionsImmediately = True, |
| 77 | 80 | historyDuplicates = AlwaysAdd, |
| 78 | 81 | customBindings = Map.empty, |
| | 82 | customViCBindings = Map.empty, |
| 79 | 83 | customKeySequences = [] |
| 80 | 84 | } |
| 81 | 85 | |
| … |
… |
|
| 98 | 102 | ,("listcompletionsimmediately", mkSettor $ \x p -> p {listCompletionsImmediately = x}) |
| 99 | 103 | ,("historyduplicates", mkSettor $ \x p -> p {historyDuplicates = x}) |
| 100 | 104 | ,("bind", addCustomBinding) |
| | 105 | ,("cbind", addCustomViCBinding) |
| 101 | 106 | ,("keyseq", addCustomKeySequence) |
| 102 | 107 | ] |
| 103 | 108 | |
| … |
… |
|
| 106 | 111 | Just (k:ks) -> p {customBindings = Map.insert k ks (customBindings p)} |
| 107 | 112 | _ -> p |
| 108 | 113 | |
| | 114 | addCustomViCBinding :: String -> Prefs -> Prefs |
| | 115 | addCustomViCBinding str p = case mapM parseKey (words str) of |
| | 116 | Just (k:ks) -> p {customViCBindings = Map.insert k ks (customViCBindings p)} |
| | 117 | _ -> p |
| | 118 | |
| 109 | 119 | addCustomKeySequence :: String -> Prefs -> Prefs |
| 110 | 120 | addCustomKeySequence str = maybe id addKS maybeParse |
| 111 | 121 | where |
| … |
… |
|
| 123 | 133 | lookupKeyBinding :: Key -> Prefs -> [Key] |
| 124 | 134 | lookupKeyBinding k = Map.findWithDefault [k] k . customBindings |
| 125 | 135 | |
| | 136 | lookupKeyViCBinding :: Key -> Prefs -> [Key] |
| | 137 | lookupKeyViCBinding k = Map.findWithDefault [k] k . customViCBindings |
| | 138 | |
| 126 | 139 | -- | Read 'Prefs' from a given file. If there is an error reading the file, |
| 127 | 140 | -- the 'defaultPrefs' will be returned. |
| 128 | 141 | readPrefs :: FilePath -> IO Prefs |
diff -rN -u old-haskeline/System/Console/Haskeline/RunCommand.hs new-haskeline/System/Console/Haskeline/RunCommand.hs
|
old
|
new
|
|
| 23 | 23 | runCommandLoop' liftE tops prefix initState cmds getEvent = do |
| 24 | 24 | let s = lineChars prefix initState |
| 25 | 25 | drawLine s |
| 26 | | readMoreKeys s (fmap (liftM (\x -> (x,[])) . ($ initState)) cmds) |
| | 26 | readMoreKeys (mode initState) s (fmap (liftM (\x -> (x,[])) . ($ initState)) cmds) |
| 27 | 27 | where |
| 28 | | readMoreKeys :: LineChars -> KeyMap (CmdM m (a,[Key])) -> n a |
| 29 | | readMoreKeys s next = do |
| | 28 | readMoreKeys :: Mode -> LineChars -> KeyMap (CmdM m (a,[Key])) -> n a |
| | 29 | readMoreKeys m s next@(KeyMap cmd) = do |
| 30 | 30 | event <- handle (\(e::SomeException) -> moveToNextLine s |
| 31 | 31 | >> throwIO e) getEvent |
| | 32 | -- liftIO $ print m |
| 32 | 33 | case event of |
| 33 | 34 | ErrorEvent e -> moveToNextLine s >> throwIO e |
| 34 | 35 | WindowResize -> do |
| 35 | 36 | drawReposition liftE tops s |
| 36 | | readMoreKeys s next |
| | 37 | readMoreKeys m s next |
| 37 | 38 | KeyInput ks -> do |
| 38 | | bound_ks <- mapM (asks . lookupKeyBinding) ks |
| 39 | | loopCmd s $ applyKeysToMap (concat bound_ks) next |
| | 39 | bound_ks <- mapM (asks . lookupKey m) ks |
| | 40 | loopCmd m s $ applyKeysToMap (concat bound_ks) next |
| | 41 | -- lookupKey cmd k p = case editMode p of |
| | 42 | -- Emacs -> lookupKeyBinding k p |
| | 43 | -- Vi -> lookupViBinding cmd k p |
| | 44 | lookupKey cmd k p = case cmd of |
| | 45 | Command -> lookupKeyViCBinding k p |
| | 46 | Insert -> lookupKeyBinding k p |
| | 47 | Arg -> lookupKeyViCBinding k p |
| 40 | 48 | |
| 41 | | loopCmd :: LineChars -> CmdM m (a,[Key]) -> n a |
| 42 | | loopCmd s (GetKey next) = readMoreKeys s next |
| | 49 | |
| | 50 | loopCmd :: Mode -> LineChars -> CmdM m (a,[Key]) -> n a |
| | 51 | loopCmd m s (GetKey next) = readMoreKeys m s next |
| 43 | 52 | -- If there are multiple consecutive LineChanges, only render the diff |
| 44 | 53 | -- to the last one, and skip the rest. This greatly improves speed when |
| 45 | 54 | -- a large amount of text is pasted in at once. |
| 46 | | loopCmd s (DoEffect (LineChange _) |
| 47 | | e@(DoEffect (LineChange _) _)) = loopCmd s e |
| 48 | | loopCmd s (DoEffect e next) = do |
| | 55 | loopCmd m s (DoEffect (LineChange m' _) |
| | 56 | e@(DoEffect (LineChange _ _) _)) = loopCmd m' s e |
| | 57 | loopCmd m s (DoEffect e@(LineChange m' _) next) = do |
| | 58 | t <- drawEffect prefix s e |
| | 59 | loopCmd m' t next |
| | 60 | loopCmd m s (DoEffect e next) = do |
| 49 | 61 | t <- drawEffect prefix s e |
| 50 | | loopCmd t next |
| 51 | | loopCmd s (CmdM next) = liftE next >>= loopCmd s |
| 52 | | loopCmd s (Result (x,ks)) = do |
| | 62 | loopCmd m t next |
| | 63 | loopCmd m s (CmdM next) = liftE next >>= loopCmd m s |
| | 64 | loopCmd m s (Result (x,ks)) = do |
| 53 | 65 | liftIO (saveUnusedKeys tops ks) |
| 54 | 66 | moveToNextLine s |
| 55 | 67 | return x |
| … |
… |
|
| 65 | 77 | |
| 66 | 78 | drawEffect :: (Term m, MonadReader Prefs m) |
| 67 | 79 | => Prefix -> LineChars -> Effect -> m LineChars |
| 68 | | drawEffect prefix s (LineChange ch) = do |
| | 80 | drawEffect prefix s (LineChange m ch) = do |
| 69 | 81 | let t = ch prefix |
| 70 | 82 | drawLineDiff s t |
| 71 | 83 | return t |
| … |
… |
|
| 81 | 93 | drawEffect _ s RingBell = actBell >> return s |
| 82 | 94 | |
| 83 | 95 | actBell :: (Term m, MonadReader Prefs m) => m () |
| 84 | | actBell = do |
| | 96 | actBell = do |
| 85 | 97 | style <- asks bellStyle |
| 86 | 98 | case style of |
| 87 | 99 | NoBell -> return () |
diff -rN -u old-haskeline/System/Console/Haskeline/Vi.hs new-haskeline/System/Console/Haskeline/Vi.hs
|
old
|
new
|
|
| 9 | 9 | import System.Console.Haskeline.Command.Undo |
| 10 | 10 | import System.Console.Haskeline.LineState |
| 11 | 11 | import System.Console.Haskeline.InputT |
| 12 | | |
| | 12 | import qualified System.Console.Haskeline.LineState as L |
| 13 | 13 | import Data.Char |
| 14 | 14 | import Control.Monad(liftM) |
| 15 | 15 | |
| … |
… |
|
| 409 | 409 | beforeCursor prefix se = beforeCursor (prefix ++ stringToGraphemes [searchChar se]) |
| 410 | 410 | (entryState se) |
| 411 | 411 | afterCursor = afterCursor . entryState |
| | 412 | mode s = L.Command |
| 412 | 413 | |
| 413 | 414 | viEnterSearch :: Monad m => Char -> Direction |
| 414 | 415 | -> Command (ViT m) CommandMode CommandMode |