packages feed

hasktags 0.69.1 → 0.69.2

raw patch · 7 files changed

+258/−133 lines, 7 filesdep +HUnitdep ~basedep ~bytestringdep ~directorynew-component:exe:testnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: HUnit

Dependency ranges changed: base, bytestring, directory, json

API changes (from Hackage documentation)

- Hasktags: instance Eq Mode
- Hasktags: instance Eq Token
- Hasktags: instance Ord Mode
- Hasktags: instance Show Mode
- Hasktags: instance Show Token
+ Hasktags: instance GHC.Classes.Eq Hasktags.Mode
+ Hasktags: instance GHC.Classes.Eq Hasktags.Token
+ Hasktags: instance GHC.Classes.Ord Hasktags.Mode
+ Hasktags: instance GHC.Show.Show Hasktags.Mode
+ Hasktags: instance GHC.Show.Show Hasktags.Token

Files

README view
@@ -1,75 +1,82 @@-hasktags: a tool to generate tag files for vim and emacs--  What is it for? A tag file is a index containing key items of your project such as-  - function names-  - module names-  - data declarations-  - ...+# hasktags+A tool to generate tag files for vim and emacs -  so that you can find / jump to them fast.+What is it for? A tag file is a index containing key items of your project such as+- function names+- module names+- data declarations+- ... -HOWTO (GENERATING TAG FILES):-  Build hasktags (standard cabal build)+So that you can find / jump to them fast. -  I've been using this bash function or something similar for a long time.-  It may be cumbersome but works:+## HOWTO (GENERATING TAG FILES):+Build hasktags (standard cabal build) -  runHaskTagsVim() {-          # use --etags instead of --ctags for emacs-          hasktags --ignore-close-implementation --ctags .; sort tags-  }+I've been using this bash function or something similar for a long time.+It may be cumbersome but works: -HOWTO (USING TAG FILES):-  VIM: let tags+=tagifle " tags,TAGS is the default setting so probably you don't have to do anything-       :tjump foo<tab> or such. See :h tags-  -  NEdit:-	Load the "tags" file using File/Load Tags File.-	Use "Ctrl-D" to search for a tag.+```bash+runHaskTagsVim() {+  # use --etags instead of --ctags for emacs+  hasktags --ignore-close-implementation --ctags .; sort tags+}+``` -  XEmacs/Emacs:-	Load the "TAGS" file using "visit-tags-table"-	Use "M-." to search for a tag.+## HOWTO (USING TAG FILES):+### ViM+```viml+let tags+=tagfile " tags,TAGS is the default setting so probably you don't have to do anything+```+`:tjump foo<tab>` or such. See `:h` tags -  jedit:-        There is a plugin-	+### NEdit+Load the "tags" file using File/Load Tags File.+Use "Ctrl-D" to search for a tag. +### XEmacs/Emacs+Load the "TAGS" file using "visit-tags-table"+Use "M-." to search for a tag. -run test cases:-  cd testcases; sh test.sh+### jedit+There is a plugin. +### Tests+To run the tests, do `cd testcases; sh test.sh`. -history:+## History In the past this tool was distributed with ghc. I forked and added some features.  hasktags itself was moved out of the ghc repository. Then I only verified that my fork finds at least as much tags as the one forked by Igloo. +## Future Things which could be done in the future: - make json support optional - Marco Túlio Pimenta Gontijo proposed replacing json by aeson because it might   be faster-- write a nice README.md file instead -maintainers: See cabal file+## Maintainers+See cabal file +## Comments about literate haskell ([lhs][]):+Alex no longer supports bird style ">", so should we drop support, too? -comments about literate haskell (lhs):-=======================================-http://www.haskell.org/haskellwiki/Literate_programming-alex no longer supports bird style ">", so should we drop support, too?+## Contributors+- Tsuru Capital (github/liyang)+- Marco Túlio Pimenta Gontijo (github/marcotmarcot) -contributors:-  Tsuru Capital (github/liyang)-  Marco Túlio Pimenta Gontijo (github/marcotmarcot)-  TODO: add all people having contributed before Oct 2012-  This includes people contributing to the darcs repository as well as people-  having contributed when this repository has been part of ghc+## TODO+Add all people having contributed before Oct 2012+This includes people contributing to the darcs repository as well as people+having contributed when this repository has been part of ghc -related work (list taken from announce of lushtags:-  https://github.com/bitc/lushtags-  http://hackage.haskell.org/package/hasktags-  http://kingfisher.nfshost.com/sw/gasbag/-  http://hackage.haskell.org/package/hothasktags-  http://majutsushi.github.com/tagbar/-and probably much more+# Related work+List taken from announce of lushtags.+- https://github.com/bitc/lushtags+- http://hackage.haskell.org/package/hasktags+- http://kingfisher.nfshost.com/sw/gasbag/+- http://hackage.haskell.org/package/hothasktags+- http://majutsushi.github.com/tagbar/++And probably much more++[lhs]: http://www.haskell.org/haskellwiki/Literate_programming
hasktags.cabal view
@@ -1,17 +1,18 @@ Name: hasktags-Version: 0.69.1+Version: 0.69.2 Copyright: The University Court of the University of Glasgow License: BSD3 License-File: LICENSE Author: The GHC Team Maintainer:+ Jack Henahan <jhenahan@me.com>,  Marc Weber <marco-oweber@gmx.de>,  Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com> homepage: http://github.com/MarcWeber/hasktags bug-reports: http://github.com/MarcWeber/hasktags/issues Synopsis: Produces ctags "tags" and etags "TAGS" files for Haskell programs Description:-	Produces ctags "tags" and etags "TAGS" files for Haskell programs.+  Produces ctags "tags" and etags "TAGS" files for Haskell programs. Category: Development build-type: Simple cabal-version: >=1.10@@ -56,8 +57,8 @@   hs-source-dirs:    src   ghc-options:       -Wall   exposed-modules:   Hasktags-  other-modules:     Tags, DebugShow -  build-depends:       +  other-modules:     Tags, DebugShow+  build-depends:     utf8-string,     base >= 4 && < 5,     bytestring >= 0.9 && < 0.11,@@ -84,38 +85,43 @@   if flag(debug)     cpp-options: -Ddebug --- Either ./Setup sdist complains about missing executable for test case or--- ./Setup configure (having same executable twice, "consider this a bug")+Executable test+    Main-Is: Test.hs+    Build-Depends:+      utf8-string,+      base,+      bytestring,+      directory,+      filepath,+      json,+      HUnit+    other-modules: Tags, Hasktags, DebugShow+    hs-source-dirs: src, tests+    ghc-options: -Wall+    default-language: Haskell2010 --- Executable test---     Main-Is: Test.hs---     Build-Depends:---       utf8-string,---       base >= 4 && < 5,---       bytestring >= 0.9 && < 0.11,---       directory >= 1.1 && < 1.3,---       filepath,---       json >= 0.5 && < 0.8,---       HUnit >= 1.2 && < 1.3---     other-modules: Tags, Hasktags, DebugShow---     hs-source-dirs: src, tests---     ghc-options: -Wall---     default-language: Haskell2010--- ---   if !os(windows)---     build-depends: unix--- ---   if flag(debug)---     cpp-options: -Ddebug--- --- Test-Suite test---   Type: exitcode-stdio-1.0---   Main-Is: Test.hs---   hs-source-dirs: src, tests---   Build-Depends: base, bytestring, directory, filepath, json,---     HUnit >= 1.2 && < 1.3---   ghc-options: -Wall---   default-language: Haskell2010--- ---   if flag(debug)---     cpp-options: -Ddebug+  if !os(windows)+    build-depends: unix++  if flag(debug)+    cpp-options: -Ddebug++Test-Suite testsuite+  Type: exitcode-stdio-1.0+  Main-Is: Test.hs+  hs-source-dirs: src, tests+  Build-Depends:+                utf8-string,+                base,+                bytestring,+                directory,+                filepath,+                json,+                HUnit,+                unix+  other-modules: Tags, Hasktags, DebugShow+  ghc-options: -Wall+  default-language: Haskell2010++  if flag(debug)+    cpp-options: -Ddebug
src/DebugShow.hs view
@@ -14,7 +14,7 @@ #else  -- id function - should have no effect-trace_ :: (Show a) => String -> a -> b -> b+trace_ :: String -> a -> b -> b trace_ _ _ ret = ret {-# INLINE trace_ #-} 
src/Hasktags.hs view
@@ -15,29 +15,42 @@    dirToFiles ) where- import Tags---- the lib+    ( FileData(..),+      FoundThing(..),+      FoundThingType(FTConsAccessor, FTFuncTypeDef, FTClass, FTType,+                     FTCons, FTNewtype, FTData, FTDataGADT, FTModule, FTFuncImpl),+      Pos(..),+      FileName,+      mywords,+      writectagsfile,+      writeetagsfile ) import qualified Data.ByteString.Char8 as BS--import qualified Data.ByteString.UTF8 as BS8 -- see notes at utf8_to_char8_hack--import Data.Char-import Data.List-import Data.Maybe-+    ( ByteString, unpack, readFile )+import qualified Data.ByteString.UTF8 as BS8 ( fromString )+import Data.Char ( isSpace )+import Data.List ( tails, nubBy, isSuffixOf, isPrefixOf )+import Data.Maybe ( maybeToList ) import System.IO+    ( IOMode(WriteMode, AppendMode),+      Handle,+      hGetContents,+      stdout,+      stdin,+      openFile,+      hClose ) import System.Directory-import Text.JSON.Generic-import Control.Monad--import DebugShow-+    ( getModificationTime,+      getDirectoryContents,+      doesFileExist,+      doesDirectoryExist )+import Text.JSON.Generic ( encodeJSON, decodeJSON )+import Control.Monad ( when )+import DebugShow ( trace_ ) #ifdef VERSION_unix-import System.Posix.Files+import System.Posix.Files ( isSymbolicLink, getSymbolicLinkStatus ) #endif-import System.FilePath ((</>))+import System.FilePath ( (</>) )  -- search for definitions of things -- we do this by looking for the following patterns:@@ -89,14 +102,14 @@ -- Reference: http://ctags.sourceforge.net/FORMAT  --- | getMode takes a list of modes and extract the mode with the+-- | getMode takes a list of modes and extracts the mode with the --   highest precedence.  These are as follows: Both, CTags, ETags --   The default case is Both. getMode :: [Mode] -> Mode getMode [] = BothTags getMode xs = maximum xs --- | getOutFile scan the modes searching for output redirection+-- | getOutFile scans the modes searching for output redirection --   if not found, open the file with name passed as parameter. --   Handle special file -, which is stdout getOutFile :: String -> IOMode -> [Mode] -> IO Handle@@ -453,8 +466,8 @@  -- this only exists for test case testcases/HUnitBase.lhs (bird literate haskell style) getTopLevelIndent :: Bool -> [[Token]] -> Int-getTopLevelIndent _ [] = 0 -- (no import found , assuming indent 0 : this can be-                         -- done better but should suffice for most needs+getTopLevelIndent _ [] = 0 -- (no import found, assuming indent 0: this can be+                           -- done better but should suffice for most needs getTopLevelIndent isLiterate ((nl:next:_):xs) = if "import" == (tokenString next)                           then let (NewLine i) = nl in i                           else getTopLevelIndent isLiterate xs
src/Main.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE CPP #-}+ module Main (main) where import Hasktags @@ -7,7 +7,6 @@  import Data.List -import System.IO import System.Directory import System.Console.GetOpt import System.Exit@@ -25,11 +24,11 @@             (NoArg BothTags) "generate both CTAGS and ETAGS"           , Option "a" ["append"]               (NoArg Append)-            $ "append to existing CTAGS and/or ETAGS file(s). After this file "-              ++ "will no longer be sorted!"+            $ "append to existing CTAGS and/or ETAGS file(s). Afterward this "+              ++ "file will no longer be sorted!"           , Option "" ["ignore-close-implementation"]               (NoArg IgnoreCloseImpl)-            $ "ignores found implementation if its closer than 7 lines  - so "+            $ "ignores found implementation if it is closer than 7 lines - so "               ++ "you can jump to definition in one shot"           , Option "o" ["output"]             (ReqArg OutRedir "")
src/Tags.hs view
@@ -3,12 +3,11 @@ -- this should be moved into its own library (after cleaning up most of it ..) -- yes, this is still specific to hasktags :( module Tags where-import Data.Char-import Data.List-import Data.Data--import System.IO-import Control.Monad+import Data.Char ( isSpace )+import Data.List ( sortBy )+import Data.Data ( Data, Typeable )+import System.IO ( Handle, hPutStrLn, hPutStr )+import Control.Monad ( when )  -- my words is mainly copied from Data.List. -- difference abc::def is recognized as three words@@ -16,7 +15,7 @@ mywords :: Bool -> String -> [String] mywords spaced s =  case rest of                         ')':xs -> (blanks' ++ ")") : mywords spaced xs-			"" -> []+                        "" -> []                         '{':'-':xs -> (blanks' ++ "{-") : mywords spaced xs                         '-':'}':xs -> (blanks' ++ "-}") : mywords spaced xs                         '{':xs -> (blanks' ++ "{") : mywords spaced xs@@ -26,22 +25,22 @@                         '=':xs -> (blanks' ++ "=") : mywords spaced xs                         ',':xs -> (blanks' ++ ",") : mywords spaced xs                         ':':':':xs -> (blanks' ++ "::") : mywords spaced xs-			s' -> (blanks' ++ w) : mywords spaced s''-			      where (w, s'') = myBreak s'-				    myBreak [] = ([],[])-				    myBreak (':':':':xs) = ([], "::"++xs)-				    myBreak (')':xs) = ([],')':xs)+                        s' -> (blanks' ++ w) : mywords spaced s''+                              where (w, s'') = myBreak s'+                                    myBreak [] = ([],[])+                                    myBreak (':':':':xs) = ([], "::"++xs)+                                    myBreak (')':xs) = ([],')':xs)                                     myBreak ('(':xs) = ([],'(':xs)-				    myBreak ('`':xs) = ([],'`':xs)-				    myBreak ('=':xs) = ([],'=':xs)-				    myBreak (',':xs) = ([],',':xs)+                                    myBreak ('`':xs) = ([],'`':xs)+                                    myBreak ('=':xs) = ([],'=':xs)+                                    myBreak (',':xs) = ([],',':xs)                                     myBreak xss@(x:xs)                                       | isSpace x                                         = if spaced                                           then ([], xss)                                           else ([], dropWhile isSpace xss)                                       | otherwise = let (a,b) = myBreak xs-						    in  (x:a,b)+                                                    in  (x:a,b)                     where blanks' = if spaced then blanks else ""                           (blanks, rest) = span {-partain:Char.-}isSpace s @@ -115,6 +114,7 @@          ++ "\t/^" ++ concatMap ctagEncode lineText          ++ "$/;\"\t" ++ show kind          ++ "\tline:" ++ show (line + 1)+         ++ "\tlanguage:Haskell"   -- stuff for dealing with ctags output format@@ -158,4 +158,3 @@         ++ "\x7f"         ++ name ++ "\x01"         ++ show line ++ "," ++ show (line + 1) ++ "\n"-
+ tests/Test.hs view
@@ -0,0 +1,101 @@+module Main where++import Hasktags+import Tags++import Control.Monad+import Data.List+import System.Directory+import System.Exit++import qualified Data.ByteString.Char8 as BS++import Test.HUnit++{- TODO+Test the library (recursive, caching, ..)+But that's less likely to break+-}++-- all comments should differ at the beginning+comments :: [BS.ByteString] -> String -> [String]+comments lns comment = filter (not . null) $ map hitOrEmpty lns+  where+    c = BS.pack $ comment ++ " "+    hitOrEmpty :: BS.ByteString -> String+    hitOrEmpty bs =+      let ds = BS.dropWhile (== ' ') bs+      in if c `BS.isPrefixOf` ds+            then BS.unpack $ BS.drop (BS.length c) ds+            else ""++tagComments :: [BS.ByteString] -> String -> [String]+tagComments lns comment+  = map (takeWhile (not . (`elem` "\n\r "))) $ comments lns comment++testToBeFound :: [String] -> [String] -> Test+testToBeFound foundTagNames toBeFound =+        "these were not found"+        ~: [] ~?= filter (not . (`elem` foundTagNames)) toBeFound++testNotToBeFound :: [String] -> [String] -> Test+testNotToBeFound foundTagNames notToBeFound =+        "these should not have been found"+        ~: [] ~=? filter (`elem` foundTagNames) notToBeFound++testToBeFoundOnce :: [String] -> [String] -> Test+testToBeFoundOnce foundTagNames list =+        "these should have been found exactly one time"+        ~: []+          ~=? [name+            | name <- list, 1 /= length (filter (==  name ) foundTagNames)]++etagsToBeFound :: String -> [String] -> Test+etagsToBeFound etags toBeFound =+        "these were not found on TAGS"+        ~: [] ~=? filter (not . (`isInfixOf` etags)) toBeFound++etagsNotToBeFound :: String -> [String] -> Test+etagsNotToBeFound etags notToBeFound =+        "these should not have been found on TAGS"+        ~: [] ~=? filter (`isInfixOf` etags) notToBeFound++etagsToBeFoundOnce :: String -> [String] -> Test+etagsToBeFoundOnce etags list =+        "these should not have been found on TAGS"+        ~: [] ~=? [ name | name <- list, 1 /= length (infixes name etags)]++infixes :: Eq a => [a] -> [a] -> [[a]]+infixes needle haystack = filter (isPrefixOf needle) (tails haystack)++createTestCase :: FilePath -> IO Test+createTestCase filename = do+  bs <- BS.readFile filename+  let lns = BS.lines bs+  let fd = findThingsInBS True filename bs+  let FileData _ things = fd++  let foundTagNames = [name | FoundThing _ name _ <- things]+  let etags = etagsDumpFileData fd++  let testList = TestList [+          testToBeFound foundTagNames (tagComments lns "-- to be found"),+          testNotToBeFound foundTagNames (tagComments lns "-- not to be found"),+          testToBeFoundOnce+            foundTagNames+            (tagComments lns "-- once to be found"),+          etagsToBeFound etags (comments lns "-- TAGS to be found"),+          etagsNotToBeFound etags (comments lns "-- TAGS not to be found"),+          etagsToBeFoundOnce etags (comments lns "-- TAGS once to be found")+        ]++  return $ filename ~: testList++main :: IO ()+main+  = do+    setCurrentDirectory "testcases"+    files <- getDirectoryContents "."+    tests <- mapM createTestCase $ filter (not . (`elem` [".", "..", "expected_failures_testing_suite.hs"])) files+    counts_ <- runTestTT $ TestList tests+    when (errors counts_ + failures counts_ > 0) exitFailure