home *** CD-ROM | disk | FTP | other *** search
- ;;;; compile.jl -- Running compilation processes
- ;;; Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
-
- ;;; This file is part of Jade.
-
- ;;; Jade 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.
-
- ;;; Jade 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.
-
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with Jade; see the file COPYING. If not, write to
- ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- (provide 'compile)
-
- (setq
- gcc-error-regexp "^(.*):([0-9]+):(.+)"
- gcc-file-expand "\\1"
- gcc-line-expand "\\2"
- gcc-error-expand "\\3")
-
- (defvar compile-error-regexp gcc-error-regexp)
- (defvar compile-file-expand gcc-file-expand)
- (defvar compile-line-expand gcc-line-expand)
- (defvar compile-error-expand gcc-error-expand)
-
- (defvar compile-keymap (make-keylist))
-
- (unless (boundp 'compile-buffer)
- (bind-keys compile-keymap
- "ctrl-c" 'kill-compilation
- "ctrl-z" 'stop-compilation
- "ctrl-f" 'continue-compilation
- "r" '(start-compile-command compile-default-cmd compile-type-str)
- "ctrl-r" 'compile))
-
- (defvar compile-buffer nil)
- (defvar compile-proc nil)
- (defvar compile-argv ["sh" "-c" nil])
- (defvar compile-errors nil "List of (ERROR-POS-MARK . ERROR-DESC-LINE)")
- (defvar compile-error-pos nil)
- (defvar compile-type-str nil)
- (defvar compile-error-parsed-errors-p nil)
- (defvar compile-errors-exist-p nil)
-
- (defvar compile-default-cmd "make"
- "Default command which `(compile)' executes, the value of the last
- command executed by `(compile)'.")
-
- (defvar compile-command nil
- "Buffer-local symbol which contains the command to compile this buffer. If
- nil or unbound use `compile-default-cmd'.")
- (set-buffer-variable 'compile-command)
-
- (defun compile-init ()
- (if compile-buffer
- (clear-buffer compile-buffer)
- (setq compile-buffer (make-buffer "*compilation*"))
- (with-buffer compile-buffer
- (setq ctrl-c-keymap compile-keymap))
- (set-buffer-special compile-buffer t))
- (when compile-buffer
- (add-buffer compile-buffer)
- (set-file-name compile-buffer (path-name (file-name)))
- ;;; (when (equal (file-name compile-buffer) "")
- ;;; (set-file-name compile-buffer "."))
- (setq
- compile-errors nil
- compile-parsed-errors-p nil
- compile-errors-exists-p nil
- compile-error-pos (pos 1 1))
- t))
-
- (defun compile-proc-end ()
- (when compile-proc
- (with-buffer compile-buffer
- (beep)
- (if (process-exit-value compile-proc)
- (format (cons compile-buffer t)
- "\ncompilation exited with value %d\n"
- (process-exit-value compile-proc))
- (format (cons compile-buffer t)
- "\ncompilation exited abnormally: status 0x%x\n"
- (process-exit-status compile-proc)))
- (aset compile-argv 2 nil)
- (setq
- compile-proc nil))))
-
- (defun start-compile-command (command type-str &aux shell-cmd)
- "(start-compile-command SHELL-COMMAND ERROR-TYPE-STR)
- Executes SHELL-COMMAND asynchronously in the directory containing the file
- being edited in the current buffer. Output from the process is sent to the
- `*compilation*' buffer."
- (if compile-proc
- (signal 'error '("Compilation process already running"))
- (save-some-buffers)
- (compile-init)
- (goto-buffer compile-buffer)
- (setq
- compile-proc (make-process (cons compile-buffer t) 'compile-proc-end)
- shell-cmd (concat "cd " (if (equal (file-name) "") "." (file-name))
- " && " command ?\n))
- (write compile-buffer shell-cmd)
- (aset compile-argv 2 shell-cmd)
- (when (fork-process compile-proc "/bin/sh" compile-argv)
- (setq compile-type-str type-str)
- compile-proc)))
-
- (defun kill-compilation ()
- (when compile-proc
- (interrupt-process compile-proc)))
- (defun stop-compilation ()
- (when (process-running-p compile-proc)
- (stop-process compile-proc)))
- (defun continue-compilation ()
- (when (process-stopped-p compile-proc)
- (continue-process compile-proc)))
-
- (defun compile (&optional command)
- (unless command
- (setq command
- (unless compile-command
- (setq compile-default-cmd (prompt "Compile command: " compile-default-cmd)))))
- (when command
- (start-compile-command command "errors" t)))
-
- (defun compile-parse-errors ()
- ;; This can be called while the process is still running, one problem though,
- ;; if the compiled file is modified and then a new error is found the line
- ;; numbers won't coincide like they normally would.
- (unless compile-parsed-errors-p
- (with-buffer compile-buffer
- (let*
- (error-file
- error-line
- last-e-line
- last-e-file
- new-errors)
- (while (setq compile-error-pos (find-next-regexp compile-error-regexp compile-error-pos))
- (setq error-line (read-from-string (regexp-expand-line compile-error-regexp compile-line-expand compile-error-pos)))
- (when (or (not last-e-line) (/= error-line last-e-line))
- (setq
- last-e-line error-line
- error-file (file-concat (file-name) (regexp-expand-line compile-error-regexp compile-file-expand compile-error-pos)))
- (if (equal last-e-file error-file)
- (setq error-file last-e-file)
- (setq last-e-file error-file))
- (setq new-errors
- (cons
- (cons
- (make-mark (pos 1 error-line) error-file)
- (pos-line compile-error-pos))
- new-errors)))
- (setq compile-error-pos find-last-end-pos))
- (when new-errors
- (setq
- compile-errors (nconc compile-errors (nreverse new-errors))
- compile-errors-exist-p t))))
- (unless compile-proc
- (setq compile-parsed-errors-p t)))
- t)
-
- (defun next-error ()
- "(next-error)
- Moves the cursor to the file and line of the next error displayed in the
- `*compilation*' buffer."
- (compile-parse-errors)
- (let*
- ((err (car compile-errors)))
- (setq compile-errors (cdr compile-errors))
- (cond
- ((not err)
- (title
- (concat
- "No "
- (if compile-errors-exist-p "more ")
- compile-type-str
- (if compile-proc " yet")))
- (beep)
- nil)
- (t
- (goto-mark (car err))
- (when (cdr err)
- (title
- (regexp-expand-line
- compile-error-regexp compile-error-expand
- (pos 1 (cdr err)) compile-buffer)))
- t))))
-
- (defun grep (&optional args)
- "(grep [ARGS-STRING])
- Runs the `grep' program with ARGS-STRING (or the result of a prompt) and
- sends its output to the `*compilation*' buffer. The `grep' process may still
- be executing when this function returns."
- (unless args
- (setq args (prompt "Grep with args: ")))
- (when args
- (start-compile-command (concat "grep -n " args " /dev/null /dev/null") "grep-hits" nil)))
-
- (defvar grep-buffer-regexp nil
- "Regular-expression which `grep-buffer' scans for")
-
- (defun grep-buffer (&optional regexp)
- "(grep-buffer [REGEXP])
- Scans the current buffer for all matches of REGEXP (or the contents of
- variable `grep-buffer-regexp'). All hits are displayed in the `*compilation*'
- buffer in a form that `goto-next-error' understands."
- (when regexp
- (setq grep-buffer-regexp regexp))
- (when (and grep-buffer-regexp (compile-init))
- (let*
- ((scanpos (pos 1 1))
- (number 0)
- (stream (cons compile-buffer t)))
- (write stream ?\n)
- (while (setq scanpos (find-next-regexp grep-buffer-regexp scanpos))
- (format stream "%s:%d:%s\n" (file-name) (pos-line scanpos) (copy-area (line-start scanpos) (line-end scanpos)))
- (setq number (+ number 1))
- (setq scanpos (line-end scanpos)))
- (goto-buffer compile-buffer)
- (goto (pos 1 1))
- number)))
-