Skip to content

trast/watch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 

Repository files navigation

watch

(The name will be changed eventually, but it's not the biggest problem right now :-)

Description

watch attempts to keep track of your most recently used directories. To this end it uses the inotify API (thus Linux only) to monitor your filesystem for pretty much any event, and whenever you do anything to a file/directory, it puts the relevant directory into a short history list.

It is inspired by Fresh which was advertised on One Thing Well. However since that is OS X only, I could not even run it to have a look.

Thinking about the idea, I noticed that I frequently want to open a shell to play with files I have open in some other program (e.g., after opening a file in Emacs I frequently want to have a shell to use git in the same directory). Of course, opening a shell does not require knowing the file path, just the directory, hence this tool.

Usage

  • make
  • Configure an ignore list (a list of fnmatch() patterns) in ~/.watch-ignore
  • ./watch
  • Do something with its output :-)

The "output" is in ~/.watchsock. Whenever you connect to that, it will send you the most-recently-used list (and close the connection immediately). So you can do things like

# see the list; note -d is required with netcat
nc -dU ~/.watchsock

# put this in your ~/.bashrc to have 1..5 aliased to 'cd $dir'
_recent=$(nc -dU ~/.watchsock)
if [ $? = 0 -a -n "$_recent" ]; then
echo "Recent directories:"
echo "$_recent" | nl
eval "$(echo "$_recent" | perl -ne 'chomp;print "alias $.=\"cd $_\"\n"')"
fi

Or for a fancier usage, I have the following in my xmonad.hs, with a key bound to recentDirPrompt myXPConfig. Pressing the key pops up a choice of recently-used dirs, and it will start a konsole in the one I pick:

import XMonad.Util.Run
import XMonad.Prompt
import XMonad.Prompt.Shell (Shell)

getRecentDirs :: IO [String]
getRecentDirs = fmap lines $ runProcessWithInput "nc" ["-dU", "/home/thomas/.watchsock"] ""

data Dirs = Dirs

instance XPrompt Dirs where
    showXPrompt Dirs      = "Dir: "

recentDirPrompt :: XPConfig -> X ()
recentDirPrompt c = do
    cmds <- io getRecentDirs
    mkXPrompt Dirs c (mkComplFunFromList' cmds) spawnKonsole

spawnKonsole :: String -> X ()
spawnKonsole dir = spawn $ "konsole --workdir " ++ dir

I'm sure you have more great ideas.

TODO

  • Give more interesting example usages
  • Do something about typical patterns that clog up the access history:
    • shell completion tends to scan a, a/b, a/b/c, etc.
    • running find etc. in a directory runs readdir() over the tree
    • running git in a directory frequently lstat()s files all over the repo The problem is that these are opposites: in one case you want only the most recent/deepest path to remain, in the other you want the parent dir which was probably accessed in the beginning.
  • Running something like rsync across the whole tree should probably be ignored, but this is even harder than the last point.
  • git (and perhaps hg etc.) handling should be improved:
    • add built-in ignore rules for .git/* etc.
    • when accessing X/.git/Y, enter X into the history etc.
  • Optionally track files instead of dirs?

About

Tracks recently-used dirs with inotify and makes them available over a socket

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages