imp: ui: Display an error message on invalid regexp, rather than

silently ignoring. (#1394)
This commit is contained in:
Stephen Morgan 2021-11-16 12:22:05 +11:00 committed by Simon Michael
parent e0dc028374
commit 59b4968929
5 changed files with 34 additions and 27 deletions

View File

@ -180,8 +180,8 @@ asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}}
nonblanks = V.takeWhile (not . T.null . asItemAccountName) $ s ^. asList . listElementsL
bottomlabel = case mode of
Minibuffer ed -> minibuffer ed
_ -> quickhelp
Minibuffer label ed -> minibuffer label ed
_ -> quickhelp
where
quickhelp = borderKeysStr' [
("?", str "help")
@ -242,15 +242,18 @@ asHandle ui0@UIState{
ui = ui0{aScreen=scr & asSelectedAccount .~ selacct}
case mode of
Minibuffer ed ->
Minibuffer _ ed ->
case ev of
VtyEvent (EvKey KEsc []) -> continue $ closeMinibuffer ui
VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui
where s = chomp $ unlines $ map strip $ getEditContents ed
VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $
case setFilter s $ closeMinibuffer ui of
Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui
Right ui' -> ui'
where s = chomp $ unlines $ map strip $ getEditContents ed
VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui
VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui
VtyEvent ev -> do ed' <- handleEditorEvent ev ed
continue $ ui{aMode=Minibuffer ed'}
continue $ ui{aMode=Minibuffer "filter" ed'}
AppEvent _ -> continue ui
MouseDown{} -> continue ui
MouseUp{} -> continue ui
@ -311,7 +314,7 @@ asHandle ui0@UIState{
VtyEvent (EvKey (KUp) [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui
VtyEvent (EvKey (KRight) [MShift]) -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui
VtyEvent (EvKey (KLeft) [MShift]) -> continue $ regenerateScreens j d $ previousReportPeriod journalspan ui
VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer ui
VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui
VtyEvent (EvKey k []) | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui)
VtyEvent e | e `elem` moveLeftEvents -> continue $ popScreen ui
VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw ui

View File

@ -227,8 +227,8 @@ rsDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}}
-- query = query_ $ reportopts_ $ cliopts_ opts
bottomlabel = case mode of
Minibuffer ed -> minibuffer ed
_ -> quickhelp
Minibuffer label ed -> minibuffer label ed
_ -> quickhelp
where
quickhelp = borderKeysStr' [
("?", str "help")
@ -288,15 +288,19 @@ rsHandle ui@UIState{
lastnonblankidx = max 0 (length nonblanks - 1)
case mode of
Minibuffer ed ->
Minibuffer _ ed ->
case ev of
VtyEvent (EvKey KEsc []) -> continue $ closeMinibuffer ui
VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui
where s = chomp $ unlines $ map strip $ getEditContents ed
VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $
case setFilter s $ closeMinibuffer ui of
Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui
Right ui' -> ui'
where s = chomp . unlines . map strip $ getEditContents ed
-- VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer ui
VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui
VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui
VtyEvent ev -> do ed' <- handleEditorEvent ev ed
continue $ ui{aMode=Minibuffer ed'}
continue $ ui{aMode=Minibuffer "filter" ed'}
AppEvent _ -> continue ui
MouseDown{} -> continue ui
MouseUp{} -> continue ui
@ -342,7 +346,7 @@ rsHandle ui@UIState{
VtyEvent (EvKey (KChar 'C') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleCleared ui
VtyEvent (EvKey (KChar 'F') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleForecast d ui
VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer ui
VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui
VtyEvent (EvKey (KDown) [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui
VtyEvent (EvKey (KUp) [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui
VtyEvent (EvKey (KRight) [MShift]) -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui

View File

@ -7,9 +7,11 @@ module Hledger.UI.UIState
where
import Brick.Widgets.Edit
import Data.Bifunctor (first)
import Data.Foldable (asum)
import Data.Either (fromRight)
import Data.List ((\\), foldl', sort)
import Data.Maybe (fromMaybe)
import Data.Semigroup (Max(..))
import qualified Data.Text as T
import Data.Text.Zipper (gotoEOL)
@ -205,11 +207,9 @@ updateReportPeriod :: (Period -> Period) -> UIState -> UIState
updateReportPeriod updatePeriod = fromRight err . overEither period updatePeriod -- PARTIAL:
where err = error "updateReportPeriod: updating period should not result in an error"
-- | Apply a new filter query.
setFilter :: String -> UIState -> UIState
setFilter s = over reportSpec update
where
update rspec = fromRight rspec $ setEither querystring (words'' prefixes $ T.pack s) rspec -- XXX silently ignores an error
-- | Apply a new filter query, or return the failing query.
setFilter :: String -> UIState -> Either String UIState
setFilter s = first (const s) . setEither querystring (words'' prefixes $ T.pack s)
-- | Reset some filters & toggles.
resetFilter :: UIState -> UIState
@ -264,11 +264,11 @@ updateReportDepth updateDepth ui = over reportSpec update ui
| otherwise = Just d
-- | Open the minibuffer, setting its content to the current query with the cursor at the end.
showMinibuffer :: UIState -> UIState
showMinibuffer ui = setMode (Minibuffer e) ui
showMinibuffer :: T.Text -> Maybe String -> UIState -> UIState
showMinibuffer label moldq ui = setMode (Minibuffer label e) ui
where
e = applyEdit gotoEOL $ editor MinibufferEditor (Just 1) oldq
oldq = T.unpack . T.unwords . map textQuoteIfNeeded $ ui^.querystring
oldq = fromMaybe (T.unpack . T.unwords . map textQuoteIfNeeded $ ui^.querystring) moldq
-- | Close the minibuffer, discarding any edit in progress.
closeMinibuffer :: UIState -> UIState

View File

@ -69,7 +69,7 @@ data UIState = UIState {
data Mode =
Normal
| Help
| Minibuffer (Editor String Name)
| Minibuffer Text (Editor String Name)
deriving (Show,Eq)
-- Ignore the editor when comparing Modes.

View File

@ -176,11 +176,11 @@ helpHandle ui ev = do
ui' = setMode Normal ui
closeHelpEvents = moveLeftEvents ++ [EvKey KEsc [], EvKey (KChar '?') [], EvKey (KChar 'q') []]
-- | Draw the minibuffer.
minibuffer :: Editor String Name -> Widget Name
minibuffer ed =
-- | Draw the minibuffer with the given label.
minibuffer :: T.Text -> Editor String Name -> Widget Name
minibuffer string ed =
forceAttr ("border" <> "minibuffer") $
hBox [txt "filter: ", renderEditor (str . unlines) True ed]
hBox [txt $ string <> ": ", renderEditor (str . unlines) True ed]
borderQueryStr :: String -> Widget Name
borderQueryStr "" = str ""