]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/meta-mode.el
Romain Francoise's and Ami Fischman's bugfixes.
[gnu-emacs] / lisp / progmodes / meta-mode.el
index 2bac7d98eb75107c8139ecbe98799ece7ab2cb84..7bf9e935710d5af2412620c84eb2f34a9a7b8232 100644 (file)
@@ -1,4 +1,4 @@
-;;; meta-mode.el --- major mode for editing Metafont or MetaPost sources.
+;;; meta-mode.el --- major mode for editing Metafont or MetaPost sources
 
 ;; Copyright (C) 1997 Free Software Foundation, Inc.
 
 ;; package or as a separate Emacs Lisp package.
 
 ;; Installation:
-;; 
+;;
 ;; An interface to running Metafont or MetaPost as a shell process
 ;; from within Emacs is currently under development as a separate
 ;; Emacs Lisp package (meta-buf.el).  In order to have that package
 ;; loaded automatically when first entering Metafont or MetaPost mode,
 ;; you might use the load-hook provided in this package by adding
 ;; these lines to your startup file:
-;; 
-;;  (add-hook 'meta-mode-load-hook 
+;;
+;;  (add-hook 'meta-mode-load-hook
 ;;            '(lambda () (require 'meta-buf)))
 ;;
 ;; The add-on package loaded this way may in turn make use of the
@@ -72,7 +72,7 @@
 ;; global-font-lock-mode or font-lock-support-mode, you can also
 ;; activate fontification in Metafont and/or MetaPost mode by adding
 ;; the following lines to your startup file:
-;; 
+;;
 ;;  (add-hook 'meta-common-mode-hook 'turn-on-font-lock)
 ;;  (add-hook 'meta-common-mode-hook 'turn-on-lazy-lock)
 
 ;;                          Improved and debbuged indentation function.
 ;; v 0.4 -- 1997/02/18  UV  Added functions to indent regions for M-C-q,
 ;;                          also added a preliminary mode-specific menu.
-;; v 0.5 -- 1997/02/19  UV  Added functions to skip to next or previous 
+;; v 0.5 -- 1997/02/19  UV  Added functions to skip to next or previous
 ;;                          defun and to re-indent or comment-out defuns.
 ;; v 0.6 -- 1997/02/20  UV  More debugging, testing and clean-up.
 ;; v 0.7 -- 1997/02/22  UV  Use easymenu to define mode-specific menu.
 
 (require 'easymenu)
 
+(defgroup meta-font nil
+  "Major mode for editing Metafont or MetaPost sources."
+  :group 'languages)
+
 ;;; Fontification.
 
 (defvar meta-font-lock-keywords
          (cons (concat "\\<" input-keywords "\\>"
                        "[ \t]+\\(\\sw+\\)")
                '((1 font-lock-keyword-face)
-                 (2 font-lock-reference-face)))
+                 (2 font-lock-constant-face)))
          ;; embedded Metafont/MetaPost code in comments
-         (cons "|\\([^|]+\\)|" 
-               '(1 font-lock-reference-face t))
+         (cons "|\\([^|]+\\)|"
+               '(1 font-lock-constant-face t))
      ))
   "Default expressions to highlight in Metafont or MetaPost mode.")
 
 ;;   grep '^primitive' texk-7.0/web2c/{mf,mp}.web |\
 ;;   sed 's/primitive(\("[a-zA-Z]*"\).*/\1/' > {mf,mp}_prim.list
 ;;
-;;   grep '\(let\|def\|vardef\|primarydef\|secondarydef\|tertiarydef\)' 
+;;   grep '\(let\|def\|vardef\|primarydef\|secondarydef\|tertiarydef\)'
 ;;     texmf/meta{font,post}/plain.{mf,mp} > {mf,mp}_plain.list
 
-(defconst meta-common-primitives-list 
+(defconst meta-common-primitives-list
   '("ASCII" "addto" "also" "and" "angle" "atleast" "batchmode"
     "begingroup" "boolean" "boundarychar" "char" "charcode" "chardp"
     "charexists" "charext" "charht" "charic" "charlist" "charwd"
     "transform" "transformed" "true" "turningnumber" "uniformdeviate"
     "unknown" "until" "vardef" "warningcheck" "withpen" "xpart"
     "xscaled" "xxpart" "xypart" "year" "ypart" "yscaled" "yxpart"
-    "yypart" "zscaled") 
+    "yypart" "zscaled")
   "List of primitives common to Metafont and MetaPost.")
 
-(defconst metafont-primitives-list 
+(defconst metafont-primitives-list
   '("at" "autorounding" "chardx" "chardy" "cull" "display"
     "dropping" "fillin" "from" "granularity" "hppp" "inwindow"
     "keeping" "numspecial" "openwindow" "proofing" "smoothing"
     "withweight" "xoffset" "yoffset")
   "List of primitives only defined in Metafont.")
 
-(defconst metapost-primitives-list 
+(defconst metapost-primitives-list
   '("arclength" "arctime" "bluepart" "bounded" "btex" "clip"
     "clipped" "color" "dashed" "dashpart" "etex" "filled" "fontpart"
     "fontsize" "greenpart" "infont" "linecap" "linejoin" "llcorner"
     "verbatimtex" "withcolor" "within" "write")
   "List of primitives only defined in MetaPost.")
 
-(defconst meta-common-plain-macros-list 
+(defconst meta-common-plain-macros-list
   '( "abs" "bot" "bye" "byte" "ceiling" "clear_pen_memory"
      "clearit" "clearpen" "clearxy" "counterclockwise" "cutdraw" "decr"
      "dir" "direction" "directionpoint" "div" "dotprod" "downto" "draw"
      "unitvector" "upto" "whatever")
   "List of macros common to plain Metafont and MetaPost.")
 
-(defconst metafont-plain-macros-list 
+(defconst metafont-plain-macros-list
   '("beginchar" "change_width" "culldraw" "cullit" "cutoff"
     "define_blacker_pixels" "define_corrected_pixels"
     "define_good_x_pixels" "define_good_y_pixels"
     "mode_proof" "mode_setup" "mode_smoke" "nodisplays" "notransforms"
     "openit" "penrazor" "pensquare" "proofoffset" "proofrule"
     "proofrulethickness" "screenchars" "screenrule" "screenstrokes"
-    "showit" "slantfont" "smode" "titlefont" "vround") 
+    "showit" "slantfont" "smode" "titlefont" "vround")
   "List of macros only defined in plain Metafont.")
 
-(defconst metapost-plain-macros-list 
+(defconst metapost-plain-macros-list
   '("arrowhead" "bbox" "beginfig" "buildcycle" "center" "cutafter"
     "cutbefore" "dashpattern" "dotlabel" "dotlabels" "drawarrow"
     "drawdblarrow" "drawoptions" "endfig" "image" "label" "off" "on"
-    "thelabel") 
+    "thelabel")
   "List of macros only defined in plain MetaPost.")
 
-(defconst metapost-graph-macros-list 
-  '("augment" "auto.x" "auto.y" "autogrid" "begingraph" "endgraph" 
-    "format" "frame" "gdata" "gdotlabel" "gdraw" "gdrawarrow" 
-    "gdrawdblarrow" "gfill" "glabel" "grid" "itick" "otick" "plot" 
+(defconst metapost-graph-macros-list
+  '("augment" "auto.x" "auto.y" "autogrid" "begingraph" "endgraph"
+    "format" "frame" "gdata" "gdotlabel" "gdraw" "gdrawarrow"
+    "gdrawdblarrow" "gfill" "glabel" "grid" "itick" "otick" "plot"
     "setcoords" "setrange")
   "List of macros only defined in MetaPost \"graph\" package.")
-  
-(defconst metapost-boxes-macros-list 
+
+(defconst metapost-boxes-macros-list
   '("boxit" "boxjoin" "bpath" "circleit" "drawboxed" "drawboxes"
     "drawunboxed" "fixpos" "fixsize" "pic" "rboxit")
   "List of macros only defined in MetaPost \"boxes\" package.")
 (defvar meta-symbol-list nil
   "List of known symbols to complete in Metafont or MetaPost mode.")
 
-(defvar meta-symbol-changed nil 
+(defvar meta-symbol-changed nil
   "Flag indicating whether `meta-symbol-list' has been initialized.")
 
 (defvar meta-complete-list nil
@@ -513,7 +517,7 @@ If the list was changed, sort the list and remove duplicates first."
   ;; utility function used in `meta-complete-symbol'
   (let ((pos (point)))
     (save-excursion
-      (and (re-search-backward 
+      (and (re-search-backward
             regexp (if limit (max (point-min) (- (point) limit))) t)
            (eq (match-end 0) pos)))))
 
@@ -529,35 +533,50 @@ If the list was changed, sort the list and remove duplicates first."
 \f
 ;;; Indentation.
 
-(defvar meta-indent-level 2
-  "*Indentation of begin-end blocks in Metafont or MetaPost mode.")
+(defcustom meta-indent-level 2
+  "*Indentation of begin-end blocks in Metafont or MetaPost mode."
+  :type 'integer
+  :group 'meta-font)
 
 
-(defvar meta-left-comment-regexp "%%+"
-  "*Regexp matching comments that should be placed on the left margin.")
+(defcustom meta-left-comment-regexp "%%+"
+  "*Regexp matching comments that should be placed on the left margin."
+  :type 'regexp
+  :group 'meta-font)
 
-(defvar meta-right-comment-regexp nil
-  "*Regexp matching comments that should be placed to the right margin.")
+(defcustom meta-right-comment-regexp nil
+  "*Regexp matching comments that should be placed to the right margin."
+  :type '(choice regexp
+                (const :tag "None" nil))
+  :group 'meta-font)
 
-(defvar meta-ignore-comment-regexp "%[^%]"
-  "*Regexp matching comments that whose indentation should not be touched.")
+(defcustom meta-ignore-comment-regexp "%[^%]"
+  "*Regexp matching comments that whose indentation should not be touched."
+  :type 'regexp
+  :group 'meta-font)
 
 
-(defvar meta-begin-environment-regexp
+(defcustom meta-begin-environment-regexp
   (concat "\\(begin\\(char\\|fig\\|gr\\(aph\\|oup\\)\\|logochar\\)\\|"
           "def\\|for\\(\\|ever\\|suffixes\\)\\|if\\|mode_def\\|"
           "primarydef\\|secondarydef\\|tertiarydef\\|vardef\\)")
-  "*Regexp matching the beginning of environments to be indented.")
+  "*Regexp matching the beginning of environments to be indented."
+  :type 'regexp
+  :group 'meta-font)
 
-(defvar meta-end-environment-regexp
+(defcustom meta-end-environment-regexp
   (concat "\\(end\\(char\\|def\\|f\\(ig\\|or\\)\\|gr\\(aph\\|oup\\)\\)"
           "\\|fi\\)")
-  "*Regexp matching the end of environments to be indented.")
+  "*Regexp matching the end of environments to be indented."
+  :type 'regexp
+  :group 'meta-font)
 
-(defvar meta-within-environment-regexp
+(defcustom meta-within-environment-regexp
 ; (concat "\\(e\\(lse\\(\\|if\\)\\|xit\\(if\\|unless\\)\\)\\)")
   (concat "\\(else\\(\\|if\\)\\)")
-  "*Regexp matching keywords within environments not to be indented.")
+  "*Regexp matching keywords within environments not to be indented."
+  :type 'regexp
+  :group 'meta-font)
 
 
 (defun meta-comment-indent ()
@@ -566,7 +585,7 @@ If the list was changed, sort the list and remove duplicates first."
            (looking-at meta-left-comment-regexp))
       (current-column)
     (skip-chars-backward "\t ")
-    (max (if (bolp) 0 (1+ (current-column))) 
+    (max (if (bolp) 0 (1+ (current-column)))
          comment-column)))
 
 (defun meta-indent-line ()
@@ -586,7 +605,7 @@ If the list was changed, sort the list and remove duplicates first."
   "Return the indentation of current line of Metafont or MetaPost source."
   (save-excursion
     (back-to-indentation)
-    (cond 
+    (cond
       ;; Comments to the left margin.
      ((and meta-left-comment-regexp
            (looking-at meta-left-comment-regexp))
@@ -596,15 +615,15 @@ If the list was changed, sort the list and remove duplicates first."
            (looking-at meta-right-comment-regexp))
       comment-column)
      ;; Comments best left alone.
-     ((and meta-ignore-comment-regexp 
+     ((and meta-ignore-comment-regexp
            (looking-at meta-ignore-comment-regexp))
       (current-indentation))
      ;; Backindent at end of environments.
-     ((looking-at 
+     ((looking-at
        (concat "\\<" meta-end-environment-regexp "\\>"))
       (- (meta-indent-calculate-last) meta-indent-level))
      ;; Backindent at keywords within environments.
-     ((looking-at 
+     ((looking-at
        (concat "\\<" meta-within-environment-regexp "\\>"))
       (- (meta-indent-calculate-last) meta-indent-level))
      (t (meta-indent-calculate-last)))))
@@ -626,11 +645,11 @@ If the list was changed, sort the list and remove duplicates first."
            (meta-indent-level-count)
            (cond
             ;; Compensate for backindent at end of environments.
-            ((looking-at 
+            ((looking-at
               (concat "\\<"meta-end-environment-regexp "\\>"))
              meta-indent-level)
             ;; Compensate for backindent within environments.
-            ((looking-at 
+            ((looking-at
               (concat "\\<" meta-within-environment-regexp "\\>"))
              meta-indent-level)
             (t 0)))))
@@ -641,7 +660,7 @@ If the list was changed, sort the list and remove duplicates first."
   (save-excursion
     (save-restriction
       (let ((count 0))
-        (narrow-to-region 
+        (narrow-to-region
          (point) (save-excursion
                    (re-search-forward "[^\\\\\"]%\\|\n\\|\\'" nil t)
                    (backward-char) (point)))
@@ -650,12 +669,12 @@ If the list was changed, sort the list and remove duplicates first."
             (goto-char (match-beginning 0))
             (cond
              ;; Count number of begin-end keywords within line.
-             ((looking-at 
+             ((looking-at
                (concat "\\<" meta-begin-environment-regexp "\\>"))
               (setq count (+ count meta-indent-level)))
-             ((looking-at 
+             ((looking-at
                (concat "\\<" meta-end-environment-regexp "\\>"))
-              (setq count (- count meta-indent-level)))     
+              (setq count (- count meta-indent-level)))
              ;; Count number of open-close parentheses within line.
              ((looking-at "(")
               (setq count (+ count meta-indent-level)))
@@ -665,122 +684,40 @@ If the list was changed, sort the list and remove duplicates first."
         count))))
 
 
-\f
-;;; Filling paragraphs.
-
-(defun meta-fill-paragraph (&optional justify)
-  "Like \\[fill-paragraph], but handle Metafont or MetaPost comments.
-If any part of the current line is a comment, fill the comment or the
-paragraph of it that point is in, preserving the comment's indentation
-and initial semicolons."
-  (interactive "P")
-  (let (has-comment             ; Non-nil if line contains a comment.
-        has-code-and-comment    ; Non-nil if line contains code and a comment.
-        comment-fill-prefix     ; If has-comment, fill-prefix for the comment.
-        )
-    ;; Figure out what kind of comment we are looking at.
-    (save-excursion
-      (beginning-of-line)
-      (cond
-       ;; A line with nothing but a comment on it?
-       ((looking-at (concat "[ \t]*" comment-start-skip))
-        (setq has-comment t)
-        (setq comment-fill-prefix 
-              (buffer-substring (match-beginning 0) (match-end 0))))
-       ;; A line with some code, followed by a comment?  
-       ((condition-case nil
-            (save-restriction
-              (narrow-to-region (point-min)
-                                (save-excursion (end-of-line) (point)))
-              (while (not (looking-at (concat comment-start "\\|$")))
-                (skip-chars-forward (concat "^" comment-start "\n\"\\\\"))
-                (cond
-                 ((eq (char-after (point)) ?\\) (forward-char 2))
-                 ((eq (char-after (point)) ?\") (forward-sexp 1))))
-              (looking-at comment-start-skip))
-          (error nil))
-        (setq has-comment t 
-              has-code-and-comment t)
-        (setq comment-fill-prefix
-              (concat (make-string (/ (current-column) 8) ?\t)
-                      (make-string (% (current-column) 8) ?\ )
-                      (buffer-substring (match-beginning 0) (match-end 0)))))
-       ))
-    (if (not has-comment)
-        (fill-paragraph justify)
-      ;; Narrow to include only the comment, and then fill the region.
-      (save-excursion
-        (save-restriction
-          (beginning-of-line)
-          (narrow-to-region
-           ;; Find the first line we should include in the region to fill.
-           (save-excursion
-             (while (and (zerop (forward-line -1))
-                         (looking-at (concat "^[ \t]*" comment-start))))
-             (or (looking-at (concat ".*" comment-start)) 
-                 (forward-line 1))
-             (point))
-           ;; Find the beginning of the first line past the region to fill.
-           (save-excursion
-             (while (progn (forward-line 1)
-                           (looking-at (concat "^[ \t]*" comment-start))))
-             (point)))
-          (let* ((paragraph-start 
-                  (concat paragraph-start "\\|[ \t%]*$"))
-                 (paragraph-separate  
-                  (concat paragraph-start "\\|[ \t%]*$"))
-                 (paragraph-ignore-fill-prefix nil)
-                 (fill-prefix comment-fill-prefix)
-                 (after-line (if has-code-and-comment
-                                 (save-excursion (forward-line 1) (point))))
-                 (end (progn (forward-paragraph)
-                             (or (bolp) (newline 1))
-                             (point)))
-                 (beg (progn (backward-paragraph)
-                             (if (eq (point) after-line) (forward-line -1))
-                             (point)))
-                 (after-pos  (save-excursion
-                               (goto-char beg)
-                               (if (not (looking-at fill-prefix))
-                                   (progn
-                                     (re-search-forward comment-start-skip)
-                                     (point)))))
-                 )
-            (fill-region-as-paragraph beg end justify nil after-pos))
-          )))
-    t))
-
-
 \f
 ;;; Editing commands.
 
-(defvar meta-begin-defun-regexp
+(defcustom meta-begin-defun-regexp
   (concat "\\(begin\\(char\\|fig\\|logochar\\)\\|def\\|mode_def\\|"
           "primarydef\\|secondarydef\\|tertiarydef\\|vardef\\)")
-  "*Regexp matching beginning of defuns in Metafont or MetaPost mode.")
+  "*Regexp matching beginning of defuns in Metafont or MetaPost mode."
+  :type 'regexp
+  :group 'meta-font)
 
-(defvar meta-end-defun-regexp
+(defcustom meta-end-defun-regexp
   (concat "\\(end\\(char\\|def\\|fig\\)\\)")
-  "*Regexp matching the end of defuns in Metafont or MetaPost mode.")
+  "*Regexp matching the end of defuns in Metafont or MetaPost mode."
+  :type 'regexp
+  :group 'meta-font)
 
 
 (defun meta-beginning-of-defun (&optional arg)
   "Move backward to beginnning of a defun in Metafont or MetaPost code.
-With numeric argument, do it that many times.  
+With numeric argument, do it that many times.
 Negative arg -N means move forward to Nth following beginning of defun.
 Returns t unless search stops due to beginning or end of buffer."
   (interactive "p")
   (if (or (null arg) (= 0 arg)) (setq arg 1))
   (and arg (< arg 0) (not (eobp)) (forward-char 1))
-  (and (re-search-backward 
+  (and (re-search-backward
         (concat "\\<" meta-begin-defun-regexp "\\>") nil t arg)
        (progn (goto-char (match-beginning 0))
               (skip-chars-backward "%")
               (skip-chars-backward " \t") t)))
-      
+
 (defun meta-end-of-defun (&optional arg)
   "Move forward to end of a defun in Metafont or MetaPost code.
-With numeric argument, do it that many times. 
+With numeric argument, do it that many times.
 Negative argument -N means move back to Nth preceding end of defun.
 Returns t unless search stops due to beginning or end of buffer."
   (interactive "p")
@@ -903,7 +840,7 @@ The environment marked is the one that contains point or follows point."
     ()
   (setq meta-mode-map (make-sparse-keymap))
   (define-key meta-mode-map "\t"        'meta-indent-line)
-  (define-key meta-mode-map "\C-m"      'reindent-then-newline-and-indent)  
+  (define-key meta-mode-map "\C-m"      'reindent-then-newline-and-indent)
   ;; Comment Paragraphs:
 ; (define-key meta-mode-map "\M-a"      'backward-sentence)
 ; (define-key meta-mode-map "\M-e"      'forward-sentence)
@@ -927,11 +864,11 @@ The environment marked is the one that contains point or follows point."
   (define-key meta-mode-map "\M-\t"     'meta-complete-symbol)
   ;; Shell Commands:
 ; (define-key meta-mode-map "\C-c\C-c"  'meta-command-file)
-; (define-key meta-mode-map "\C-c\C-k"  'meta-kill-job)            
+; (define-key meta-mode-map "\C-c\C-k"  'meta-kill-job)
 ; (define-key meta-mode-map "\C-c\C-l"  'meta-recenter-output)
   )
 
-(easy-menu-define 
+(easy-menu-define
  meta-mode-menu meta-mode-map
  "Menu used in Metafont or MetaPost mode."
  (list "Meta"
@@ -940,15 +877,15 @@ The environment marked is the one that contains point or follows point."
        "--"
        ["Indent Line"                   meta-indent-line t]
        ["Indent Environment"            meta-indent-defun t]
-       ["Indent Region"                 meta-indent-region 
+       ["Indent Region"                 meta-indent-region
         :active (meta-mark-active)]
        ["Indent Buffer"                 meta-indent-buffer t]
        "--"
        ["Comment Out Environment"       meta-comment-defun t]
        ["Uncomment Environment"         meta-uncomment-defun t]
-       ["Comment Out Region"            meta-comment-region 
+       ["Comment Out Region"            meta-comment-region
         :active (meta-mark-active)]
-       ["Uncomment Region"              meta-uncomment-region 
+       ["Uncomment Region"              meta-uncomment-region
         :active (meta-mark-active)]
        "--"
        ["Complete Symbol"               meta-complete-symbol t]
@@ -967,16 +904,24 @@ The environment marked is the one that contains point or follows point."
 \f
 ;;; Hook variables.
 
-(defvar meta-mode-load-hook nil
-  "*Hook evaluated when first loading Metafont or MetaPost mode.")
+(defcustom meta-mode-load-hook nil
+  "*Hook evaluated when first loading Metafont or MetaPost mode."
+  :type 'hook
+  :group 'meta-font)
 
-(defvar meta-common-mode-hook nil
-  "*Hook evaluated by both `metafont-mode' and `metapost-mode'.")
+(defcustom meta-common-mode-hook nil
+  "*Hook evaluated by both `metafont-mode' and `metapost-mode'."
+  :type 'hook
+  :group 'meta-font)
 
-(defvar metafont-mode-hook nil
-  "*Hook evaluated by `metafont-mode' after `meta-common-mode-hook'.")
-(defvar metapost-mode-hook nil
-  "*Hook evaluated by `metapost-mode' after `meta-common-mode-hook'.")
+(defcustom metafont-mode-hook nil
+  "*Hook evaluated by `metafont-mode' after `meta-common-mode-hook'."
+  :type 'hook
+  :group 'meta-font)
+(defcustom metapost-mode-hook nil
+  "*Hook evaluated by `metapost-mode' after `meta-common-mode-hook'."
+  :type 'hook
+  :group 'meta-font)
 
 
 \f
@@ -988,9 +933,9 @@ The environment marked is the one that contains point or follows point."
 
   (make-local-variable 'paragraph-start)
   (make-local-variable 'paragraph-separate)
-  (setq paragraph-start 
+  (setq paragraph-start
         (concat page-delimiter "\\|$"))
-  (setq paragraph-separate 
+  (setq paragraph-separate
         (concat page-delimiter "\\|$"))
 
   (make-local-variable 'paragraph-ignore-fill-prefix)
@@ -1010,8 +955,6 @@ The environment marked is the one that contains point or follows point."
 
   (make-local-variable 'comment-indent-function)
   (setq comment-indent-function 'meta-comment-indent)
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'meta-fill-paragraph)
   (make-local-variable 'indent-line-function)
   (setq indent-line-function 'meta-indent-line)
   ;; No need to define a mode-specific 'indent-region-function.
@@ -1088,4 +1031,5 @@ Turning on MetaPost mode calls the value of the variable
 (provide 'meta-mode)
 (run-hooks 'meta-mode-load-hook)
 
+;;; arch-tag: ec2916b2-3a83-4cf7-962d-d8019370c006
 ;;; meta-mode.el ends here