add: also let enter end transactions if no more default postings

To end a transaction, period is required because there might be another
default posting being suggested, and enter usually means "accept the
default". But having to switch back and forth from enter to period
during data entry is a bit unergonomic, requiring too much thought.

Now, in the (common) case where you have entered a balanced transaction
and there are no more default postings to suggest, enter is also allowed
to end the transaction. Experimental; this might be too inconsistent.
This commit is contained in:
Simon Michael 2014-03-16 09:29:09 -07:00
parent 88d52a9da8
commit 814008d648

View File

@ -190,11 +190,11 @@ postingsWizard es@EntryState{..} = do
postingWizard es@EntryState{..} = do postingWizard es@EntryState{..} = do
acct <- accountWizard es acct <- accountWizard es
if acct == "." if acct `elem` [".",""]
then case (esPostings, postingsBalanced esPostings) of then case (esPostings, postingsBalanced esPostings) of
([],_) -> liftIO (hPutStrLn stderr "Please enter some postings first.") >> postingWizard es ([],_) -> liftIO (hPutStrLn stderr "Please enter some postings first.") >> postingWizard es
(_,False) -> liftIO (hPutStrLn stderr "Please enter more postings to balance the transaction.") >> postingWizard es (_,False) -> liftIO (hPutStrLn stderr "Please enter more postings to balance the transaction.") >> postingWizard es
(_,True) -> return Nothing (_,True) -> return Nothing -- no more postings, end of transaction
else do else do
let es1 = es{esArgs=drop 1 esArgs} let es1 = es{esArgs=drop 1 esArgs}
(amt,comment) <- amountAndCommentWizard es1 (amt,comment) <- amountAndCommentWizard es1
@ -213,20 +213,24 @@ accountWizard EntryState{..} = do
historicalacct = case historicalp of Just p -> showAccountName Nothing (ptype p) (paccount p) historicalacct = case historicalp of Just p -> showAccountName Nothing (ptype p) (paccount p)
Nothing -> "" Nothing -> ""
def = headDef historicalacct esArgs def = headDef historicalacct esArgs
endmsg | canfinish && null def = " (or . or enter to finish this transaction)"
| canfinish = " (or . to finish this transaction)"
| otherwise = ""
retryMsg "A valid hledger account name is required. Eg: assets:cash, expenses:food:eating out." $ retryMsg "A valid hledger account name is required. Eg: assets:cash, expenses:food:eating out." $
parser parseAccount $ parser (parseAccountOrDotOrNull def canfinish) $
withCompletion (accountCompleter esJournal def) $ withCompletion (accountCompleter esJournal def) $
defaultTo' def $ nonEmpty $ defaultTo' def $ -- nonEmpty $
maybeRestartTransaction $ maybeRestartTransaction $
line $ green $ printf "Account %d%s%s: " pnum endmsg (showDefault def) line $ green $ printf "Account %d%s%s: " pnum endmsg (showDefault def)
where where
canfinish = not (null esPostings) && postingsBalanced esPostings canfinish = not (null esPostings) && postingsBalanced esPostings
endmsg | canfinish = " (or . to finish this transaction)" parseAccountOrDotOrNull _ _ "." = dbg $ Just "." -- . always signals end of txn
| otherwise = "" parseAccountOrDotOrNull "" True "" = dbg $ Just "" -- when there's no default and txn is balanced, "" also signals end of txn
parseAccount s = either (const Nothing) validateAccount $ parseWithCtx (jContext esJournal) accountnamep s parseAccountOrDotOrNull def@(_:_) _ "" = dbg $ Just def -- when there's a default, "" means use that
validateAccount s | null s = Nothing parseAccountOrDotOrNull _ _ s = dbg $ either (const Nothing) validateAccount $ parseWithCtx (jContext esJournal) accountnamep s -- otherwise, try to parse the input as an accountname
| no_new_accounts_ esOpts && not (s `elem` journalAccountNames esJournal) = Nothing dbg = id -- strace
| otherwise = Just s validateAccount s | no_new_accounts_ esOpts && not (s `elem` journalAccountNames esJournal) = Nothing
| otherwise = Just s
amountAndCommentWizard EntryState{..} = do amountAndCommentWizard EntryState{..} = do
let pnum = length esPostings + 1 let pnum = length esPostings + 1