haskeline 0.8.0.1 → 0.8.1.0
raw patch · 12 files changed
+89/−37 lines, 12 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ System.Console.Haskeline: withRunInBase :: Monad m => ((forall a. InputT m a -> m a) -> m b) -> InputT m b
Files
- Changelog +9/−0
- System/Console/Haskeline.hs +1/−0
- System/Console/Haskeline/Backend/DumbTerm.hs +1/−1
- System/Console/Haskeline/Backend/Terminfo.hs +2/−2
- System/Console/Haskeline/Backend/WCWidth.hs +1/−1
- System/Console/Haskeline/Backend/Win32.hsc +13/−5
- System/Console/Haskeline/Backend/Win32/Echo.hs +24/−2
- System/Console/Haskeline/Command/Completion.hs +13/−13
- System/Console/Haskeline/InputT.hs +21/−0
- cbits/h_wcwidth.c +2/−2
- haskeline.cabal +2/−2
- includes/h_iconv.h +0/−9
Changelog view
@@ -1,3 +1,12 @@+Changed in version 0.8.1.0:+ * Use grapheme's width to align a list of completions (#143)+ * Add withRunInBase to help decompose InputT (#131)+ * Add support for WINIO to haskeline. (#140)+ * Allow base-4.15+ * Eta expand as required by simplified subsumption rules in newer GHC+ * Remove unused iconv cbits (#135)+ * Support non-BMP characters (or, surrogate pairs) on Windows (#125)+ Changed in version 0.8.0.1: * Add a Cabal flag to disable the example executable as well as the test that uses it.
System/Console/Haskeline.hs view
@@ -64,6 +64,7 @@ defaultPrefs, runInputTWithPrefs, runInputTBehaviorWithPrefs,+ withRunInBase, -- ** History -- $history getHistory,
System/Console/Haskeline/Backend/DumbTerm.hs view
@@ -39,7 +39,7 @@ instance (MonadIO m, MonadMask m, MonadReader Layout m) => Term (DumbTerm m) where reposition _ s = refitLine s- drawLineDiff = drawLineDiff'+ drawLineDiff x y = drawLineDiff' x y printLines = mapM_ (printText . (++ crlf)) moveToNextLine _ = printText crlf
System/Console/Haskeline/Backend/Terminfo.hs view
@@ -202,7 +202,7 @@ -- see GHC ticket #1749). outputText :: String -> ActionM ()-outputText = output . const . termText+outputText s = output (const (termText s)) left,right,up :: Int -> TermAction left = flip leftA@@ -238,7 +238,7 @@ moveRelative :: Int -> ActionM () moveRelative n = liftM3 (advancePos n) ask get get- >>= moveToPos+ >>= \p -> moveToPos p -- Note that these move by a certain number of cells, not graphemes. changeRight, changeLeft :: Int -> ActionM ()
System/Console/Haskeline/Backend/WCWidth.hs view
@@ -13,7 +13,7 @@ import Data.List import Foreign.C.Types -foreign import ccall unsafe haskeline_mk_wcwidth :: CWchar -> CInt+foreign import ccall unsafe haskeline_mk_wcwidth :: CInt -> CInt wcwidth :: Char -> Int wcwidth c = case haskeline_mk_wcwidth $ toEnum $ fromEnum c of
System/Console/Haskeline/Backend/Win32.hsc view
@@ -13,7 +13,7 @@ import Data.List(intercalate) import Control.Concurrent.STM import Control.Concurrent hiding (throwTo)-import Data.Char(isPrint)+import Data.Char(isPrint, chr, ord) import Data.Maybe(mapMaybe) import Control.Exception (IOException, throwTo) import Control.Monad@@ -66,8 +66,16 @@ then eventReader h else do es <- readEvents h- return $ mapMaybe processEvent es+ return $ combineSurrogatePairs $ mapMaybe processEvent es +combineSurrogatePairs :: [Event] -> [Event]+combineSurrogatePairs (KeyInput [Key m1 (KeyChar c1)] : KeyInput [Key _ (KeyChar c2)] : es)+ | 0xD800 <= ord c1 && ord c1 < 0xDC00 && 0xDC00 <= ord c2 && ord c2 < 0xE000+ = let c = (((ord c1 .&. 0x3FF) `shiftL` 10) .|. (ord c2 .&. 0x3FF)) + 0x10000+ in KeyInput [Key m1 (KeyChar (chr c))] : combineSurrogatePairs es+combineSurrogatePairs (e:es) = e : combineSurrogatePairs es+combineSurrogatePairs [] = []+ consoleHandles :: MaybeT IO Handles consoleHandles = do h_in <- open "CONIN$"@@ -226,10 +234,10 @@ -- To be safe, we pick a round number we know to be less than the limit. limit = 20000 -- known to be less than WriteConsoleW's buffer limit writeConsole'- = withArray (map (toEnum . fromEnum) xs)- $ \t_arr -> alloca $ \numWritten -> do+ = withCWStringLen xs+ $ \(t_arr, len) -> alloca $ \numWritten -> do failIfFalse_ "WriteConsoleW"- $ c_WriteConsoleW h t_arr (toEnum $ length xs)+ $ c_WriteConsoleW h t_arr (toEnum len) numWritten nullPtr foreign import WINDOWS_CCONV "windows.h MessageBeep" c_messageBeep :: UINT -> IO Bool
System/Console/Haskeline/Backend/Win32/Echo.hs view
@@ -21,6 +21,10 @@ import Foreign.StablePtr (StablePtr, freeStablePtr, newStablePtr) import GHC.IO.FD (FD(..))+#if defined(__IO_MANAGER_WINIO__)+import GHC.IO.Handle.Windows (handleToHANDLE)+import GHC.IO.SubSystem ((<!>))+#endif import GHC.IO.Handle.Types (Handle(..), Handle__(..)) import System.Win32.Types (HANDLE)@@ -145,11 +149,30 @@ -- Originally authored by Max Bolingbroke in the ansi-terminal library withHandleToHANDLE :: Handle -> (HANDLE -> IO a) -> IO a-withHandleToHANDLE haskell_handle action =+#if defined(__IO_MANAGER_WINIO__)+withHandleToHANDLE = withHandleToHANDLEPosix <!> withHandleToHANDLENative+#else+withHandleToHANDLE = withHandleToHANDLEPosix+#endif++#if defined(__IO_MANAGER_WINIO__)+withHandleToHANDLENative :: Handle -> (HANDLE -> IO a) -> IO a+withHandleToHANDLENative haskell_handle action = -- Create a stable pointer to the Handle. This prevents the garbage collector -- getting to it while we are doing horrible manipulations with it, and hence -- stops it being finalized (and closed). withStablePtr haskell_handle $ const $ do+ windows_handle <- handleToHANDLE haskell_handle+ -- Do what the user originally wanted+ action windows_handle+#endif++withHandleToHANDLEPosix :: Handle -> (HANDLE -> IO a) -> IO a+withHandleToHANDLEPosix haskell_handle action =+ -- Create a stable pointer to the Handle. This prevents the garbage collector+ -- getting to it while we are doing horrible manipulations with it, and hence+ -- stops it being finalized (and closed).+ withStablePtr haskell_handle $ const $ do -- Grab the write handle variable from the Handle let write_handle_mvar = case haskell_handle of FileHandle _ handle_mvar -> handle_mvar@@ -162,7 +185,6 @@ -- Finally, turn that (C-land) FD into a HANDLE using msvcrt windows_handle <- c_get_osfhandle fd- -- Do what the user originally wanted action windows_handle
System/Console/Haskeline/Command/Completion.hs view
@@ -5,6 +5,7 @@ completionCmd ) where +import System.Console.Haskeline.Backend.WCWidth (gsWidth) import System.Console.Haskeline.Command import System.Console.Haskeline.Command.Undo import System.Console.Haskeline.Key@@ -120,27 +121,26 @@ makeLines ws layout = let minColPad = 2 printWidth = width layout- maxLength = min printWidth (maximum (map length ws) + minColPad)- numCols = printWidth `div` maxLength- ls = if maxLength >= printWidth+ maxWidth = min printWidth (maximum (map (gsWidth . stringToGraphemes) ws) + minColPad)+ numCols = printWidth `div` maxWidth+ ls = if maxWidth >= printWidth then map (: []) ws else splitIntoGroups numCols ws- in map (padWords maxLength) ls+ in map (padWords maxWidth) ls --- Add spaces to the end of each word so that it takes up the given length.--- Don't padd the word in the last column, since printing a space in the last column+-- Add spaces to the end of each word so that it takes up the given visual width.+-- Don't pad the word in the last column, since printing a space in the last column -- causes a line wrap on some terminals. padWords :: Int -> [String] -> String padWords _ [x] = x padWords _ [] = ""-padWords len (x:xs) = x ++ replicate (len - glength x) ' '- ++ padWords len xs+padWords wid (x:xs) = x ++ replicate (wid - widthOf x) ' '+ ++ padWords wid xs where- -- kludge: compute the length in graphemes, not chars.- -- but don't use graphemes for the max length, since I'm not convinced- -- that would work correctly. (This way, the worst that can happen is- -- that columns are longer than necessary.)- glength = length . stringToGraphemes+ -- kludge: compute the width in graphemes, not chars.+ -- also use graphemes for the max width so that multi-width characters+ -- such as CJK letters are aligned correctly.+ widthOf = gsWidth . stringToGraphemes -- Split xs into rows of length n, -- such that the list increases incrementally along the columns.
System/Console/Haskeline/InputT.hs view
@@ -65,6 +65,27 @@ instance ( MonadFix m ) => MonadFix (InputT m) where mfix f = InputT (mfix (unInputT . f)) +-- | Run an action in the underlying monad, as per 'lift', passing it a runner+-- function which restores the current 'InputT' context. This can be used in+-- the event that we have some function that takes an action in the underlying+-- monad as an argument (such as 'lift', 'hoist', 'forkIO', etc) and we want+-- to compose it with actions in 'InputT'.+withRunInBase :: Monad m =>+ ((forall a . InputT m a -> m a) -> m b) -> InputT m b+withRunInBase inner = InputT $ do+ runTerm <- ask+ history <- ask+ killRing <- ask+ prefs <- ask+ settings <- ask+ lift $ lift $ lift $ lift $ lift $ inner $+ flip runReaderT settings .+ flip runReaderT prefs .+ flip runReaderT killRing .+ flip runReaderT history .+ flip runReaderT runTerm .+ unInputT+ -- | Get the current line input history. getHistory :: MonadIO m => InputT m History getHistory = InputT get
cbits/h_wcwidth.c view
@@ -67,7 +67,7 @@ }; /* auxiliary function for binary search in interval table */-static int haskeline_bisearch(wchar_t ucs, const struct interval *table, int max) {+static int haskeline_bisearch(int ucs, const struct interval *table, int max) { int min = 0; int mid; @@ -119,7 +119,7 @@ * in ISO 10646. */ -int haskeline_mk_wcwidth(wchar_t ucs)+int haskeline_mk_wcwidth(int ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
haskeline.cabal view
@@ -1,6 +1,6 @@ Name: haskeline Cabal-Version: >=1.10-Version: 0.8.0.1+Version: 0.8.1.0 Category: User Interfaces License: BSD3 License-File: LICENSE@@ -49,7 +49,7 @@ -- We require ghc>=7.4.1 (base>=4.5) to use the base library encodings, even -- though it was implemented in earlier releases, due to GHC bug #5436 which -- wasn't fixed until 7.4.1- Build-depends: base >=4.9 && < 4.15, containers>=0.4 && < 0.7,+ Build-depends: base >=4.9 && < 4.16, containers>=0.4 && < 0.7, directory>=1.1 && < 1.4, bytestring>=0.9 && < 0.11, filepath >= 1.2 && < 1.5, transformers >= 0.2 && < 0.6, process >= 1.0 && < 1.7, stm >= 2.4 && < 2.6,
− includes/h_iconv.h
@@ -1,9 +0,0 @@-#include <iconv.h>--iconv_t haskeline_iconv_open(const char *tocode, const char *fromcode);--void haskeline_iconv_close(iconv_t cd);--size_t haskeline_iconv(iconv_t cd, char **inbuf, size_t *inbytesleft,- char **outbuf, size_t *outbytesleft);-