Avoid offering account names for completion in inapproriate contexts.

This commit is contained in:
Eric Kow 2011-03-12 19:59:35 +00:00
parent 9f539f0138
commit 18a53194b2

View File

@ -38,7 +38,7 @@ import Control.Exception (throw)
etc in add prompt etc in add prompt
-} -}
data PostingState = PostingState { data PostingState = PostingState {
psContext :: JournalContext, psJournal :: Journal,
psAccept :: AccountName -> Bool, psAccept :: AccountName -> Bool,
psSuggestHistoricalAmount :: Bool, psSuggestHistoricalAmount :: Bool,
psHistory :: Maybe [Posting]} psHistory :: Maybe [Posting]}
@ -55,7 +55,7 @@ add opts args j
++"To complete a transaction, enter . when prompted for an account.\n" ++"To complete a transaction, enter . when prompted for an account.\n"
++"To quit, press control-d or control-c." ++"To quit, press control-d or control-c."
today <- getCurrentDay today <- getCurrentDay
runInteraction j (getAndAddTransactions j opts args today) getAndAddTransactions j opts args today
`catch` (\e -> unless (isEOFError e) $ ioError e) `catch` (\e -> unless (isEOFError e) $ ioError e)
where f = journalFilePath j where f = journalFilePath j
@ -63,22 +63,22 @@ add opts args j
-- validating, displaying and appending them to the journal file, until -- validating, displaying and appending them to the journal file, until
-- end of input (then raise an EOF exception). Any command-line arguments -- end of input (then raise an EOF exception). Any command-line arguments
-- are used as the first transaction's description. -- are used as the first transaction's description.
getAndAddTransactions :: Journal -> [Opt] -> [String] -> Day -> InputT IO () getAndAddTransactions :: Journal -> [Opt] -> [String] -> Day -> IO ()
getAndAddTransactions j opts args defaultDate = do getAndAddTransactions j opts args defaultDate = do
(t, d) <- getTransaction j opts args defaultDate (t, d) <- getTransaction j opts args defaultDate
j <- liftIO $ journalAddTransaction j opts t j <- journalAddTransaction j opts t
getAndAddTransactions j opts args d getAndAddTransactions j opts args d
-- | Read a transaction from the command line, with history-aware prompting. -- | Read a transaction from the command line, with history-aware prompting.
getTransaction :: Journal -> [Opt] -> [String] -> Day getTransaction :: Journal -> [Opt] -> [String] -> Day
-> InputT IO (Transaction,Day) -> IO (Transaction,Day)
getTransaction j opts args defaultDate = do getTransaction j opts args defaultDate = do
today <- liftIO getCurrentDay today <- getCurrentDay
datestr <- askFor "date" datestr <- runInteractionDefault $ askFor "date"
(Just $ showDate defaultDate) (Just $ showDate defaultDate)
(Just $ \s -> null s || (Just $ \s -> null s ||
isRight (parse (smartdate >> many spacenonewline >> eof) "" $ lowercase s)) isRight (parse (smartdate >> many spacenonewline >> eof) "" $ lowercase s))
description <- askFor "description" (Just "") Nothing description <- runInteractionDefault $ askFor "description" (Just "") Nothing
let historymatches = transactionsSimilarTo j args description let historymatches = transactionsSimilarTo j args description
bestmatch | null historymatches = Nothing bestmatch | null historymatches = Nothing
| otherwise = Just $ snd $ head historymatches | otherwise = Just $ snd $ head historymatches
@ -90,7 +90,7 @@ getTransaction j opts args defaultDate = do
else True else True
where (ant,_,_,_) = groupPostings $ journalPostings j where (ant,_,_,_) = groupPostings $ journalPostings j
getpostingsandvalidate = do getpostingsandvalidate = do
ps <- getPostings (PostingState (jContext j) accept True bestmatchpostings) [] ps <- getPostings (PostingState j accept True bestmatchpostings) []
let t = nulltransaction{tdate=date let t = nulltransaction{tdate=date
,tstatus=False ,tstatus=False
,tdescription=description ,tdescription=description
@ -109,14 +109,14 @@ getTransaction j opts args defaultDate = do
-- fragile -- fragile
-- | Read postings from the command line until . is entered, using any -- | Read postings from the command line until . is entered, using any
-- provided historical postings and the journal context to guess defaults. -- provided historical postings and the journal context to guess defaults.
getPostings :: PostingState -> [Posting] -> InputT IO [Posting] getPostings :: PostingState -> [Posting] -> IO [Posting]
getPostings st enteredps = do getPostings st enteredps = do
let bestmatch | isNothing historicalps = Nothing let bestmatch | isNothing historicalps = Nothing
| n <= length ps = Just $ ps !! (n-1) | n <= length ps = Just $ ps !! (n-1)
| otherwise = Nothing | otherwise = Nothing
where Just ps = historicalps where Just ps = historicalps
defaultaccount = maybe Nothing (Just . showacctname) bestmatch defaultaccount = maybe Nothing (Just . showacctname) bestmatch
account <- askFor (printf "account %d" n) defaultaccount (Just accept) account <- runInteraction j $ askFor (printf "account %d" n) defaultaccount (Just accept)
if account=="." if account=="."
then return enteredps then return enteredps
else do else do
@ -134,7 +134,7 @@ getPostings st enteredps = do
-- digit group separator that would be mistaken for one -- digit group separator that would be mistaken for one
historicalamountstr = showMixedAmountWithPrecision maxprecisionwithpoint $ pamount $ fromJust bestmatch' historicalamountstr = showMixedAmountWithPrecision maxprecisionwithpoint $ pamount $ fromJust bestmatch'
balancingamountstr = showMixedAmountWithPrecision maxprecisionwithpoint $ negate $ sumMixedAmountsPreservingHighestPrecision $ map pamount enteredrealps balancingamountstr = showMixedAmountWithPrecision maxprecisionwithpoint $ negate $ sumMixedAmountsPreservingHighestPrecision $ map pamount enteredrealps
amountstr <- askFor (printf "amount %d" n) defaultamountstr validateamount amountstr <- runInteractionDefault $ askFor (printf "amount %d" n) defaultamountstr validateamount
let amount = fromparse $ runParser (someamount <|> return missingamt) ctx "" amountstr let amount = fromparse $ runParser (someamount <|> return missingamt) ctx "" amountstr
amount' = fromparse $ runParser (someamount <|> return missingamt) nullctx "" amountstr amount' = fromparse $ runParser (someamount <|> return missingamt) nullctx "" amountstr
defaultamtused = Just (showMixedAmount amount) == defaultamountstr defaultamtused = Just (showMixedAmount amount) == defaultamountstr
@ -153,8 +153,9 @@ getPostings st enteredps = do
liftIO $ hPutStrLn stderr $ printf "using default commodity (%s)" (symbol $ fromJust commodityadded) liftIO $ hPutStrLn stderr $ printf "using default commodity (%s)" (symbol $ fromJust commodityadded)
getPostings st' (enteredps ++ [p]) getPostings st' (enteredps ++ [p])
where where
j = psJournal st
historicalps = psHistory st historicalps = psHistory st
ctx = psContext st ctx = jContext j
accept = psAccept st accept = psAccept st
suggesthistorical = psSuggestHistoricalAmount st suggesthistorical = psSuggestHistoricalAmount st
n = length enteredps + 1 n = length enteredps + 1
@ -255,6 +256,10 @@ runInteraction j m = do
let cc = completionCache j let cc = completionCache j
runInputT (setComplete (accountCompletion cc) defaultSettings) m runInputT (setComplete (accountCompletion cc) defaultSettings) m
runInteractionDefault :: InputT IO a -> IO a
runInteractionDefault m = do
runInputT (setComplete noCompletion defaultSettings) m
-- A precomputed list of all accounts previously entered into the journal. -- A precomputed list of all accounts previously entered into the journal.
type CompletionCache = [AccountName] type CompletionCache = [AccountName]