(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)."
(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
--- /dev/null
+;;; 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)