aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tromey2018-06-24 11:18:19 -0600
committerTom Tromey2018-06-24 11:33:02 -0600
commitcd5bb4bf3dbad8941d25823f398b595b8f0edbb9 (patch)
tree09ad146d785847a05fb96a998a357165176b5402
parenteaa054a94b786ce7dc4169c9b14893f50335f657 (diff)
downloademacs-cd5bb4bf3dbad8941d25823f398b595b8f0edbb9.tar.gz
emacs-cd5bb4bf3dbad8941d25823f398b595b8f0edbb9.zip
Fix two tcl-mode defun-related bugs
Fixes bug#23565 * lisp/progmodes/tcl.el (tcl-mode): Set beginning-of-defun-function and end-of-defun-function. (tcl-beginning-of-defun-function, tcl-end-of-defun-function): New defuns. * test/lisp/progmodes/tcl-tests.el: New file.
-rw-r--r--lisp/progmodes/tcl.el49
-rw-r--r--test/lisp/progmodes/tcl-tests.el68
2 files changed, 111 insertions, 6 deletions
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index 0d9322359c9..fad62e100a4 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -611,6 +611,9 @@ already exist."
611 (set (make-local-variable 'add-log-current-defun-function) 611 (set (make-local-variable 'add-log-current-defun-function)
612 'tcl-add-log-defun) 612 'tcl-add-log-defun)
613 613
614 (setq-local beginning-of-defun-function #'tcl-beginning-of-defun-function)
615 (setq-local end-of-defun-function #'tcl-end-of-defun-function)
616
614 (easy-menu-add tcl-mode-menu) 617 (easy-menu-add tcl-mode-menu)
615 ;; Append Tcl menu to popup menu for XEmacs. 618 ;; Append Tcl menu to popup menu for XEmacs.
616 (if (boundp 'mode-popup-menu) 619 (if (boundp 'mode-popup-menu)
@@ -993,15 +996,49 @@ Returns nil if line starts inside a string, t if in a comment."
993;; Interfaces to other packages. 996;; Interfaces to other packages.
994;; 997;;
995 998
996;; FIXME Definition of function is very ad-hoc. Should use 999(defun tcl-beginning-of-defun-function (&optional arg)
997;; beginning-of-defun. Also has incestuous knowledge about the 1000 "`beginning-of-defun-function' for Tcl mode."
998;; format of tcl-proc-regexp. 1001 (when (or (not arg) (= arg 0))
1002 (setq arg 1))
1003 (let* ((search-fn (if (> arg 0)
1004 ;; Positive arg means to search backward.
1005 #'re-search-backward
1006 #'re-search-forward))
1007 (arg (abs arg))
1008 (result t))
1009 (while (and (> arg 0) result)
1010 (unless (funcall search-fn tcl-proc-regexp nil t)
1011 (setq result nil))
1012 (setq arg (1- arg)))
1013 result))
1014
1015(defun tcl-end-of-defun-function ()
1016 "`end-of-defun-function' for Tcl mode."
1017 ;; Because we let users redefine tcl-proc-list, we don't really know
1018 ;; too much about the exact arguments passed to the "proc"-defining
1019 ;; command. Instead we just skip words and lists until we see
1020 ;; either a ";" or a newline, either of which terminates a command.
1021 (skip-syntax-forward "-")
1022 (while (and (not (eobp))
1023 (not (looking-at-p "[\n;]")))
1024 (condition-case nil
1025 (forward-sexp)
1026 (scan-error
1027 (goto-char (point-max))))
1028 ;; Note that here we do not want to skip \n.
1029 (skip-chars-forward " \t")))
1030
999(defun tcl-add-log-defun () 1031(defun tcl-add-log-defun ()
1000 "Return name of Tcl function point is in, or nil." 1032 "Return name of Tcl function point is in, or nil."
1001 (save-excursion 1033 (save-excursion
1002 (end-of-line) 1034 (let ((orig-point (point)))
1003 (if (re-search-backward (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t) 1035 (when (beginning-of-defun)
1004 (match-string 2)))) 1036 ;; Only return the name when in the body of the function.
1037 (when (save-excursion
1038 (end-of-defun)
1039 (>= (point) orig-point))
1040 (when (looking-at (concat tcl-proc-regexp "\\([^ \t\n{]+\\)"))
1041 (match-string 2)))))))
1005 1042
1006(defun tcl-outline-level () 1043(defun tcl-outline-level ()
1007 (save-excursion 1044 (save-excursion
diff --git a/test/lisp/progmodes/tcl-tests.el b/test/lisp/progmodes/tcl-tests.el
new file mode 100644
index 00000000000..55211b70be2
--- /dev/null
+++ b/test/lisp/progmodes/tcl-tests.el
@@ -0,0 +1,68 @@
1;;; tcl-tests.el --- Test suite for tcl-mode
2
3;; Copyright (C) 2018 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software: you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20;;; Commentary:
21
22;;; Code:
23
24(require 'ert)
25(require 'tcl)
26
27;; From bug#23565
28(ert-deftest tcl-mode-beginning-of-defun-1 ()
29 (with-temp-buffer
30 (tcl-mode)
31 (insert "proc bad {{value \"\"}} {\n # do something\n}")
32 (should (beginning-of-defun))
33 (should (= (point) (point-min)))
34 (end-of-defun)
35 (should (= (point) (point-max)))))
36
37;; From bug#23565
38(ert-deftest tcl-mode-beginning-of-defun-2 ()
39 (with-temp-buffer
40 (tcl-mode)
41 (insert "proc good {{value}} {\n # do something\n}")
42 (should (beginning-of-defun))
43 (should (= (point) (point-min)))
44 (end-of-defun)
45 (should (= (point) (point-max)))))
46
47(ert-deftest tcl-mode-function-name ()
48 (with-temp-buffer
49 (tcl-mode)
50 (insert "proc notinthis {} {\n # nothing\n}\n\n")
51 (should-not (add-log-current-defun))))
52
53(ert-deftest tcl-mode-function-name ()
54 (with-temp-buffer
55 (tcl-mode)
56 (insert "proc simple {} {\n # nothing\n}")
57 (backward-char 3)
58 (should (equal "simple" (add-log-current-defun)))))
59
60(ert-deftest tcl-mode-function-name ()
61 (with-temp-buffer
62 (tcl-mode)
63 (insert "proc inthis {} {\n # nothing\n")
64 (should (equal "inthis" (add-log-current-defun)))))
65
66(provide 'tcl-tests)
67
68;;; tcl-tests.el ends here