diff --git a/src/character.c b/src/character.c index b17f44b1422..8920da2748f 100644 --- a/src/character.c +++ b/src/character.c @@ -289,15 +289,18 @@ char_width (int c, struct Lisp_Char_Table *dp) if (VECTORP (disp)) for (i = 0, width = 0; i < ASIZE (disp); i++) { - int c; + int c = -1; ch = AREF (disp, i); if (GLYPH_CODE_P (ch)) c = GLYPH_CODE_CHAR (ch); else if (CHARACTERP (ch)) c = XFASTINT (ch); - int w = CHARACTER_WIDTH (c); - if (INT_ADD_WRAPV (width, w, &width)) - string_overflow (); + if (c >= 0) + { + int w = CHARACTER_WIDTH (c); + if (INT_ADD_WRAPV (width, w, &width)) + string_overflow (); + } } } return width; diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el new file mode 100644 index 00000000000..7199470ea96 --- /dev/null +++ b/test/lisp/wdired-tests.el @@ -0,0 +1,105 @@ +;;; wdired-tests.el --- tests for wdired.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Code: + +(require 'ert) +(require 'dired) + +(ert-deftest wdired-test-bug32173-01 () + "Test using non-nil wdired-use-interactive-rename. +Partially modifying a file name should succeed." + (let* ((test-dir (make-temp-file "test-dir-" t)) + (test-file (concat (file-name-as-directory test-dir) "foo.c")) + (replace "bar") + (new-file (replace-regexp-in-string "foo" replace test-file)) + (wdired-use-interactive-rename t)) + (write-region "" nil test-file nil 'silent) + (advice-add 'dired-query ; Don't ask confirmation to overwrite a file. + :override + (lambda (_sym _prompt &rest _args) (setq dired-query t)) + '((name . "advice-dired-query"))) + (let ((buf (find-file-noselect test-dir))) + (unwind-protect + (with-current-buffer buf + (should (equal (dired-file-name-at-point) test-file)) + (dired-toggle-read-only) + (kill-region (point) (progn (search-forward ".") + (forward-char -1) (point))) + (insert replace) + (wdired-finish-edit) + (should (equal (dired-file-name-at-point) new-file))) + (if buf (kill-buffer buf)) + (delete-directory test-dir t))))) + +(ert-deftest wdired-test-bug32173-02 () + "Test using non-nil wdired-use-interactive-rename. +Aborting an edit should leaving original file name unchanged." + (let* ((test-dir (make-temp-file "test-dir-" t)) + (test-file (concat (file-name-as-directory test-dir) "foo.c")) + (wdired-use-interactive-rename t)) + (write-region "" nil test-file nil 'silent) + ;; Make dired-do-create-files-regexp a noop to mimic typing C-g + ;; at its prompt before wdired-finish-edit returns. + (advice-add 'dired-do-create-files-regexp + :override + (lambda (&rest _) (ignore)) + '((name . "advice-dired-do-create-files-regexp"))) + (let ((buf (find-file-noselect test-dir))) + (unwind-protect + (with-current-buffer buf + (should (equal (dired-file-name-at-point) test-file)) + (dired-toggle-read-only) + (kill-region (point) (progn (search-forward ".") + (forward-char -1) (point))) + (insert "bar") + (wdired-finish-edit) + (should (equal (dired-get-filename) test-file))) + (if buf (kill-buffer buf)) + (delete-directory test-dir t))))) + +(ert-deftest wdired-test-unfinished-edit-01 () + "Test editing a file name without saving the change. +Finding the new name should be possible while still in +wdired-mode." + :expected-result (if (< emacs-major-version 27) :failed :passed) + (let* ((test-dir (make-temp-file "test-dir-" t)) + (test-file (concat (file-name-as-directory test-dir) "foo.c")) + (replace "bar") + (new-file (replace-regexp-in-string "foo" replace test-file))) + (write-region "" nil test-file nil 'silent) + (let ((buf (find-file-noselect test-dir))) + (unwind-protect + (with-current-buffer buf + (should (equal (dired-file-name-at-point) test-file)) + (dired-toggle-read-only) + (kill-region (point) (progn (search-forward ".") + (forward-char -1) (point))) + (insert replace) + (should (equal (dired-get-filename) new-file)))) + (when buf + (with-current-buffer buf + ;; Prevent kill-buffer-query-functions from chiming in. + (set-buffer-modified-p nil) + (kill-buffer buf))) + (delete-directory test-dir t)))) + + +(provide 'wdired-tests) +;;; wdired-tests.el ends here