diff --git a/htags.cabal b/htags.cabal
--- a/htags.cabal
+++ b/htags.cabal
@@ -1,7 +1,7 @@
 Author:         David Sankel
 Maintainer:     david@sankelsoftware.com
 Name:           htags
-Version:        1.0
+Version:        1.0.1
 Cabal-Version:  >= 1.2
 License:        BSD3
 Category:       Development, Source-tools, Utils
@@ -19,4 +19,5 @@
 Executable htags
   Build-Depends:  base, filepath, directory, mtl, haskell-src
   Main-Is:        htags.hs
+  other-modules: ExCommand, GenTags, Tag
   Hs-Source-Dirs: src
diff --git a/src/ExCommand.hs b/src/ExCommand.hs
new file mode 100644
--- /dev/null
+++ b/src/ExCommand.hs
@@ -0,0 +1,24 @@
+module ExCommand
+  ( ExCommand
+  , exGotoLine
+  , exSearch
+  , exToStr
+  ) where
+
+import Control.Applicative
+
+newtype ExCommand = EC String
+
+exToStr (EC s) = s
+
+exGotoLine :: Int -> ExCommand
+exGotoLine i = EC (show i)
+
+-- TODO: maybe use this later to search to get to the appropriate tag.
+exSearch :: String -> ExCommand
+exSearch s = EC ("/^" ++ exEscape s ++ "/")
+  where
+    exEscape = concatMap f
+      where
+        f '\\' = "\\\\"
+        f a = pure a
diff --git a/src/GenTags.hs b/src/GenTags.hs
new file mode 100644
--- /dev/null
+++ b/src/GenTags.hs
@@ -0,0 +1,57 @@
+module GenTags
+  ( modToTags
+  ) where
+
+import Language.Haskell.Syntax
+import Tag
+import ExCommand
+import Data.Monoid
+import Control.Applicative
+
+--
+-- HsModule Helpers
+--
+
+decls :: HsModule -> [HsDecl]
+decls (HsModule _ _ _ _ a) = a
+
+--
+-- (HsModule -> Tag) Helpers
+--
+
+l :: SrcLoc -> HsName -> Tag
+l loc = \n -> tag (nToStr n) (srcFilename loc) (ziffy loc)
+  where
+    ziffy :: SrcLoc -> ExCommand
+    ziffy = exGotoLine . srcLine
+    nToStr :: HsName -> String
+    nToStr (HsIdent s) = s
+    nToStr (HsSymbol s) = s
+
+z :: SrcLoc -> [HsName] -> [Tag]
+z = fmap . l
+
+f :: SrcLoc -> HsName -> [Tag]
+f = (fmap.fmap) pure l
+
+--
+-- (HsModule -> Tag)
+--
+
+modToTags :: HsModule -> [Tag]
+modToTags = declsToTags . decls
+
+declsToTags ::  [HsDecl] -> [Tag]
+declsToTags = concatMap declToTags
+
+declToTags :: HsDecl -> [Tag]
+declToTags (HsTypeDecl    loc name _ _)            = f loc name
+declToTags (HsDataDecl    loc _ name _ condecls _) = f loc name `mappend` concatMap cdToTags condecls
+declToTags (HsNewTypeDecl loc _ name _ condecl _)  = f loc name `mappend` cdToTags condecl
+declToTags (HsClassDecl   loc _ name _ decls)      = f loc name `mappend` declsToTags decls
+declToTags (HsTypeSig     loc names _)             = z loc names
+declToTags _                                       = mempty
+
+cdToTags :: HsConDecl -> [Tag]
+cdToTags (HsConDecl loc name _)    = f loc name
+cdToTags (HsRecDecl loc name recs) = f loc name `mappend` z loc (concatMap fst recs)
diff --git a/src/Tag.hs b/src/Tag.hs
new file mode 100644
--- /dev/null
+++ b/src/Tag.hs
@@ -0,0 +1,31 @@
+module Tag
+  ( Tag
+  , tag
+  , identT
+  , fnameT
+  , exComT
+  , tagsToTagfile
+  ) where
+
+import ExCommand
+import Data.Ord (comparing)
+import Data.List (sortBy, intercalate)
+import Data.Traversable (sequenceA)
+
+data Tag = T { identT :: String
+             , fnameT :: String
+             , exComT :: ExCommand
+             }
+
+tag :: String -> String -> ExCommand -> Tag
+tag = T
+
+tagsToTagfile ::  [Tag] -> String
+tagsToTagfile = unlines . fmap tagline . sortBy (comparing identT)
+  where
+    tagline :: Tag -> String
+    tagline = intercalate "\t" . sequenceA [identT, fnameT, exToStr.exComT]
+    -- Alt. defn.
+    -- tagline t =  (identT t) ++ "\t" 
+    --           ++ (fnameT t) ++ "\t"
+    --           ++ (exToStr (exComT t))
