Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First repo.

  • Loading branch information...
commit 3f40bd4bbbf3966327b2abc8774e907622223488 0 parents
@bjornbm authored
Showing with 106 additions and 0 deletions.
  1. +45 −0 NNUtil.hs
  2. +61 −0 nn.hs
45 NNUtil.hs
@@ -0,0 +1,45 @@
+module NNUtil where
+
+import Control.Applicative
+import Data.List
+import Data.List.Split
+import Data.Time
+import System
+import System.Directory
+import System.FilePath
+import System.Process
+
+
+-- | Find files. We used the ASCII NULL terminated paths since file
+-- names can contain @\n@ and would get split by @lines@.
+mdfind dir args = endBy "\0" <$> readProcess "mdfind" (stdArgs dir ++ args) ""
+ where
+ stdArgs dir = [ "-onlyin", dir
+ , "-0"
+ -- , "name:_" -- FIXME this is an embarrasing kludge!
+ ]
+
+-- | List all files in the directory except for hidden files.
+mdlist dir = filter ((/='.') . head) <$> getDirectoryContents dir
+
+-- Regex patterns.
+obsP = "^\\+?"
+idP = "\\<[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{4}\\>"
+tagP = "-[a-zA-Z0-9_.]+-"
+restP = ".+[^~]$" -- Ignore unix (vim) backup files.
+filePattern = obsP ++ idP ++ tagP ++ restP
+filePattern' = obsP ++ idP ++ tagP -- Allows backup files to match.
+filePattern0 = "^" ++ idP ++ tagP -- Don't match obsolete files.
+
+-- | Extract tags from file names.
+tags :: [FilePath] -> [(String, Int)]
+tags = f . group . sort . map (takeWhile (/='-') . tail . dropWhile (/='-'))
+ where f xs = zip (map head xs) (map length xs)
+
+-- | Create an ID for a new file. Specifically a time stamp
+-- based on the current local time with minute precision.
+makeID :: IO String
+makeID = do
+ t <- getCurrentTime
+ tz <- getCurrentTimeZone
+ return $ formatTime undefined ("%Y_%m_%d_%H%M") $ utcToLocalTime tz t
61 nn.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
+import Control.Applicative
+import Data.List hiding (all)
+import System
+import System.FilePath
+import System.Process
+import NNUtil
+import System.Console.CmdArgs
+import System.Directory
+import Prelude hiding (all)
+
+import Text.Regex.TDFA
+
+
+{- TODO:
+- global option to specify NN_DIR.
+-}
+
+data NN = List { all :: Bool, exec :: Maybe String, terms :: [String] }
+ | Cat { iD :: String }
+ | Junk
+ deriving (Show, Data, Typeable)
+
+
+main = do
+ mode <- cmdArgs (modes [listMode &= auto, catMode])
+ dir <- getEnv "NN_HOME"
+ setCurrentDirectory dir
+ case mode of
+ List _ _ _ -> list dir mode
+ Cat _ -> print mode
+ otherwise -> list dir mode
+
+
+listMode = List { exec = def &= help "Pass files as arguments to COMMAND" &= typ "COMMAND"
+ , all = def &= help "Include obsoleted files in search"
+ , terms = def &= args &= typ "SEARCH TERMS"
+ }
+catMode = Cat { iD = def &= args &= typ "FILE ID" }
+
+getFiles dir [] = do
+ processFiles <$> mdlist dir
+
+getFiles dir terms = do
+ processFiles <$> mdfind dir terms
+
+-- List the names of files matching the terms.
+list dir (List _ Nothing terms) = putStr . unlines =<< getFiles dir terms
+
+-- Apply command specified with --exec to files matching the terms.
+list dir (List _ (Just exec) terms) = do
+ files <- getFiles dir terms
+ let cmd:args = words exec
+ code <- rawSystem cmd (args ++ files)
+ case code of
+ ExitSuccess -> return ()
+ otherwise -> print code
+
+
+processFiles = sort . filter (=~ filePattern0) . fmap takeFileName
Please sign in to comment.
Something went wrong with that request. Please try again.