Fix compilation errors
- Remove nonexistent confDebounce field from WatchConfig (fsnotify 0.4.4.0) - Remove unused Generic deriving and GHC.Generics import - Replace .!= with fromMaybe (not re-exported by Data.Yaml) - Add missing Data.Text import in Main.hs - Use git -C flag in runGitIn to run in the correct repo directory - Clean up unused imports
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
--
|
||||
-- Copyright (c) 2012 Mark Dittmer - http://www.markdittmer.org
|
||||
-- Developed for a Google Summer of Code project - http://gsoc2012.markdittmer.org
|
||||
--
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||
|
||||
module System.FSNotify.Win32 (
|
||||
FileListener(..)
|
||||
, NativeManager
|
||||
) where
|
||||
|
||||
import Control.Concurrent
|
||||
import Control.Monad (when)
|
||||
import Data.Bits
|
||||
import qualified Data.Map as Map
|
||||
import Data.Time (getCurrentTime, UTCTime)
|
||||
import Prelude
|
||||
import System.FSNotify.Listener
|
||||
import System.FSNotify.Path (canonicalizeDirPath)
|
||||
import System.FSNotify.Types
|
||||
import System.FilePath
|
||||
import qualified System.Win32.Notify as WNo
|
||||
|
||||
|
||||
type NativeManager = WNo.WatchManager
|
||||
|
||||
-- Win32-notify has (temporarily?) dropped support for Renamed events.
|
||||
fsnEvent :: EventIsDirectory -> FilePath -> UTCTime -> WNo.Event -> Event
|
||||
fsnEvent isDirectory basedir timestamp (WNo.Created name) = Added (normalise (basedir </> name)) timestamp isDirectory
|
||||
fsnEvent isDirectory basedir timestamp (WNo.Modified name) = Modified (normalise (basedir </> name)) timestamp isDirectory
|
||||
fsnEvent isDirectory basedir timestamp (WNo.Deleted name) = Removed (normalise (basedir </> name)) timestamp isDirectory
|
||||
|
||||
handleWNoEvent :: EventIsDirectory -> FilePath -> ActionPredicate -> EventCallback -> WNo.Event -> IO ()
|
||||
handleWNoEvent isDirectory basedir actPred callback inoEvent = do
|
||||
currentTime <- getCurrentTime
|
||||
let event = fsnEvent isDirectory basedir currentTime inoEvent
|
||||
when (actPred event) $ callback event
|
||||
|
||||
watchDirectory :: Bool -> WatchConfig -> WNo.WatchManager -> FilePath -> ActionPredicate -> EventCallback -> IO (IO ())
|
||||
watchDirectory isRecursive _conf watchManager@(WNo.WatchManager mvarMap) path actPred callback = do
|
||||
path' <- canonicalizeDirPath path
|
||||
|
||||
let fileFlags = foldl (.|.) 0 [WNo.fILE_NOTIFY_CHANGE_FILE_NAME
|
||||
, WNo.fILE_NOTIFY_CHANGE_SIZE
|
||||
, WNo.fILE_NOTIFY_CHANGE_ATTRIBUTES]
|
||||
let dirFlags = foldl (.|.) 0 [WNo.fILE_NOTIFY_CHANGE_DIR_NAME]
|
||||
|
||||
-- Start one watch for file events and one for directory events
|
||||
-- (There seems to be no other way to provide isDirectory information)
|
||||
wid1 <- WNo.watchDirectory watchManager path' isRecursive fileFlags (handleWNoEvent IsFile path' actPred callback)
|
||||
wid2 <- WNo.watchDirectory watchManager path' isRecursive dirFlags (handleWNoEvent IsDirectory path' actPred callback)
|
||||
|
||||
-- The StopListening action should make sure to remove the watches from the manager after they're killed.
|
||||
-- Otherwise, a call to killSession would cause us to try to kill them again, resulting in an invalid handle error.
|
||||
return $ do
|
||||
WNo.killWatch wid1
|
||||
modifyMVar_ mvarMap $ \watchMap -> return (Map.delete wid1 watchMap)
|
||||
|
||||
WNo.killWatch wid2
|
||||
modifyMVar_ mvarMap $ \watchMap -> return (Map.delete wid2 watchMap)
|
||||
|
||||
instance FileListener WNo.WatchManager () where
|
||||
-- TODO: This should actually lookup a Windows API version and possibly return
|
||||
-- Nothing the calls we need are not available. This will require that API
|
||||
-- version information be exposed by Win32-notify.
|
||||
initSession _ = Right <$> WNo.initWatchManager
|
||||
|
||||
killSession = WNo.killWatchManager
|
||||
|
||||
listen = watchDirectory False
|
||||
listenRecursive = watchDirectory True
|
||||
Reference in New Issue
Block a user