[comp.lang.modula2] EMACS Binding for Modula-2

reid@CTC.CONTEL.COM (Tom Reid) (07/07/89)

Does anyone have a set of macros for a syntax directed editor (or at least a
set of skeleton templates) for Modula-2 and Emacs that they would like to
share.

Thanks.


Thomas F. Reid
Project Manager - Software Engineering Environments
 -----------------------------------------------------------------------
| Contel Technology Center           C C C C   T T T T T     C C C C    |
| 15000 Conference Center Blvd.    C      C       T        C      C     |
| P.O. Box 10814                  C              T        C             |
| Chantilly, Va.  22021-3038     C              T        C              |
| (703)359-7944                 C C C C        T        C C C C         |
| Net: reid@ctc.contel.com                                              |
 -----------------------------------------------------------------------

doug@bear.cis.ohio-state.edu (Doug Kerr) (07/11/89)

In article <8907062021.AA13058@thinman.ctc.contel.com> Modula2 List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes:
>Does anyone have a set of macros for a syntax directed editor (or at least a
>set of skeleton templates) for Modula-2 and Emacs that they would like to
>share.

GNU Emacs contains a Modula-2 editing support package.  I don't
understand the GNU "copyleft" very well so I'm not sure I can mail you
a copy.  The header of the file is shown below.

	; Modula-2 editing support package
	; Author Mick Jordan
	; amended Peter Robinson
	; ported to GNU Michael Schmidt
	;;;From: "Michael Schmidt" <michael@pbinfo.UUCP>
	;;;Modified by Tom Perrine <Perrin@LOGICON.ARPA> (TEP)

-=-
 Douglas S. Kerr, Department of Computer and Information Science
 The Ohio State University; 2036 Neil Ave. Columbus OH USA 43210-1277
 doug@cis.ohio-state.edu                    614/292-1519
 ...!{pyramid,killer}!osu-cis!cis.ohio-state.edu!doug

samlb@magellan.arc.nasa.gov (Samuel B. Bassett) (07/12/89)

	In plain English, what the FSF "Copylefts" says is that if you
give anyone any of the GNU-thingies, you must give them (or at least
offer them) the sources, too.  If the GNU-thingie in question _is_
source, you're doing it just right.


Sam'l Bassett, Sterling Software @ NASA Ames Research Center, 
Moffett Field CA 94035 Work: (415) 694-4792;  Home: (415) 454-7282
samlb%well@lll-crg.ARPA                 samlb@pioneer.arc.nasa.gov 
<Standard Disclaimer> := 'Sterling doesn't _have_ opinions -- much less NASA!'

maner@ANDY.BGSU.EDU (Walter Maner) (07/12/89)

reid@CTC.CONTEL.COM (Tom Reid):
> Does anyone have a set of macros for a syntax directed editor (or at least a
> set of skeleton templates) for Modula-2 and Emacs that they would like to
> share.
>

I haven't actually *tried* these, but ...
WALT


CSNet    maner@andy.bgsu.edu           | 419/372-8719
InterNet maner@andy.bgsu.edu 129.1.1.2 | BGSU Comp Sci Dept
UUCP     ... !osu-cis!bgsuvax!maner    | Bowling Green, OH 43403
BITNet   MANER@BGSUOPIE

----------------------------------------------------------------------------

m2.init
-------
(autoload 'mod2-mode "mod2" "Major mode for modula 2 source code." t)

m2.help
-------

Modula-2 Mode:
This is a mode intended to support program development in Modula-2.
All control constructs of Modula-2 can be reached by typing
Control-C followed by the first character of the construct.

C-x             Prefix Command
C-c             Prefix Command
RET             m2-newline
TAB             m2-tab

C-c C-c         m2-compile
C-c C-l         m2-link
C-c C-t         m2-toggle
C-c C-v         m2-visit
C-c C-z         suspend-emacs
C-c }           m2-end-comment
C-c {           m2-begin-comment
C-c y           m2-import
C-c x           m2-export
C-c w           m2-while
C-c v           m2-var
C-c u           m2-until
C-c t           m2-type
C-c s           m2-stdio
C-c r           m2-record
C-c C-w         m2-with
C-c p           m2-procedure
C-c o           m2-or
C-c l           m2-loop
C-c m           m2-module
C-c i           m2-if
C-c h           m2-header
C-c f           m2-for
C-c e           m2-else
C-c d           m2-definition
C-c c           m2-case
C-c b           m2-begin

C-x `           next-error

  Control-i (TAB) tab       Control-m (RETURN) newline
  Control-c b begin         Control-c c case
  Control-c d definition    Control-c e else
  Control-c f for           Control-c h header
  Control-c i if            Control-c m module
  Control-c l loop          Control-c o or
  Control-c p procedure     Control-c Control-w with
  Control-c r record        Control-c s stdio
  Control-c t type          Control-c u until
  Control-c v var           Control-c w while
  Control-c x export        Control-c y import
  Control-c { begin-comment Control-c } end-comment
  Control-c Control-z suspend-emacs     Control-c Control-t toggle
  Control-c Control-c compile           Control-x ` next-error
  Control-c Control-l link

   m2-indent controls the number of spaces for each indentation.


m2.el
-----


; Modula-2 editing support package
; Author Mick Jordan
; amended Peter Robinson
; ported to GNU Michael Schmidt
;;;From: "Michael Schmidt" <michael@pbinfo.UUCP>
;;;Modified by Tom Perrine <Perrin@LOGICON.ARPA> (TEP)


;;; Added by TEP
(defvar m2-mode-syntax-table nil
  "Syntax table in use in Modula-2-mode buffers.")

;;; Added by TEP
(defvar m2-mode-map (make-sparse-keymap)
  "Keymap used in Modula-2 mode.")

(define-key m2-mode-map "\^i" 'm2-tab)
(define-key m2-mode-map "\^m" 'm2-newline)
(define-key m2-mode-map "\^cb" 'm2-begin)
(define-key m2-mode-map "\^cc" 'm2-case)
(define-key m2-mode-map "\^cd" 'm2-definition)
(define-key m2-mode-map "\^ce" 'm2-else)
(define-key m2-mode-map "\^cf" 'm2-for)
(define-key m2-mode-map "\^ch" 'm2-header)
(define-key m2-mode-map "\^ci" 'm2-if)
(define-key m2-mode-map "\^cm" 'm2-module)
(define-key m2-mode-map "\^cl" 'm2-loop)
(define-key m2-mode-map "\^co" 'm2-or)
(define-key m2-mode-map "\^cp" 'm2-procedure)
(define-key m2-mode-map "\^c\^w" 'm2-with)
(define-key m2-mode-map "\^cr" 'm2-record)
(define-key m2-mode-map "\^cs" 'm2-stdio)
(define-key m2-mode-map "\^ct" 'm2-type)
(define-key m2-mode-map "\^cu" 'm2-until)
(define-key m2-mode-map "\^cv" 'm2-var)
(define-key m2-mode-map "\^cw" 'm2-while)
(define-key m2-mode-map "\^cx" 'm2-export)
(define-key m2-mode-map "\^cy" 'm2-import)
(define-key m2-mode-map "\^c{" 'm2-begin-comment)
(define-key m2-mode-map "\^c}" 'm2-end-comment)
(define-key m2-mode-map "\^c\^z" 'suspend-emacs)
(define-key m2-mode-map "\^c\^v" 'm2-visit)
(define-key m2-mode-map "\^c\^t" 'm2-toggle)
(define-key m2-mode-map "\^c\^l" 'm2-link)
(define-key m2-mode-map "\^c\^c" 'm2-compile)
(define-key m2-mode-map "\^x`" 'next-error) ;;; ;ike c-mode (TEP)

(defvar m2-indent 5 "*This variable gives the indentation in Modula-2-Mode")

(defun mod2-mode ()
"This is a mode intended to support program development in Modula-2.
All control constructs of Modula-2 can be reached by typing
Control-C followed by the first character of the construct.
\\{m2-mode-map}
  Control-i (TAB) tab       Control-m (RETURN) newline
  Control-c b begin         Control-c c case
  Control-c d definition    Control-c e else
  Control-c f for           Control-c h header
  Control-c i if            Control-c m module
  Control-c l loop          Control-c o or
  Control-c p procedure     Control-c Control-w with
  Control-c r record        Control-c s stdio
  Control-c t type          Control-c u until
  Control-c v var           Control-c w while
  Control-c x export        Control-c y import
  Control-c { begin-comment Control-c } end-comment
  Control-c Control-z suspend-emacs     Control-c Control-t toggle
  Control-c Control-c compile           Control-x ` next-error
  Control-c Control-l link

   m2-indent controls the number of spaces for each indentation."
  (interactive)
  (kill-all-local-variables)
  (use-local-map m2-mode-map)
  (setq major-mode 'mod2-mode)
  (setq mode-name "Modula-2")
  (make-local-variable 'comment-column)
  (setq comment-column 41)
  (make-local-variable 'end-comment-column)
  (setq end-comment-column 75)
  (if (not m2-mode-syntax-table)
      (let ((i 0))
        (setq m2-mode-syntax-table (make-syntax-table))
        (set-syntax-table m2-mode-syntax-table)
        (modify-syntax-entry ?\\ "\\")
        (modify-syntax-entry ?( ". 1")
        (modify-syntax-entry ?) ". 4")
        (modify-syntax-entry ?* ". 23")
        (modify-syntax-entry ?+ ".")
        (modify-syntax-entry ?- ".")
        (modify-syntax-entry ?= ".")
        (modify-syntax-entry ?% ".")
        (modify-syntax-entry ?< ".")
        (modify-syntax-entry ?> ".")
        (modify-syntax-entry ?\' "\""))
    (set-syntax-table m2-mode-syntax-table))
  (make-local-variable 'paragraph-start)
  (setq paragraph-start (concat "^$\\|" page-delimiter))
  (make-local-variable 'paragraph-separate)
  (setq paragraph-separate paragraph-start)
;;;  (make-local-variable 'indent-line-function)
;;;  (setq indent-line-function 'c-indent-line)
  (make-local-variable 'require-final-newline)
  (setq require-final-newline t)
  (make-local-variable 'comment-start)
  (setq comment-start "(* ")
  (make-local-variable 'comment-end)
  (setq comment-end " *)")
  (make-local-variable 'comment-column)
  (setq comment-column 41)
  (make-local-variable 'comment-start-skip)
  (setq comment-start-skip "/\\*+ *")
  (make-local-variable 'comment-indent-hook)
  (setq comment-indent-hook 'c-comment-indent)
  (make-local-variable 'parse-sexp-ignore-comments)
  (setq parse-sexp-ignore-comments t)
  (run-hooks 'm2-mode-hook))

(defun m2-newline ()
  "Insert newline and indent for next line."
  (interactive)
  (setq cc (current-indentation))
  (newline)
  (indent-to cc)
  )

(defun m2-tab ()
  "Indent to next tab stop."
  (interactive)
  (indent-to (* (1+ (/ (current-indentation) m2-indent)) m2-indent))
  )

(defun m2-begin ()
  "Insert a BEGIN keyword and indent for the next line."
  (interactive)
  (insert-string "BEGIN")
  (m2-newline)
  (m2-tab)
  )

(defun m2-case ()
  "Build skeleton CASE statment, prompting for the <expression>."
  (interactive)
  (insert-string "CASE ")
  (insert-string (read-string ": "))
  (insert-string " OF")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* case *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-definition ()
  "Build skeleton DEFINITION MODULE, prompting for the <module name>."
  (interactive)
  (insert-string "DEFINITION MODULE ")
  (setq name (read-string "Name: "))
  (insert-string name)
  (insert-string ";\n\n\n\nEND ")
  (insert-string name)
  (insert-string ".\n")
  (previous-line 3)
  )

(defun m2-else ()
  "Insert ELSE keyword and indent for next line."
  (interactive)
  (m2-newline)
  (backward-delete-char-untabify m2-indent ())
  (insert-string "ELSE")
  (m2-newline)
  (m2-tab)
  )

(defun m2-for ()
  "Build skeleton FOR loop statment, prompting for the loop parameters."
  (interactive)
  (insert-string "FOR ")
  (insert-string (read-string ": "))
  (insert-string " TO ")
  (insert-string (read-string ": "))
  (setq by (read-string ": "))
  (if (not (string-equal by ""))
      (concat (insert-string " BY ")
              (insert-string by))
      )
  (insert-string " DO")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* for *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-header ()
  "Insert a comment block containing the module title, author, etc."
  (interactive)
  (insert-string "(*\n    Title: \t")
  (insert-string (read-string "Title: "))
  (insert-string "\n    Created:\t")
  (insert-string (current-time-string))
  (insert-string "\n    Author: \t")
  (insert-string (user-full-name))
  (insert-string (concat "\n\t\t<" (user-login-name) "@" (system-name) ">\n"))
  (insert-string "*)\n\n")
  )

(defun m2-if ()
  "Insert skeleton IF statment, prompting for <boolean-expression>."
  (interactive)
  (insert-string "IF ")
  (insert-string (read-string "<boolean-expression>: "))
  (insert-string " THEN")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* if *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-loop ()
  "Build skeleton LOOP (with END)."
  (interactive)
  (insert-string "LOOP")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* loop *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-module ()
  "Build skeleton IMPLEMENTATION MODULE, prompting for <module-name>."
  (interactive)
  (insert-string "IMPLEMENTATION MODULE ")
  (setq name (read-string "Name: "))
  (insert-string name)
  (insert-string ";\n\n\n\nEND ")
  (insert-string name)
  (insert-string ".\n")
  (previous-line 3)
  )

(defun m2-or ()
  (interactive)
  (m2-newline)
  (backward-delete-char-untabify m2-indent)
  (insert-string "|")
  (m2-newline)
  (m2-tab)
  )

(defun m2-procedure ()
  (interactive)
  (insert-string "PROCEDURE ")
  (setq name (read-string "Name: " ))
  (insert-string name)
  (insert-string " (")
  (insert-string (read-string "Arguments: "))
  (insert-string ")")
  (setq args (read-string "Result Type: "))
  (if (not (string-equal args ""))
      (concat (insert-string " : ")
              (insert-string args)
              )
      )
  (insert-string ";")
  (m2-newline)
  (insert-string "BEGIN")
  (m2-newline)
  (m2-newline)
  (insert-string "END ")
  (insert-string name)
  (insert-string ";")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-with ()
  (interactive)
  (insert-string "WITH ")
  (insert-string (read-string ": "))
  (insert-string " DO")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* with *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-record ()
  (interactive)
  (insert-string "RECORD")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* record *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-stdio ()
  (interactive)
  (insert "
FROM TextIO IMPORT
   WriteCHAR, ReadCHAR, WriteINTEGER, ReadINTEGER,
   WriteCARDINAL, ReadCARDINAL, WriteBOOLEAN, ReadBOOLEAN,
   WriteREAL, ReadREAL, WriteBITSET, ReadBITSET,
   WriteBasedCARDINAL, ReadBasedCARDINAL, WriteChars, ReadChars,
   WriteString, ReadString, WhiteSpace, EndOfLine;

FROM SysStreams IMPORT sysIn, sysOut, sysErr;

")
  )

(defun m2-type ()
  (interactive)
  (insert-string "TYPE")
  (m2-newline)
  (m2-tab)
  )

(defun m2-until ()
  (interactive)
  (insert-string "REPEAT")
  (m2-newline)
  (m2-newline)
  (insert-string "UNTIL ")
  (insert-string (read-string ": "))
  (insert-string ";")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-var ()
  (interactive)
  (m2-newline)
  (insert-string "VAR")
  (m2-newline)
  (m2-tab)
  )

(defun m2-while ()
  (interactive)
  (insert-string "WHILE ")
  (insert-string (read-string ": "))
  (insert-string " DO")
  (m2-newline)
  (m2-newline)
  (insert-string "END (* while *);")
  (end-of-line 0)
  (m2-tab)
  )

(defun m2-export ()
  (interactive)
  (insert-string "EXPORT QUALIFIED ")
  )

(defun m2-import ()
  (interactive)
  (insert-string "FROM ")
  (insert-string (read-string "Module: "))
  (insert-string " IMPORT ")
  )

(defun m2-begin-comment ()
  (interactive)
  (if (not (bolp))
      (indent-to comment-column 0)
      )
  (insert-string "(*  ")
  )

(defun m2-end-comment ()
  (interactive)
  (if (not (bolp))
      (indent-to end-comment-column)
      )
  (insert-string "*)")
  )

(defun m2-compile ()
  (interactive)
  (setq modulename (buffer-name))
  (compile (concat "m2c " modulename))
  )

(defun m2-link ()
  (interactive)
  (setq modulename (buffer-name))
  (compile (concat "m2l " (substring modulename 0 -4)))
  )

(defun execute-monitor-command (command)
  (let* ((shell shell-file-name)
         (csh (equal (file-name-nondirectory shell) "csh")))
    (call-process shell nil t t "-cf" (concat "exec " command))))

(defun error-occurred (&quote &rest body)
  (condition-case ()
      (progn
        (while body
          (eval (car body)) (setq body (cdr body)))
        nil)
    (error t)))

(defun m2-visit ()
  (interactive)
  (defvar deffilefound 0)
  (defvar modfilefound 0)
  (progn
    (save-window-excursion
      (setq modulename
            (read-string "Module name: ")
            )
      (switch-to-buffer "*Command Execution*")
      (execute-monitor-command
       (concat  "m2whereis "    modulename)
       )
      (beginning-of-buffer)
      (if
       (error-occurred
        (re-search-forward "\\(.*\\.def\\) *$")
        )
       (beginning-of-buffer)
       (progn
         (region-around-match 1)
         (setq deffilename (region-to-string))
         (setq deffilefound 1)
         )
       )

      (if
       (error-occurred
        (re-search-forward "\\(.*\\.mod\\) *$")
        )
       ()
       (progn
         (region-around-match 1)
         (setq modfilename (region-to-string))
         (setq modfilefound 1)
         )
       )
      (if
       (not (or deffilefound modfilefound))
       (message "Error: %s"
        "I can find neither definition nor implementation of "
        modulename
        )
       )
      )

    (if
     deffilefound
     (progn
       (find-file deffilename)
       (if
        modfilefound
        (save-window-excursion
          (find-file modfilename)
          )
        )
       )
     (if
      modfilefound
      (find-file modfilename)
      )
     )
    )
  )

(defun m2-toggle ()
  "Toggle between .mod and .def files for the module."
  (interactive)
  (progn
    (if
     (string-equal (substring (buffer-name) -4) ".def")
     (find-file-other-window
      (concat (substring (buffer-name) 0 -4) ".mod")
      )
     (if
         (string-equal (substring (buffer-name) -4) ".mod")
         (find-file-other-window
          (concat (substring (buffer-name) 0 -4)  ".def")
          )
         )
     )
    )
  )

(defun old-newline ()
  (interactive)
  (insert-string "\^m")    )

wyle@inf.ethz.ch (Mitchell Wyle) (07/17/89)

In article <54474@tut.cis.ohio-state.edu> Doug Kerr <doug@cis.ohio-state.edu> writes:
>In article <8907062021.AA13058@thinman.ctc.contel.com> Modula2 List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes:
>>Does anyone have a set of macros for a syntax directed editor (or at least a
>>set of skeleton templates) for Modula-2 and Emacs that they would like to
>>share.

>GNU Emacs contains a Modula-2 editing support package.

...and it ain't so good.  I watched the emacs fanatics use it and explain
how great it is before porting professor Gutknecht's sara macro set to vi. 
The "electric modula2" emacs macro set which comes with gnu has the
following shortcomings:

1.  It is not orthogonal.  Some macros are 4 keystrokes, others are 2,
    still others are command-meta-shift-control-left-toe-under-up 7.

2.  It saves an average of 5 keystrokes a pop, not 25 (like mine)

3.  It's in emacs (blech) and if your box doesn't have emacs you're sol.
    (that's "sh*t out of luck" for you non anglo-people)

Here (once again) is Mitch's port of Gutknecht's sara modula-2 macro
package in vi map macros:

begin 644 elec.m2.exrc
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
H:6YG(BD[(%=R:71E26YT*'9A<BD[(%=R:71E3&X[%@T6&VMW=V-W"B@B
 
end
-- 
-Mitchell F. Wyle
Institut fuer Informationssysteme         wyle@inf.ethz.ch 
ETH Zentrum / 8092 Zurich, Switzerland    +41 1 256 5237