From f6c359cb66a0e9b851e3467b1ba9cab7efa8f744 Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Thu, 31 Oct 2024 10:46:27 +0100 Subject: [PATCH] Fix bugs in dabbrev-expand (bug#74090) * lisp/dabbrev.el (dabbrev-expand): Use the buffer where the expansion was found when setting the internal variables used to determine the next expansion or a replacement expansion. * test/lisp/dabbrev-tests.el (ert-x): Require for 'ert-with-temp-directory', 'ert-resource-directory' and 'ert-resource-file'. (with-dabbrev-test): New macro. (dabbrev-expand-test-same-buffer-{1,2,3,4}) (dabbrev-expand-test-other-buffer-{1,2,3,4}) (dabbrev-expand-test-minibuffer-{1,2,3,4}): New tests. * test/lisp/dabbrev-resources/dabbrev-expand.el: * test/lisp/dabbrev-resources/INSTALL_BEGIN: New test resources. --- lisp/dabbrev.el | 65 ++++-- test/lisp/dabbrev-resources/INSTALL_BEGIN | 153 +++++++++++++ test/lisp/dabbrev-resources/dabbrev-expand.el | 132 +++++++++++ test/lisp/dabbrev-tests.el | 207 ++++++++++++++++++ 4 files changed, 542 insertions(+), 15 deletions(-) create mode 100644 test/lisp/dabbrev-resources/INSTALL_BEGIN create mode 100644 test/lisp/dabbrev-resources/dabbrev-expand.el diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index 7b6cbb78cef..bbe6a64b626 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -464,8 +464,21 @@ direction of search to backward if set non-nil. See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (interactive "*P") - (let (abbrev record-case-pattern - expansion old direction (orig-point (point))) + ;; There are three possible sources of the expansion, which we need to + ;; check in a specific order: + (let ((buf (cond ((window-minibuffer-p) + ;; If we invoked dabbrev-expand in the minibuffer, + ;; this is the buffer from which we entered the + ;; minibuffer. + (window-buffer (get-mru-window))) + ;; Otherwise, if we found the expansion in another + ;; buffer, use that buffer for further expansions. + (dabbrev--last-buffer-found dabbrev--last-buffer-found) + ;; Otherwise, use the buffer where we invoked + ;; dabbrev-expand. + (t (current-buffer)))) + abbrev record-case-pattern expansion old direction + (orig-point (point))) ;; abbrev -- the abbrev to expand ;; expansion -- the expansion found (eventually) or nil until then ;; old -- the text currently in the buffer @@ -480,6 +493,7 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (point))))) ;; Find a different expansion for the same abbrev as last time. (progn + (setq dabbrev--last-buffer-found nil) (setq abbrev dabbrev--last-abbreviation) (setq old dabbrev--last-expansion) (setq direction dabbrev--last-direction)) @@ -488,7 +502,14 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (if (and (eq (preceding-char) ?\s) (markerp dabbrev--last-abbrev-location) (marker-position dabbrev--last-abbrev-location) - (= (point) (1+ dabbrev--last-abbrev-location))) + ;; Comparing with point only makes sense in the buffer + ;; where we called dabbrev-expand, but if that differs + ;; from the buffer containing the expansion, we want to + ;; get the next word in the latter buffer, so we skip + ;; the comparison. + (if (eq buf (current-buffer)) + (= (point) (1+ dabbrev--last-abbrev-location)) + t)) (progn ;; The "abbrev" to expand is just the space. (setq abbrev " ") @@ -549,29 +570,43 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (if old " further" "") abbrev)) (t (if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found) - (minibuffer-window-active-p (selected-window)))) + ;; If we are in the minibuffer and an expansion has + ;; been found but dabbrev--last-buffer-found is not + ;; yet set, we need to set it now. + (and dabbrev--last-buffer-found + (minibuffer-window-active-p (selected-window))))) (progn (when (buffer-name dabbrev--last-buffer) (message "Expansion found in `%s'" (buffer-name dabbrev--last-buffer))) (setq dabbrev--last-buffer-found dabbrev--last-buffer)) (message nil)) - (if (and (or (eq (current-buffer) dabbrev--last-buffer) - (null dabbrev--last-buffer) - (buffer-live-p dabbrev--last-buffer)) - (numberp dabbrev--last-expansion-location) - (and (> dabbrev--last-expansion-location (point)))) - (setq dabbrev--last-expansion-location - (copy-marker dabbrev--last-expansion-location))) + ;; To get correct further expansions we have to be sure to use the + ;; buffer containing the already found expansions. + (when dabbrev--last-buffer-found + (setq buf dabbrev--last-buffer-found)) + ;; If the buffer where we called dabbrev-expand differs from the + ;; buffer containing the expansion, make sure copy-marker is + ;; called in the latter buffer. + (with-current-buffer buf + (if (and (or (eq (current-buffer) dabbrev--last-buffer) + (null dabbrev--last-buffer) + (buffer-live-p dabbrev--last-buffer)) + (numberp dabbrev--last-expansion-location) + (and (> dabbrev--last-expansion-location (point)))) + (setq dabbrev--last-expansion-location + (copy-marker dabbrev--last-expansion-location)))) ;; Success: stick it in and return. (setq buffer-undo-list (cons orig-point buffer-undo-list)) (setq expansion (dabbrev--substitute-expansion old abbrev expansion record-case-pattern)) - ;; Save state for re-expand. - (setq dabbrev--last-expansion expansion) - (setq dabbrev--last-abbreviation abbrev) - (setq dabbrev--last-abbrev-location (point-marker)))))) + ;; Save state for re-expand (making sure it's the state of the + ;; buffer containing the already found expansions). + (with-current-buffer buf + (setq dabbrev--last-expansion expansion) + (setq dabbrev--last-abbreviation abbrev) + (setq dabbrev--last-abbrev-location (point-marker))))))) ;;---------------------------------------------------------------- ;; Local functions diff --git a/test/lisp/dabbrev-resources/INSTALL_BEGIN b/test/lisp/dabbrev-resources/INSTALL_BEGIN new file mode 100644 index 00000000000..6309419dccf --- /dev/null +++ b/test/lisp/dabbrev-resources/INSTALL_BEGIN @@ -0,0 +1,153 @@ +GNU Emacs Installation Guide +Copyright (C) 1992, 1994, 1996-1997, 2000-2024 Free Software Foundation, +Inc. +See the end of the file for license conditions. + + +This file contains general information on building GNU Emacs. If you +are building an Emacs release tarball on a Unix or a GNU system, the +instructions in this file should be sufficient. For other +configurations, we have additional specialized files: + + . INSTALL.REPO if you build from a Git checkout + . nt/INSTALL if you build for MS-Windows + . nextstep/INSTALL if you build for GNUstep/macOS + . java/INSTALL if you build for Android + . msdos/INSTALL if you build for MS-DOS + + +BASIC INSTALLATION + +On most Unix systems, you build Emacs by first running the 'configure' +shell script. This attempts to deduce the correct values for +various system-dependent variables and features, and find the +directories where certain system headers and libraries are kept. +In a few cases, you may need to explicitly tell configure where to +find some things, or what options to use. + +'configure' creates a 'Makefile' in several subdirectories, and a +'src/config.h' file containing system-dependent definitions. +Running the 'make' utility then builds the package for your system. + +Building Emacs requires GNU make, . +On most systems that Emacs supports, this is the default 'make' program. + +Here's the procedure to build Emacs using 'configure' on systems which +are supported by it. In some cases, if the simplified procedure fails, +you might need to use various non-default options, and maybe perform +some of the steps manually. The more detailed description in the other +sections of this guide will help you do that, so please refer to those +sections if you need to. + + 1. Obtain and unpack the Emacs release, with commands like this: + + wget https://ftp.gnu.org/gnu/emacs/emacs-VERSION.tar.xz + tar -xf emacs-VERSION.tar.xz + + where VERSION is the Emacs version number. + + 2a. 'cd' to the directory where you unpacked Emacs and invoke the + 'configure' script: + + ./configure + + 2b. Alternatively, create a separate directory, outside the source + directory, where you want to build Emacs, and invoke 'configure' + from there: + + SOURCE-DIR/configure + + where SOURCE-DIR is the top-level Emacs source directory. + + 2c. If you don't have write access to the default directory where + Emacs and its data files will be installed, specify an alternative + installation directory: + + ./configure --prefix=/SOME/OTHER/DIRECTORY + + where /SOME/OTHER/DIRECTORY is a directory writable by your user, + for example, a subdirectory of your home directory. + + 3. When 'configure' finishes, it prints several lines of details + about the system configuration. Read those details carefully + looking for anything suspicious, such as wrong CPU and operating + system names, wrong places for headers or libraries, missing + libraries that you know are installed on your system, etc. + + If you find anything wrong, you may have to pass to 'configure' + one or more options specifying the explicit machine configuration + name, where to find various headers and libraries, etc. + Refer to the section DETAILED BUILDING AND INSTALLATION below. + + If 'configure' didn't find some image support libraries, such as + Xpm and jpeg, refer to "Image support libraries" below. + + If the details printed by 'configure' don't make any sense to + you, but there are no obvious errors, assume that 'configure' did + its job and proceed. + + 4. Invoke the 'make' program: + + make + + 5. If 'make' succeeds, it will build an executable program 'emacs' + in the 'src' directory. You can try this program, to make sure + it works: + + src/emacs -Q + + To test Emacs further (intended mostly to help developers): + + make check + + 6. Assuming that the program 'src/emacs' starts and displays its + opening screen, you can install the program and its auxiliary + files into their installation directories: + + make install + + You are now ready to use Emacs. If you wish to conserve space, + you may remove the program binaries and object files from the + directory where you built Emacs: + + make clean + + You can delete the entire build directory if you do not plan to + build Emacs again, but it can be useful to keep for debugging. + If you want to build Emacs again with different configure options, + first clean the source directories: + + make distclean + + Note that the install automatically saves space by compressing + (provided you have the 'gzip' program) those installed Lisp source (.el) + files that have corresponding .elc versions, as well as the Info files. + + You can read a brief summary about common make targets: + + make help + + +ADDITIONAL DISTRIBUTION FILES + +* Complex Text Layout support libraries + +On GNU and Unix systems, Emacs needs optional libraries to correctly +display such complex scripts as Indic and Khmer, and also for scripts +that require Arabic shaping support (Arabic and Farsi). If the +HarfBuzz library is installed, Emacs will build with it and use it for +this purpose. HarfBuzz is the preferred shaping engine, both on Posix +hosts and on MS-Windows, so we recommend installing it before building +Emacs. The alternative for GNU/Linux and Posix systems is to use the +"m17n-db", "libm17n-flt", and "libotf" libraries. (On some systems, +particularly GNU/Linux, these libraries may be already present or +available as additional packages.) Note that if there is a separate +'dev' or 'devel' package, for use at compilation time rather than run +time, you will need that as well as the corresponding run time +package; typically the dev package will contain header files and a +library archive. On MS-Windows, if HarfBuzz is not available, Emacs +will use the Uniscribe shaping engine that is part of the OS. + +Note that Emacs cannot support complex scripts on a TTY, unless the +terminal includes such a support. However, most modern terminal +emulators, such as xterm, do support such scripts. diff --git a/test/lisp/dabbrev-resources/dabbrev-expand.el b/test/lisp/dabbrev-resources/dabbrev-expand.el new file mode 100644 index 00000000000..c986b0ed633 --- /dev/null +++ b/test/lisp/dabbrev-resources/dabbrev-expand.el @@ -0,0 +1,132 @@ +(defun dabbrev-expand (arg) + "Expand previous word \"dynamically\". + +Expands to the most recent, preceding word for which this is a prefix. +If no suitable preceding word is found, words following point are +considered. If still no suitable word is found, then look in the +buffers accepted by the function pointed out by variable +`dabbrev-friend-buffer-function', if `dabbrev-check-other-buffers' +says so. Then, if `dabbrev-check-all-buffers' is non-nil, look in +all the other buffers, subject to constraints specified +by `dabbrev-ignored-buffer-names' and `dabbrev-ignored-buffer-regexps'. + +A positive prefix argument, N, says to take the Nth backward *distinct* +possibility. A negative argument says search forward. + +If the cursor has not moved from the end of the previous expansion and +no argument is given, replace the previously-made expansion +with the next possible expansion not yet tried. + +The variable `dabbrev-backward-only' may be used to limit the +direction of search to backward if set non-nil. + +See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." + (interactive "*P") + (let (abbrev record-case-pattern + expansion old direction (orig-point (point))) + ;; abbrev -- the abbrev to expand + ;; expansion -- the expansion found (eventually) or nil until then + ;; old -- the text currently in the buffer + ;; (the abbrev, or the previously-made expansion) + (save-excursion + (if (and (null arg) + (markerp dabbrev--last-abbrev-location) + (marker-position dabbrev--last-abbrev-location) + (or (eq last-command this-command) + (and (window-minibuffer-p) + (= dabbrev--last-abbrev-location + (point))))) + ;; Find a different expansion for the same abbrev as last time. + (progn + (setq abbrev dabbrev--last-abbreviation) + (setq old dabbrev--last-expansion) + (setq direction dabbrev--last-direction)) + ;; If the user inserts a space after expanding + ;; and then asks to expand again, always fetch the next word. + (if (and (eq (preceding-char) ?\s) + (markerp dabbrev--last-abbrev-location) + (marker-position dabbrev--last-abbrev-location) + (= (point) (1+ dabbrev--last-abbrev-location))) + (progn + ;; The "abbrev" to expand is just the space. + (setq abbrev " ") + (save-excursion + (save-restriction + (widen) + (if (buffer-live-p dabbrev--last-buffer) + (set-buffer dabbrev--last-buffer)) + ;; Find the end of the last "expansion" word. + (if (or (eq dabbrev--last-direction 1) + (and (eq dabbrev--last-direction 0) + (< dabbrev--last-expansion-location (point)))) + (setq dabbrev--last-expansion-location + (+ dabbrev--last-expansion-location + (length dabbrev--last-expansion)))) + (goto-char dabbrev--last-expansion-location) + ;; Take the following word, with intermediate separators, + ;; as our expansion this time. + (re-search-forward + (concat "\\(?:" dabbrev--abbrev-char-regexp "\\)+")) + (setq expansion (buffer-substring-no-properties + dabbrev--last-expansion-location (point))) + + ;; Record the end of this expansion, in case we repeat this. + (setq dabbrev--last-expansion-location (point)))) + ;; Indicate that dabbrev--last-expansion-location is + ;; at the end of the expansion. + (setq dabbrev--last-direction -1)) + + ;; We have a different abbrev to expand. + (dabbrev--reset-global-variables) + (setq direction (if (null arg) + (if dabbrev-backward-only 1 0) + (prefix-numeric-value arg))) + (setq abbrev (dabbrev--abbrev-at-point)) + (setq record-case-pattern t) + (setq old nil))) + + ;;-------------------------------- + ;; Find the expansion + ;;-------------------------------- + (or expansion + (setq expansion + (dabbrev--find-expansion + abbrev direction + (dabbrev--ignore-case-p abbrev))))) + (cond + ((not expansion) + (dabbrev--reset-global-variables) + (if old + (save-excursion + (setq buffer-undo-list (cons orig-point buffer-undo-list)) + ;; Put back the original abbrev with its original case pattern. + (search-backward old) + (insert abbrev) + (delete-region (point) (+ (point) (length old))))) + (user-error "No%s dynamic expansion for `%s' found" + (if old " further" "") abbrev)) + (t + (if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found) + (minibuffer-window-active-p (selected-window)))) + (progn + (when (buffer-name dabbrev--last-buffer) + (message "Expansion found in `%s'" + (buffer-name dabbrev--last-buffer))) + (setq dabbrev--last-buffer-found dabbrev--last-buffer)) + (message nil)) + (if (and (or (eq (current-buffer) dabbrev--last-buffer) + (null dabbrev--last-buffer) + (buffer-live-p dabbrev--last-buffer)) + (numberp dabbrev--last-expansion-location) + (and (> dabbrev--last-expansion-location (point)))) + (setq dabbrev--last-expansion-location + (copy-marker dabbrev--last-expansion-location))) + ;; Success: stick it in and return. + (setq buffer-undo-list (cons orig-point buffer-undo-list)) + (setq expansion (dabbrev--substitute-expansion old abbrev expansion + record-case-pattern)) + + ;; Save state for re-expand. + (setq dabbrev--last-expansion expansion) + (setq dabbrev--last-abbreviation abbrev) + (setq dabbrev--last-abbrev-location (point-marker)))))) diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el index c7574403949..987106aa5af 100644 --- a/test/lisp/dabbrev-tests.el +++ b/test/lisp/dabbrev-tests.el @@ -25,6 +25,7 @@ ;;; Code: (require 'ert) +(require 'ert-x) (require 'dabbrev) (ert-deftest dabbrev-expand-test () @@ -68,4 +69,210 @@ multiple expansions." (execute-kbd-macro (kbd "C-u C-u C-M-/"))) (should (string= (buffer-string) "abc\na"))))) +(defmacro with-dabbrev-test (&rest body) + "Set up an isolated `dabbrev' test environment." + (declare (debug (body))) + `(ert-with-temp-directory dabbrev-test-home + (let* (;; Since we change HOME, clear this to avoid a conflict + ;; e.g. if Emacs runs within the user's home directory. + (abbreviated-home-dir nil) + (process-environment (cons (format "HOME=%s" dabbrev-test-home) + process-environment)) + (dabbrev-directory (ert-resource-directory))) + (unwind-protect + (progn ,@body) + ;; Restore pre-test-run state of test files. + (dolist (f (directory-files dabbrev-directory)) + (let ((buf (get-file-buffer f))) + (when buf + (with-current-buffer buf + (restore-buffer-modified-p nil) + (kill-buffer))))) + (dabbrev--reset-global-variables))))) + +(ert-deftest dabbrev-expand-test-same-buffer-1 () + "Test expanding a string twice within a single buffer. +The first expansion should expand the input (a prefix-string) to a +string in the buffer containing no whitespace character, the second +expansion, after adding a space to the first expansion, should extend +the string with the following string in the buffer up to the next +whitespace character." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-max)) + (terpri) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic and")))) + +(ert-deftest dabbrev-expand-test-same-buffer-2 () + "Test expanding a string plus space twice within a single buffer. +Each expansion should extend the string with the following string in the +buffer up to the next whitespace character." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-max)) + (terpri) + (execute-kbd-macro (kbd "Indic SPC M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic and")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic and Khmer")))) + +(ert-deftest dabbrev-expand-test-same-buffer-3 () + "Test replacing an expansion within a single buffer." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-max)) + (terpri) + (insert-file-contents (ert-resource-file "dabbrev-expand.el")) + (goto-char (point-max)) + (terpri) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indicate")) + (kill-whole-line) + (execute-kbd-macro (kbd "Ind M-/ M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic and")))) + +(ert-deftest dabbrev-expand-test-same-buffer-4 () + "Test expanding a string in a narrowed-region." + (with-dabbrev-test + (let (disabled-command-function) ; Enable narrow-to-region. + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-min)) + (execute-kbd-macro (kbd "C-s Ind M-a C-SPC M-} C-x n n")) + (goto-char (point-max)) + (terpri) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-substring (pos-bol) (pos-eol)) "Indic and"))))) + +(ert-deftest dabbrev-expand-test-other-buffer-1 () + "Test expanding a prefix string to a string from another buffer." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (switch-to-buffer (get-buffer-create "a" t)) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-string) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-string) "Indic and")) + (kill-buffer "a"))) + +(ert-deftest dabbrev-expand-test-other-buffer-2 () + "Test expanding a string + space to a string from another buffer." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (switch-to-buffer (get-buffer-create "a" t)) + (execute-kbd-macro (kbd "Indic SPC M-/")) + (should (string= (buffer-string) "Indic and")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-string) "Indic and Khmer")) + (kill-buffer "a"))) + +(ert-deftest dabbrev-expand-test-other-buffer-3 () + "Test replacing an expansion with three different buffers. +A prefix string in a buffer should find the first expansion in a +different buffer and then find a replacement expansion is yet another +buffer." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (find-file (ert-resource-file "dabbrev-expand.el")) + (switch-to-buffer (get-buffer-create "a" t)) + (emacs-lisp-mode) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-string) "Indicate")) + (erase-buffer) + (execute-kbd-macro (kbd "Ind M-/ M-/")) + (should (string= (buffer-string) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-string) "Indic and")) + (kill-buffer "a"))) + +(ert-deftest dabbrev-expand-test-other-buffer-4 () + "Test expanding a string using another narrowed buffer." + (with-dabbrev-test + (let (disabled-command-function) ; Enable narrow-to-region. + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-min)) + (execute-kbd-macro (kbd "C-s Ind M-a C-SPC M-} C-x n n")) + (switch-to-buffer (get-buffer-create "a" t)) + (execute-kbd-macro (kbd "Ind M-/")) + (should (string= (buffer-string) "Indic")) + (execute-kbd-macro (kbd "SPC M-/")) + (should (string= (buffer-string) "Indic and")) + (kill-buffer "a")))) + +(ert-deftest dabbrev-expand-test-minibuffer-1 () + "Test expanding a prefix string twice in the minibuffer. +Both expansions should come from the buffer from which the minibuffer +was entered." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (with-selected-window (minibuffer-window) + (insert "Ind") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic")) + (insert " ") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic and")) + (delete-minibuffer-contents)))) + +(ert-deftest dabbrev-expand-test-minibuffer-2 () + "Test expanding a string + space in the minibuffer. +The expansions should come from the buffer from which the minibuffer was +entered." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (with-selected-window (minibuffer-window) + (insert "Indic ") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic and")) + (insert " ") + (dabbrev-expand nil) + (should (string= (buffer-string) "Indic and Khmer")) + (delete-minibuffer-contents)))) + +;; FIXME: Why is dabbrev--reset-global-variables needed here? +(ert-deftest dabbrev-expand-test-minibuffer-3 () + "Test replacing an expansion in the minibuffer using two buffers. +The first expansion should befound in the buffer from which the +minibuffer was entered, the replacement should found in another buffer." + (with-dabbrev-test + (find-file (ert-resource-file "INSTALL_BEGIN")) + (find-file (ert-resource-file "dabbrev-expand.el")) + (with-selected-window (minibuffer-window) + (insert "Ind") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indicate")) + (kill-whole-line) + (dabbrev--reset-global-variables) + (insert "Ind") + (dabbrev-expand nil) + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic")) + (dabbrev--reset-global-variables) + (insert " ") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic and")) + (delete-minibuffer-contents)))) + +(ert-deftest dabbrev-expand-test-minibuffer-4 () + "Test expansion in the minibuffer using another narrowed buffer." + (with-dabbrev-test + (let (disabled-command-function) ; Enable narrow-to-region. + (find-file (ert-resource-file "INSTALL_BEGIN")) + (goto-char (point-min)) + (execute-kbd-macro (kbd "C-s Ind M-a C-SPC M-} C-x n n"))) + (with-selected-window (minibuffer-window) + (insert "Ind") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic")) + (insert " ") + (dabbrev-expand nil) + (should (string= (minibuffer-contents) "Indic and")) + (delete-minibuffer-contents)))) + ;;; dabbrev-tests.el ends here