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 c)   [] | c `elem` ['h','?'] -> 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 (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 '0') [] -> continue $ regenerateScreens j d $ setDepth (Just 0) ui | ||||||
|         EvKey (KChar '1') [] -> continue $ regenerateScreens j d $ setDepth (Just 1) ui |         EvKey (KChar '1') [] -> continue $ regenerateScreens j d $ setDepth (Just 1) ui | ||||||
|         EvKey (KChar '2') [] -> continue $ regenerateScreens j d $ setDepth (Just 2) 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, | -- | 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; | -- on the main journal file, blocking until it exits, and returning the exit code; | ||||||
| -- or raise an error. | -- or raise an error. | ||||||
| journalRunEditor :: Maybe TextPosition -> Journal -> IO ExitCode | runEditor :: Maybe TextPosition -> FilePath -> IO ExitCode | ||||||
| journalRunEditor mpos j = | runEditor mpos f = editorOpenPositionCommand mpos f >>= runCommand >>= waitForProcess | ||||||
|   editorOpenPositionCommand mpos (journalFilePath j) >>= runCommand >>= waitForProcess |  | ||||||
| 
 | 
 | ||||||
| -- Get the basic shell command to start the user's preferred text editor. | -- 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 | -- 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 |   let f' = singleQuoteIfNeeded f | ||||||
|   return $ |   return $ | ||||||
|    case (identifyEditor cmd, mpos) of |    case (identifyEditor cmd, mpos) of | ||||||
|     (Emacs, Just (line,_))    | line < 0  -> cmd ++ " " ++ f' ++ " -f end-of-buffer" |     (EmacsClient, Just (l,mc)) | l >= 0 -> cmd ++ " " ++ emacsposopt l mc ++ " " ++ f' | ||||||
|     (Emacs, Just (line,mcol)) | line >= 0 -> cmd ++ " " ++ posopt ++ " " ++ f' |     (EmacsClient, Just (l,mc)) | l < 0  -> cmd ++ " " ++ emacsposopt 999999999 mc ++ " " ++ f' | ||||||
|       where posopt = "+" ++ show line ++ maybe "" ((":"++).show) mcol |     (Emacs, Just (l,mc))       | l >= 0 -> cmd ++ " " ++ emacsposopt l mc ++ " " ++ f' | ||||||
|     (Vi, Just (line,_))                   -> cmd ++ " " ++ posopt ++ " " ++ f' |     (Emacs, Just (l,_))        | l < 0  -> cmd ++ " " ++ f' ++ " -f end-of-buffer" | ||||||
|       where posopt = "+" ++ if line >= 0 then show line else "" |     (Vi, Just (l,_))                    -> cmd ++ " " ++ viposopt l ++ " " ++ f' | ||||||
|     _                                     -> cmd ++ " " ++ 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. | -- Identify which text editor is used in the basic editor command, if possible. | ||||||
| identifyEditor :: String -> EditorType | identifyEditor :: String -> EditorType | ||||||
|  | |||||||
| @ -8,12 +8,13 @@ module Hledger.UI.ErrorScreen | |||||||
|  ) |  ) | ||||||
| where | where | ||||||
| 
 | 
 | ||||||
|  | import Brick | ||||||
| import Control.Monad | import Control.Monad | ||||||
| import Control.Monad.IO.Class (liftIO) | import Control.Monad.IO.Class (liftIO) | ||||||
| import Data.Monoid | import Data.Monoid | ||||||
| import Data.Time.Calendar (Day) | import Data.Time.Calendar (Day) | ||||||
| import Graphics.Vty | import Graphics.Vty hiding (char, string)-- (Event(..)) | ||||||
| import Brick | import Text.Parsec | ||||||
| 
 | 
 | ||||||
| import Hledger.Cli hiding (progname,prognameandversion,green) | import Hledger.Cli hiding (progname,prognameandversion,green) | ||||||
| import Hledger.UI.UIOptions | 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 :: UIState -> Event -> EventM (Next UIState) | ||||||
| esHandle ui@UIState{ | esHandle ui@UIState{ | ||||||
|    aScreen=ErrorScreen{} |    aScreen=ErrorScreen{..} | ||||||
|   ,aopts=UIOpts{cliopts_=copts} |   ,aopts=UIOpts{cliopts_=copts} | ||||||
|   ,ajournal=j |   ,ajournal=j | ||||||
|   ,aMode=mode |   ,aMode=mode | ||||||
| @ -78,7 +79,11 @@ esHandle ui@UIState{ | |||||||
|         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` ['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 |         EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j (popScreen ui)) >>= continue | ||||||
| --           (ej, _) <- liftIO $ journalReloadIfChanged copts d j | --           (ej, _) <- liftIO $ journalReloadIfChanged copts d j | ||||||
| --           case ej of | --           case ej of | ||||||
| @ -88,6 +93,17 @@ esHandle ui@UIState{ | |||||||
| 
 | 
 | ||||||
| esHandle _ _ = error "event handler called with wrong screen type, should not happen" | 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. | -- If journal file(s) have changed, reload the journal and regenerate all screens. | ||||||
| -- This is here so it can reference the error screen. | -- This is here so it can reference the error screen. | ||||||
| uiReloadJournalIfChanged :: CliOpts -> Day -> Journal -> UIState -> IO UIState | 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 c)   [] | c `elem` ['h','?'] -> 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 (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 'F') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleFlat ui) | ||||||
|         EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui) |         EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui) | ||||||
|         EvKey (KChar 'C') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleCleared 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 (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` ['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 |         EvKey (KChar 'g') [] -> do | ||||||
|           d <- liftIO getCurrentDay |           d <- liftIO getCurrentDay | ||||||
|           (ej, _) <- liftIO $ journalReloadIfChanged copts d j |           (ej, _) <- liftIO $ journalReloadIfChanged copts d j | ||||||
|  | |||||||
| @ -70,6 +70,7 @@ executable hledger-ui | |||||||
|     , HUnit |     , HUnit | ||||||
|     , microlens >= 0.4 && < 0.5 |     , microlens >= 0.4 && < 0.5 | ||||||
|     , microlens-platform >= 0.2.3.1 && < 0.4 |     , microlens-platform >= 0.2.3.1 && < 0.4 | ||||||
|  |     , parsec >= 3 | ||||||
|     , process >= 1.2 |     , process >= 1.2 | ||||||
|     , safe >= 0.2 |     , safe >= 0.2 | ||||||
|     , split >= 0.1 && < 0.3 |     , split >= 0.1 && < 0.3 | ||||||
|  | |||||||
| @ -75,6 +75,7 @@ executables: | |||||||
|       - HUnit |       - HUnit | ||||||
|       - microlens >= 0.4 && < 0.5 |       - microlens >= 0.4 && < 0.5 | ||||||
|       - microlens-platform >= 0.2.3.1 && < 0.4 |       - microlens-platform >= 0.2.3.1 && < 0.4 | ||||||
|  |       - parsec >= 3 | ||||||
|       - process >= 1.2 |       - process >= 1.2 | ||||||
|       - safe >= 0.2 |       - safe >= 0.2 | ||||||
|       - split >= 0.1 && < 0.3 |       - split >= 0.1 && < 0.3 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user