mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-27 12:24:43 +03:00
ui: editor: jump to current txn or error location (emacs, emacsclient, vi)
This commit is contained in:
parent
c79750bafd
commit
1d419eb7e6
@ -268,7 +268,7 @@ asHandle ui0@UIState{
|
||||
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui
|
||||
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 'E') [] -> suspendAndResume $ void (journalRunEditor endPos j) >> uiReloadJournalIfChanged copts d j ui
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor endPos (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui
|
||||
EvKey (KChar '0') [] -> continue $ regenerateScreens j d $ setDepth (Just 0) ui
|
||||
EvKey (KChar '1') [] -> continue $ regenerateScreens j d $ setDepth (Just 1) ui
|
||||
EvKey (KChar '2') [] -> continue $ regenerateScreens j d $ setDepth (Just 2) ui
|
||||
|
@ -29,9 +29,8 @@ endPos = Just (-1,Nothing)
|
||||
-- | Try running the user's preferred text editor, or a default edit command,
|
||||
-- on the main journal file, blocking until it exits, and returning the exit code;
|
||||
-- or raise an error.
|
||||
journalRunEditor :: Maybe TextPosition -> Journal -> IO ExitCode
|
||||
journalRunEditor mpos j =
|
||||
editorOpenPositionCommand mpos (journalFilePath j) >>= runCommand >>= waitForProcess
|
||||
runEditor :: Maybe TextPosition -> FilePath -> IO ExitCode
|
||||
runEditor mpos f = editorOpenPositionCommand mpos f >>= runCommand >>= waitForProcess
|
||||
|
||||
-- Get the basic shell command to start the user's preferred text editor.
|
||||
-- This is the value of environment variable $HLEDGER_UI_EDITOR, or $EDITOR, or
|
||||
@ -64,12 +63,15 @@ editorOpenPositionCommand mpos f = do
|
||||
let f' = singleQuoteIfNeeded f
|
||||
return $
|
||||
case (identifyEditor cmd, mpos) of
|
||||
(Emacs, Just (line,_)) | line < 0 -> cmd ++ " " ++ f' ++ " -f end-of-buffer"
|
||||
(Emacs, Just (line,mcol)) | line >= 0 -> cmd ++ " " ++ posopt ++ " " ++ f'
|
||||
where posopt = "+" ++ show line ++ maybe "" ((":"++).show) mcol
|
||||
(Vi, Just (line,_)) -> cmd ++ " " ++ posopt ++ " " ++ f'
|
||||
where posopt = "+" ++ if line >= 0 then show line else ""
|
||||
_ -> cmd ++ " " ++ f'
|
||||
(EmacsClient, Just (l,mc)) | l >= 0 -> cmd ++ " " ++ emacsposopt l mc ++ " " ++ f'
|
||||
(EmacsClient, Just (l,mc)) | l < 0 -> cmd ++ " " ++ emacsposopt 999999999 mc ++ " " ++ f'
|
||||
(Emacs, Just (l,mc)) | l >= 0 -> cmd ++ " " ++ emacsposopt l mc ++ " " ++ f'
|
||||
(Emacs, Just (l,_)) | l < 0 -> cmd ++ " " ++ f' ++ " -f end-of-buffer"
|
||||
(Vi, Just (l,_)) -> cmd ++ " " ++ viposopt l ++ " " ++ f'
|
||||
_ -> cmd ++ " " ++ f'
|
||||
where
|
||||
emacsposopt l mc = "+" ++ show l ++ maybe "" ((":"++).show) mc
|
||||
viposopt l = "+" ++ if l >= 0 then show l else ""
|
||||
|
||||
-- Identify which text editor is used in the basic editor command, if possible.
|
||||
identifyEditor :: String -> EditorType
|
||||
|
@ -8,12 +8,13 @@ module Hledger.UI.ErrorScreen
|
||||
)
|
||||
where
|
||||
|
||||
import Brick
|
||||
import Control.Monad
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
import Data.Monoid
|
||||
import Data.Time.Calendar (Day)
|
||||
import Graphics.Vty
|
||||
import Brick
|
||||
import Graphics.Vty hiding (char, string)-- (Event(..))
|
||||
import Text.Parsec
|
||||
|
||||
import Hledger.Cli hiding (progname,prognameandversion,green)
|
||||
import Hledger.UI.UIOptions
|
||||
@ -61,7 +62,7 @@ esDraw _ = error "draw function called with wrong screen type, should not happen
|
||||
|
||||
esHandle :: UIState -> Event -> EventM (Next UIState)
|
||||
esHandle ui@UIState{
|
||||
aScreen=ErrorScreen{}
|
||||
aScreen=ErrorScreen{..}
|
||||
,aopts=UIOpts{cliopts_=copts}
|
||||
,ajournal=j
|
||||
,aMode=mode
|
||||
@ -78,7 +79,11 @@ esHandle ui@UIState{
|
||||
EvKey (KChar 'q') [] -> halt ui
|
||||
EvKey KEsc [] -> continue $ resetScreens d ui
|
||||
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (journalRunEditor endPos j) >> uiReloadJournalIfChanged copts d j (popScreen ui)
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j (popScreen ui)
|
||||
where
|
||||
(pos,f) = case parsewith hledgerparseerrorpositionp esError of
|
||||
Right (f,l,c) -> (Just (l, Just c),f)
|
||||
Left _ -> (endPos, journalFilePath j)
|
||||
EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j (popScreen ui)) >>= continue
|
||||
-- (ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
||||
-- case ej of
|
||||
@ -88,6 +93,17 @@ esHandle ui@UIState{
|
||||
|
||||
esHandle _ _ = error "event handler called with wrong screen type, should not happen"
|
||||
|
||||
-- | Parse the file name, line and column number from a hledger parse error message, if possible.
|
||||
-- Temporary, we should keep the original parse error location. XXX
|
||||
hledgerparseerrorpositionp = do
|
||||
anyChar `manyTill` char '"'
|
||||
f <- anyChar `manyTill` (oneOf ['"','\n'])
|
||||
string " (line "
|
||||
l <- read <$> many1 digit
|
||||
string ", column "
|
||||
c <- read <$> many1 digit
|
||||
return (f, l, c)
|
||||
|
||||
-- If journal file(s) have changed, reload the journal and regenerate all screens.
|
||||
-- This is here so it can reference the error screen.
|
||||
uiReloadJournalIfChanged :: CliOpts -> Day -> Journal -> UIState -> IO UIState
|
||||
|
@ -250,7 +250,11 @@ rsHandle ui@UIState{
|
||||
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui
|
||||
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 'E') [] -> suspendAndResume $ void (journalRunEditor endPos j) >> uiReloadJournalIfChanged copts d j ui
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui
|
||||
where
|
||||
(pos,f) = case listSelectedElement rsList of
|
||||
Nothing -> (endPos, journalFilePath j)
|
||||
Just (_, RegisterScreenItem{rsItemTransaction=Transaction{tsourcepos=GenericSourcePos f l c}}) -> (Just (l, Just c),f)
|
||||
EvKey (KChar 'F') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleFlat ui)
|
||||
EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui)
|
||||
EvKey (KChar 'C') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleCleared ui)
|
||||
|
@ -124,7 +124,9 @@ tsHandle ui@UIState{aScreen=s@TransactionScreen{tsTransaction=(i,t)
|
||||
EvKey (KChar 'q') [] -> halt ui
|
||||
EvKey KEsc [] -> continue $ resetScreens d ui
|
||||
EvKey (KChar c) [] | c `elem` ['h','?'] -> continue $ setMode Help ui
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (journalRunEditor endPos j) >> uiReloadJournalIfChanged copts d j ui
|
||||
EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui
|
||||
where
|
||||
(pos,f) = let GenericSourcePos f l c = tsourcepos t in (Just (l, Just c),f)
|
||||
EvKey (KChar 'g') [] -> do
|
||||
d <- liftIO getCurrentDay
|
||||
(ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
||||
|
@ -70,6 +70,7 @@ executable hledger-ui
|
||||
, HUnit
|
||||
, microlens >= 0.4 && < 0.5
|
||||
, microlens-platform >= 0.2.3.1 && < 0.4
|
||||
, parsec >= 3
|
||||
, process >= 1.2
|
||||
, safe >= 0.2
|
||||
, split >= 0.1 && < 0.3
|
||||
|
@ -75,6 +75,7 @@ executables:
|
||||
- HUnit
|
||||
- microlens >= 0.4 && < 0.5
|
||||
- microlens-platform >= 0.2.3.1 && < 0.4
|
||||
- parsec >= 3
|
||||
- process >= 1.2
|
||||
- safe >= 0.2
|
||||
- split >= 0.1 && < 0.3
|
||||
|
Loading…
Reference in New Issue
Block a user