Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
This commit is contained in:
commit
44697457c6
13 changed files with 302 additions and 155 deletions
9
etc/NEWS
9
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
|
||||
|
||||
+++
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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")))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
162
src/textconv.c
162
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue