🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.functional
Article #1213

Re: gofer.el under emacs 19?

#1213
From: Denis Howe
Date: Mon, 17 Jan 1994 10:43
231 lines
9209 bytes
In article <1994Jan16.164131.24545@newsserver.rrzn.uni-hannover.de> in
comp.lang.functional nhabkosl@rrzn-nis.uni-hannover.de wrote:

> Has anybody managed to get gofer.el to run under emacs 19?

Here's my current gofer.el which I've hacked quite a bit from Stuart's
original.  My .emacs says:

    (autoload 'gofer-mode "gofer" "Autoload gofer mode" t nil)
    (autoload 'gofer-run "gofer" "Autoload gofer mode" t nil)

    (add-item 'auto-mode-alist '("\\.hs$" . gofer-mode))
    (add-hook 'gofer-mode-hook (function (lambda ()
      (local-set-key [f7] 'gofer-load))))

Bug reports, comments and suggestions welcome.

--------8<---------8<-------- CUT HERE --------8<---------8<--------

;Gofer mode for GNU Emacs v1 25-Jun-1993
;
;Updated and tidied by Denis Howe <dbh@doc.ic.ac.uk> for Emacs 19.
;
;Based on 06-Dec-1991 original by Stuart Clayman <sclayman@uk.ac.ucl.cs>.
;
;In ~/.emacs put
;
;  (autoload 'gofer-mode "gofer" "Go into gofer mode" t)
;  (autoload 'gofer-run "gofer" "Run gofer as inferior process" t)
;  (autoload 'gofer-project "gofer" "Go into a gofer project" t)
;
;  (set-variable 'auto-mode-alist
;       (append '(
;  		("\\.gs$" . gofer-mode)    ;Gofer source
;		("\\.gp$" . gofer-project) ;Gofer project files
;		) auto-mode-alist))
;
;Gofer source files should end in .gs, gofer project files should end
;in .gp.
;
;In a Gofer (project) buffer:
; C-c C-f saves the current file (project) and loads it into Gofer.
; C-c C-a saves the current file and adds it into Gofer.
; C-c C-e locates the source of a Gofer error message.
; C-c C-c interrupts the Gofer process.
;
;If the prefix argument to C-c C-f or C-c C-a is non-nil, the Gofer
;process changes to the current buffer's directory before loading the
;file.
;
;If the variable gofer-command is set then its value will be sent to
;the Gofer process after the file is loaded.  This can be used for a
;top-level expression to evaluate.

(require 'comint)
(require 'shell)			;For directory tracking.

(defvar gofer-mode-hook nil
  "Gofer mode hook run in each Gofer mode buffer and in the Gofer
process buffer.")

(defvar gofer-load-hook nil "Hook run after gofer.el is loaded.")

(defvar gofer-load-mark 0
  "End of last load command in Gofer process buffer.")

(defun gofer-mode ()
  "Major mode for editing Gofer source files.
\\{gofer-mode-map}
Entry to this mode calls the value of `gofer-mode-hook'
if that value is non-nil."
  (interactive)
  (setq major-mode 'gofer-mode)
  (setq mode-name "Gofer")
  (make-variable-buffer-local 'indent-line-function)
  (setq indent-line-function 'indent-relative)
  (auto-fill-mode 0)			;Turn off auto fill.
  (setq gofer-mode-map (make-keymap))
  (use-local-map gofer-mode-map)
  (local-set-key "\C-c\C-f" 'gofer-load)
  (local-set-key "\C-c\C-a" 'gofer-add)
  (local-set-key "\C-c\C-e" 'gofer-error)
  (local-set-key "\C-c\C-c" 'gofer-interrupt)
  (local-set-key "\177"	    'backward-delete-char-untabify)
  (set-syntax-table (copy-syntax-table))
  (modify-syntax-entry ?- ". 12")
  (modify-syntax-entry ?' "w")
  (setq comment-start "-- ")
  (setq comment-start-skip "-- *")
  (run-hooks 'gofer-mode-hook))

(defun gofer-project ()
  "Major mode for Gofer project files"
  (interactive)
  (setq mode-name "Gofer-project")
  (local-set-key "\C-c\C-f" 'gofer-save-project-and-go))

(defun gofer-run ()
  "Run a Gofer process in a buffer called \"*gofer*\".  Return the buffer."
  (interactive)
  (message "Starting Gofer...")
  (let ((buf (make-comint "gofer" "gofer")))
    ;If interactive put cursor in Gofer buffer else select it temporarily.
    (if (interactive-p)
	(switch-to-buffer buf)
      (set-buffer buf)
      (display-buffer buf))		;Ensure visible.
;Done in comint.el    (process-kill-without-query (get-buffer-process buf))
    (make-variable-buffer-local 'shell-cd-regexp)
    (setq shell-cd-regexp ":cd")
    (make-local-variable 'shell-dirtrackp)
    (setq shell-dirtrackp t)
    (setq comint-input-sentinel 'shell-directory-tracker)
					;Allow for multiple stacked up prompts.
    (setq comint-prompt-regexp "^[? ]*? ")
    (run-hooks 'gofer-mode-hook)
    buf))

(defun gofer-go (load-command cd)
  "Save the current buffer and load its file into the Gofer process.  The
first argument LOAD-COMMAND specifies how the file should be loaded:
as a new file (\":load \"), as an additional file (\":add \") or as a
Gofer project file (\":project \").

If the second argument CD is non-nil, change the Gofer process to the
current buffer's directory before loading the file.

If the variable gofer-command is set then its value will be sent to
the Gofer process after the load command.  This can be used for a
top-level expression to evaluate."
  (save-buffer)
  (hack-local-variables)		;In case they've changed.
  (let ((file (buffer-file-name))
	(dir (expand-file-name default-directory))
	(cmd (if (and (boundp 'gofer-command) gofer-command)
		 (if (stringp gofer-command)
		     gofer-command
		   (symbol-name gofer-command))))
	(buf (get-buffer "*gofer*"))
	(win (selected-window))
	proc)
    (if (and buf
	     (setq proc (get-buffer-process buf))
	     (eq (process-status proc) 'run))
	(progn
	  ;Ensure the Gofer window is selected and visible so we can
	  ;watch what happens.
	  (select-window (display-buffer buf)))
      (setq buf (gofer-run))		;Start gofer process.
      (select-window (display-buffer buf))
      (setq proc (get-buffer-process buf))
      (sit-for 1))			;Wait for it to start.
    (if cd (gofer-send proc (concat ":cd " dir)))
    (gofer-send proc load-command file)
    (setq gofer-load-mark (or (marker-position comint-last-input-start) (point-min)))
    (if cmd (gofer-send proc cmd))
    (select-window win)))

(defun gofer-send (proc &rest string)
  "Send process PROC the argument(s) (one or more strings) followed by a
newline and insert them in the current buffer after the last output."
  (let ((s (concat (apply 'concat string) "\n"))
	(pmark (process-mark proc)))
    ;Wait for the next prompt.
    (while (progn ;Go to where the last input (if any) started.
	     (goto-char (or (marker-position comint-last-input-start)
			    (point-min)))
	     (not (re-search-forward comint-prompt-regexp nil t)))
      (or (accept-process-output proc)
	  (message "Waiting for prompt...")(sit-for 0)))
    (message "")(sit-for 0)
    ;Position for this input.
    (goto-char pmark)
    (set-marker comint-last-input-start (point))
    (insert s)				;Doesn't move markers.
    (set-marker comint-last-input-end (point))
    (set-marker pmark (point-max))
    (process-send-string proc s)))

(defun gofer-load (arg)
  "Save a gofer source file and load it."
  (interactive "P")
  (gofer-go ":load " arg))

(defun gofer-add (arg)
  "Save a gofer source file and add it to the file list."
  (interactive "P")
  (gofer-go ":add " arg))

(defun gofer-save-project-and-go (arg)
  "Save a gofer project file and run."
  (interactive "P")
  (gofer-go ":project " arg))

(defun gofer-error ()
  "Find the first error message in the Gofer process buffer since the
last input and then go to the relevant point in the errant file."
  (interactive)
  ;Save selected window.  Can't use save-window-excursion
  ;since we want to scroll windows.
  (let ((win (selected-window))
	gofer-window file line top)
    (set-buffer "*gofer*")
    (select-window (display-buffer (current-buffer)))
    (goto-char gofer-load-mark)
    (if (re-search-forward "\"\\(.*\\)\" (line \\([0-9]*\\)" nil t)
	(setq file (buffer-substring (match-beginning 1) (match-end 1))
	      line (buffer-substring (match-beginning 2) (match-end 2))))
    (recenter 0)			;scroll point to top.
    (if file
	(progn
	  (find-file-other-window file)
	  (goto-line (string-to-int line)))
      (select-window win)
      (message "No errors"))))

(defun gofer-interrupt ()
  "Interrupt the current Gofer process."
  (interactive)
  (set-buffer "*gofer*")
  (comint-interrupt-subjob))

(run-hooks 'gofer-load-hook)

; End of gofer.el

--------8<---------8<-------- CUT HERE --------8<---------8<--------
--
Denis Howe <dbh@doc.ic.ac.uk>
The Free On-Line Dictionary of Computing
Gopher/FTP wombat.doc.ic.ac.uk (146.169.22.42)
Technical Details
Message-ID: <DBH.94Jan17104306@wombat.doc.ic.ac.uk>
Path: arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!howland.reston.ans.net!agate!doc.ic.ac.uk!news!dbh
References: <1994Jan16.164131.24545@newsserver.rrzn.uni-hannover.de>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 107f24,24b85e1ebccda62a
X-Google-Attributes: gid107f24,public
X-Google-Thread: 107729,e1fc6e39d5e8178d,start
X-Google-Attributes: gid107729,public
X-Google-ArrivalTime: 1994-01-17 02:46:10 PST
Path: arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!howland.reston.ans.net!agate!doc.ic.ac.uk!news!dbh
From: dbh@doc.ic.ac.uk (Denis Howe)
Newsgroups: comp.lang.functional,gnu.emacs.sources
Subject: Re: gofer.el under emacs 19?
Date: 17 Jan 1994 10:43:06 GMT
Organization: Computing Department, Imperial College, London, UK
Lines: 231
Message-ID: <DBH.94Jan17104306@wombat.doc.ic.ac.uk>
References: <1994Jan16.164131.24545@newsserver.rrzn.uni-hannover.de>
NNTP-Posting-Host: wombat.doc.ic.ac.uk
In-reply-to: nhabkosl@rrzn-nis.uni-hannover.de's message of Sun, 16 Jan 1994 16:41:31 GMT