{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, TypeOperators #-}-- Copyright (c) 2008 Jean-Philippe Bernardy-- | Various high-level functions to further classify.moduleYi.Miscwhere{- Standard Library Module Imports -}importData.List(isPrefixOf,(\\),filter)importSystem.FriendlyPath(expandTilda,isAbsolute')importSystem.FilePath(takeDirectory,(</>),addTrailingPathSeparator,hasTrailingPathSeparator,takeFileName)importSystem.Directory(doesDirectoryExist,getDirectoryContents,getCurrentDirectory)importControl.Monad.Trans(MonadIO(..)){- External Library Module Imports -}{- Local (yi) module imports -}importPrelude()importYi.CoreimportYi.MiniBuffer(simpleComplete,withMinibufferGen)importSystem.CanonicalizePath(canonicalizePath)-- | Given a possible starting path (which if not given defaults to-- the current directory) and a fragment of a path we find all-- files within the given (or current) directory which can complete-- the given path fragment.-- We return a pair of both directory plus the filenames on their own-- that is without their directories. The reason for this is that if-- we return all of the filenames then we get a 'hint' which is way too-- long to be particularly useful.getAppropriateFiles::MaybeString->String->YiM(String,[String])getAppropriateFilesstarts=docurDir<-casestartofNothing->dobufferPath<-withBuffer$getsfileliftIO$getFolderbufferPath(Justpath)->returnpathletsDir=ifhasTrailingPathSeparatorsthenselsetakeDirectoryssearchDir=ifnullsDirthencurDirelseifisAbsolute'sDirthensDirelsecurDir</>sDirsearchDir'<-liftIO$expandTildasearchDirletfixTrailingPathSeparatorf=doisDir<-doesDirectoryExist(searchDir'</>f)return$ifisDirthenaddTrailingPathSeparatorfelseffiles<-liftIO$getDirectoryContentssearchDir'-- Remove the two standard current-dir and parent-dir as we do not-- need to complete or hint about these as they are known by users.letfiles'=files\\[".",".."]fs<-liftIO$mapMfixTrailingPathSeparatorfiles'letmatching=filter(isPrefixOf$takeFileNames)fsreturn(sDir,matching)-- | Given a path, trim the file name bit if it exists. If no path-- given, return current directory.getFolder::MaybeString->IOStringgetFolderNothing=getCurrentDirectorygetFolder(Justpath)=doisDir<-doesDirectoryExistpathletdir=ifisDirthenpathelsetakeDirectorypathifnulldirthengetCurrentDirectoryelsereturndir-- | Given a possible path and a prefix, return matching file names.matchingFileNames::MaybeString->String->YiM[String]matchingFileNamesstarts=do(sDir,files)<-getAppropriateFilesstartsreturn$fmap(sDir</>)filesadjBlock::Int->BufferM()adjBlockx=withSyntaxB'(\ms->modeAdjustBlockmsx)-- | A simple wrapper to adjust the current indentation using-- the mode specific indentation function but according to the-- given indent behaviour.adjIndent::IndentBehaviour->BufferM()adjIndentib=withSyntaxB'(\ms->modeIndentmsib)-- | Generic emacs style prompt file action. Takes a @prompt and a continuation @act-- and prompts the user with file hintspromptFile::String->(String->YiM())->YiM()promptFilepromptact=domaybePath<-withBuffer$getsfilestartPath<-addTrailingPathSeparator<$>(liftIO$canonicalizePath=<<getFoldermaybePath)-- TODO: Just call withMinibufferwithMinibufferGenstartPath(findFileHintstartPath)prompt(simpleComplete$matchingFileNames(JuststartPath))act-- | For use as the hint when opening a file using the minibuffer.-- We essentially return all the files in the given directory which-- have the given prefix.findFileHint::String->String->YiM[String]findFileHintstartPaths=snd<$>getAppropriateFiles(JuststartPath)s