Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs

This commit is contained in:
Michael Albinus 2023-08-19 19:32:29 +02:00
commit 44697457c6
13 changed files with 302 additions and 155 deletions

View file

@ -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
+++

View file

@ -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.

View file

@ -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))

View file

@ -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")))

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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