moduleYi.Keymap.Vim2.Ex.Commands.Common(parse,parseWithBang,parseRange,OptionAction(..),parseOption,filenameComplete,forAllBuffers,pureExCommand,impureExCommand,errorNoWrite)whereimportControl.ApplicativeimportControl.MonadimportData.List(isPrefixOf)importSystem.DirectoryimportqualifiedText.ParserCombinators.ParsecasPimportYi.BufferimportYi.EditorimportYi.KeymapimportYi.Keymap.Vim2.Ex.TypesimportYi.MiscimportYi.UtilsimportYi.MonadimportYi.Style(errorStyle)parse::P.GenParserChar()ExCommand->String->MaybeExCommandparseparsers=either(constNothing)Just(P.parseparser""s)parseWithBang::P.GenParserChar()a-- ^ The command name parser.->(a->Bool->P.GenParserChar()ExCommand)-- ^ A parser for the remaining command arguments.->String-- ^ The string to parse.->MaybeExCommandparseWithBangnameParserargumentParsers=doeither(constNothing)Just(P.parseparser""s)whereparser=doa<-nameParserbang<-parseBangargumentParserabangparseBang::P.GenParserChar()BoolparseBang=P.string"!"*>returnTrue<|>returnFalseparseRange::P.GenParserChar()LineRangeparseRange=returnCurrentLineRangedataOptionAction=Set!Bool|Invert|AskparseOption::String->(OptionAction->Action)->String->MaybeExCommandparseOptionnameaction=parse$dovoid$P.string"set "nos<-P.many(P.string"no")invs<-P.many(P.string"inv")void$P.stringnamebangs<-P.many(P.string"!")qs<-P.many(P.string"?")return$pureExCommand{cmdShow="set "++concatnos++name++concatbangs++concatqs,cmdAction=action$casefmap(not.null)[qs,bangs,invs,nos]of[True,_,_,_]->Ask[_,True,_,_]->Invert[_,_,True,_]->Invert[_,_,_,True]->SetFalse_->SetTrue}removePwd::FilePath->YiMFilePathremovePwdpath=dopwd<-iogetCurrentDirectoryreturn$!if(pwd++"/")`isPrefixOf`paththendrop(1+lengthpwd)pathelsepathfilenameComplete::FilePath->YiM[FilePath]filenameComplete"%"=do-- current buffer is minibuffer-- actual file is in the second buffer in bufferStackbufferRef<-withEditor$gets(head.drop1.bufferStack)currentFileName<-withGivenBufferbufferRef$fmapbufInfoFileNamebufInfoBletsanitizedFileName=casecurrentFileNameof('/':'/':f')->'/':f'_->currentFileNamefmap(:[])$removePwdsanitizedFileNamefilenameCompletef=dofiles<-matchingFileNamesNothingfcasefilesof[]->return[][x]->fmap(:[])$removePwdxxs->sequence$fmapremovePwdxsforAllBuffers::MonadEditorm=>(BufferRef->m())->m()forAllBuffersf=mapM_f=<<readEditorbufferStackpureExCommand::ExCommandpureExCommand=ExCommand{cmdIsPure=True,cmdComplete=return[],cmdAcceptsRange=False,cmdAction=undefined,cmdShow=undefined}impureExCommand::ExCommandimpureExCommand=pureExCommand{cmdIsPure=False}-- | Show an error on the status line.errorEditor::String->EditorM()errorEditors=printStatus(["error: "++s],errorStyle)-- | Show the common error message about an unsaved file on the status line.errorNoWrite::EditorM()errorNoWrite=errorEditor"No write since last change (add ! to override)"