I have mostly converted entirely to using Emacs as my primary text/code editor, but one of the few things I always found a bit lacking was Emacs' ability to manage code projects (or at least, my knowledge of whatever ability Emacs has). Though Emacs is great with tags (and if you are using Slime, finding function definitons and usages is fairly easy), I would find myself constantly going back to Textmate to do things like see a listing of all my files or search for certain bits of code in my project.
I finally decided this must stop.
I started with trying to make it easier to find files in Emacs. This is not directly related to project management in Emacs, but it seemed like something that could be tied in (and plus, I've wanted to do this for a while). I toyed around with a few things (icicles and ido - Divia settled on icicles), but finally decided on anything. Anything is, as many others have mentioned, like Quicksilver for Emacs. Essentially, it lets you operate by first picking an "object" (where an object can pretty much be anything - some examples are files, buffers, or Emacs commands) and then commit and action on that object (like open in new frame for a file). Bill Clementson has a great writeup of how anything works here.
Installing anything isn't too difficult (if only I could mean that sentence literally for Lisp). Configuring it, however, can take some time - not because it is hard, but because there are so many things you can do with it. There are a variety of "sources" that anything uses which describe different actions/objects you can do when you invoke anything. These sources can be set up in your .emacs file.
So, at first, my .emacs file looked as follows:
;; anything setup
(require 'anything-config)
(global-set-key "\C-u" 'anything)
(global-set-key "\C-c\C-u" 'universal-argument)
(setq anything-sources '(anything-c-source-buffers+
anything-c-source-locate
anything-c-source-recentf
anything-c-source-org-headline
anything-c-source-buffer-not-found))
As you can see above, I set control-U to invoke anything easily. This worked great - I could now type in the first part of any file I wanted, and it would search for it very fast anywhere in my directory (the anything-c-source-locate source does this). The problem now was that I was getting too many results for a given file name candidate. What I realized I do about 80% of the time is look for files in one of two project directories. So, I added two custom sources in anything-config.el:
(defvar anything-contentrees-c-source-file-search
'((name . "Contentrees Search")
(candidates . (lambda ()
(let ((args
(format "'%s' \\( -path \\*/.svn \\) -prune
-o -iregex '.*%s.*' -print"
(get-source-directory "contentrees")
anything-pattern)))
(start-process-shell-command "file-search-process" nil
"find" args))))
(type . file)
(requires-pattern . 4)
(delayed))
"Source for searching matching files in contentrees recursively.")
(defvar anything-weblocks-saikat-c-source-file-search
'((name . "Weblocks-saikat Search")
(candidates . (lambda ()
(let ((args
(format "'%s' \\( -path \\*/.svn \\) -prune
-o -iregex '.*%s.*' -print"
(get-source-directory "weblocks-saikat")
anything-pattern)))
(start-process-shell-command "file-search-process" nil
"find" args))))
(type . file)
(requires-pattern . 4)
(delayed))
"Source for searching matching files in weblocks-saikat recursively.")
Then, in my .emacs, I changed my anything setup to:
;; anything setup
(require 'anything-config)
(global-set-key "\C-u" 'anything)
(setq anything-sources '(anything-c-source-buffers+
anything-weblocks-saikat-c-source-file-search
anything-contentrees-c-source-file-search
anything-c-source-locate
anything-c-source-recentf
anything-c-source-org-headline
anything-c-source-buffer-not-found))
Now, when I invoke anything and start typing in a word, I first get a list of possible buffers with that name followed by files in my two project directories, followed by a locate on my entire home directory, which is pretty much exactly what I wanted (and I got the added benefit of anything actions on these files, making it easier to do things like open the file in a new frame when I want). Note that I had to remap the command to make prefix arguments to C-c C-u.
One BIG caveat to using anything: I was using anything in Aquamacs at first, but it would constantly move my current window to the top right corner of my screen and resize it. After some research, it seemed like Aquamacs just doesn't really work with anything, so I had to switch to Carbon Emacs. Carbon Emacs is fine, although it handles frames and buffers the "true Emacs" way (whereas Aquamacs attaches buffers to frames), and this has taken some getting used to.
Next, I want to get fuzzy matching working with anything, start using proel, and get Mercurial working from within Emacs.