ui: add vi-style movement keys, use ? for help (#357)

This commit is contained in:
Simon Michael 2016-06-24 18:48:14 -07:00
parent 529d55dd54
commit dbeb4e3020
8 changed files with 122 additions and 109 deletions

View File

@ -186,7 +186,7 @@ asDraw UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
Minibuffer ed -> minibuffer ed Minibuffer ed -> minibuffer ed
_ -> quickhelp _ -> quickhelp
quickhelp = borderKeysStr [ quickhelp = borderKeysStr [
("h", "help") ("?", "help")
,("right", "register") ,("right", "register")
,("F", "flat?") ,("F", "flat?")
,("-+0123456789", "depth") ,("-+0123456789", "depth")
@ -265,7 +265,7 @@ asHandle ui0@UIState{
EvKey (KChar 'q') [] -> halt ui EvKey (KChar 'q') [] -> halt ui
-- EvKey (KChar 'l') [MCtrl] -> do -- EvKey (KChar 'l') [MCtrl] -> do
EvKey KEsc [] -> continue $ resetScreens d ui EvKey KEsc [] -> continue $ resetScreens d ui
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui EvKey (KChar c) [] | c `elem` ['?'] -> continue $ setMode Help ui
EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j ui) >>= continue EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j ui) >>= continue
EvKey (KChar 'a') [] -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui EvKey (KChar 'a') [] -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor endPos (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor endPos (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui
@ -289,14 +289,18 @@ asHandle ui0@UIState{
EvKey (KChar 'R') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleReal ui) EvKey (KChar 'R') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleReal ui)
EvKey (KChar '/') [] -> continue $ regenerateScreens j d $ showMinibuffer ui EvKey (KChar '/') [] -> continue $ regenerateScreens j d $ showMinibuffer ui
EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui) EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui)
EvKey (KLeft) [] -> continue $ popScreen ui EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KEnter] -> scrollTopRegister >> continue (screenEnter d scr ui) EvKey k [] | k `elem` [KRight, KChar 'l', KEnter] -> scrollTopRegister >> continue (screenEnter d scr ui)
where where
scr = rsSetAccount selacct registerScreen scr = rsSetAccount selacct registerScreen
-- fall through to the list's event handler (handles up/down) -- fall through to the list's event handler (handles up/down)
ev -> do ev -> do
newitems <- handleEvent ev (scr ^. asList) let ev' = case ev of
EvKey (KChar 'k') [] -> EvKey (KUp) []
EvKey (KChar 'j') [] -> EvKey (KDown) []
_ -> ev
newitems <- handleEvent ev' (scr ^. asList)
continue $ ui{aScreen=scr & asList .~ newitems continue $ ui{aScreen=scr & asList .~ newitems
& asSelectedAccount .~ selacct & asSelectedAccount .~ selacct
} }

View File

@ -186,7 +186,7 @@ rsDraw UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
Minibuffer ed -> minibuffer ed Minibuffer ed -> minibuffer ed
_ -> quickhelp _ -> quickhelp
quickhelp = borderKeysStr [ quickhelp = borderKeysStr [
("h", "help") ("?", "help")
,("left", "back") ,("left", "back")
,("right", "transaction") ,("right", "transaction")
,("/", "filter") ,("/", "filter")
@ -247,7 +247,7 @@ rsHandle ui@UIState{
case ev of case ev of
EvKey (KChar 'q') [] -> halt ui EvKey (KChar 'q') [] -> halt ui
EvKey KEsc [] -> continue $ resetScreens d ui EvKey KEsc [] -> continue $ resetScreens d ui
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui EvKey (KChar c) [] | c `elem` ['?'] -> continue $ setMode Help ui
EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j ui) >>= continue EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j ui) >>= continue
EvKey (KChar 'a') [] -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui EvKey (KChar 'a') [] -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui
@ -262,8 +262,8 @@ rsHandle ui@UIState{
EvKey (KChar 'R') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleReal ui) EvKey (KChar 'R') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleReal ui)
EvKey (KChar '/') [] -> (continue $ regenerateScreens j d $ showMinibuffer ui) EvKey (KChar '/') [] -> (continue $ regenerateScreens j d $ showMinibuffer ui)
EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui) EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui)
EvKey (KLeft) [] -> continue $ popScreen ui EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KEnter] -> do EvKey k [] | k `elem` [KRight, KChar 'l', KEnter] -> do
case listSelectedElement rsList of case listSelectedElement rsList of
Just (_, RegisterScreenItem{rsItemTransaction=t}) -> Just (_, RegisterScreenItem{rsItemTransaction=t}) ->
let let
@ -276,7 +276,12 @@ rsHandle ui@UIState{
,tsAccount=rsAccount} ui ,tsAccount=rsAccount} ui
Nothing -> continue ui Nothing -> continue ui
-- fall through to the list's event handler (handles [pg]up/down) -- fall through to the list's event handler (handles [pg]up/down)
ev -> do newitems <- handleEvent ev rsList ev -> do
let ev' = case ev of
EvKey (KChar 'k') [] -> EvKey (KUp) []
EvKey (KChar 'j') [] -> EvKey (KDown) []
_ -> ev
newitems <- handleEvent ev' rsList
continue ui{aScreen=s{rsList=newitems}} continue ui{aScreen=s{rsList=newitems}}
-- continue =<< handleEventLensed ui someLens ev -- continue =<< handleEventLensed ui someLens ev
where where

View File

@ -89,7 +89,7 @@ tsDraw UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
-- Minibuffer ed -> minibuffer ed -- Minibuffer ed -> minibuffer ed
_ -> quickhelp _ -> quickhelp
quickhelp = borderKeysStr [ quickhelp = borderKeysStr [
("h", "help") ("?", "help")
,("left", "back") ,("left", "back")
,("up/down", "prev/next") ,("up/down", "prev/next")
--,("ESC", "cancel/top") --,("ESC", "cancel/top")
@ -124,7 +124,7 @@ tsHandle ui@UIState{aScreen=s@TransactionScreen{tsTransaction=(i,t)
case ev of case ev of
EvKey (KChar 'q') [] -> halt ui EvKey (KChar 'q') [] -> halt ui
EvKey KEsc [] -> continue $ resetScreens d ui EvKey KEsc [] -> continue $ resetScreens d ui
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui EvKey (KChar c) [] | c `elem` ['?'] -> continue $ setMode Help ui
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui
where where
(pos,f) = let GenericSourcePos f l c = tsourcepos t in (Just (l, Just c),f) (pos,f) = let GenericSourcePos f l c = tsourcepos t in (Just (l, Just c),f)
@ -160,9 +160,9 @@ tsHandle ui@UIState{aScreen=s@TransactionScreen{tsTransaction=(i,t)
-- EvKey (KChar 'E') [] -> continue $ regenerateScreens j d $ stToggleEmpty ui -- EvKey (KChar 'E') [] -> continue $ regenerateScreens j d $ stToggleEmpty ui
-- EvKey (KChar 'C') [] -> continue $ regenerateScreens j d $ stToggleCleared ui -- EvKey (KChar 'C') [] -> continue $ regenerateScreens j d $ stToggleCleared ui
-- EvKey (KChar 'R') [] -> continue $ regenerateScreens j d $ stToggleReal ui -- EvKey (KChar 'R') [] -> continue $ regenerateScreens j d $ stToggleReal ui
EvKey KUp [] -> continue $ regenerateScreens j d ui{aScreen=s{tsTransaction=(iprev,tprev)}} EvKey k [] | k `elem` [KUp, KChar 'k'] -> continue $ regenerateScreens j d ui{aScreen=s{tsTransaction=(iprev,tprev)}}
EvKey KDown [] -> continue $ regenerateScreens j d ui{aScreen=s{tsTransaction=(inext,tnext)}} EvKey k [] | k `elem` [KDown, KChar 'j'] -> continue $ regenerateScreens j d ui{aScreen=s{tsTransaction=(inext,tnext)}}
EvKey KLeft [] -> continue ui'' EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue ui''
where where
ui'@UIState{aScreen=scr} = popScreen ui ui'@UIState{aScreen=scr} = popScreen ui
ui'' = ui'{aScreen=rsSelect (fromIntegral i) scr} ui'' = ui'{aScreen=rsSelect (fromIntegral i) scr}

View File

@ -34,25 +34,25 @@ helpDialog =
Widget Fixed Fixed $ do Widget Fixed Fixed $ do
c <- getContext c <- getContext
render $ render $
renderDialog (dialog "help" (Just "Help (h/ESC to close)") Nothing (c^.availWidthL - 2)) $ -- (Just (0,[("ok",())])) renderDialog (dialog "help" (Just "Help (?/LEFT/ESC to close)") Nothing (c^.availWidthL - 2)) $ -- (Just (0,[("ok",())]))
padTopBottom 1 $ padLeftRight 1 $ padTopBottom 1 $ padLeftRight 1 $
vBox [ vBox [
hBox [ hBox [
padLeftRight 1 $ padLeftRight 1 $
vBox [ vBox [
str "MISC" str "NAVIGATION"
,renderKey ("h", "toggle help") ,renderKey ("UP/DOWN/k/j/PGUP/PGDN/HOME/END", "")
,str " move selection"
,renderKey ("RIGHT/l/ENTER", "drill down")
,renderKey ("LEFT/h", "previous screen")
,renderKey ("ESC", "cancel / reset")
,str " "
,str "MISC"
,renderKey ("?", "toggle help")
,renderKey ("a", "add transaction") ,renderKey ("a", "add transaction")
,renderKey ("E", "open editor") ,renderKey ("E", "open editor")
,renderKey ("g", "reload data") ,renderKey ("g", "reload data")
,renderKey ("q", "quit") ,renderKey ("q", "quit")
,str " "
,str "NAVIGATION"
,renderKey ("UP/DOWN/PGUP/PGDN/HOME/END", "")
,str " move selection"
,renderKey ("RIGHT/ENTER", "drill down")
,renderKey ("LEFT", "previous screen")
,renderKey ("ESC", "cancel / reset")
] ]
,padLeftRight 1 $ ,padLeftRight 1 $
vBox [ vBox [
@ -89,7 +89,7 @@ helpDialog =
helpHandle :: UIState -> Event -> EventM (Next UIState) helpHandle :: UIState -> Event -> EventM (Next UIState)
helpHandle ui ev = helpHandle ui ev =
case ev of case ev of
EvKey k [] | k `elem` [KEsc, KChar 'h', KChar '?'] -> continue $ setMode Normal ui EvKey k [] | k `elem` [KEsc, KLeft, KChar 'h', KChar '?'] -> continue $ setMode Normal ui
EvKey (KChar 't') [] -> suspendAndResume $ runHelp >> return (setMode Normal ui) EvKey (KChar 't') [] -> suspendAndResume $ runHelp >> return (setMode Normal ui)
EvKey (KChar 'm') [] -> suspendAndResume $ runMan >> return (setMode Normal ui) EvKey (KChar 'm') [] -> suspendAndResume $ runMan >> return (setMode Normal ui)
EvKey (KChar 'i') [] -> suspendAndResume $ runInfo >> return (setMode Normal ui) EvKey (KChar 'i') [] -> suspendAndResume $ runInfo >> return (setMode Normal ui)

View File

@ -217,15 +217,17 @@ be "TAG:multi:level:account:name".
.RE .RE
.SH KEYS .SH KEYS
.PP .PP
\f[C]h\f[] shows a help dialog listing all keys. \f[C]?\f[] shows a help dialog listing all keys.
(Some but not all of these also appear in the quick help at the bottom (Some but not all of these also appear in the quick help at the bottom
of each screen.) Press \f[C]h\f[] again (or \f[C]ESCAPE\f[]) to close of each screen.) Press \f[C]?\f[] again (or \f[C]ESCAPE\f[], or
it. \f[C]LEFT\f[]) to close it.
.PP .PP
The cursor keys navigate: \f[C]right\f[] (or \f[C]enter\f[]) goes The cursor keys navigate: \f[C]right\f[] (or \f[C]enter\f[]) goes
deeper, \f[C]left\f[] returns to the previous screen, deeper, \f[C]left\f[] returns to the previous screen,
\f[C]up\f[]/\f[C]down\f[]/\f[C]page\ up\f[]/\f[C]page\ down\f[]/\f[C]home\f[]/\f[C]end\f[] \f[C]up\f[]/\f[C]down\f[]/\f[C]page\ up\f[]/\f[C]page\ down\f[]/\f[C]home\f[]/\f[C]end\f[]
move up and down through lists. move up and down through lists.
Vi\-style \f[C]h\f[]/\f[C]j\f[]/\f[C]k\f[]/\f[C]l\f[] movement keys are
also supported.
.PP .PP
\f[C]/\f[] lets you set or change the filter query, which limits the \f[C]/\f[] lets you set or change the filter query, which limits the
data shown on most screens (in addition to the quick filters described data shown on most screens (in addition to the quick filters described

View File

@ -152,13 +152,14 @@ File: hledger-ui.1.info, Node: KEYS, Next: SCREENS, Prev: OPTIONS, Up: Top
2 KEYS 2 KEYS
****** ******
`h' shows a help dialog listing all keys. (Some but not all of these `?' shows a help dialog listing all keys. (Some but not all of these
also appear in the quick help at the bottom of each screen.) Press `h' also appear in the quick help at the bottom of each screen.) Press `?'
again (or `ESCAPE') to close it. again (or `ESCAPE', or `LEFT') to close it.
The cursor keys navigate: `right' (or `enter') goes deeper, `left' The cursor keys navigate: `right' (or `enter') goes deeper, `left'
returns to the previous screen, `up'/`down'/`page up'/`page returns to the previous screen, `up'/`down'/`page up'/`page
down'/`home'/`end' move up and down through lists. down'/`home'/`end' move up and down through lists. Vi-style
`h'/`j'/`k'/`l' movement keys are also supported.
`/' lets you set or change the filter query, which limits the data `/' lets you set or change the filter query, which limits the data
shown on most screens (in addition to the quick filters described shown on most screens (in addition to the quick filters described
@ -334,15 +335,15 @@ Node: OPTIONS825
Ref: #options924 Ref: #options924
Node: KEYS3800 Node: KEYS3800
Ref: #keys3897 Ref: #keys3897
Node: SCREENS5391 Node: SCREENS5461
Ref: #screens5478 Ref: #screens5548
Node: Accounts screen5568 Node: Accounts screen5638
Ref: #accounts-screen5698 Ref: #accounts-screen5768
Node: Register screen7003 Node: Register screen7073
Ref: #register-screen7160 Ref: #register-screen7230
Node: Transaction screen8981 Node: Transaction screen9051
Ref: #transaction-screen9141 Ref: #transaction-screen9211
Node: Error screen10008 Node: Error screen10078
Ref: #error-screen10132 Ref: #error-screen10202
 
End Tag Table End Tag Table

View File

@ -75,14 +75,15 @@ _reportingoptions_
# KEYS # KEYS
`h` shows a help dialog listing all keys. `?` shows a help dialog listing all keys.
(Some but not all of these also appear in the quick help at the bottom of each screen.) (Some but not all of these also appear in the quick help at the bottom of each screen.)
Press `h` again (or `ESCAPE`) to close it. Press `?` again (or `ESCAPE`, or `LEFT`) to close it.
The cursor keys navigate: The cursor keys navigate:
`right` (or `enter`) goes deeper, `right` (or `enter`) goes deeper,
`left` returns to the previous screen, `left` returns to the previous screen,
`up`/`down`/`page up`/`page down`/`home`/`end` move up and down through lists. `up`/`down`/`page up`/`page down`/`home`/`end` move up and down through lists.
Vi-style `h`/`j`/`k`/`l` movement keys are also supported.
`/` lets you set or change the [filter query](/hledger.html#queries), `/` lets you set or change the [filter query](/hledger.html#queries),
which limits the data shown on most screens (in addition to the quick which limits the data shown on most screens (in addition to the quick

View File

@ -141,13 +141,13 @@ OPTIONS
name will be "TAG:multi:level:account:name". name will be "TAG:multi:level:account:name".
KEYS KEYS
h shows a help dialog listing all keys. (Some but not all of these ? shows a help dialog listing all keys. (Some but not all of these
also appear in the quick help at the bottom of each screen.) Press h also appear in the quick help at the bottom of each screen.) Press ?
again (or ESCAPE) to close it. again (or ESCAPE, or LEFT) to close it.
The cursor keys navigate: right (or enter) goes deeper, left returns to The cursor keys navigate: right (or enter) goes deeper, left returns to
the previous screen, up/down/page up/page down/home/end move up and the previous screen, up/down/page up/page down/home/end move up and
down through lists. down through lists. Vi-style h/j/k/l movement keys are also supported.
/ lets you set or change the filter query, which limits the data shown / lets you set or change the filter query, which limits the data shown
on most screens (in addition to the quick filters described below). on most screens (in addition to the quick filters described below).