diff options
-rw-r--r-- | Config.hs | 2 | ||||
-rw-r--r-- | Handlers.hs | 45 | ||||
-rw-r--r-- | Screen.hs | 18 | ||||
-rw-r--r-- | State.hs | 19 |
4 files changed, 70 insertions, 14 deletions
@@ -37,7 +37,7 @@ defaultConfig = LazymailConfig { -- --customConfig = defaultConfig { initialPath = "/home/rul/mail/"} -customConfig = defaultConfig { initialPath = "/home/rul/mail/linti" +customConfig = defaultConfig { initialPath = "/home/rul/mail/" , filterMaildirsHook = filterSymlinks } filterSymlinks :: [FilePath] -> IO [FilePath] diff --git a/Handlers.hs b/Handlers.hs index 007933d..4605756 100644 --- a/Handlers.hs +++ b/Handlers.hs @@ -19,9 +19,12 @@ import System.IO(IOMode(..), hGetContents, openFile) import Types (LazymailCurses) previousMode :: Mode -> LazymailCurses () -previousMode IndexMode = (=<<) put $ get >>= \st -> return st { mode = MaildirMode } -previousMode EmailMode = (=<<) put $ get >>= \st -> return st { mode = IndexMode } previousMode MaildirMode = (=<<) put $ get >>= \st -> return st { exitRequested = True } +previousMode EmailMode = (=<<) put $ get >>= \st -> return st { mode = IndexMode } +previousMode IndexMode = do + st <- get + let ist = (indexState st) { selectedRowIn = 0, scrollRowIn = 0 } + put $ st { mode = MaildirMode, indexState = ist } changeMode :: Mode -> LazymailCurses () changeMode EmailMode = return () @@ -44,6 +47,7 @@ changeMode MaildirMode = do } put $ st { mode = IndexMode, indexState = indexState' } +{- Boilerplate code -} incSelectedRow IndexMode = do st <- get let inSt = indexState st @@ -60,9 +64,27 @@ incSelectedRow IndexMode = do put st { indexState = inSt' } else -- Move the selected row put $ incrementSelectedRow st + +incSelectedRow MaildirMode = do + st <- get + let mdSt = maildirState st + let selRow = selectedRowMD mdSt + let topScrollRow = scrollRowMD mdSt + let startScrolling = (div (screenRows st) 4) * 3 + let totalRows = length $ detectedMDs mdSt + + if selRow > startScrolling && (topScrollRow <= (totalRows - (screenRows st))) + then do -- Scroll emails + let scrollRowMD' = topScrollRow + 1 + let scrollBufferMD' = scrollCrop scrollRowMD' (screenRows st) $ detectedMDs mdSt + let mdSt' = mdSt { scrollRowMD = scrollRowMD', scrollBufferMD = scrollBufferMD' } + put st { maildirState = mdSt' } + else -- Move the selected row + put $ incrementSelectedRow st incSelectedRow _ = (=<<) put $ get >>= \st -> return $ incrementSelectedRow st +{- More boilerplate code -} decSelectedRow IndexMode = do st <- get let inSt = indexState st @@ -77,6 +99,22 @@ decSelectedRow IndexMode = do put st { indexState = inSt' } else put $ decrementSelectedRow st + +decSelectedRow MaildirMode = do + st <- get + let mdSt = maildirState st + let selRow = selectedRowMD mdSt + let startScrolling = (div (screenRows st) 4) + let topScrollRow = scrollRowMD mdSt + if topScrollRow > 0 && selRow < startScrolling + then do + let scrollRowMD' = scrollRowMD mdSt - 1 + let scrollBufferMD' = scrollCrop scrollRowMD' (screenRows st) $ detectedMDs mdSt + let mdSt' = mdSt { scrollRowMD = scrollRowMD', scrollBufferMD = scrollBufferMD' } + put st { maildirState = mdSt' } + else + put $ decrementSelectedRow st + decSelectedRow _ = (=<<) put $ get >>= \st -> return $ decrementSelectedRow st {- Given a list, it returns the elements that will be in the next screen refresh @@ -89,8 +127,7 @@ formatIndexModeRows st = mapM formatRow where let email = parseEmail msg let fs = getFields email let str = normalizeLen (screenColumns st) . concat $ - [ show $ (currentRow st) + (scrollRowIn . indexState $ st) + 1 - , (ppSep ++) $ ppFlags . getFlags $ fp + [ (ppSep ++) $ ppFlags . getFlags $ fp , (ppSep ++) $ ppIndexNameAddr . getFrom $ fs , (ppSep ++) $ ppIndexSubject . getSubject $ fs ] @@ -54,6 +54,8 @@ startCurses = do return $ st { screenRows = fromIntegral $ rows - 1 , screenColumns = fromIntegral $ cols , colorStyle = style } + + resetScrollBuffer screenLoop {- This function will loop til the user decides to leave -} @@ -79,7 +81,7 @@ performUpdate = do {- Pattern match on the received mode and draw it in the screen. -} drawMode :: Mode -> LazymailUpdate () -drawMode MaildirMode = get >>= \st -> drawSelectionList $ detectedMDs . maildirState $ st +drawMode MaildirMode = get >>= \st -> drawSelectionList $ scrollBufferMD . maildirState $ st drawMode IndexMode = get >>= \st -> drawSelectionList $ scrollBufferIn . indexState $ st drawMode EmailMode = drawEmailHelper @@ -170,7 +172,7 @@ drawStatus = do drawStatusHelper MaildirMode st = ["Maildir listing - " - , "(", show ((+ 1) . selectedRow $ st), "/" + , "(", show ((selectedRow st) + (scrollRowMD . maildirState $ st) + 1), "/" , show (length $ detectedMDs . maildirState $ st), ")"] drawStatusHelper IndexMode st = @@ -208,5 +210,17 @@ handleEvent = loop where resetCurrentRow = (=<<) put $ get >>= \st -> return $ st { currentRow = 0 } incrementCurrentRow = (=<<) put $ get >>= \st -> return $ st { currentRow = (currentRow st) + 1 } +resetScrollBuffer = do + st <- get + case (mode st) of + MaildirMode -> do + let mst = (maildirState st) { + scrollBufferMD = EH.scrollCrop 0 (screenRows st) $ detectedMDs . maildirState $ st } + put st { maildirState = mst} + IndexMode -> do + let ist = (indexState st) { + scrollBufferIn = EH.scrollCrop 0 (screenRows st) $ selectedEmails . indexState $ st } + put st { indexState = ist } + liftCurses = lift . lift liftUpdate = lift . lift @@ -34,6 +34,9 @@ data MaildirState = MaildirState { selectedRowMD :: Int , selectedMD :: String , detectedMDs :: [(FilePath, String)] + , scrollRowMD :: Int + , scrollBufferMD :: [(FilePath, String)] + } data IndexState = IndexState { @@ -72,9 +75,11 @@ initialState = LazymailState { } initialMaildirState = MaildirState { - selectedRowMD = 0 - , selectedMD = "" - , detectedMDs = [] + selectedRowMD = 0 + , selectedMD = "" + , detectedMDs = [] + , scrollRowMD = 0 + , scrollBufferMD = [] } initialIndexState = IndexState { @@ -121,11 +126,11 @@ incrementSelectedRow st | (selectedRow st) < limit = | otherwise = st where scrRows = screenRows st + curInLen = length $ selectedEmails . indexState $ st + curMDLen = length $ detectedMDs . maildirState $ st limit' = case (mode st) of - MaildirMode -> (length $ detectedMDs . maildirState $ st ) - 1 - IndexMode -> if (currentInLen . indexState $ st) < scrRows - then (currentInLen . indexState $ st) - 1 - else scrRows + MaildirMode -> if curMDLen < scrRows then curMDLen - 1 else scrRows + IndexMode -> if curInLen < scrRows then curInLen - 1 else scrRows limit = if (statusBar st) && (limit' == scrRows) then fromIntegral $ limit' - 2 else fromIntegral limit' |