1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-18 10:16:51 +00:00

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.
This commit is contained in:
Tom Tromey 2018-06-24 11:18:19 -06:00
parent eaa054a94b
commit cd5bb4bf3d
2 changed files with 111 additions and 6 deletions

View File

@ -611,6 +611,9 @@ already exist."
(set (make-local-variable 'add-log-current-defun-function)
'tcl-add-log-defun)
(setq-local beginning-of-defun-function #'tcl-beginning-of-defun-function)
(setq-local end-of-defun-function #'tcl-end-of-defun-function)
(easy-menu-add tcl-mode-menu)
;; Append Tcl menu to popup menu for XEmacs.
(if (boundp 'mode-popup-menu)
@ -993,15 +996,49 @@ Returns nil if line starts inside a string, t if in a comment."
;; Interfaces to other packages.
;;
;; FIXME Definition of function is very ad-hoc. Should use
;; beginning-of-defun. Also has incestuous knowledge about the
;; format of tcl-proc-regexp.
(defun tcl-beginning-of-defun-function (&optional arg)
"`beginning-of-defun-function' for Tcl mode."
(when (or (not arg) (= arg 0))
(setq arg 1))
(let* ((search-fn (if (> arg 0)
;; Positive arg means to search backward.
#'re-search-backward
#'re-search-forward))
(arg (abs arg))
(result t))
(while (and (> arg 0) result)
(unless (funcall search-fn tcl-proc-regexp nil t)
(setq result nil))
(setq arg (1- arg)))
result))
(defun tcl-end-of-defun-function ()
"`end-of-defun-function' for Tcl mode."
;; Because we let users redefine tcl-proc-list, we don't really know
;; too much about the exact arguments passed to the "proc"-defining
;; command. Instead we just skip words and lists until we see
;; either a ";" or a newline, either of which terminates a command.
(skip-syntax-forward "-")
(while (and (not (eobp))
(not (looking-at-p "[\n;]")))
(condition-case nil
(forward-sexp)
(scan-error
(goto-char (point-max))))
;; Note that here we do not want to skip \n.
(skip-chars-forward " \t")))
(defun tcl-add-log-defun ()
"Return name of Tcl function point is in, or nil."
(save-excursion
(end-of-line)
(if (re-search-backward (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
(match-string 2))))
(let ((orig-point (point)))
(when (beginning-of-defun)
;; Only return the name when in the body of the function.
(when (save-excursion
(end-of-defun)
(>= (point) orig-point))
(when (looking-at (concat tcl-proc-regexp "\\([^ \t\n{]+\\)"))
(match-string 2)))))))
(defun tcl-outline-level ()
(save-excursion

View File

@ -0,0 +1,68 @@
;;; tcl-tests.el --- Test suite for tcl-mode
;; Copyright (C) 2018 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(require 'ert)
(require 'tcl)
;; From bug#23565
(ert-deftest tcl-mode-beginning-of-defun-1 ()
(with-temp-buffer
(tcl-mode)
(insert "proc bad {{value \"\"}} {\n # do something\n}")
(should (beginning-of-defun))
(should (= (point) (point-min)))
(end-of-defun)
(should (= (point) (point-max)))))
;; From bug#23565
(ert-deftest tcl-mode-beginning-of-defun-2 ()
(with-temp-buffer
(tcl-mode)
(insert "proc good {{value}} {\n # do something\n}")
(should (beginning-of-defun))
(should (= (point) (point-min)))
(end-of-defun)
(should (= (point) (point-max)))))
(ert-deftest tcl-mode-function-name ()
(with-temp-buffer
(tcl-mode)
(insert "proc notinthis {} {\n # nothing\n}\n\n")
(should-not (add-log-current-defun))))
(ert-deftest tcl-mode-function-name ()
(with-temp-buffer
(tcl-mode)
(insert "proc simple {} {\n # nothing\n}")
(backward-char 3)
(should (equal "simple" (add-log-current-defun)))))
(ert-deftest tcl-mode-function-name ()
(with-temp-buffer
(tcl-mode)
(insert "proc inthis {} {\n # nothing\n")
(should (equal "inthis" (add-log-current-defun)))))
(provide 'tcl-tests)
;;; tcl-tests.el ends here