emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 44697457c60 2/2: Merge branch 'master' of git.sv.gnu.org:/srv/git


From: Michael Albinus
Subject: master 44697457c60 2/2: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Date: Sat, 19 Aug 2023 13:32:45 -0400 (EDT)

branch: master
commit 44697457c6048464a68b6d58a1c4cf967fd5be06
Merge: 9ecd6553ade 9e0524a8820
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>

    Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
---
 etc/NEWS                       |   9 +++
 lisp/emacs-lisp/package.el     |  76 +++++++++++++++++--
 lisp/net/dictionary.el         |  12 +--
 lisp/progmodes/eglot.el        |   3 +-
 lisp/textmodes/reftex-index.el |   6 +-
 lisp/textmodes/reftex-ref.el   |   2 +-
 lisp/textmodes/reftex-toc.el   |  31 ++------
 lisp/textmodes/reftex.el       |  38 ++++------
 lisp/wid-edit.el               |  32 +++++++-
 src/androidterm.c              |  12 +--
 src/textconv.c                 | 162 +++++++++++++++++++++--------------------
 test/lisp/cus-edit-tests.el    |  43 +++++++++++
 test/lisp/wid-edit-tests.el    |  31 ++++++++
 13 files changed, 302 insertions(+), 155 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 966d1f8c292..6588299c532 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -514,6 +514,15 @@ project, that you can quickly select using 
'project-switch-project'
 When non-nil, package specifications with side-effects for building
 software will be used when building a package.
 
+---
+*** New command to start an inferior Emacs loading only specific packages.
+The new command 'package-isolate' will start a new Emacs process, as
+a sub-process of Emacs where you invoke the command, in a way that
+causes the new process to load only some of the installed packages.
+The command prompts for the packages to activate in this
+sub-process, and is intended for testing Emacs and/or the packages
+in a clean environment.
+
 ** Flymake
 
 +++
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index b3062d2608b..e1172d69bf0 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2330,12 +2330,25 @@ from ELPA by either using `\\[package-upgrade]' or
       (mapc #'package-upgrade upgradeable))))
 
 (defun package--dependencies (pkg)
-  "Return a list of all dependencies PKG has.
-This is done recursively."
-  ;; Can we have circular dependencies?  Assume "nope".
-  (when-let* ((desc (cadr (assq pkg package-archive-contents)))
-              (deps (mapcar #'car (package-desc-reqs desc))))
-    (delete-dups (apply #'nconc deps (mapcar #'package--dependencies deps)))))
+  "Return a list of all transitive dependencies of PKG.
+If PKG is a package descriptor, the return value is a list of
+package descriptors.  If PKG is a symbol designating a package,
+the return value is a list of symbols designating packages."
+  (when-let* ((desc (if (package-desc-p pkg) pkg
+                      (cadr (assq pkg package-archive-contents)))))
+    ;; Can we have circular dependencies?  Assume "nope".
+    (let ((all (named-let more ((pkg-desc desc))
+                 (let (deps)
+                   (dolist (req (package-desc-reqs pkg-desc))
+                     (setq deps (nconc
+                                 (catch 'found
+                                   (dolist (p (apply #'append (mapcar #'cdr 
(package--alist))))
+                                     (when (and (string= (car req) 
(package-desc-name p))
+                                                (version-list-<= (cadr req) 
(package-desc-version p)))
+                                       (throw 'found (more p)))))
+                                 deps)))
+                   (delete-dups (cons pkg-desc deps))))))
+      (remq pkg (mapcar (if (package-desc-p pkg) #'identity 
#'package-desc-name) all)))))
 
 (defun package-strip-rcs-id (str)
   "Strip RCS version ID from the version string STR.
@@ -2625,6 +2638,57 @@ will be deleted."
                   removable))
         (message "Nothing to autoremove")))))
 
+(defun package-isolate (packages &optional temp-init)
+  "Start an uncustomised Emacs and only load a set of PACKAGES.
+If TEMP-INIT is non-nil, or when invoked with a prefix argument,
+the Emacs user directory is set to a temporary directory."
+  (interactive
+   (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
+           unless (package-built-in-p p)
+           collect (cons (package-desc-full-name p) p) into table
+           finally return
+           (list (cl-loop for c in (completing-read-multiple
+                                     "Isolate packages: " table
+                                     nil t)
+                          collect (alist-get c table nil nil #'string=))
+                  current-prefix-arg)))
+  (let* ((name (concat "package-isolate-"
+                       (mapconcat #'package-desc-full-name packages ",")))
+         (all-packages (delete-consecutive-dups
+                        (sort (append packages (mapcan #'package--dependencies 
packages))
+                              (lambda (p0 p1)
+                                (string< (package-desc-name p0) 
(package-desc-name p1))))))
+         initial-scratch-message package-load-list)
+    (with-temp-buffer
+      (insert ";; This is an isolated testing environment, with these packages 
enabled:\n\n")
+      (dolist (package all-packages)
+        (push (list (package-desc-name package)
+                    (package-version-join (package-desc-version package)))
+              package-load-list)
+        (insert ";; - " (package-desc-full-name package))
+        (unless (memq package packages)
+          (insert " (dependency)"))
+        (insert "\n"))
+      (insert "\n")
+      (setq initial-scratch-message (buffer-string)))
+    (apply #'start-process (concat "*" name "*") nil
+           (list (expand-file-name invocation-name invocation-directory)
+                 "--quick" "--debug-init"
+                 "--init-directory" (if temp-init
+                                        (make-temp-file name t)
+                                      user-emacs-directory)
+                 (format "--eval=%S"
+                         `(progn
+                            (setq initial-scratch-message 
,initial-scratch-message)
+
+                            (require 'package)
+                            ,@(mapcar
+                               (lambda (dir)
+                                 `(add-to-list 'package-directory-list ,dir))
+                               (cons package-user-dir package-directory-list))
+                            (setq package-load-list ',package-load-list)
+                            (package-initialize)))))))
+
 
 ;;;; Package description buffer.
 
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index 58f36db2523..ca706c3c6e9 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -573,22 +573,12 @@ The connection takes the proxy setting in customization 
group
 ;; Dealing with closing the buffer
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defun dictionary--count-mode-buffers ()
-  (seq-reduce (lambda (count buf)
-                (if (provided-mode-derived-p
-                     (buffer-local-value 'major-mode buf)
-                     'dictionary-mode)
-                    (+ count 1)
-                  count))
-              (buffer-list)
-              0))
-
 (defun dictionary-close (&rest _ignored)
   "Close the current dictionary buffer and its connection."
   (interactive)
   (when (derived-mode-p 'dictionary-mode)
     (setq major-mode nil)
-    (if (<= (dictionary--count-mode-buffers) 0)
+    (if (<= (length (match-buffers '(derived-mode . dictionary-mode))) 0)
         (dictionary-connection-close dictionary-connection))
     (let ((configuration dictionary-window-configuration)
           (selected-window dictionary-selected-window))
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 113ff08e94e..65daa0941d5 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -222,7 +222,8 @@ chosen (interactively or automatically)."
                                  . ,(if (and (fboundp 'w32-shell-dos-semantics)
                                              (w32-shell-dos-semantics))
                                         '("language_server.bat")
-                                      '("language_server.sh")))
+                                      (eglot-alternatives
+                                       '("language_server.sh" 
"start_lexical.sh"))))
                                 (ada-mode . ("ada_language_server"))
                                 (scala-mode . ,(eglot-alternatives
                                                 '("metals" "metals-emacs")))
diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el
index c7a297d5dac..c8a45f068d1 100644
--- a/lisp/textmodes/reftex-index.el
+++ b/lisp/textmodes/reftex-index.el
@@ -539,11 +539,7 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan 
[f]ollow [?]Help
       (if (reftex-use-fonts)
           (put-text-property (point-min) (point)
                              'face reftex-index-header-face))
-      (if (fboundp 'cursor-intangible-mode)
-          (cursor-intangible-mode 1)
-        ;; If `cursor-intangible' is not available, fallback on the old
-        ;; intrusive `intangible' property.
-        (put-text-property (point-min) (point) 'intangible t))
+      (cursor-intangible-mode 1)
       (add-text-properties (point-min) (point)
                            '(cursor-intangible t
                              front-sticky (cursor-intangible)
diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el
index da0779c8e8d..d0a44eca17c 100644
--- a/lisp/textmodes/reftex-ref.el
+++ b/lisp/textmodes/reftex-ref.el
@@ -784,7 +784,7 @@ When called with 2 \\[universal-argument] prefix args, 
disable magic word recogn
 (defvar font-lock-mode)
 (defun reftex-show-entry (beg-hlt end-hlt)
   ;; Show entry if point is hidden
-  (let* ((n (/ (reftex-window-height) 2))
+  (let* ((n (/ (window-height) 2))
          (beg (save-excursion
                (re-search-backward "[\n\r]" nil 1 n) (point)))
          (end (save-excursion
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 3b3f892a688..de49b7c6c70 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -1,6 +1,6 @@
 ;;; reftex-toc.el --- RefTeX's table of contents mode  -*- lexical-binding: t; 
-*-
 
-;; Copyright (C) 1997-2000, 2003-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2023 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <dominik@science.uva.nl>
 ;; Maintainer: auctex-devel@gnu.org
@@ -215,9 +215,7 @@ When called with a raw \\[universal-argument] prefix, 
rescan the document first.
          (here-I-am (if reftex--rebuilding-toc
                         (get 'reftex-toc :reftex-data)
                       (car (reftex-where-am-I))))
-         (unsplittable (if (fboundp 'frame-property)
-                           (frame-property (selected-frame) 'unsplittable)
-                         (frame-parameter nil 'unsplittable)))
+         (unsplittable (frame-parameter nil 'unsplittable))
          offset toc-window)
 
     (if (setq toc-window (get-buffer-window
@@ -267,11 +265,7 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels 
[f]ollow [x]r [?]Help
 
       (if (reftex-use-fonts)
           (put-text-property (point-min) (point) 'font-lock-face 
reftex-toc-header-face))
-      (if (fboundp 'cursor-intangible-mode)
-          (cursor-intangible-mode 1)
-        ;; If `cursor-intangible' is not available, fallback on the old
-        ;; intrusive `intangible' property.
-        (put-text-property (point-min) (point) 'intangible t))
+      (cursor-intangible-mode 1)
       (add-text-properties (point-min) (point)
                            '(cursor-intangible t
                              front-sticky (cursor-intangible)
@@ -385,11 +379,8 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels 
[f]ollow [x]r [?]Help
   ;; Check if FRAME is the dedicated TOC frame.
   ;; If yes, and ERROR is non-nil, throw an error.
   (setq frame (or frame (selected-frame)))
-  (let ((res (equal
-              (if (fboundp 'frame-property)
-                  (frame-property frame 'name)
-                (frame-parameter  frame 'name))
-              "RefTeX TOC Frame")))
+  (let ((res (equal (frame-parameter frame 'name)
+                    "RefTeX TOC Frame")))
     (if (and res error)
         (error (substitute-command-keys
                 "This frame is view-only.  Use \\[reftex-toc] \
@@ -586,10 +577,7 @@ With prefix arg 1, restrict index to the section at point."
 (defun reftex-toc-revert (&rest _)
   "Regenerate the TOC from the internal lists."
   (interactive)
-  (let ((unsplittable
-         (if (fboundp 'frame-property)
-             (frame-property (selected-frame) 'unsplittable)
-           (frame-parameter nil 'unsplittable)))
+  (let ((unsplittable (frame-parameter nil 'unsplittable))
         (reftex--rebuilding-toc t))
     (if unsplittable
         (switch-to-buffer
@@ -1036,12 +1024,9 @@ always show the current section in connection with the 
option
 `reftex-auto-recenter-toc'."
   (interactive)
   (catch 'exit
-    (let* ((frames (frame-list)) frame
-           (get-frame-prop-func (if (fboundp 'frame-property)
-                                    'frame-property
-                                  'frame-parameter)))
+    (let* ((frames (frame-list)) frame)
       (while (setq frame (pop frames))
-        (if (equal (funcall get-frame-prop-func frame 'name)
+        (if (equal (frame-parameter frame 'name)
                    "RefTeX TOC Frame")
             (progn
               (delete-frame frame)
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el
index 916e0d89a1d..50bec6ef172 100644
--- a/lisp/textmodes/reftex.el
+++ b/lisp/textmodes/reftex.el
@@ -1,6 +1,6 @@
 ;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX  
-*- lexical-binding: t; -*-
 
-;; Copyright (C) 1997-2000, 2003-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2023 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <dominik@science.uva.nl>
 ;; Maintainer: auctex-devel@gnu.org
@@ -1664,11 +1664,6 @@ When DIE is non-nil, throw an error if file not found."
       (pop alist))
     (nreverse out)))
 
-(defun reftex-window-height ()
-  (if (fboundp 'window-displayed-height)
-      (window-displayed-height)
-    (window-height)))
-
 (defun reftex-enlarge-to-fit (buf2 &optional keep-current)
   ;; Enlarge other window displaying buffer to show whole buffer if possible.
   ;; If KEEP-CURRENT in non-nil, current buffer must remain visible.
@@ -1680,7 +1675,7 @@ When DIE is non-nil, throw an error if file not found."
       (unless (and (pos-visible-in-window-p (point-min))
                    (pos-visible-in-window-p (point-max)))
         (enlarge-window (1+ (- (count-lines (point-min) (point-max))
-                               (reftex-window-height))))))
+                               (window-height))))))
     (cond
      ((window-live-p win1) (select-window win1))
      (keep-current
@@ -1705,7 +1700,7 @@ When DIE is non-nil, throw an error if file not found."
           (unless (and (pos-visible-in-window-p (point-min))
                        (pos-visible-in-window-p (point-max)))
             (enlarge-window (1+ (- (count-lines (point-min) (point-max))
-                                   (reftex-window-height)))))
+                                   (window-height)))))
           (setq truncate-lines t))
         (if (and (pos-visible-in-window-p (point-min))
                  (pos-visible-in-window-p (point-max)))
@@ -2274,20 +2269,17 @@ IGNORE-WORDS List of words which should be removed from 
the string."
 (defun reftex-create-customize-menu ()
   "Create a full customization menu for RefTeX, insert it into the menu."
   (interactive)
-  (if (fboundp 'customize-menu-create)
-      (progn
-        (easy-menu-change
-         '("Ref") "Customize"
-         `(["Browse RefTeX group" reftex-customize t]
-           "--"
-           ,(customize-menu-create 'reftex)
-           ["Set" Custom-set t]
-           ["Save" Custom-save t]
-           ["Reset to Current" Custom-reset-current t]
-           ["Reset to Saved" Custom-reset-saved t]
-           ["Reset to Standard Settings" Custom-reset-standard t]))
-        (message "\"Ref\"-menu now contains full customization menu"))
-    (error "Cannot expand menu (outdated version of cus-edit.el)")))
+  (easy-menu-change
+   '("Ref") "Customize"
+   `(["Browse RefTeX group" reftex-customize t]
+     "--"
+     ,(customize-menu-create 'reftex)
+     ["Set" Custom-set t]
+     ["Save" Custom-save t]
+     ["Reset to Current" Custom-reset-current t]
+     ["Reset to Saved" Custom-reset-saved t]
+     ["Reset to Standard Settings" Custom-reset-standard t]))
+  (message "\"Ref\"-menu now contains full customization menu"))
 
 
 ;;; Misc
@@ -2348,6 +2340,8 @@ Your bug report will be posted to the AUCTeX bug 
reporting list.
 
 (setq reftex-tables-dirty t)  ; in case this file is evaluated by hand
 
+(define-obsolete-function-alias 'reftex-window-height #'window-height "30.1")
+
 (provide 'reftex)
 
 ;;; reftex.el ends here
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index fabf590f6b8..a70598bb6c9 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3801,8 +3801,19 @@ like the newline character or the tab character."
 (define-widget 'list 'group
   "A Lisp list."
   :tag "List"
+  :default-get #'widget-list-default-get
   :format "%{%t%}:\n%v")
 
+(defun widget-list-default-get (widget)
+  "Return the default external value for a list WIDGET.
+
+The default value is the one stored in the :value property, even if it is nil,
+or a list with the default value of each component of the list WIDGET."
+  (widget-apply widget :value-to-external
+                (if (widget-member widget :value)
+                    (widget-get widget :value)
+                  (widget-group-default-get widget))))
+
 (define-widget 'vector 'group
   "A Lisp vector."
   :tag "Vector"
@@ -3931,7 +3942,6 @@ example:
            value-type widget-plist-value-type))
     `(group :format "Key: %v" :inline t ,key-type ,value-type)))
 
-
 ;;; The `alist' Widget.
 ;;
 ;; Association lists.
@@ -3941,6 +3951,7 @@ example:
   :key-type '(sexp :tag "Key")
   :value-type '(sexp :tag "Value")
   :convert-widget 'widget-alist-convert-widget
+  :default-get #'widget-alist-default-get
   :tag "Alist")
 
 (defvar widget-alist-value-type)       ;Dynamic variable
@@ -3975,6 +3986,25 @@ example:
       (setq key-type `(const ,option)
            value-type widget-alist-value-type))
     `(cons :format "Key: %v" ,key-type ,value-type)))
+
+(defun widget-alist-default-get (widget)
+  "Return the default value for WIDGET, an alist widget.
+
+The default value may be one of:
+- The one stored in the :value property, even if it is nil.
+- If WIDGET has options available, an alist consisting of the
+default values for each option.
+- nil, otherwise."
+  (widget-apply widget :value-to-external
+                (cond ((widget-member widget :value)
+                       (widget-get widget :value))
+                      ((widget-get widget :options)
+                       (mapcar #'widget-default-get
+                               ;; Last one is the editable-list part, and
+                               ;; we don't want those showing up as
+                               ;; part of the default value.  (Bug#63290)
+                               (butlast (widget-get widget :args))))
+                      (t nil))))
 
 (define-widget 'choice 'menu-choice
   "A union of several sexp types.
diff --git a/src/androidterm.c b/src/androidterm.c
index f74463f88cd..473bea76ef5 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -4869,17 +4869,17 @@ android_perform_conversion_query (void *data)
   context->success = true;
 }
 
-/* Convert a string BUFFERS containing N characters in Emacs's
-   internal multibyte encoding to a Java string utilizing the
-   specified JNI environment.
+/* Convert a string in BUFFER, containing N characters in Emacs's
+   internal multibyte encoding, to a Java string utilizing the
+   specified JNI environment ENV.
 
-   If N is equal to BYTES, then BUFFER is a single byte buffer.
-   Otherwise, BUFFER is a multibyte buffer.
+   If N is equal to BYTES, then BUFFER holds unibyte or plain-ASCII
+   characters.  Otherwise, BUFFER holds multibyte characters.
 
    Make sure N and BYTES are absolutely correct, or you are asking for
    trouble.
 
-   Value is the string upon success, NULL otherwise.  Any exceptions
+   Value is a jstring upon success, NULL otherwise.  Any exceptions
    generated are not cleared.  */
 
 static jstring
diff --git a/src/textconv.c b/src/textconv.c
index 590292013db..57daa7e53b6 100644
--- a/src/textconv.c
+++ b/src/textconv.c
@@ -78,14 +78,14 @@ enum textconv_batch_edit_flags
 
 
 
-/* Copy the portion of the current buffer described by BEG, BEG_BYTE,
-   END, END_BYTE to the buffer BUFFER, which is END_BYTE - BEG_BYTEs
-   long.  */
+/* Copy the portion of the current buffer's text described by BEG,
+   BEG_BYTE, END, END_BYTE to the char * buffer BUFFER, which should
+   be at least END_BYTE - BEG_BYTEs long.  */
 
 static void
-copy_buffer (ptrdiff_t beg, ptrdiff_t beg_byte,
-            ptrdiff_t end, ptrdiff_t end_byte,
-            char *buffer)
+copy_buffer_text (ptrdiff_t beg, ptrdiff_t beg_byte,
+                 ptrdiff_t end, ptrdiff_t end_byte,
+                 char *buffer)
 {
   ptrdiff_t beg0, end0, beg1, end1, size;
 
@@ -130,7 +130,7 @@ get_mark (void)
   return -1;
 }
 
-/* Like Fselect_window.  However, if WINDOW is a mini buffer window
+/* Like Fselect_window.  However, if WINDOW is a minibuffer window
    but not the active minibuffer window, select its frame's selected
    window instead.  */
 
@@ -152,8 +152,8 @@ select_window (Lisp_Object window, Lisp_Object norecord)
 /* Perform the text conversion operation specified in QUERY and return
    the results.
 
-   Find the text between QUERY->position from point on F's selected
-   window and QUERY->factor times QUERY->direction from that
+   Find the text between QUERY->position from point on frame F's
+   selected window and QUERY->factor times QUERY->direction from that
    position.  Return it in QUERY->text.
 
    If QUERY->position is TYPE_MINIMUM (EMACS_INT) or EMACS_INT_MAX,
@@ -163,8 +163,9 @@ select_window (Lisp_Object window, Lisp_Object norecord)
    Then, either delete that text from the buffer if QUERY->operation
    is TEXTCONV_SUBSTITUTION, or return 0.
 
-   If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move PT past
-   the conversion region in the specified direction if it is inside.
+   If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move point
+   past the conversion region in the specified direction if it is
+   inside.
 
    Value is 0 if QUERY->operation was not TEXTCONV_SUBSTITUTION
    or if deleting the text was successful, and 1 otherwise.  */
@@ -291,7 +292,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
       break;
 
     case TEXTCONV_FORWARD_WORD:
-      /* Move forward by query->factor word.  */
+      /* Move forward by query->factor words.  */
       end = scan_words (pos, (EMACS_INT) query->factor);
 
       if (!end)
@@ -305,7 +306,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
       break;
 
     case TEXTCONV_BACKWARD_WORD:
-      /* Move backwards by query->factor word.  */
+      /* Move backwards by query->factor words.  */
       end = scan_words (pos, 0 - (EMACS_INT) query->factor);
 
       if (!end)
@@ -392,7 +393,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
 
   /* Return the string first.  */
   buffer = xmalloc (end_byte - pos_byte);
-  copy_buffer (pos, pos_byte, end, end_byte, buffer);
+  copy_buffer_text (pos, pos_byte, end, end_byte, buffer);
   query->text.text = buffer;
   query->text.length = end - pos;
   query->text.bytes = end_byte - pos_byte;
@@ -418,8 +419,8 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
   return 0;
 }
 
-/* Update the overlay displaying the conversion area on F after a
-   change to the conversion region.  */
+/* Update the overlay displaying the conversion area on frame F after
+   a change to the conversion region.  */
 
 static void
 sync_overlay (struct frame *f)
@@ -449,7 +450,7 @@ sync_overlay (struct frame *f)
 }
 
 /* Record a change to the current buffer as a result of an
-   asynchronous text conversion operation on F.
+   asynchronous text conversion operation.
 
    Consult the doc string of `text-conversion-edits' for the meaning
    of BEG, END, and EPHEMERAL.  */
@@ -487,7 +488,7 @@ record_buffer_change (ptrdiff_t beg, ptrdiff_t end,
             Vtext_conversion_edits);
 }
 
-/* Reset F's text conversion state.  Delete any overlays or
+/* Reset text conversion state of frame F.  Delete any overlays or
    markers inside.  */
 
 void
@@ -562,9 +563,9 @@ restore_selected_window (Lisp_Object window)
 }
 
 /* Commit the given text in the composing region.  If there is no
-   composing region, then insert the text after F's selected window's
-   last point instead, unless the mark is active.  Finally, remove the
-   composing region.
+   composing region, then insert the text after frame F's selected
+   window's last point instead, unless the mark is active.  Finally,
+   remove the composing region.
 
    If the mark is active, delete the text between mark and point.
 
@@ -580,7 +581,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
   ptrdiff_t wanted, start, end, mark;
   struct window *w;
 
-  /* If F's old selected window is no longer live, fail.  */
+  /* If F's old selected window is no longer alive, fail.  */
 
   if (!WINDOW_LIVE_P (f->old_selected_window))
     return;
@@ -769,7 +770,7 @@ really_finish_composing_text (struct frame *f, bool update)
   TEXTCONV_DEBUG ("conversion region removed");
 }
 
-/* Set the composing text on F to TEXT.  Then, move point to an
+/* Set the composing text on frame F to TEXT.  Then, move point to an
    appropriate position relative to POSITION, and call
    `compose_region_changed' in the text conversion interface should
    point not have been changed relative to F's old selected window's
@@ -927,8 +928,8 @@ really_set_composing_text (struct frame *f, ptrdiff_t 
position,
   unbind_to (count, Qnil);
 }
 
-/* Set the composing region to START by END.  Make it that it is not
-   already set.  */
+/* Set the composing region of frame F to START by END.  Make it if
+   it is not already set.  */
 
 static void
 really_set_composing_region (struct frame *f, ptrdiff_t start,
@@ -986,8 +987,8 @@ really_set_composing_region (struct frame *f, ptrdiff_t 
start,
 }
 
 /* Delete LEFT and RIGHT chars around point or the active mark,
-   whichever is larger, avoiding the composing region if
-   necessary.  */
+   whichever is larger, in frame F's selected window, avoiding the
+   composing region if necessary.  */
 
 static void
 really_delete_surrounding_text (struct frame *f, ptrdiff_t left,
@@ -1077,8 +1078,8 @@ really_delete_surrounding_text (struct frame *f, 
ptrdiff_t left,
   unbind_to (count, Qnil);
 }
 
-/* Update the interface with F's new point and mark.  If a batch edit
-   is in progress, schedule the update for when it finishes
+/* Update the interface with frame F's new point and mark.  If a batch
+   edit is in progress, schedule the update for when it finishes
    instead.  */
 
 static void
@@ -1097,10 +1098,10 @@ really_request_point_update (struct frame *f)
                                   current_buffer);
 }
 
-/* Set point in F to POSITION.  If MARK is not POSITION, activate the
-   mark and set MARK to that as well.
+/* Set point in frame F's selected window to POSITION.  If MARK is not
+   at POSITION, activate the mark and set MARK to that as well.
 
-   If it has not changed, signal an update through the text input
+   If point was not changed, signal an update through the text input
    interface, which is necessary for the IME to acknowledge that the
    change has completed.  */
 
@@ -1173,9 +1174,9 @@ struct complete_edit_check_context
   bool check;
 };
 
-/* If CONTEXT->check is false, then update W's ephemeral last point
-   and give it to the input method, the assumption being that an
-   editing operation signalled.  */
+/* Convert PTR to CONTEXT.  If CONTEXT->check is false, then update
+   CONTEXT->w's ephemeral last point and give it to the input method,
+   the assumption being that an editing operation signalled.  */
 
 static void
 complete_edit_check (void *ptr)
@@ -1429,8 +1430,8 @@ handle_pending_conversion_events (void)
   unbind_to (count, Qnil);
 }
 
-/* Start a ``batch edit'' in F.  During a batch edit, point_changed
-   will not be called until the batch edit ends.
+/* Start a ``batch edit'' in frame F.  During a batch edit,
+   point_changed will not be called until the batch edit ends.
 
    Process the actual operation in the event loop in keyboard.c; then,
    call `notify_conversion' in the text conversion interface with
@@ -1473,8 +1474,9 @@ end_batch_edit (struct frame *f, unsigned long counter)
   input_pending = true;
 }
 
-/* Insert the specified STRING into F's current buffer's composition
-   region, and set point to POSITION relative to STRING.
+/* Insert the specified STRING into frame F's selected-window's
+   buffer's composition region, and set point to POSITION relative to
+   STRING.
 
    If there is no composition region, use the active region instead.
    If that doesn't exist either, insert STRING after point.
@@ -1498,8 +1500,9 @@ commit_text (struct frame *f, Lisp_Object string,
   input_pending = true;
 }
 
-/* Remove the composition region and its overlay from F's current
-   buffer.  Leave the text being composed intact.
+/* Remove the composition region and its overlay from frame F's
+   selected-window's current buffer.  Leave the text being composed
+   intact.
 
    If UPDATE, call `compose_region_changed' after the region is
    removed.
@@ -1557,7 +1560,7 @@ set_composing_text (struct frame *f, Lisp_Object object,
 }
 
 /* Make the region between START and END the currently active
-   ``composing region''.
+   ``composing region'' on frame F.
 
    The ``composing region'' is a region of text in the buffer that is
    about to undergo editing by the input method.  */
@@ -1586,7 +1589,8 @@ set_composing_region (struct frame *f, ptrdiff_t start,
   input_pending = true;
 }
 
-/* Move point in F's selected buffer to POINT and maybe push MARK.
+/* Move point in frame F's selected-window's buffer to POINT and maybe
+   push MARK.
 
    COUNTER means the same as in `start_batch_edit'.  */
 
@@ -1611,8 +1615,8 @@ textconv_set_point_and_mark (struct frame *f, ptrdiff_t 
point,
   input_pending = true;
 }
 
-/* Delete LEFT and RIGHT characters around point in F's old selected
-   window.  */
+/* Delete LEFT and RIGHT characters around point in frame F's old
+   selected window.  */
 
 void
 delete_surrounding_text (struct frame *f, ptrdiff_t left,
@@ -1632,8 +1636,9 @@ delete_surrounding_text (struct frame *f, ptrdiff_t left,
   input_pending = true;
 }
 
-/* Request an immediate call to INTERFACE->point_changed with the new
-   details of F's region unless a batch edit is in progress.  */
+/* Request an immediate call to TEXT_INTERFACE->point_changed with the
+   new details of frame F's region unless a batch edit is in
+   progress.  */
 
 void
 request_point_update (struct frame *f, unsigned long counter)
@@ -1651,8 +1656,8 @@ request_point_update (struct frame *f, unsigned long 
counter)
   input_pending = true;
 }
 
-/* Request that text conversion on F pause until the keyboard buffer
-   becomes empty.
+/* Request that text conversion on frame F pause until the keyboard
+   buffer becomes empty.
 
    Use this function to ensure that edits associated with a keyboard
    event complete before the text conversion edits after the barrier
@@ -1674,19 +1679,18 @@ textconv_barrier (struct frame *f, unsigned long 
counter)
   input_pending = true;
 }
 
-/* Return N characters of text around point in F's old selected
+/* Return N characters of text around point in frame F's old selected
    window.
 
    If N is -1, return the text between point and mark instead, given
    that the mark is active.
 
-   Set *N to the actual number of characters returned, *START_RETURN
-   to the position of the first character returned, *START_OFFSET to
-   the offset of the lesser of mark and point within that text,
-   *END_OFFSET to the greater of mark and point within that text, and
-   *LENGTH to the actual number of characters returned, *BYTES to the
-   actual number of bytes returned, and *MARK_ACTIVE to whether or not
-   the mark is active.
+   Set *START_RETURN to the position of the first character returned,
+   *START_OFFSET to the offset of the lesser of mark and point within
+   that text, *END_OFFSET to the greater of mark and point within that
+   text, and *LENGTH to the actual number of characters returned,
+   *BYTES to the actual number of bytes returned, and *MARK_ACTIVE to
+   whether or not the mark is active.
 
    Value is NULL upon failure, and a malloced string upon success.  */
 
@@ -1763,8 +1767,7 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
 
   /* Extract the text from the buffer.  */
   buffer = xmalloc (end_byte - start_byte);
-  copy_buffer (start, start_byte, end, end_byte,
-              buffer);
+  copy_buffer_text (start, start_byte, end, end_byte, buffer);
 
   /* Get the mark.  If it's not active, use PT.  */
 
@@ -1792,7 +1795,8 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
   return buffer;
 }
 
-/* Return the text between the positions PT - LEFT and PT + RIGHT.  If
+/* Return the text between the positions pt - LEFT and pt + RIGHT,
+   where pt is the position of point in frame F's selected window.  If
    the mark is active, return the range of text relative to the bounds
    of the region instead.
 
@@ -1868,8 +1872,7 @@ get_surrounding_text (struct frame *f, ptrdiff_t left,
 
   /* Extract the text from the buffer.  */
   buffer = xmalloc (end_byte - start_byte);
-  copy_buffer (start, start_byte, end, end_byte,
-              buffer);
+  copy_buffer_text (start, start_byte, end, end_byte, buffer);
 
   /* Get the mark.  If it's not active, use PT.  */
 
@@ -1907,7 +1910,7 @@ conversion_disabled_p (void)
 /* Window system interface.  These are called from the rest of
    Emacs.  */
 
-/* Notice that F's selected window has been set from redisplay.
+/* Notice that frame F's selected window has been set from redisplay.
    Reset F's input method state.  */
 
 void
@@ -1934,11 +1937,11 @@ report_selected_window_change (struct frame *f)
   text_interface->reset (f);
 }
 
-/* Notice that the point in F's selected window's current buffer has
+/* Notice that point in frame F's selected window's current buffer has
    changed.
 
-   F is the frame whose selected window was changed, W is the window
-   in question, and BUFFER is that window's current buffer.
+   F is the frame whose selected window was changed, WINDOW is the
+   window in question, and BUFFER is that window's buffer.
 
    Tell the text conversion interface about the change; it will likely
    pass the information on to the system input method.  */
@@ -2081,10 +2084,11 @@ check_postponed_buffers (void)
 
 DEFUN ("set-text-conversion-style", Fset_text_conversion_style,
        Sset_text_conversion_style, 1, 2, 0,
-       doc: /* Set the text conversion style in the current buffer.
+       doc: /* Set the current buffer's text conversion style to VALUE.
 
-Set `text-conversion-style' to VALUE, then force any input method
-editing frame displaying this buffer to stop itself.
+After setting `text-conversion-style', force input methods
+editing in a selected window displaying this buffer on any frame
+to stop themselves.
 
 This can lead to a significant amount of time being taken by the input
 method resetting itself, so you should not use this function lightly;
@@ -2110,7 +2114,7 @@ replacement key sequence returned starts a new key 
sequence and makes
   if (!text_interface)
     return Qnil;
 
-  /* If there are any seleted windows displaying this buffer, reset
+  /* If there are any selected windows displaying this buffer, reset
      text conversion on their associated frames.  */
 
   if (buffer_window_count (current_buffer))
@@ -2167,13 +2171,13 @@ syms_of_textconv (void)
          "overriding-text-conversion-style");
 
   DEFVAR_LISP ("text-conversion-edits", Vtext_conversion_edits,
-    doc: /* List of buffers that were last edited as a result of text 
conversion.
+    doc: /* List of buffers that were last edited as result of text conversion.
 
 This list can be used while handling a `text-conversion' event to
 determine which changes have taken place.
 
-Each element of the list describes a single edit in a buffer, of the
-form:
+Each element of the list describes a single edit in a buffer, and
+is of the form:
 
     (BUFFER BEG END EPHEMERAL)
 
@@ -2189,8 +2193,8 @@ as indenting or automatically filling text, should not 
take place.
 Otherwise, it is either a string containing text that was inserted,
 text deleted before point, or nil if text was deleted after point.
 
-The list contents are ordered later edits first, so you must iterate
-through the list in reverse.  */);
+The list contents are ordered in the reverse order of editing, i.e.
+the latest edit first, so you must iterate through the list in reverse.  */);
   Vtext_conversion_edits = Qnil;
 
   DEFVAR_LISP ("overriding-text-conversion-style",
@@ -2198,14 +2202,14 @@ through the list in reverse.  */);
     doc: /* Non-buffer local version of `text-conversion-style'.
 
 If this variable is the symbol `lambda', it means to consult the
-buffer local variable `text-conversion-style' to determine whether or
-not to activate the input method.  Otherwise, its value is used in
-preference to any buffer local value of `text-conversion-style'.  */);
+buffer-local value of `text-conversion-style' to determine whether or
+not to activate the input method.  Otherwise, the value is used in
+preference to any buffer-local value of `text-conversion-style'.  */);
   Voverriding_text_conversion_style = Qlambda;
 
   DEFVAR_LISP ("text-conversion-face", Vtext_conversion_face,
     doc: /* Face in which to display temporary edits by an input method.
-nil means to display no indication of a temporary edit.  */);
+The value nil means to display no indication of a temporary edit.  */);
   Vtext_conversion_face = Qunderline;
 
   defsubr (&Sset_text_conversion_style);
diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el
index eca35d7c96a..3a788f19745 100644
--- a/test/lisp/cus-edit-tests.el
+++ b/test/lisp/cus-edit-tests.el
@@ -92,5 +92,48 @@
             (buffer-substring-no-properties (point-min) (point-max)))))
     (should (string-search "Value `:foo' does not match type number"
                            warn-txt))))
+
+(defcustom cus-edit-test-bug63290-option nil
+  "Choice option for testing Bug#63290."
+  :type '(choice (alist
+                  :key-type (string :tag "key")
+                  :value-type (string :tag "value"))
+                 (const :tag "auto" auto)))
+
+(defcustom cus-edit-test-bug63290-option2 'some
+  "Choice option for testing Bug#63290."
+  :type '(choice
+          (const :tag "some" some)
+          (alist
+           :key-type (string :tag "key")
+           :value-type (string :tag "value"))))
+
+(ert-deftest cus-edit-test-bug63290 ()
+  "Test that changing a choice value back to an alist respects its nil value."
+  (customize-variable 'cus-edit-test-bug63290-option)
+  (search-forward "Value")
+  ;; Simulate changing the value.
+  (let* ((choice (widget-at))
+         (args (widget-get choice :args))
+         (list-opt (car (widget-get choice :children)))
+         (const-opt (nth 1 args)))
+    (widget-put choice :explicit-choice const-opt)
+    (widget-value-set choice (widget-default-get const-opt))
+    (widget-put choice :explicit-choice list-opt)
+    (widget-value-set choice (widget-default-get list-opt)))
+  ;; No empty key/value pairs should show up.
+  (should-not (search-forward "key" nil t))
+  (customize-variable 'cus-edit-test-bug63290-option2)
+  (search-forward "Value")
+  ;; Simulate changing the value.
+  (let* ((choice (widget-at))
+         (args (widget-get choice :args))
+         (const-opt (car (widget-get choice :children)))
+         (list-opt (nth 1 args)))
+    (widget-put choice :explicit-choice list-opt)
+    (widget-value-set choice (widget-default-get list-opt)))
+  ;; No empty key/value pairs should show up.
+  (should-not (search-forward "key" nil t)))
+
 (provide 'cus-edit-tests)
 ;;; cus-edit-tests.el ends here
diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el
index b379c7c91a8..ebfe729bc9a 100644
--- a/test/lisp/wid-edit-tests.el
+++ b/test/lisp/wid-edit-tests.el
@@ -349,4 +349,35 @@ return nil, even with a non-nil bubblep argument."
     (should-not (widget-apply widget :match "someundefinedcolorihope"))
     (should-not (widget-apply widget :match "#11223"))))
 
+(ert-deftest widget-test-alist-default-value-1 ()
+  "Test getting the default value for an alist widget with options."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :options (("0" (integer)))))))
+      (should (equal '(("0" . 0)) (widget-default-get w))))))
+
+(ert-deftest widget-test-alist-default-value-2 ()
+  "Test getting the default value for an alist widget without :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer))))
+      (should-not (widget-default-get w)))))
+
+(ert-deftest widget-test-alist-default-value-3 ()
+  "Test getting the default value for an alist widget with nil :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :value nil))))
+      (should-not (widget-default-get w)))))
+
+(ert-deftest widget-test-alist-default-value-4 ()
+  "Test getting the default value for an alist widget with non-nil :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :value (("1" . 1) ("2" . 2))))))
+      (should (equal '(("1" . 1) ("2" . 2)) (widget-default-get w))))))
+
 ;;; wid-edit-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]