| 1 |
;;; smart-compile.el --- an interface to `compile'
|
| 2 |
|
| 3 |
;; Copyright (C) 1998-2011 by Seiji Zenitani
|
| 4 |
|
| 5 |
;; Author: Seiji Zenitani <zenitani@mac.com>
|
| 6 |
;; $Id$
|
| 7 |
;; Keywords: tools, unix
|
| 8 |
;; Created: 1998-12-27
|
| 9 |
;; Compatibility: Emacs 21 or later
|
| 10 |
;; URL(en): http://homepage.mac.com/zenitani/comp-e.html
|
| 11 |
;; URL(jp): http://homepage.mac.com/zenitani/elisp-j.html#smart-compile
|
| 12 |
|
| 13 |
;; Contributors: Sakito Hisakura
|
| 14 |
|
| 15 |
;; This file is free software; you can redistribute it and/or modify
|
| 16 |
;; it under the terms of the GNU General Public License as published by
|
| 17 |
;; the Free Software Foundation; either version 2, or (at your option)
|
| 18 |
;; any later version.
|
| 19 |
|
| 20 |
;; This file is distributed in the hope that it will be useful,
|
| 21 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 22 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 23 |
;; GNU General Public License for more details.
|
| 24 |
|
| 25 |
;; You should have received a copy of the GNU General Public License
|
| 26 |
;; along with GNU Emacs; see the file COPYING. If not, write to
|
| 27 |
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
| 28 |
;; Boston, MA 02111-1307, USA.
|
| 29 |
|
| 30 |
;;; Commentary:
|
| 31 |
|
| 32 |
;; This package provides `smart-compile' function.
|
| 33 |
;; You can associates a particular file with a particular compile functions,
|
| 34 |
;; by editing `smart-compile-alist'.
|
| 35 |
;;
|
| 36 |
;; To use this package, add these lines to your .emacs file:
|
| 37 |
;; (require 'smart-compile)
|
| 38 |
;;
|
| 39 |
;; Note that it requires emacs 21 or later.
|
| 40 |
|
| 41 |
;;; Code:
|
| 42 |
|
| 43 |
(defgroup smart-compile nil
|
| 44 |
"An interface to `compile'."
|
| 45 |
:group 'processes
|
| 46 |
:prefix "smarct-compile")
|
| 47 |
|
| 48 |
(defcustom smart-compile-alist '(
|
| 49 |
(emacs-lisp-mode . (emacs-lisp-byte-compile))
|
| 50 |
(html-mode . (browse-url-of-buffer))
|
| 51 |
(nxhtml-mode . (browse-url-of-buffer))
|
| 52 |
(html-helper-mode . (browse-url-of-buffer))
|
| 53 |
(octave-mode . (run-octave))
|
| 54 |
("\\.c\\'" . "gcc -O2 %f -lm -o %n")
|
| 55 |
;; ("\\.c\\'" . "gcc -O2 %f -lm -o %n && ./%n")
|
| 56 |
("\\.[Cc]+[Pp]*\\'" . "g++ -O2 %f -lm -o %n")
|
| 57 |
("\\.m\\'" . "gcc -O2 %f -lobjc -lpthread -o %n")
|
| 58 |
("\\.java\\'" . "javac %f")
|
| 59 |
("\\.php\\'" . "php -l %f")
|
| 60 |
("\\.f90\\'" . "gfortran %f -o %n")
|
| 61 |
("\\.[Ff]\\'" . "gfortran %f -o %n")
|
| 62 |
("\\.cron\\(tab\\)?\\'" . "crontab %f")
|
| 63 |
("\\.tex\\'" . (tex-file))
|
| 64 |
("\\.texi\\'" . "makeinfo %f")
|
| 65 |
("\\.mp\\'" . "mptopdf %f")
|
| 66 |
("\\.pl\\'" . "perl -cw %f")
|
| 67 |
("\\.rb\\'" . "ruby -cw %f")
|
| 68 |
) "List of compile commands. In argument,
|
| 69 |
some keywords beginning with '%' will be replaced by:
|
| 70 |
|
| 71 |
%F absolute pathname ( /usr/local/bin/netscape.bin )
|
| 72 |
%f file name without directory ( netscape.bin )
|
| 73 |
%n file name without extension ( netscape )
|
| 74 |
%e extension of file name ( bin )
|
| 75 |
|
| 76 |
"
|
| 77 |
:type '(repeat
|
| 78 |
(cons
|
| 79 |
(choice
|
| 80 |
(regexp :tag "Filename pattern")
|
| 81 |
(function :tag "Major-mode"))
|
| 82 |
(choice
|
| 83 |
(string :tag "Compilation command")
|
| 84 |
(sexp :tag "Lisp expression"))))
|
| 85 |
:group 'smart-compile)
|
| 86 |
(put 'smart-compile-alist 'risky-local-variable t)
|
| 87 |
|
| 88 |
(defconst smart-compile-replace-alist '(
|
| 89 |
("%F" . (buffer-file-name))
|
| 90 |
("%f" . (file-name-nondirectory (buffer-file-name)))
|
| 91 |
("%n" . (file-name-sans-extension
|
| 92 |
(file-name-nondirectory (buffer-file-name))))
|
| 93 |
("%e" . (or (file-name-extension (buffer-file-name)) ""))
|
| 94 |
))
|
| 95 |
(put 'smart-compile-replace-alist 'risky-local-variable t)
|
| 96 |
|
| 97 |
(defvar smart-compile-check-makefile t)
|
| 98 |
(make-variable-buffer-local 'smart-compile-check-makefile)
|
| 99 |
|
| 100 |
(defcustom smart-compile-make-program "make "
|
| 101 |
"The command by which to invoke the make program."
|
| 102 |
:type 'string
|
| 103 |
:group 'smart-compile)
|
| 104 |
|
| 105 |
|
| 106 |
;;;###autoload
|
| 107 |
(defun smart-compile (&optional arg)
|
| 108 |
"An interface to `compile'.
|
| 109 |
It calls `compile' or other compile function,
|
| 110 |
which is defined in `smart-compile-alist'."
|
| 111 |
(interactive "p")
|
| 112 |
(let ((name (buffer-file-name))
|
| 113 |
(not-yet t))
|
| 114 |
|
| 115 |
(if (not name)(error "cannot get filename."))
|
| 116 |
;; (message (number-to-string arg))
|
| 117 |
|
| 118 |
(cond
|
| 119 |
|
| 120 |
;; local command
|
| 121 |
;; The prefix 4 (C-u M-x smart-compile) skips this section
|
| 122 |
;; in order to re-generate the compile-command
|
| 123 |
((and (not (= arg 4)) ; C-u M-x smart-compile
|
| 124 |
(local-variable-p 'compile-command)
|
| 125 |
compile-command)
|
| 126 |
(call-interactively 'compile)
|
| 127 |
(setq not-yet nil)
|
| 128 |
)
|
| 129 |
|
| 130 |
;; make?
|
| 131 |
((and smart-compile-check-makefile
|
| 132 |
(or (file-readable-p "Makefile")
|
| 133 |
(file-readable-p "makefile")))
|
| 134 |
(if (y-or-n-p "Makefile is found. Try 'make'? ")
|
| 135 |
(progn
|
| 136 |
(set (make-local-variable 'compile-command) "make ")
|
| 137 |
(call-interactively 'compile)
|
| 138 |
(setq not-yet nil)
|
| 139 |
)
|
| 140 |
(setq smart-compile-check-makefile nil)))
|
| 141 |
|
| 142 |
) ;; end of (cond ...)
|
| 143 |
|
| 144 |
;; compile
|
| 145 |
(let( (alist smart-compile-alist)
|
| 146 |
(case-fold-search nil)
|
| 147 |
(function nil) )
|
| 148 |
(while (and alist not-yet)
|
| 149 |
(if (or
|
| 150 |
(and (symbolp (caar alist))
|
| 151 |
(eq (caar alist) major-mode))
|
| 152 |
(and (stringp (caar alist))
|
| 153 |
(string-match (caar alist) name))
|
| 154 |
)
|
| 155 |
(progn
|
| 156 |
(setq function (cdar alist))
|
| 157 |
(if (stringp function)
|
| 158 |
(progn
|
| 159 |
(set (make-local-variable 'compile-command)
|
| 160 |
(smart-compile-string function))
|
| 161 |
(call-interactively 'compile)
|
| 162 |
)
|
| 163 |
(if (listp function)
|
| 164 |
(eval function)
|
| 165 |
))
|
| 166 |
(setq alist nil)
|
| 167 |
(setq not-yet nil)
|
| 168 |
)
|
| 169 |
(setq alist (cdr alist)) )
|
| 170 |
))
|
| 171 |
|
| 172 |
;; If compile-command is not defined and the contents begins with "#!",
|
| 173 |
;; set compile-command to filename.
|
| 174 |
(if (and not-yet
|
| 175 |
(not (memq system-type '(windows-nt ms-dos)))
|
| 176 |
(not (string-match "/\\.[^/]+$" name))
|
| 177 |
(not
|
| 178 |
(and (local-variable-p 'compile-command)
|
| 179 |
compile-command))
|
| 180 |
)
|
| 181 |
(save-restriction
|
| 182 |
(widen)
|
| 183 |
(if (equal "#!" (buffer-substring 1 (min 3 (point-max))))
|
| 184 |
(set (make-local-variable 'compile-command) name)
|
| 185 |
))
|
| 186 |
)
|
| 187 |
|
| 188 |
;; compile
|
| 189 |
(if not-yet (call-interactively 'compile) )
|
| 190 |
|
| 191 |
))
|
| 192 |
|
| 193 |
(defun smart-compile-string (arg)
|
| 194 |
"Document forthcoming..."
|
| 195 |
(if (and (boundp 'buffer-file-name)
|
| 196 |
(stringp buffer-file-name))
|
| 197 |
(let ((rlist smart-compile-replace-alist)
|
| 198 |
(case-fold-search nil))
|
| 199 |
(while rlist
|
| 200 |
(while (string-match (caar rlist) arg)
|
| 201 |
(setq arg
|
| 202 |
(replace-match
|
| 203 |
(eval (cdar rlist)) t nil arg)))
|
| 204 |
(setq rlist (cdr rlist))
|
| 205 |
)
|
| 206 |
))
|
| 207 |
arg)
|
| 208 |
|
| 209 |
(provide 'smart-compile)
|
| 210 |
|
| 211 |
;;; smart-compile.el ends here
|