(command-line): Set `temporary-file-directory' based
[bpt/emacs.git] / lisp / progmodes / tcl.el
index 4c854f5..ef8e27b 100644 (file)
@@ -6,7 +6,7 @@
 ;; Author: Tom Tromey <tromey@busco.lanl.gov>
 ;;    Chris Lindblad <cjl@lcs.mit.edu>
 ;; Keywords: languages tcl modes
-;; Version: $Revision: 1.36 $
+;; Version: $Revision: 1.50 $
 
 ;; This file is part of GNU Emacs.
 
@@ -51,7 +51,7 @@
 ;; LCD Archive Entry:
 ;; tcl|Tom Tromey|tromey@busco.lanl.gov|
 ;; Major mode for editing Tcl|
-;; $Date: 1995/07/09 01:07:57 $|$Revision: 1.36 $|~/modes/tcl.el.Z|
+;; $Date: 1996/03/23 05:14:50 $|$Revision: 1.50 $|~/modes/tcl.el.Z|
 
 ;; CUSTOMIZATION NOTES:
 ;; * tcl-proc-list can be used to customize a list of things that
 
 ;; Change log:
 ;; $Log: tcl.el,v $
+;; Revision 1.50  1996/03/23  05:14:50  tromey
+;; (tcl-using-emacs-19): Work with XEmacs 20.0.  From Ben Wing.
+;;
+;; Revision 1.49  1995/12/07  18:27:47  tromey
+;; (add-log-tcl-defun): Don't use tcl-beginning-of-defun; just go to end
+;; of line before searching.
+;;
+;; Revision 1.48  1995/12/07  18:18:21  tromey
+;; (add-log-tcl-defun): Now uses tcl-beginning-of-defun.
+;;
+;; Revision 1.47  1995/08/22  17:49:45  tromey
+;; (tcl-hilit): New function from "Chris Alfeld" <calfeld@math.utah.edu>
+;; (tcl-mode): Call it
+;;
+;; Revision 1.46  1995/08/07  16:02:01  tromey
+;; (tcl-do-auto-fill): Only fill past fill-column; for 19.29.
+;; (tcl-auto-fill-mode): Use force-mode-line-update.
+;;
+;; Revision 1.45  1995/07/23  23:51:25  tromey
+;; (tcl-word-no-props): New function.
+;; (tcl-figure-type): Use it.
+;; (tcl-current-word): Ditto.
+;;
+;; Revision 1.44  1995/07/23  20:26:47  tromey
+;; Doc fixes.
+;;
+;; Revision 1.43  1995/07/17  19:59:49  tromey
+;; (inferior-tcl-mode): Use modeline-process if it exists.
+;;
+;; Revision 1.42  1995/07/17  19:55:25  tromey
+;; XEmacs currently must use tcl-internal-end-of-defun
+;;
+;; Revision 1.41  1995/07/14  21:54:56  tromey
+;; Changes to make menus work in XEmacs.
+;; From Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
+;;
+;; Revision 1.40  1995/07/11  03:13:15  tromey
+;; (tcl-mode): Customize for new dabbrev.
+;;
+;; Revision 1.39  1995/07/09  21:58:03  tromey
+;; (tcl-do-fill-paragraph): New function.
+;; (tcl-mode): Set up for paragraph filling.
+;;
+;; Revision 1.38  1995/07/09  21:30:32  tromey
+;; (tcl-mode): Fixes to 19.29 paragraph variables.
+;;
+;; Revision 1.37  1995/07/09  18:52:16  tromey
+;; (tcl-do-auto-fill): Set fill-prefix.
+;;
 ;; Revision 1.36  1995/07/09  01:07:57  tromey
 ;; (tcl-imenu-create-index-function): Work with imenu from Emacs 19.29
 ;;
 ;; T. V. Raman <raman@crl.dec.com>
 ;; Jesper Pedersen <blackie@imada.ou.dk>
 ;; dfarmer@evolving.com (Doug Farmer)
+;; "Chris Alfeld" <calfeld@math.utah.edu>
+;; Ben Wing <wing@666.com>
 
 ;; KNOWN BUGS:
 ;; * indent-region should skip blank lines.  (It does in v19, so I'm
 ;;; Code:
 
 ;; I sure wish Emacs had a package that made it easy to extract this
-;; sort of information.
-(defconst tcl-using-emacs-19 (string-match "19\\." emacs-version)
+;; sort of information.  Strange definition works with XEmacs 20.0.
+(defconst tcl-using-emacs-19 (not (string-match "18\\." emacs-version))
   "Nil unless using Emacs 19 (XEmacs or FSF).")
 
 ;; FIXME this will break on Emacs 19.100.
           (require 'imenu))
        ()))
 
-(defconst tcl-version "$Revision: 1.36 $")
+(defconst tcl-version "$Revision: 1.50 $")
 (defconst tcl-maintainer "Tom Tromey <tromey@drip.colorado.edu>")
 
 ;;
@@ -359,7 +410,7 @@ detecting function is used.  This variable is only used in GNU Emacs
 (defvar tcl-electric-hash-style 'smart
   "*Style of electric hash insertion to use.
 Possible values are 'backslash, meaning that `\\' quoting should be
-done; `quote, meaning that `\"' quoting should be done; 'smart,
+done; 'quote, meaning that `\"' quoting should be done; 'smart,
 meaning that the choice between 'backslash and 'quote should be
 made depending on the number of hashes inserted; or nil, meaning that
 no quoting should be done.  Any other value for this variable is
@@ -438,8 +489,7 @@ quoted for Tcl.")
 
 ;; XEmacs menu.
 (defvar tcl-xemacs-menu
-  '("Tcl"
-    ["Beginning of function" tcl-beginning-of-defun t]
+  '(["Beginning of function" tcl-beginning-of-defun t]
     ["End of function" tcl-end-of-defun t]
     ["Mark function" tcl-mark-defun t]
     ["Indent region" indent-region (tcl-mark)]
@@ -465,7 +515,7 @@ quoted for Tcl.")
   (define-key map [menu-bar] (make-sparse-keymap))
   ;; This fails in Emacs 19.22 and earlier.
   (require 'lmenu)
-  (let ((menu (make-lucid-menu-keymap "Tcl" (cdr tcl-xemacs-menu))))
+  (let ((menu (make-lucid-menu-keymap "Tcl" tcl-xemacs-menu)))
     (define-key map [menu-bar tcl] (cons "Tcl" menu))
     ;; The following is intended to compute the key sequence
     ;; information for the menu.  It doesn't work.
@@ -770,7 +820,7 @@ An end of a defun is found by moving forward from the beginning of one."
 
 ;; Ditto end-of-defun.
 (fset 'tcl-end-of-defun
-      (if tcl-using-emacs-19
+      (if (and tcl-using-emacs-19 (not tcl-using-xemacs-19))
          'end-of-defun
        'tcl-internal-end-of-defun))
 
@@ -880,6 +930,9 @@ documentation for details):
   tcl-use-hairy-comment-detector
     If t, use more complicated, but slower, comment detector.
     This variable is only used in GNU Emacs 19.
+  tcl-use-smart-word-finder
+    If not nil, use a smarter, Tcl-specific way to find the current
+    word when looking up help on a Tcl command.
 
 Turning on Tcl mode calls the value of the variable `tcl-mode-hook'
 with no args, if that value is non-nil.  Read the documentation for
@@ -897,11 +950,20 @@ Commands:
   (set-syntax-table tcl-mode-syntax-table)
 
   (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat "^$\\|" page-delimiter))
   (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
+  (if (and tcl-using-emacs-19-23
+          (>= emacs-minor-version 29))
+      (progn
+       ;; In Emacs 19.29, you aren't supposed to start these with a
+       ;; ^.
+       (setq paragraph-start "$\\|\f")
+       (setq paragraph-separate paragraph-start))
+    (setq paragraph-start (concat "^$\\|" page-delimiter))
+    (setq paragraph-separate paragraph-start))
   (make-local-variable 'paragraph-ignore-fill-prefix)
   (setq paragraph-ignore-fill-prefix t)
+  (make-local-variable 'fill-paragraph-function)
+  (setq fill-paragraph-function 'tcl-do-fill-paragraph)
 
   (make-local-variable 'indent-line-function)
   (setq indent-line-function 'tcl-indent-line)
@@ -931,6 +993,16 @@ Commands:
   (setq imenu-create-index-function 'tcl-imenu-create-index-function)
   (make-local-variable 'parse-sexp-ignore-comments)
 
+  ;; Settings for new dabbrev code.
+  (make-local-variable 'dabbrev-case-fold-search)
+  (setq dabbrev-case-fold-search nil)
+  (make-local-variable 'dabbrev-case-replace)
+  (setq dabbrev-case-replace nil)
+  (make-local-variable 'dabbrev-abbrev-skip-leading-regexp)
+  (setq dabbrev-abbrev-skip-leading-regexp "[$!]")
+  (make-local-variable 'dabbrev-abbrev-char-regexp)
+  (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+
   (if tcl-using-emacs-19
       (progn
        ;; This can only be set to t in Emacs 19 and XEmacs.
@@ -957,7 +1029,12 @@ Commands:
        (add-menu nil "Tcl" tcl-xemacs-menu)))
   ;; Append Tcl menu to popup menu for XEmacs.
   (if (and tcl-using-xemacs-19 (boundp 'mode-popup-menu))
-      (setq mode-popup-menu tcl-xemacs-menu))
+      (setq mode-popup-menu
+           (cons (concat mode-name " Mode Commands") tcl-xemacs-menu)))
+
+  ;; If hilit19 is loaded, add our stuff.
+  (if (featurep 'hilit19)
+      (tcl-hilit))
 
   (run-hooks 'tcl-mode-hook))
 
@@ -1024,7 +1101,7 @@ from the following list to take place:
     ;; Indent if in indentation area, otherwise insert TAB.
     (if (<= (current-column) (current-indentation))
        (tcl-indent-line)
-      (self-insert-command arg)))
+      (insert-tab arg)))
    ((eq tcl-tab-always-indent t)
     ;; Always indent.
     (tcl-indent-line))
@@ -1123,7 +1200,7 @@ See documentation for variable `tcl-type-alist' for more information."
            (if (looking-at "[a-zA-Z_]+")
                (let ((list tcl-type-alist)
                      entry)
-                 (setq word-stack (cons (current-word) word-stack))
+                 (setq word-stack (cons (tcl-word-no-props) word-stack))
                  (while (and list (not result))
                    (setq entry (car list))
                    (setq list (cdr list))
@@ -1377,8 +1454,8 @@ Returns nil if line starts inside a string, t if in a comment."
 (defun add-log-tcl-defun ()
   "Return name of Tcl function point is in, or nil."
   (save-excursion
-    (if (re-search-backward
-        (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
+    (end-of-line)
+    (if (re-search-backward (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
        (buffer-substring (match-beginning 2)
                          (match-end 2)))))
 
@@ -1512,7 +1589,9 @@ The following commands are available:
                                         ">")))
   (setq major-mode 'inferior-tcl-mode)
   (setq mode-name "Inferior Tcl")
-  (setq mode-line-process '(": %s"))
+  (if (boundp 'modeline-process)
+      (setq modeline-process '(": %s"))        ; For XEmacs.
+    (setq mode-line-process '(": %s")))
   (use-local-map inferior-tcl-mode-map)
   (setq local-abbrev-table tcl-mode-abbrev-table)
   (set-syntax-table tcl-mode-syntax-table)
@@ -1650,23 +1729,65 @@ of comment."
       (tcl-hairy-in-comment)
     (tcl-simple-in-comment)))
 
-(defun tcl-do-auto-fill ()
-  "Auto-fill function for Tcl mode.  Only auto-fills in a comment."
-  (let ((fill-prefix "# ")
-       in-comment col)
+(defun tcl-do-fill-paragraph (ignore)
+  "fill-paragraph function for Tcl mode.  Only fills in a comment."
+  (let (in-comment col where)
     (save-excursion
+      (end-of-line)
       (setq in-comment (tcl-in-comment))
       (if in-comment
-         (setq col (1- (current-column)))))
-    (if in-comment
-       (progn
-         (do-auto-fill)
-         (save-excursion
-           (back-to-indentation)
-           (delete-region (point) (save-excursion
-                                    (beginning-of-line)
-                                    (point)))
-           (indent-to-column col))))))
+         (progn
+           (setq where (1+ (point)))
+           (setq col (1- (current-column))))))
+    (and in-comment
+        (save-excursion
+          (back-to-indentation)
+          (= col (current-column)))
+        ;; In a comment.  Set the fill prefix, and find the paragraph
+        ;; boundaries by searching for lines that look like
+        ;; comment-only lines.
+        (let ((fill-prefix (buffer-substring (progn
+                                               (beginning-of-line)
+                                               (point))
+                                             where))
+              p-start p-end)
+          ;; Search backwards.
+          (save-excursion
+            (while (looking-at "^[ \t]*#")
+              (forward-line -1))
+            (forward-line)
+            (setq p-start (point)))
+
+          ;; Search forwards.
+          (save-excursion
+            (while (looking-at "^[ \t]*#")
+              (forward-line))
+            (setq p-end (point)))
+
+          ;; Narrow and do the fill.
+          (save-restriction
+            (narrow-to-region p-start p-end)
+            (fill-paragraph ignore)))))
+  t)
+
+(defun tcl-do-auto-fill ()
+  "Auto-fill function for Tcl mode.  Only auto-fills in a comment."
+  (if (> (current-column) fill-column)
+      (let ((fill-prefix "# ")
+           in-comment col)
+       (save-excursion
+         (setq in-comment (tcl-in-comment))
+         (if in-comment
+             (setq col (1- (current-column)))))
+       (if in-comment
+           (progn
+             (do-auto-fill)
+             (save-excursion
+               (back-to-indentation)
+               (delete-region (point) (save-excursion
+                                        (beginning-of-line)
+                                        (point)))
+               (indent-to-column col)))))))
 
 \f
 
@@ -1713,6 +1834,13 @@ to update the alist.")
   (tcl-help-snarf-commands tcl-help-directory-list)
   (message "Building Tcl help file index...done"))
 
+(defun tcl-word-no-props ()
+  "Like current-word, but strips properties."
+  (let ((word (current-word)))
+    (and (fboundp 'set-text-properties)
+        (set-text-properties 0 (length word) nil word))
+    word))
+
 (defun tcl-current-word (flag)
   "Return current command word, or nil.
 If FLAG is nil, just uses `current-word'.
@@ -1727,10 +1855,10 @@ Otherwise scans backward for most likely Tcl command word."
              (while (and (not (bobp))
                          (not (tcl-real-command-p)))
                (backward-sexp)))
-           (if (assoc (current-word) tcl-help-alist)
-               (current-word)))
+           (if (assoc (tcl-word-no-props) tcl-help-alist)
+               (tcl-word-no-props)))
        (error nil))
-    (current-word)))
+    (tcl-word-no-props)))
 
 ;;;###autoload
 (defun tcl-help-on-word (command &optional arg)
@@ -1858,9 +1986,21 @@ Prefix argument means switch to the Tcl buffer afterwards."
                  (> (prefix-numeric-value arg) 0))
                'tcl-do-auto-fill
              nil))
-    ;; Update mode line.  FIXME I'd use force-mode-line-update, but I
-    ;; don't know if it exists in v18.
-    (set-buffer-modified-p (buffer-modified-p))))
+    (force-mode-line-update)))
+
+;; hilit19 support from "Chris Alfeld" <calfeld@math.utah.edu>
+(defun tcl-hilit ()
+  (hilit-set-mode-patterns
+   '(tcl-mode)
+   '(
+     ("\\(^ *\\|\; *\\)#.*$" nil comment)
+     ("[^\\]\\(\\$[A-Za-z0-9\\-\\_./\\(\\)]+\\)" 1 label)
+     ("[^_]\\<\\(append\\|array\\|auto_execok\\|auto_load\\|auto_mkindex\\|auto_reset\\|break\\|case\\|catch\\|cd\\|close\\|concat\\|continue\\|eof\\|error\\|eval\\|exec\\|exit\\|expr\\|file\\|flush\\|for\\|foreach\\|format\\|gets\\|glob\\|global\\|history\\|if\\|incr\\|info\\|join\\|lappend\\|lindex\\|linsert\\|list\\|llength\\|lrange\\|lreplace\\|lsearch\\|lsort\\|open\\|pid\\|proc\\|puts\\|pwd\\|read\\|regexp\\|regsub\\|rename\\|return\\|scan\\|seek\\|set\\|source\\|split\\|string\\|switch\\|tell\\|time\\|trace\\|unknown\\|unset\\|uplevel\\|upvar\\|while\\)\\>[^_]" 1 keyword) ; tcl keywords
+     ("[^_]\\<\\(after\\|bell\\|bind\\|bindtags\\|clipboard\\|destroy\\|fileevent\\|focus\\|grab\\|image\\|lower\\|option\\|pack\\|place\\|raise\\|scale\\|selection\\|send\\|subst\\|tk\\|tk_popup\\|tkwait\\|update\\|winfo\\|wm\\)\\>[^_]" 1 define) ; tk keywords
+     ("[^_]\\<\\(button\\|canvas\\|checkbutton\\|entry\\|frame\\|label\\|listbox\\|menu\\|menubutton\\|message\\|radiobutton\\|scrollbar\\|text\\|toplevel\\)\\>[^_]" 1 decl) ; tk widgets
+     ("[^_]\\<\\(tix\\((ButtonBox\\|Baloon\\|Control\\|DirList\\|ExFileSelectBox\\|ExFileSelectDialog\\|FileEntry\\|HList\\|LabelEntry\\|LabelFrame\\|NoteBook\\|OptionMenu\\|PanedWindow\\|PopupMenu\\|ScrolledHList\\|ScrolledText\\|ScrolledWindow\\|Select\\|StdButtonBox\\)\\)\\>[^_]" 1 defun) ; tix widgets
+     ("[{}\\\"\\(\\)]" nil include) ; misc punctuation
+     )))
 
 (defun tcl-electric-hash (&optional count)
   "Insert a `#' and quote if it does not start a real comment.