{- |
'Prefs' allow the user to customize the line-editing interface. They are
read by default from @~/.haskeline@; to override that behavior, use
'readPrefs' and 'runInputTWithPrefs'.
Each line of a @.haskeline@ file defines
one field of the 'Prefs' datatype; field names are case-insensitive and
unparseable lines are ignored. For example:
> editMode: Vi
> completionType: MenuCompletion
> maxhistorysize: Just 40
-}moduleSystem.Console.Haskeline.PrefswhereimportLanguage.Haskell.THimportData.Char(isSpace,toLower)importData.List(foldl')importControl.Exception(handle)dataPrefs=Prefs{bellStyle::!BellStyle,editMode::!EditMode,maxHistorySize::!(MaybeInt),completionType::!CompletionType,completionPaging::!Bool,-- ^ When listing completion alternatives, only display-- one screen of possibilities at a time.completionPromptLimit::!(MaybeInt),-- ^ If more than this number of completion-- possibilities are found, then ask before listing-- them.listCompletionsImmediately::!Bool-- ^ If 'False', completions with multiple possibilities-- will ring the bell and only display them if the user-- presses @TAB@ again.}deriving(Read,Show)dataCompletionType=ListCompletion|MenuCompletionderiving(Read,Show)dataBellStyle=NoBell|VisualBell|AudibleBellderiving(Show,Read)dataEditMode=Vi|Emacsderiving(Show,Read){- | The default preferences which may be overwritten in the @.haskeline@ file:
> defaultPrefs = Prefs {bellStyle = AudibleBell,
> maxHistorySize = Nothing,
> editMode = Emacs,
> completionType = ListCompletion,
> completionPaging = True,
> completionPromptLimit = Just 100,
> listCompletionsImmediately = True
> }
-}defaultPrefs::PrefsdefaultPrefs=Prefs{bellStyle=AudibleBell,maxHistorySize=Nothing,editMode=Emacs,completionType=ListCompletion,completionPaging=True,completionPromptLimit=Just100,listCompletionsImmediately=True}mkSettor::Reada=>(a->Prefs->Prefs)->String->Prefs->PrefsmkSettorfstr=casereadsstrof[(x,_)]->fx_->idsettors::[(String,String->Prefs->Prefs)]settors=$(doDataConI__prefsType_<-reify'PrefsTyConI(DataD___[RecC_fields]_)<-reifyprefsTypex<-newName"x"p<-newName"p"-- settor f => ("f", mkSettor (\x p -> p {f=x}))letsettor(f,_,_)=TupE[LitE(StringL(maptoLower$nameBasef)),AppE(VarE'mkSettor)$LamE[VarPx,VarPp]$RecUpdE(VarEp)[(f,VarEx)]]return$ListE$mapsettorfields)-- | Read 'Prefs' from a given file. If there is an error reading the file,-- the 'defaultPrefs' will be returned.readPrefs::FilePath->IOPrefsreadPrefsfile=handle(\_->returndefaultPrefs)$dols<-fmaplines$readFilefilereturn$foldl'applyFielddefaultPrefslswhereapplyFieldpl=casebreak(==':')lof(name,val)->caselookup(maptoLower$trimSpacesname)settorsofNothing->pJustset->set(drop1val)p-- drop initial ":", don't crash if val==""trimSpaces=dropWhileisSpace.reverse.dropWhileisSpace.reverse