module CompletionStringF (stdcc,completeFromList, completionStringF,completionStringF',completionStringF'') where import Fudgets import Data.List(isPrefixOf) import HbcUtils(mapSnd) completionStringF = completionStringF' stdcc standard stdcc = argReadKey "stdcc" ' ' -- standard completion char completionStringF' cc cust = completionStringF'' cc cust >=^< mapEither id Right completionStringF'' cc cust = -- cc = completion character loopThroughRightF (absF completeSP0) (stringF'' cust) where completeSP0 = completeSP (const []) ([],[]) "" completeSP listfun updownlist current = getSP $ either fromStringF fromOutside where list = listfun current same = completeSP listfun updownlist current newList listfun' = completeSP listfun' ([],[]) current newString' p s = putSP (toOutput (InputChange s)) $ completeSP listfun p s newString = newString' ([],[]) toStringF'' = Left toString = toStringF'' . Right toCustomiser = toStringF'' . Left toOutput = Right . Right toCompletionList = Right . Left fromOutside = either newList inputToStringF'' inputToStringF'' msg = putSP (toStringF'' msg) same fromStringF msg = case msg of InputDone "Up" _ -> goto above InputDone "Down" _ -> goto below InputDone "Tab" _ -> doCompletion InputDone _ _ -> putSP (toOutput msg) same InputChange s -> if s==current++[cc] then doCompletion else if fromupdownlist s then same else newString s -- erase completion list? fromupdownlist s = case updownlist of (_,(_,s'):_) -> s==s' _ -> False goto (_,[]) = same goto l@(_,item@(_,s):_) = putSP (toString s) $ putSP (toCompletionList [item]) $ putSP (toOutput (InputChange s)) $ newString' l current above = case updownlist of ([],[]) -> case reverse updownlist' of x:xs -> (xs,[x]) _ -> ([],[]) (x:xs,ys) -> (xs,x:ys) _ -> updownlist below = case updownlist of ([],[]) -> ([],updownlist') (xs,x1:x2:ys) -> (x1:xs,x2:ys) _ -> updownlist updownlist' = mapSnd (current++) list doCompletion = putSP (toCompletionList list) $ putNewString (current++commonPrefix (map snd list)) putNewString new = putSP (toString new) $ putSP (toCustomiser (setCursorPos (length new))) $ newString new commonPrefix ((c:s):ss) = case filter ((/=[c]).take 1) ss of [] -> c:commonPrefix (s:map tail ss) _ -> [] commonPrefix _ = [] pos y xs = case [ix|ix@(i,x)<-number 0 xs,y `isPrefixOf` x] of [] -> (0,False) (i,x):_ -> (i,x==y) completeFromList list current = [(current,compl)|(pre,compl)<-splits,pre==current] where splits = map (splitAt n) list n = length current