Skip to content

Commit

Permalink
Check modification time of directories (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
arybczak authored Sep 23, 2023
1 parent f6997c2 commit 4a3a0ba
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# ghc-tags-1.8 (2023-??-??)
* Check modification time of directories.

# ghc-tags-1.7 (2023-06-29)
* Add support for GHC 9.6 and drop support for GHC 9.0.

Expand Down
2 changes: 1 addition & 1 deletion ghc-tags.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 2.4
name: ghc-tags
version: 1.7
version: 1.8
synopsis: Utility for generating ctags and etags with GHC API.
description: Utility for generating etags (Emacs) and ctags (Vim and other
editors) with GHC API for efficient project navigation.
Expand Down
46 changes: 29 additions & 17 deletions src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,39 @@ generateTagsForProject threads wd pc = runConcurrently . F.fold
processFiles = mapM_ $ \origPath -> do
let path = normalise origPath
unless (path `elem` pcExcludePaths pc) $ do
let tagPath = TagFileName (T.pack path)
doesDirectoryExist path >>= \case
True -> do
paths <- map (path </>) <$> listDirectory path
processFiles paths
True -> showIOError $ do
-- Enter directories only if their mtime changed or is not recorded.
mtime <- getModificationTime path
goIn <- modifyMVar (wdTimes wd) $ \times -> do
let goIn = eligibleForUpdate tagPath mtime times
pure . (, goIn) $! if goIn
then updateTimesWith tagPath mtime times
else times
when goIn $ do
paths <- map (path </>) <$> listDirectory path
processFiles paths
False -> F.forM_ (takeExtension path `lookup` haskellExts) $ \hsType -> do
showIOError $ do
-- Source files are scanned and updated only if their mtime changed or
-- it's not recorded.
time <- getModificationTime path
updateTags <- withMVar (wdTimes wd) $ \times -> pure $
case TagFileName (T.pack path) `Map.lookup` times of
-- If the file was already updated, it means it's eligible for
-- the update with regard to its mtime, but it was already
-- processed. In such case we let it through in order to
-- support the case of parsing the same file multiple times
-- with different CPP options.
Just (Updated updated oldTime) -> updated || oldTime < time
Nothing -> True
-- Source files are scanned and updated only if their mtime
-- changed or it's not recorded.
mtime <- getModificationTime path
updateTags <- withMVar (wdTimes wd) $ \times -> do
pure $ eligibleForUpdate tagPath mtime times
when updateTags $ do
atomically . writeTBQueue (wdQueue wd) $ Just (path, hsType, time)
atomically . writeTBQueue (wdQueue wd) $ Just (path, hsType, mtime)
where
eligibleForUpdate tagPath mtime times =
case tagPath `Map.lookup` times of
-- If the file was already updated, it means it's eligible for
-- the update with regard to its mtime, but it was already
-- processed. In such case we let it through in order to
-- support the case of parsing the same file multiple times
-- with different CPP options.
Just (Updated updated oldTime) -> updated || oldTime < mtime
Nothing -> True

haskellExts = [ (".hs", HsFile)
, (".hs-boot", HsBootFile)
, (".lhs", LHsFile)
Expand Down Expand Up @@ -249,7 +261,7 @@ cleanupTimes Tags{..} = Map.traverseMaybeWithKey $ \file -> \case
| updated || file `Map.member` tTags -> pure $ Just time
| otherwise -> do
let path = T.unpack $ getTagFileName file
doesFileExist path >>= \case
doesPathExist path >>= \case
True -> pure $ Just time
False -> pure Nothing

Expand Down

0 comments on commit 4a3a0ba

Please sign in to comment.