Preserve point in pascal-mode completion (bug#41740)
Failure to do so caused errors in several cases. Reported by Shinichi Sakata. * lisp/progmodes/pascal.el (pascal-type-completion) (pascal-completion): Wrap code that may move point in save-excursion. * test/lisp/progmodes/pascal-tests.el: New file.
This commit is contained in:
parent
ce4ec17930
commit
73daab9991
2 changed files with 82 additions and 24 deletions
|
@ -1170,26 +1170,27 @@ indent of the current line in parameterlist."
|
|||
|
||||
(defun pascal-type-completion (pascal-str)
|
||||
"Calculate all possible completions for types."
|
||||
(let ((start (point))
|
||||
(pascal-all ())
|
||||
goon)
|
||||
;; Search for all reachable type declarations
|
||||
(while (or (pascal-beg-of-defun)
|
||||
(setq goon (not goon)))
|
||||
(save-excursion
|
||||
(if (and (< start (prog1 (save-excursion (pascal-end-of-defun)
|
||||
(point))
|
||||
(forward-char 1)))
|
||||
(re-search-forward
|
||||
"\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
|
||||
start t)
|
||||
(not (match-end 1)))
|
||||
;; Check current type declaration
|
||||
(setq pascal-all
|
||||
(nconc (pascal-get-completion-decl pascal-str)
|
||||
pascal-all)))))
|
||||
(save-excursion
|
||||
(let ((start (point))
|
||||
(pascal-all ())
|
||||
goon)
|
||||
;; Search for all reachable type declarations
|
||||
(while (or (pascal-beg-of-defun)
|
||||
(setq goon (not goon)))
|
||||
(save-excursion
|
||||
(if (and (< start (prog1 (save-excursion (pascal-end-of-defun)
|
||||
(point))
|
||||
(forward-char 1)))
|
||||
(re-search-forward
|
||||
"\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
|
||||
start t)
|
||||
(not (match-end 1)))
|
||||
;; Check current type declaration
|
||||
(setq pascal-all
|
||||
(nconc (pascal-get-completion-decl pascal-str)
|
||||
pascal-all)))))
|
||||
|
||||
pascal-all))
|
||||
pascal-all)))
|
||||
|
||||
(defun pascal-var-completion (prefix)
|
||||
"Calculate all possible completions for variables (or constants)."
|
||||
|
@ -1263,11 +1264,13 @@ indent of the current line in parameterlist."
|
|||
(and (eq state 'defun)
|
||||
(save-excursion
|
||||
(re-search-backward ")[ \t]*:" (point-at-bol) t))))
|
||||
(if (or (eq state 'paramlist) (eq state 'defun))
|
||||
(pascal-beg-of-defun))
|
||||
(nconc
|
||||
(pascal-type-completion pascal-str)
|
||||
(pascal-keyword-completion pascal-type-keywords pascal-str)))
|
||||
(save-excursion
|
||||
(if (or (eq state 'paramlist) (eq state 'defun))
|
||||
(pascal-beg-of-defun))
|
||||
(nconc
|
||||
(pascal-type-completion pascal-str)
|
||||
(pascal-keyword-completion pascal-type-keywords
|
||||
pascal-str))))
|
||||
( ;--Starting a new statement
|
||||
(and (not (eq state 'contexp))
|
||||
(save-excursion
|
||||
|
|
55
test/lisp/progmodes/pascal-tests.el
Normal file
55
test/lisp/progmodes/pascal-tests.el
Normal file
|
@ -0,0 +1,55 @@
|
|||
;;; pascal-tests.el --- tests for pascal.el -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2020 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/>.
|
||||
|
||||
(require 'ert)
|
||||
(require 'pascal)
|
||||
|
||||
(ert-deftest pascal-completion ()
|
||||
;; Bug#41740: completion functions must preserve point.
|
||||
(let ((pascal-completion-cache nil))
|
||||
(with-temp-buffer
|
||||
(pascal-mode)
|
||||
(insert "program test; var")
|
||||
(let* ((point-before (point))
|
||||
(completions (pascal-completion "var" nil 'metadata))
|
||||
(point-after (point)))
|
||||
(should (equal completions nil))
|
||||
(should (equal point-before point-after)))))
|
||||
|
||||
(let ((pascal-completion-cache nil))
|
||||
(with-temp-buffer
|
||||
(pascal-mode)
|
||||
(insert "program test; function f(x : i")
|
||||
(let* ((point-before (point))
|
||||
(completions (pascal-completion "i" nil 'metadata))
|
||||
(point-after (point)))
|
||||
(should (equal completions nil))
|
||||
(should (equal point-before point-after)))))
|
||||
|
||||
(let ((pascal-completion-cache nil))
|
||||
(with-temp-buffer
|
||||
(pascal-mode)
|
||||
(insert "program test; function f(x : integer) : real")
|
||||
(let* ((point-before (point))
|
||||
(completions (pascal-completion "real" nil 'metadata))
|
||||
(point-after (point)))
|
||||
(should (equal completions nil))
|
||||
(should (equal point-before point-after))))))
|
||||
|
||||
(provide 'pascal-tests)
|
Loading…
Add table
Reference in a new issue