ack.el
Since I'm unfortunately required to use Windows at work, I've become quite a fan of ack to search for items within my code (or otherwise). It's convenient to execute the ack search from within emacs, and treat it as a compile, so that the results can be located using the compile mode's capacity for viewing each error or event of interest - Voyager figured that stuff out, and I was most grateful.
Interfacing with ack to make it do this from within emacs can be a trifle tedious though, since ack wants to know what to look for (the pattern) and where to look. This can all be provided on a command line, but that's irritating, since directory autocompletion doesn't work. I hacked together the following code (borrowed liberally from Voyager's efforts and the w32-find-dired.el file):
;; ack.el ;; With credit to w32-find-dired.el ;; Copyright (C) 2008 Kim van Wyk and Johan Kohler ;; This file is not currently part of GNU Emacs. ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 2, or (at ;; your option) any later version. ;; This program is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. (require 'compile) (require 'thingatpt) (defvar ack-command "ack" "The command run by the ack function.") (defvar ack-mode-font-lock-keywords '(("^\\(Compilation\\|Ack\\) started.*" (0 '(face nil message nil help-echo nil mouse-face nil) t)))) (defvar ack-use-search-in-buffer-name t "If non-nil, use the search string in the ack buffer's name.") (define-compilation-mode ack-mode "Ack" "Specialization of compilation-mode for use with ack." nil) (defun ack (dir pattern args) "Run ack, with user-specified ARGS, and collect output in a buffer. While ack runs asynchronously, you can use the \\[next-error] command to find the text that ack hits refer to. The command actually run is defined by the ack-command variable." (interactive (list (read-file-name "Run ack in directory: " nil "" t) (read-string "Search for: " (thing-at-point 'symbol)) (read-string "Ack arguments: " "-i" nil "-i" nil) )) ; Get dir into an the right state, incase a file name was used (setq dir (abbreviate-file-name (file-name-as-directory (expand-file-name dir)))) ;; Check that it's really a directory. (or (file-directory-p dir) (error "ack needs a directory: %s" dir)) (let (compile-command (compilation-error-regexp-alist grep-regexp-alist) (compilation-directory default-directory) (ack-full-buffer-name (concat "*ack-" pattern "*"))) ;; (save-some-buffers (not compilation-ask-about-save) nil) ;; lambda defined here since compilation-start expects to call a function to get the buffer name (compilation-start (concat ack-command " " args " " pattern " " dir) 'ack-mode (when ack-use-search-in-buffer-name (function (lambda (ignore) ack-full-buffer-name))) (regexp-quote pattern)))) (provide 'ack-emacs)
Placing this code somewhere in your emacs path should allow you to call the "ack" function, which will prompt for where to search (with a history of previous entries), what to search for (again with a history) and what arguments to give to ack (with a default "-i" for case-insensitivity) and display the output in a compilation buffer.
It's hardly challenging or mind-bending elisp, but it's the first elisp I've ever made work, so I'm kinda proud of it :-)
--group in compile mode
Thanks for the code!
I prefer the output formatting of ack with the --group option (I use mostly vertical window).
But in that format, the lines do not behave as links any longer.
I suppose it is because they are not considered as "errors" by the compile mode?
Any idea how I can get the output in the --group form, but still press enter on a line of the ouput to jump to the original file, at the correct line?
Sorry, I don't have a clue
Sorry, I don't have a clue how to make it do that.
Just as a feature request,
Just as a feature request, it would be nice if this was implemented in a manner similar to find-grep, which does similar things, but allows for easier navigation to those files. Any interest in throwing this on github or something so I can get improvements to it? (like the comment left above this one) :)
It didn't actually occur to
It didn't actually occur to me to make it more widely available - I'll drop it onto github, but I can't promise to make any actual updates to it.
It also lives in my public .emacs repo at http://hg.rooijan.za.net/addons/file, called ack.el. Any changes should reflect there as well.
use with carbon emacs
Thanks for the emacs ack front-end! I found that when using carbon emacs I got some garbage printed on the screen since emacs couldn't interpret the color commands correctly and in order to be able to click on files and be taken to the location I had to turn off the headings. My changes to get ack working on my mac (and possibly for all macs) is the following:
(read-string "Ack arguments: " "-i --noheading --nocolor" nil "-i --noheading --nocolor" nil)
Post new comment