packages feed

glirc 2.20.4 → 2.20.5

raw patch · 13 files changed

+135/−59 lines, 13 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Client.Image.Palette: [_palLineMarker] :: Palette -> Attr
+ Client.Image.Palette: palLineMarker :: Lens' Palette Attr
+ Client.State: setExtraFocus :: [Focus] -> ClientState -> ClientState
+ Client.State.Window: [_winMarker] :: Window -> !(Maybe Int)
+ Client.State.Window: instance GHC.Classes.Eq Client.State.Window.ActivityLevel
+ Client.State.Window: instance GHC.Classes.Ord Client.State.Window.ActivityLevel
+ Client.State.Window: instance GHC.Classes.Ord Client.State.Window.WindowLineImportance
+ Client.State.Window: instance GHC.Read.Read Client.State.Window.ActivityLevel
+ Client.State.Window: instance GHC.Read.Read Client.State.Window.WindowLineImportance
+ Client.State.Window: instance GHC.Show.Show Client.State.Window.ActivityLevel
+ Client.State.Window: winMarker :: Lens' Window (Maybe Int)
+ Client.State.Window: windowActivate :: Window -> Window
+ Client.State.Window: windowDeactivate :: Window -> Window
- Client.Image.Palette: Palette :: Vector Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Palette
+ Client.Image.Palette: Palette :: Vector Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Attr -> Palette
- Client.State: clientMatcher :: ClientState -> Text -> Bool
+ Client.State: clientMatcher :: ClientState -> Maybe (Text -> Bool)
- Client.State.Window: Window :: !WindowLines -> !Int -> !Int -> !Bool -> Window
+ Client.State.Window: Window :: !WindowLines -> !(Maybe Int) -> !Int -> !Int -> !WindowLineImportance -> Window
- Client.State.Window: [_winMention] :: Window -> !Bool
+ Client.State.Window: [_winMention] :: Window -> !WindowLineImportance
- Client.State.Window: winMention :: Lens' Window Bool
+ Client.State.Window: winMention :: Lens' Window WindowLineImportance

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for glirc2 +## 2.20.5++* Add line indicating message since previous time window was focused.+  The palette for this is configurable as `line-marker`+ ## 2.20.4  * Add `/query` alias for `/channel`
README.md view
@@ -33,10 +33,10 @@ $ cabal build ``` -Building with stack using ghc-8 resolver (lts-7 resolvers can work using --solver)+Building with stack  ```-$ stack init --resolver=ghc-8+$ stack init --resolver=lts-8 --solver $ stack build ``` @@ -229,6 +229,7 @@ | `command-ready`       | attr         | recognized command with arguments filled | | `command-placeholder` | attr         | command argument placeholder             | | `window-divider`      | attr         | the dividing line between split windows  |+| `line-marker`         | attr         | the dividing line for new messages       |  Text Attributes ---------------
glirc.cabal view
@@ -1,5 +1,5 @@ name:                glirc-version:             2.20.4+version:             2.20.5 synopsis:            Console IRC client description:         Console IRC client                      .@@ -20,7 +20,7 @@ cabal-version:       >=1.23 homepage:            https://github.com/glguy/irc-core bug-reports:         https://github.com/glguy/irc-core/issues-tested-with:         GHC==8.0.1+tested-with:         GHC==8.0.2  custom-setup   setup-depends: base  >=4.9  && <4.11,@@ -157,5 +157,5 @@   main-is:             Main.hs   hs-source-dirs:      test   build-depends:       base, glirc,-                       HUnit                >=1.3 && <1.4+                       HUnit                >=1.3 && <1.7   default-language:    Haskell2010
src/Client/Commands.hs view
@@ -1073,25 +1073,24 @@ renderFocus (ChannelFocus x y) = x <> ":" <> idText y  - -- | Implementation of @/splits@ cmdSplits :: ClientCommand String-cmdSplits st str = commandSuccess (set clientExtraFocus extras st)+cmdSplits st str = commandSuccess (setExtraFocus extras st)   where     extras = nub (parseFocuses str)   -- | Implementation of @/splits+@ cmdSplitsAdd :: ClientCommand String-cmdSplitsAdd st str = commandSuccess (over clientExtraFocus extras st)+cmdSplitsAdd st str = commandSuccess (setExtraFocus extras st)   where-    extras prev = nub (parseFocuses str ++ prev)+    extras = nub (parseFocuses str ++ view clientExtraFocus st)  -- | Implementation of @/splits-@ cmdSplitsDel :: ClientCommand String-cmdSplitsDel st str = commandSuccess (over clientExtraFocus extras st)+cmdSplitsDel st str = commandSuccess (setExtraFocus extras st)   where-    extras prev = prev \\ parseFocuses str+    extras = view clientExtraFocus st \\ parseFocuses str   tabHelp :: Bool -> ClientCommand String
src/Client/Image/Palette.hs view
@@ -33,6 +33,7 @@   , palCommandPrefix   , palCommandError   , palWindowDivider+  , palLineMarker    , paletteMap @@ -66,6 +67,7 @@   , _palCommandError  :: Attr -- ^ unknown command   , _palCommandPlaceholder :: Attr -- ^ command argument placeholder   , _palWindowDivider :: Attr -- ^ Divider between split windows+  , _palLineMarker    :: Attr -- ^ Divider between new and old messages   }   deriving Show @@ -93,6 +95,7 @@   , _palCommandError            = withForeColor defAttr red   , _palCommandPlaceholder      = withStyle defAttr reverseVideo   , _palWindowDivider           = withStyle defAttr reverseVideo+  , _palLineMarker              = defAttr   }  -- | Default nick highlighting colors that look nice in my dark solarized@@ -103,6 +106,8 @@     [cyan, magenta, green, yellow, blue,      brightCyan, brightMagenta, brightGreen, brightBlue] +-- | List of palette entry names and lenses for accessing that component+-- of the palette. paletteMap :: [(Text, ReifiedLens' Palette Attr)] paletteMap =   [ ("self"             , Lens palSelf)@@ -123,4 +128,5 @@   , ("command-prefix"   , Lens palCommandPrefix)   , ("command-error"    , Lens palCommandError)   , ("window-divider"   , Lens palWindowDivider)+  , ("line-marker"      , Lens palLineMarker)   ]
src/Client/Image/StatusLine.hs view
@@ -156,13 +156,13 @@     indicators = foldr aux [] (zip winNames windows)     windows    = views clientWindows Map.elems st -    aux (i,w) rest-      | view winUnread w == 0 = rest-      | otherwise = char attr i : rest+    aux (i,w) rest =+      case view winMention w of+        WLImportant -> char (view palMention  pal) i : rest+        WLNormal    -> char (view palActivity pal) i : rest+        WLBoring    -> rest       where         pal = clientPalette st-        attr | view winMention w = view palMention pal-             | otherwise         = view palActivity pal  -- | Multi-line activity information enabled by F3 activityBarImages :: ClientState -> [Image]@@ -189,8 +189,9 @@       where         n   = view winUnread w         pal = clientPalette st-        attr | view winMention w = view palMention pal-             | otherwise         = view palActivity pal+        attr = case view winMention w of+                 WLImportant -> view palMention pal+                 _           -> view palActivity pal         focusText =           case focus of             Unfocused           -> Text.pack "*"
src/Client/State.hs view
@@ -83,6 +83,7 @@   , retreatFocus   , jumpToActivity   , jumpFocus+  , setExtraFocus    -- * Scrolling   , scrollClient@@ -483,7 +484,7 @@        | otherwise = st1 -    hasMention = orOf (clientWindows . folded . winMention)+    hasMention = elemOf (clientWindows . folded . winMention) WLImportant  toWindowLine :: MessageRendererParams -> WindowLineImportance -> ClientMessage -> WindowLine toWindowLine params importance msg = WindowLine@@ -565,16 +566,15 @@   views (clientConnection network . csChannels . ix channel . chanUsers) HashMap.keys  --- | Returns the current filtering predicate.+-- | Returns the current filtering predicate if one is active. clientMatcher ::-  ClientState {- ^ client state  -} ->-  Text        {- ^ text to match -} ->-  Bool        {- ^ is match      -}+  ClientState          {- ^ client state       -} ->+  Maybe (Text -> Bool) {- ^ optional predicate -} clientMatcher st =-  case clientActiveRegex st of-    Nothing -> const True-    Just r  -> matchTest r . Text.unpack+  do r <- clientActiveRegex st+     return (matchTest r . Text.unpack) + -- | Construct a text matching predicate used to filter the message window. clientActiveRegex :: ClientState -> Maybe Regex clientActiveRegex st =@@ -627,7 +627,7 @@        _                                  -> t  -- | Remove a network connection and unlink it from the network map.--- This operation assumes that the networkconnection exists and should+-- This operation assumes that the network connection exists and should -- only be applied once per connection. removeNetwork :: NetworkId -> ClientState -> (NetworkState, ClientState) removeNetwork networkId st =@@ -675,7 +675,7 @@  applyMessageToClientState ::   ZonedTime                  {- ^ timestamp                -} ->-  IrcMsg                     {- ^ message recieved         -} ->+  IrcMsg                     {- ^ message received         -} ->   NetworkId                  {- ^ message network          -} ->   NetworkState               {- ^ network connection state -} ->   ClientState                {- ^ client state             -} ->@@ -785,7 +785,7 @@ jumpToActivity st = changeFocus newFocus st   where     windowList   = views clientWindows Map.toAscList st-    highPriority = find (view winMention . snd) windowList+    highPriority = find (\x -> WLImportant == view winMention (snd x)) windowList     lowPriority  = find (\x -> view winUnread (snd x) > 0) windowList     newFocus =       case mplus highPriority lowPriority of@@ -808,11 +808,13 @@ -- to message view, reset the scroll, remember the previous focus -- if it changed. changeFocus ::-  Focus       {- ^ new focus             -} ->-  ClientState {- ^ client state          -} ->+  Focus       {- ^ new focus    -} ->+  ClientState {- ^ client state -} ->   ClientState changeFocus focus st   = set clientScroll 0+  . activateCurrent+  . deactivatePrevious   . updatePrevious   . set clientFocus focus   . set clientSubfocus FocusMessages@@ -823,6 +825,32 @@     updatePrevious       | focus == oldFocus = id       | otherwise         = set clientPrevFocus oldFocus++    -- always activate the new window. If it was already active this+    -- will clear the marker.+    activateCurrent = over (clientWindows . ix focus) windowActivate++    -- Don't deactivate a window if it's going to stay active+    deactivatePrevious+      | oldFocus `elem` focus : view clientExtraFocus st = id+      | otherwise = over (clientWindows . ix oldFocus) windowDeactivate+++-- | Unified logic for assigning to the extra focuses field that activates+-- and deactivates windows as needed.+setExtraFocus :: [Focus] -> ClientState -> ClientState+setExtraFocus newFocuses st+  = aux windowDeactivate newlyInactive+  $ aux windowActivate   newlyActive+  $ set clientExtraFocus newFocuses st+  where+    newlyActive = newFocuses \\ (view clientFocus st : view clientExtraFocus st)++    newlyInactive = view clientExtraFocus st \\ (view clientFocus st : newFocuses)++    aux f xs st1 =+      foldl' (\acc w -> overStrict (clientWindows . ix w) f acc) st1 xs+  -- | Change the subfocus to the given value, preserve the focus, reset -- the scroll.
src/Client/State/Window.hs view
@@ -19,6 +19,7 @@   , winUnread   , winTotal   , winMention+  , winMarker    -- * Window lines   , WindowLine(..)@@ -36,6 +37,8 @@   , emptyWindow   , addToWindow   , windowSeen+  , windowActivate+  , windowDeactivate   ) where  import           Client.Image.PackedImage@@ -62,18 +65,22 @@ -- | A 'Window' tracks all of the messages and metadata for a particular -- message buffer. data Window = Window-  { _winMessages :: !WindowLines  -- ^ Messages to display, newest first-  , _winUnread   :: !Int          -- ^ Messages added since buffer was visible-  , _winTotal    :: !Int          -- ^ Messages in buffer-  , _winMention  :: !Bool         -- ^ Indicates an important event is unread+  { _winMessages :: !WindowLines   -- ^ Messages to display, newest first+  , _winMarker   :: !(Maybe Int)   -- ^ Location of line drawn to indicate newer messages+  , _winUnread   :: !Int           -- ^ Messages added since buffer was visible+  , _winTotal    :: !Int           -- ^ Messages in buffer+  , _winMention  :: !WindowLineImportance -- ^ Indicates an important event is unread   } +data ActivityLevel = NoActivity | NormalActivity | HighActivity+  deriving (Eq, Ord, Read, Show)+ -- | Flag for the important of a message being added to a window data WindowLineImportance   = WLBoring -- ^ Don't update unread count   | WLNormal -- ^ Increment unread count   | WLImportant -- ^ Increment unread count and set important flag-  deriving (Eq, Show)+  deriving (Eq, Ord, Show, Read)  makeLenses ''Window makeLenses ''WindowLine@@ -94,9 +101,10 @@ emptyWindow :: Window emptyWindow = Window   { _winMessages = Nil+  , _winMarker   = Nothing   , _winUnread   = 0   , _winTotal    = 0-  , _winMention  = False+  , _winMention  = WLBoring   }  -- | Adds a given line to a window as the newest message. Window's@@ -105,16 +113,31 @@ addToWindow !msg !win = Window     { _winMessages = msg :- view winMessages win     , _winTotal    = view winTotal win + 1-    , _winUnread   = view winUnread win-                   + (if view wlImportance msg == WLBoring then 0 else 1)-    , _winMention  = view winMention win-                  || view wlImportance msg == WLImportant+    , _winMarker   = do i <- view winMarker win; return $! i+1+    , _winUnread   = if view wlImportance msg == WLBoring+                     then view winUnread win+                     else view winUnread win + 1+    , _winMention  = max (view winMention win) (view wlImportance msg)     }  -- | Update the window clearing the unread count and important flag. windowSeen :: Window -> Window windowSeen = set winUnread 0-           . set winMention False+           . set winMention WLBoring+++-- | Update the window when it first becomes active. If only /boring/+-- messages have been added since last time the marker will be hidden.+windowActivate :: Window -> Window+windowActivate win+  | view winUnread win == 0 = set winMarker Nothing win+  | otherwise               = win+++-- | Update the window when it becomes inactive. This resets the activity+-- marker to the bottom of the window.+windowDeactivate :: Window -> Window+windowDeactivate = set winMarker (Just 0)   instance Each WindowLines WindowLines WindowLine WindowLine where
src/Client/View/Digraphs.hs view
@@ -29,12 +29,12 @@   = map (horizCat . intersperse sep)   $ chunksOf entriesPerLine   $ map (text' defAttr)-  $ filter matcher+  $ matcher   $ map (Text.pack . drawEntry)   $ digraphListToList digraphs   where     w              = view clientWidth st-    matcher        = clientMatcher st+    matcher        = maybe id filter (clientMatcher st)     entriesPerLine = max 1 -- just in case?                    $ (w + sepWidth) `quot` (entryWidth + sepWidth) 
src/Client/View/MaskList.hs view
@@ -22,6 +22,7 @@ import qualified Data.HashMap.Strict as HashMap import           Data.List import           Data.Ord+import           Data.Maybe import           Data.Text (Text) import           Data.Time import           Graphics.Vty.Attributes@@ -57,7 +58,7 @@                  char (view palLabel pal) '/' <|>                  string defAttr (show (HashMap.size entries)) -    matcher = clientMatcher st+    matcher = fromMaybe (const True) (clientMatcher st)      matcher' (mask,entry) = matcher mask || matcher (view maskListSetter entry) 
src/Client/View/Messages.hs view
@@ -32,17 +32,27 @@   chatMessageImages :: Focus -> ClientState -> [Image]-chatMessageImages focus st = windowLineProcessor focusedMessages-  where-    matcher = clientMatcher st--    focusedMessages-        = toListOf ( clientWindows . ix focus-                   . winMessages . each-                   . filtered (views wlText matcher)) st+chatMessageImages focus st =+  case preview (clientWindows . ix focus) st of+    Nothing  -> []+    Just win ->+      let msgs = toListOf each (view winMessages win) in+      case clientMatcher st of+        Just matcher -> windowLineProcessor (filter (views wlText matcher) msgs)+        Nothing ->+          case view winMarker win of+            Nothing -> windowLineProcessor msgs+            Just n  ->+              windowLineProcessor l +++              [marker] +++              windowLineProcessor r+              where+                (l,r) = splitAt n msgs +  where+    palette = clientPalette st+    marker = string (view palLineMarker palette) (replicate (view clientWidth st) '-')     windowLineProcessor-       | view clientDetailView st =           if view clientShowMetadata st             then map (view wlFullImage)
src/Client/View/UserList.hs view
@@ -22,6 +22,7 @@ import qualified Data.HashMap.Strict as HashMap import qualified Data.Map.Strict as Map import           Data.List+import           Data.Maybe import           Data.Ord import           Data.Text (Text) import qualified Data.Text as Text@@ -52,7 +53,7 @@     countImage = text' (view palLabel pal) "Users:" <|>                  sigilCountImage -    matcher = clientMatcher st+    matcher = fromMaybe (const True) (clientMatcher st)      myNicks = clientHighlights cs st @@ -100,7 +101,7 @@ userInfoImages' :: NetworkState -> Identifier -> ClientState -> [Image] userInfoImages' cs channel st = renderEntry <$> usersList   where-    matcher = clientMatcher st+    matcher = fromMaybe (const True) (clientMatcher st)      myNicks = clientHighlights cs st 
src/Client/View/Windows.hs view
@@ -95,6 +95,7 @@   char defAttr '/' <|>   string (view palActivity pal) (views winTotal show win)   where-    newMsgAttrLens-      | view winMention win = palMention-      | otherwise           = palActivity+    newMsgAttrLens =+      case view winMention win of+        WLImportant -> palMention+        _           -> palActivity