module Manatee.Plugin.Anything.AnythingLocate where
import DBus.Client hiding (Signal)
import Data.ByteString.UTF8 hiding (drop, length)
import Data.List
import Data.Typeable
import Manatee.Core.DBus
import Manatee.Core.FileOpenRule
import Manatee.Core.Types
import Manatee.Plugin.Anything.Anything
import Manatee.Plugin.Anything.Types
import Manatee.Toolkit.General.FilePath
import Manatee.Toolkit.General.Maybe
import Manatee.Toolkit.General.Misc
import Manatee.Toolkit.Gio.Gio
import System.Environment
import System.FilePath
import System.GIO.Enums
import System.GIO.File.FileInfo hiding (FileInfo)
import qualified Data.ByteString.Char8 as B
data FileInfo =
FileInfo {fileInfoPath :: ByteString
,fileInfoDisplayName :: String
,fileInfoContentType :: String
,fileInfoFileType :: FileType
,fileInfoSize :: String
} deriving Typeable
instance AnythingCandidate FileInfo where
candidateCommandName _ = ""
candidateFilterName a = fileInfoDisplayName a ++ " " ++ fileInfoSize a
candidateCompletionName a _ = fileInfoDisplayName a
candidateExpandName a input = do
home <- getEnv "HOME"
return $
if ("~" :: String) `isPrefixOf` input
then '~' : drop (length home) (toString $ fileInfoPath a)
else toString $ fileInfoPath a
anythingLocate :: Anything
anythingLocate =
Anything {anythingColumnTitle = ["Locate", "Size"]
,anythingColumnFun = anythingLocateColumnFun
,anythingSearch = AnythingSearch (anythingLocateSearch False)
,anythingFilterRule = anythingLocateFilterRule
,anythingCompletionRule = takeFileName
,anythingInputDepend = True
,anythingCommandFun = anythingLocateCommandFun
,anythingCalculateDelay = 0
}
anythingLocateSearch :: Bool -> AnythingInput -> Client -> IO [FileInfo]
anythingLocateSearch filterDir filepath _ = do
home <- getEnv "HOME"
let
path = if ("~" :: String) `isPrefixOf` filepath
then home ++ drop (length ("~" :: String)) filepath
else filepath
upperDir | hasTrailingPathSeparator path
= fromString path
| otherwise
= fromString $ getUpperDirectory path
anythingLocateGetFileInfos upperDir filterDir
anythingLocateGetFileInfos :: ByteString -> Bool -> IO [FileInfo]
anythingLocateGetFileInfos upperDir filterDir =
if directoryDoesExist upperDir
then do
infos <- do
fileInfos <- directoryGetFileInfos upperDir
return $
map (\info ->
FileInfo (B.concat [upperDir, fileInfoGetNameWithType info])
(fileInfoGetDisplayNameWithType info)
(maybeError (fileInfoGetContentType info)
"anythingInteractiveDirectorySearch - fileInfoGetContentType.")
(fileInfoGetFileType info)
(formatFileSizeForDisplay $ toInteger $ fileInfoGetSize info))
$ (\x ->
if filterDir
then filter (\x -> fileInfoGetFileType x == FileTypeDirectory) x
else x
) fileInfos
return $ sortBy (\ a b -> compareFileWithType
(fileInfoDisplayName a, fileInfoFileType a)
(fileInfoDisplayName b, fileInfoFileType b)
) infos
else return []
anythingLocateFilterRule :: AnythingInput -> String -> Bool
anythingLocateFilterRule input candidate =
hasTrailingPathSeparator input ||
(takeFileName input `isPrefixOf` candidate)
anythingLocateColumnFun :: [AnythingColumnFun]
anythingLocateColumnFun =
[fileInfoDisplayName . anythingCandidateUnpack
,fileInfoSize . anythingCandidateUnpack]
anythingLocateCommandFun :: AnythingCommandFun
anythingLocateCommandFun _ wrap _
| directoryDoesExist path
= return [("Open directory", anythingLocateActionOpenDirectory filepath)
,("Play directory", anythingLocateActionPlayDirectory filepath)]
| otherwise =
fileOpenRule filepath contentType
where path = fileInfoPath $ anythingCandidateUnpack wrap
filepath = toString path
contentType = fileInfoContentType $ anythingCandidateUnpack wrap
anythingLocateActionOpenFile :: FilePath -> Client -> IO ()
anythingLocateActionOpenFile path client =
mkDaemonSignal client NewTab (NewTabArgs "PageEditor" path)
anythingLocateActionOpenDirectory :: FilePath -> Client -> IO ()
anythingLocateActionOpenDirectory path client =
mkDaemonSignal client NewTab (NewTabArgs "PageFileManager" path)
anythingLocateActionPlayDirectory :: FilePath -> Client -> IO ()
anythingLocateActionPlayDirectory path client =
mkDaemonSignal client NewTab (NewTabArgs "PagePlayer" path)