imp: ui: Display an error message on invalid regexp, rather than
silently ignoring. (#1394)
This commit is contained in:
		
							parent
							
								
									e0dc028374
								
							
						
					
					
						commit
						59b4968929
					
				| @ -180,8 +180,8 @@ asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | |||||||
|                 nonblanks = V.takeWhile (not . T.null . asItemAccountName) $ s ^. asList . listElementsL |                 nonblanks = V.takeWhile (not . T.null . asItemAccountName) $ s ^. asList . listElementsL | ||||||
| 
 | 
 | ||||||
|         bottomlabel = case mode of |         bottomlabel = case mode of | ||||||
|                         Minibuffer ed -> minibuffer ed |                         Minibuffer label ed -> minibuffer label ed | ||||||
|                         _             -> quickhelp |                         _                   -> quickhelp | ||||||
|           where |           where | ||||||
|             quickhelp = borderKeysStr' [ |             quickhelp = borderKeysStr' [ | ||||||
|                ("?", str "help") |                ("?", str "help") | ||||||
| @ -242,15 +242,18 @@ asHandle ui0@UIState{ | |||||||
|     ui = ui0{aScreen=scr & asSelectedAccount .~ selacct} |     ui = ui0{aScreen=scr & asSelectedAccount .~ selacct} | ||||||
| 
 | 
 | ||||||
|   case mode of |   case mode of | ||||||
|     Minibuffer ed -> |     Minibuffer _ ed -> | ||||||
|       case ev of |       case ev of | ||||||
|         VtyEvent (EvKey KEsc   []) -> continue $ closeMinibuffer ui |         VtyEvent (EvKey KEsc   []) -> continue $ closeMinibuffer ui | ||||||
|         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui |         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ | ||||||
|                             where s = chomp $ unlines $ map strip $ getEditContents ed |             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 'l') [MCtrl]) -> redraw ui | ||||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|         VtyEvent ev        -> do ed' <- handleEditorEvent ev ed |         VtyEvent ev        -> do ed' <- handleEditorEvent ev ed | ||||||
|                                  continue $ ui{aMode=Minibuffer ed'} |                                  continue $ ui{aMode=Minibuffer "filter" ed'} | ||||||
|         AppEvent _        -> continue ui |         AppEvent _        -> continue ui | ||||||
|         MouseDown{}       -> continue ui |         MouseDown{}       -> continue ui | ||||||
|         MouseUp{}         -> 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 (KUp)       [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui | ||||||
|         VtyEvent (EvKey (KRight)    [MShift]) -> continue $ regenerateScreens j d $ nextReportPeriod journalspan 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 (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 (EvKey k           []) | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui) | ||||||
|         VtyEvent e | e `elem` moveLeftEvents -> continue $ popScreen ui |         VtyEvent e | e `elem` moveLeftEvents -> continue $ popScreen ui | ||||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw ui |         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw ui | ||||||
|  | |||||||
| @ -227,8 +227,8 @@ rsDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | |||||||
|             -- query = query_ $ reportopts_ $ cliopts_ opts |             -- query = query_ $ reportopts_ $ cliopts_ opts | ||||||
| 
 | 
 | ||||||
|         bottomlabel = case mode of |         bottomlabel = case mode of | ||||||
|                         Minibuffer ed -> minibuffer ed |                         Minibuffer label ed -> minibuffer label ed | ||||||
|                         _             -> quickhelp |                         _                   -> quickhelp | ||||||
|           where |           where | ||||||
|             quickhelp = borderKeysStr' [ |             quickhelp = borderKeysStr' [ | ||||||
|                ("?", str "help") |                ("?", str "help") | ||||||
| @ -288,15 +288,19 @@ rsHandle ui@UIState{ | |||||||
|     lastnonblankidx = max 0 (length nonblanks - 1) |     lastnonblankidx = max 0 (length nonblanks - 1) | ||||||
| 
 | 
 | ||||||
|   case mode of |   case mode of | ||||||
|     Minibuffer ed -> |     Minibuffer _ ed -> | ||||||
|       case ev of |       case ev of | ||||||
|         VtyEvent (EvKey KEsc   []) -> continue $ closeMinibuffer ui |         VtyEvent (EvKey KEsc   []) -> continue $ closeMinibuffer ui | ||||||
|         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui |         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ | ||||||
|                             where s = chomp $ unlines $ map strip $ getEditContents ed |             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 'l') [MCtrl]) -> redraw ui | ||||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|         VtyEvent ev              -> do ed' <- handleEditorEvent ev ed |         VtyEvent ev              -> do ed' <- handleEditorEvent ev ed | ||||||
|                                        continue $ ui{aMode=Minibuffer ed'} |                                        continue $ ui{aMode=Minibuffer "filter" ed'} | ||||||
|         AppEvent _        -> continue ui |         AppEvent _        -> continue ui | ||||||
|         MouseDown{}       -> continue ui |         MouseDown{}       -> continue ui | ||||||
|         MouseUp{}         -> 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 'C') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleCleared ui | ||||||
|         VtyEvent (EvKey (KChar 'F') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleForecast d 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 (KDown)     [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui | ||||||
|         VtyEvent (EvKey (KUp)       [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui |         VtyEvent (EvKey (KUp)       [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui | ||||||
|         VtyEvent (EvKey (KRight)    [MShift]) -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui |         VtyEvent (EvKey (KRight)    [MShift]) -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui | ||||||
|  | |||||||
| @ -7,9 +7,11 @@ module Hledger.UI.UIState | |||||||
| where | where | ||||||
| 
 | 
 | ||||||
| import Brick.Widgets.Edit | import Brick.Widgets.Edit | ||||||
|  | import Data.Bifunctor (first) | ||||||
| import Data.Foldable (asum) | import Data.Foldable (asum) | ||||||
| import Data.Either (fromRight) | import Data.Either (fromRight) | ||||||
| import Data.List ((\\), foldl', sort) | import Data.List ((\\), foldl', sort) | ||||||
|  | import Data.Maybe (fromMaybe) | ||||||
| import Data.Semigroup (Max(..)) | import Data.Semigroup (Max(..)) | ||||||
| import qualified Data.Text as T | import qualified Data.Text as T | ||||||
| import Data.Text.Zipper (gotoEOL) | import Data.Text.Zipper (gotoEOL) | ||||||
| @ -205,11 +207,9 @@ updateReportPeriod :: (Period -> Period) -> UIState -> UIState | |||||||
| updateReportPeriod updatePeriod = fromRight err . overEither period updatePeriod  -- PARTIAL: | updateReportPeriod updatePeriod = fromRight err . overEither period updatePeriod  -- PARTIAL: | ||||||
|   where err = error "updateReportPeriod: updating period should not result in an error" |   where err = error "updateReportPeriod: updating period should not result in an error" | ||||||
| 
 | 
 | ||||||
| -- | Apply a new filter query. | -- | Apply a new filter query, or return the failing query. | ||||||
| setFilter :: String -> UIState -> UIState | setFilter :: String -> UIState -> Either String UIState | ||||||
| setFilter s = over reportSpec update | setFilter s = first (const s) . setEither querystring (words'' prefixes $ T.pack s) | ||||||
|   where |  | ||||||
|     update rspec = fromRight rspec $ setEither querystring (words'' prefixes $ T.pack s) rspec  -- XXX silently ignores an error |  | ||||||
| 
 | 
 | ||||||
| -- | Reset some filters & toggles. | -- | Reset some filters & toggles. | ||||||
| resetFilter :: UIState -> UIState | resetFilter :: UIState -> UIState | ||||||
| @ -264,11 +264,11 @@ updateReportDepth updateDepth ui = over reportSpec update ui | |||||||
|                       | otherwise        = Just d |                       | otherwise        = Just d | ||||||
| 
 | 
 | ||||||
| -- | Open the minibuffer, setting its content to the current query with the cursor at the end. | -- | Open the minibuffer, setting its content to the current query with the cursor at the end. | ||||||
| showMinibuffer :: UIState -> UIState | showMinibuffer :: T.Text -> Maybe String -> UIState -> UIState | ||||||
| showMinibuffer ui = setMode (Minibuffer e) ui | showMinibuffer label moldq ui = setMode (Minibuffer label e) ui | ||||||
|   where |   where | ||||||
|     e = applyEdit gotoEOL $ editor MinibufferEditor (Just 1) oldq |     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. | -- | Close the minibuffer, discarding any edit in progress. | ||||||
| closeMinibuffer :: UIState -> UIState | closeMinibuffer :: UIState -> UIState | ||||||
|  | |||||||
| @ -69,7 +69,7 @@ data UIState = UIState { | |||||||
| data Mode = | data Mode = | ||||||
|     Normal |     Normal | ||||||
|   | Help |   | Help | ||||||
|   | Minibuffer (Editor String Name) |   | Minibuffer Text (Editor String Name) | ||||||
|   deriving (Show,Eq) |   deriving (Show,Eq) | ||||||
| 
 | 
 | ||||||
| -- Ignore the editor when comparing Modes. | -- Ignore the editor when comparing Modes. | ||||||
|  | |||||||
| @ -176,11 +176,11 @@ helpHandle ui ev = do | |||||||
|     ui' = setMode Normal ui |     ui' = setMode Normal ui | ||||||
|     closeHelpEvents = moveLeftEvents ++ [EvKey KEsc [], EvKey (KChar '?') [], EvKey (KChar 'q') []] |     closeHelpEvents = moveLeftEvents ++ [EvKey KEsc [], EvKey (KChar '?') [], EvKey (KChar 'q') []] | ||||||
| 
 | 
 | ||||||
| -- | Draw the minibuffer. | -- | Draw the minibuffer with the given label. | ||||||
| minibuffer :: Editor String Name -> Widget Name | minibuffer :: T.Text -> Editor String Name -> Widget Name | ||||||
| minibuffer ed = | minibuffer string ed = | ||||||
|   forceAttr ("border" <> "minibuffer") $ |   forceAttr ("border" <> "minibuffer") $ | ||||||
|   hBox [txt "filter: ", renderEditor (str . unlines) True ed] |   hBox [txt $ string <> ": ", renderEditor (str . unlines) True ed] | ||||||
| 
 | 
 | ||||||
| borderQueryStr :: String -> Widget Name | borderQueryStr :: String -> Widget Name | ||||||
| borderQueryStr ""  = str "" | borderQueryStr ""  = str "" | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user