Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
221 lines (157 sloc) 7.29 KB

What It Is

simp is a dead simple project definition system that allows you to specify project properties and use them to do things like quick finding and grepping of project files.

Overview of How it Works

When you attempt to take a simp project action in a buffer, simp looks for a simp-buffer-project variable, and if it doesn’t find one it will set one by looking at the ancestor directories of the file or directory associated with the buffer to determine which project to use. simp makes this determination by verifying that some ancestor directory of the buffer’s associated file or directory has all of the paths specified in a project definitions ‘:has’ property. Once we know which project we are working with, it is easy to scope actions to the project directory and files.

Installing It

First, make sure you have [melpa in your package archives list](http://melpa.milkbox.net/#/getting-started)

M-x package-install simp

then, somewhere in your init

(require 'simp)

Defining A Project

A very simple generic project definition to work with git projects:

(simp-project-define
 '(:has (.git)
   :ignore (.git)))

A buffer will match as a member of the above simp project if it’s associated file has an ancestor directory that contains a .git file or directory, and that when dealing with files in this project, the .git file or directory should be excluded because you don’t care about it.

You could likewise work with generic mercurial project like:

(simp-project-define
 '(:has (.hg)
   :ignore (.hg)))

Globs can also be used in project definitions. A definition for a Rubygem might look like this:

(simp-project-define
  '(:type ruby-gem
    :has (*.gemspec)
    :ignore (.git)))

A more complex project definition might look like this:

(simp-project-define
 '(:type rails
   :has (config.ru app/views app/models app/controllers)
   :ignore (tmp coverage log vendor .git public/system public/assets)))

For a buffer to match as a member of this project, it must be a descendant of some directory that contains each path in the :has list.

As above, the list of paths in the :ignore property will be excluded when dealing with project files

In this example, ‘:type’ is not actually going to be used by built-in simp functions, but rather would be used to extend projects that match the ‘:has’ criteria. Like all properties, a buffer’s project’s ‘:type’ can be accessed using (simp-project-get :type)

I use the following to work in my .emacs.d directory:

(simp-project-define
 '(:type emacs
   :has (init.el)))

Project definitions are checked in last-in-first-out order. That is, given the following:

(simp-project-define
  '(:has (.git)
    :ignore (.git)))

:

(simp-project-define
  '(:type ruby-gem
    :has (*.gemspec)
    :ignore (.git)))

If the project has both a `whatever.gemspec` file and a `.git` directory, the `ruby-gem` entry will match first.

Bindings

;; I bind the handy stuff like so:
(global-set-key (kbd "C-c f") 'simp-project-find-file)
(global-set-key (kbd "C-c d") 'simp-project-root-dired)
(global-set-key (kbd "C-c s") 'simp-project-rgrep)
(global-set-key (kbd "C-c S") 'simp-project-rgrep-dwim)
(global-set-key (kbd "C-c b") 'simp-project-ibuffer-files-only)
(global-set-key (kbd "C-c B") 'simp-project-ibuffer)
(global-set-key (kbd "C-c C-f") 'simp-project-with-bookmark-find-file)
(global-set-key (kbd "C-c C-s") 'simp-project-with-bookmark-rgrep)
(global-set-key (kbd "C-c C-b") 'simp-project-with-bookmark-ibuffer)

Features

Finding Files

simp-project-find-file

Helps you find files in your project. It uses your system find command to quickly identify which files you are interested in selecting from.

It uses the :ignore property of simp-project-define to exclude directories from the search.

Files are presented in shorted path to longest for selection.

Recommendations

  • Customize the simp-completing-read-command variable. I use ido with ido-enable-flex-matching. This will allow you to do find-as-you-type fuzzy file finding. It works out very nicely. If you are encountering performance problems with this approach, please refer to: https://github.com/re5et/simp/issues/4
  • Ignore directories you don’t pick files from. Lots of projects create cache directories and other junk you don’t care about. The more you ignore, the faster it goes.
  • Bind this to something handy. I find that I use it very often. I bind like:
    (global-set-key (kbd "C-c f") 'simp-project-find-file)
        

rgrep Enhancements

simp-project-rgrep

Helps you search your project quickly. The bulk of the work that this does is to customize the find command that rgrep already uses to exclude more things, specifically the things you specify with the :ignore property of simp-project-define

Recommendations

  • Ignore stuff you don’t want to text search. For me this includes log files, caches, directories that store binary files (assets/images), revision control directories, etc. I usually find that if I ignore these types of things, my searches are about 10 times faster.
  • I also use this quite a bit, especially in an unfamiliar codebase.
    (global-set-key (kbd "C-c s") 'simp-project-rgrep)
        

simp-project-rgrep-dwim (previously simp-project-rgrep-thing-at-point)

A single command to immediately search your whole project, for any type of file (still taking the :ignore property of simp-project-define into consideration) for your active region, or for the symbol at point. It takes care of the arguments you have to step through using rgrep or simp-project-rgrep.

Recommendations

  • I might actually use this one even more than simp-project-rgrep, this is how I bind it:
    (global-set-key (kbd "C-c S") 'simp-project-rgrep-dwim)
        

Ibuffer

simp-project-ibuffer

Use Ibuffer to show buffers associated with the current simp project

simp-project-ibuffer-files-only

Use Ibuffer to show buffers associated with the current simp project, but only show files. This makes it easy to save all modified project files, etc.

ibuffer-filter-by-simp-project-buffers

Filter an existing Ibuffer buffer by buffers associated with the current simp project

ibuffer-filter-by-simp-project-file-buffers

Filter an existing Ibuffer buffer by buffers associated with the current simp project, but only show files

with bookmarks

You can use with bookmark simp commands to take a project action like rgrepping or finding a file when you are not in a buffer that is not associated with the project you want to work with.

When you run one of the following it will first prompt you to select a bookmark and then scope the simp command to the location of the bookmark.

I would recommend that you bookmark each project you define so you can take advantage of this. For information on working with Emacs’ bookmarks, see http://emacswiki.org/emacs/BookMarks

simp-project-with-bookmark-find-file

simp-project-find-file scoped to bookmark selected

simp-project-with-bookmark-rgrep

simp-project-rgrep scoped to bookmark selected

simp-project-with-bookmark-ibuffer

simp-project-ibuffer scoped to bookmark selected

Have any good ideas?

Feel free to fork it and send pull requests. Also, if you have a good idea but don’t know how to implement it, I will likely be more than happy to write it, so let me know.