Merge from origin/emacs-29

7acae22f42 Fix auto-filling in Texinfo mode
4bda962734 ; * admin/git-bisect-start: Update failing commits
dcf8c01102 Merge branch 'scratch/long-lines-cleanup' into 'emacs-29'
1e3a66df45 Add an assertion in, and a commentary for, 'get_nearby_bo...
f0f08eeb05 Fix the return type of 'labeled_restrictions_get_bound'
acf4763417 Fix mouse highlight with some fonts in Cairo builds
32b42b333c ; * etc/NEWS: Fix wording in last change.
09d6070e56 ; Improve and update documentation of built-in package up...
ba2c76fa2b Ensure that package menu respects 'package-install-upgrad...
6fa9332e7c Ensure that EXTRA-DATA are always written when generating...
60d5a015d1 Update to Transient v0.4.0
b8bcd42cab Revert "Don't have nntp-report signal an error"
ef1f4068f6 ; * lisp/wid-edit.el (widget-specify-insert): Fix debug s...
09bf476836 Make c-emacs-features use the proper binding of parse-sex...
c9e2a5ec26 ; * lisp/obsolete/autoload.el (make-directory-autoloads):...
346f4ac3bf ; Fix example in ELisp manual
91fff05ae3 ; Fix wording in Emacs manual
2438fa2e6c ; Fix minor documentation issue ion replace.el
93005cd9dc with-display-message: Workaround for bug#63253
6924c81a6d ; Don't use literal non-ASCII characters in Texinfo
f1675df3d0 Fido-mode: never shadow 'external' completion style
56d2949d44 ; * lisp/leim/quail/persian.el: Fix a typo in last commit.
d94ea9efca Avoid crashes in --without-all build trying to scale non-...
387ddc0ccc Improve instructions for dealing with Emacs crashes
e6b4784a37 Improved transliterations + improved bidi insertion suppo...
c1363a04bb Fix crash when creating a child frame in NS (bug#63107)
7d6855c9ab Fix outgoing mime type regression (Bug#62815)
e920dd2b6f define-minor-mode: sanitize mode function messages
910a7b30df Fix beginning/end-of-defun with tree-sitter
e205f68717 Fix indent for enums in csharp-mode
dfde902f3b ; Expand 'package-vc-install' documentation
7133784303 Teach c-ts-mode about the 'restrict' keyword
15e06260ae * lisp/x-dnd.el (x-dnd-after-move-frame): Skip dead frame...
a081b6625b ; Updated Elispref-Manual: `nil' cannot be defun'ed
97b818a4fb Fix doc strings of 'mark-sexp' and 'mark-word'
6f910ad932 ; * etc/EGLOT-NEWS: Fix misspellings.
9b775ddc05 ; * etc/EGLOT-NEWS: Fix wording of last change.
79a886ba36 (package-upgrade): Don't remove the package from 'package...
c0ab4e9ca9 Eglot: re-rename eglot-upgrade to eglot-upgrade-eglot
b4e90070f9 Fix arguments of xml.c functions as displayed in Help buf...
b1bda8228e More fixes for NetBSD/vax
a2d4cd06f4 Improve VHDL mode highlighting
2f3a514b6d Clarify documentation wrt floating point division by zero...
94e984e670 Make loaddefs-generate slightly more tolerant
aba41d2c4b ; Minor doc cleanups in go-ts-mode.el
b42ccb2e5c ; Minor grammar fix in treesit manual.
ab44c8a6f9 Fix order of rcirc-connect arguments
8eb6e33691 Fix rcirc messages printing in the wrong place
2901a3443c Prevent unnecessary modifications of 'package-vc-selected...
eaad302bd6 Rename eglot-update to eglot-upgrade
eaf25b9c6a go-ts-mode: Use iota query only if supported (Bug#63086)
cc090294d7 (rng-complete-tag): Add the (ignored) argument to the :co...
21ec6c1d5c Update to Transient v0.3.7-219-g3ded15b
8d5aa8df4a Fix inserting selection data into Mozilla programs
57562c3fd0 Recognize defstruct slot names in various eieio functions
b93eb68cc3 Use 'calendar-buffer' instead of fixed string
e338a8ac41 Handle point not at EOB in minibuffer-choose-completion
fceaf230b0 Note that Emacs pauses when handling sentinel errors
46392c1623 Fix vertical-motion when tab-line is displayed in a window
0e52beeace Update to Org 9.6.5-3-g2993f4
dd21003878 Prevent generating empty autoload files
2bcf11d0ef * lisp/org/org-macs.el (org--inhibit-version-check): Fix ...
ca43435816 Fix redisplay of mode line after its format changes from nil
610a7657e0 Fix c-ts-mode--emacs-c-range-query
7f94558b77 Improve documentation of warnings
5a3f0e2c55 ; Doc fix in c-ts-mode.el
21361d0563 Fix FOR_EACH_TAIL fontification (bug#62951)
d0df3404fd ; * etc/EGLOT-NEWS:  chsharp-le -> csharp-ls
c229e83c3c ; * etc/EGLOT-NEWS (https): Elglot -> Eglot.
b4f2f49978 Fix documentation of libxml-parse-* functions
5dd784961d ; * src/treesit.c (syms_of_treesit): Fix error messages.
ddfa0d8da9 ; Remove some leftover text
212e30f678 ; Fix byte-compilation warnings in c-ts-mode.el
1f2214dabd Skip over whitespace in annotation-top-cont check (bug#63...
7e136c51f6 Update zh-CN tutorial translation
d3ca0b3aa2 ; * lisp/progmodes/c-ts-mode.el: Fix comments and doc str...
c6f15c2486 ; Fix last change.
b9e06330f7 ; * etc/NEWS: Followup to bug#62720.
b33d25f596 ; Minor improvements in doc strings of package-upgrade co...
c3a61870b9 Fix eglot.texi
a40f181623 Fix two crashes upon startup
44ebd9cbd5 Eglot: explain how to update Eglot in manual (bug#62720)
941ef044f2 Eglot: fix edge case when deleting inlay hint overlays
a365984d9e package-upgrade[-all]: Expand docstrings to note the curr...
f965f35b33 Rename all functions called package-*-update-* to package...
31b58161bb Fix FOR_EACH_TAIL in c-ts-mode (bug#62951)
0cf6e0998b * Makefile.in (distclean): Remove the 'native-lisp' direc...
933705d61e Improve greek-ibycus4 input method
c46e93b1f5 Explain ERC 5.5 regressions in new version 5.5.0.29.1
af43f0a295 * doc/misc/erc.texi: Elaborate on upgrading via ELPA.
10948948c1 Improve outline-default-state docstring
b5ace2eed8 Document problems with /bin/sh on Solaris 10
7b2ad8f199 ; Add missing <<inserted by help-with-tutorial>> line to ...
524e161a53 Followup to addition of TUTORIAL.fa
76f50df153 Add Farsi/Persian translation of the tutorial
8eacfaea6d Add Mongolian language environments
fe8efbb8f7 Document the 'end-session' event on MS-Windows
d80f959bed Update to Org 9.6.4-9-g8eb209
98c6cfcbe4 Don't support versioned grammar libraries on MS-Windows
8f71c1546d Accept versioned tree-sitter language grammar files
99add09d5e tab-bar-new-tab: inhibit side-window checks
087e818194 * etc/NEWS: Fix outline level.  (Bug#63042)
d7f38558c4 ; Improve font selection for Traditional Mongolian
965c5e0231 Fix rendering of Traditional Mongolian script
9a0f10b5f8 Fix line-number-at-pos when POSITION is out of narrowing
4e0f4292aa ; * etc/tutorials/TUTORIAL: Fix punctuation.
dec2ac0c65 Fix exiting Emacs after saving a tutorial
44145bf07e Add indentation style setting for c-ts-mode in .dir-local...
e7db6c59cc ; * .dir-locals.el (c-ts-mode): Add settings.
d041f01b02 ; Minor fix in Emacs Lisp Intro manual
3899acbb33 ; * src/fringe.c: Fix description of large circle.  (Bug#...
2b10e1827d sql: add missing postgresql types
9ac1259278 Fix display of menu-bar bindings of commands in *Help* bu...
ecdd3a9efa Improve Completion Example section in the Emacs manual
626e1ac62b Improve 'message-server-alist' docstring
327986936c Add index entry for fallback modes
1c4783c330 ; * etc/NEWS: Copyedits and grammar fixes.
3d6f755331 xref-search-program-alist: Fix searching larger file list...
1b8b2cf61b Fix typo and inaccuracy in the ELisp Reference manual
df17682ebf ; Support 'dart-ts-mode' in Eglot
e0dc60e078 ; Fix typos in gdb-mi.el
60560cc7ad Fix description of lexical environment's internals
1456adf424 ; Eglot: fix a typo in a customization type
2f59595f5f ; * etc/NEWS: Grammar fixes.
596b780ab7 Update to Org 9.6.4-2-g0f6ae7
a0b04a2247 Documentation copyedits for 'package-install-upgrade-buil...
580d8278c5 Allow upgrading built-in packages with 'package-install'
329304c23f ; * src/term.c (init_tty): Fix last change.  (Bug#62877)
200dbf7d30 Minor changes in c-ts-mode.el's support of DEFUNs
9686b015a0 Fix strike-through attribute support on TTY frames
39035fbfc5 Avoid crashes in 'describe-keymap' due to shadowing
b7023da662 Make image-map bindings available on image links
d9e96c029b * CONTRIBUTE: Fix a typo
3f71a2a0cf ; * lisp/progmodes/c-ts-mode.el (treesit-node-next-siblin...
adf9c956c2 Add to Eglot support for additional language-servers.
b3603b84bd Partial support for DEFUN in c-ts-mode (bug#62825)
14e809ddff Fix style and unwinding code in treesit.c
759cdf1e51 Catch signals produced by PRED in tree-sitter search func...
864a4dc236 Fix compilation of w32.c with old MinGW system headers
a22eb9ae0f ruby-add-log-current-method: Reduce the use of 'nreverse'
17d803d0a7 Fix detection of WebP images by their signature
43290391ce ; Eglot: make version parseable by version-to-list
6e6e8b5c97 Add more documentation for the keys of `package-vc-select...
7972b76c2c ; vc-checkout: Wrap var lookup in 'bound-and-true-p'
e9fef1d70f vc-checkout: Try to use the vc-dir's backend first
372e024acc ; Fix wallpaper-tests on XFCE
7055fd8e43 Improve documentation related to 'ispell-complete-word'
61fd017abd * configure.ac: Add -lbsd on Haiku.
05971c4d9a Add menu to 'c-ts-mode' and 'c++-ts-mode'
954e2d96a9 Update manual about `sort`
c62afb10cf Fix wallpaper-tests on MS-Windows
f2d212c696 Fix a couple of eglot-tests
338b3718b6 Fix visiting RPM files
b4afee0319 Fix ff-quiet-mode doc
2445100d7d ; Improve documentation of 'match-buffers'
d4d0da96f0 ; Update make-tarball.txt for Emacs 29.
9b0bf694da ; Fix ldefs-boot.el.
0cb86a348c ; Update ChangeLog.4.
5e039d5a6e * lisp/ldefs-boot.el: Regenerate.
671abd0cc4 Merge branch 'emacs-29' of git.sv.gnu.org:/srv/git/emacs ...
4bc678ec9f Bump Emacs version to 29.0.90
db8f207e52 Fix some cases of incomplete code's indentation [c/c++-ts...
589959fb09 project-search: Pipe the list of files through 'file-regu...
2b91567bf6 Update ChangeLog and AUTHORS for Emacs 29
d6af1f1498 ; doc/lispref/windows.texi: Fix @pxref paren.
57490fff6e ; Backport: Eglot: fix misplaced parenthesis in last comm...
2a62273f3b Backport: Eglot: no more tests based on Pylsp (bug#62694)
5ef7ff0573 ; Start a new ChangeLog.4 file.
11126c6d30 Fix 'C-h k' for "Paste from Kill Menu" in context menus
74ddfe811f ; * doc/misc/calc.texi (Rewrites Tutorial): Fix a typo (b...
08cda286c3 Improve the documentation of the XDS support
14d1c00e80 Allow reindentation of images inserted by 'mm-inline-image'
b63a9eda01 Fix "C-h k" and "C-h c" with Paste from Kill Menu
b36c21e27d Change cursor color on NS port when it matches the face b...
96714c106b Improve documentation of image-related commands
6a2863ca01 Fix handling of sliced images
5be79fd05a ; * etc/NEWS: Announce 'cyrillic-mongolian' IM.
ca1a0fda98 ; Fix last change.
ce63462dbd Add cyrillic-mongolian input method
5880179270 ; Minor addition to the Emacs FAQ
88847dee12 Jsonrpc: don't bind inhibit-read-only to t so early
cb8c87a423 Allow active region when IM is used
305246d972 Add emoji-zoom-reset
470d269ec1 Make emoji-zoom-{increase,decrease} set text properties c...
63d4a86f8d Fix transforming sliced images
5e1953a8f8 ; * etc/NEWS: Minor copyedits of entry for 'keymap-*' fun...
6b9f9df945 ; Improve documentation of 'declare-function'
81d1f46d0f ; Avoid compiler warning in eglot.el.
38cdfcb212 ; Fix description of new 'keymap-*' functions
257090b872 Adapt EMBA scripts.
90c07d3fdd Another terminology fix in ELisp reference manual
a832bc7090 Correct terminology in Elisp Reference Manual
db308233cb Comment out GNUSTEP jobs on EMBA (again)
8c1b102243 ; * lisp/image.el (put-image): Doc fix.
eda88c63ad ; * doc/emacs/trouble.texi (Checklist): Minor grammar fix.
728bc09cf3 Fix regexp string escaping mistake in vhdl-mode.el (bug#6...
479626dbac Update to Org 9.6.3-2-gf2949d
5a1c9aace7 ; Add a bit more docstring to tsx-ts-mode (bug#62429)
86cf9fd932 Eglot: don't watch directories that don't exist
82d0b6c64e ; * lisp/subr.el (use-dialog-box-p): Fix last change.
3619663f98 Preserve peer information for web page in eww-readable
cb8d6ab648 * lisp/subr.el (use-dialog-box-p): Fix conditions for GUI...
fb2c440920 ; * lisp/progmodes/c-ts-mode.el (c++-ts-mode): Add some n...
c0b9530862 Another final fix to last changes
0cc8d6826a Three final fixes to last changes
89e337c3fc ; Make sure 'eshell-command' tests don't prompt the user
097c5ee8f5 Two further fixes to last changes
b39c3cd112 ; * etc/NEWS: Fix typos.
dce08cf05c Improve and fix last changes
89ac5ba11c Fix ModelSim error regexp in vhdl-mode
24ed9c7ae7 ; * doc/emacs/trouble.texi (Checklist): Minor copyedits (...
d1d39a0f09 Document enhancements in handling of echo-area messages
46209b2453 ; Fix last change
21a4ee209c Fix new Eshell tests on MS-Windows
e2ebf3995d ; Auto-commit of loaddefs files.
6419d78fa6 Fix using background commands in 'eshell-command'
3bdbb66efb ; CONTRIBUTE: Minor stylistic changes.
d0eb12e8d3 Fix typo in section 14.1 of Emacs Manual
b2fbec37f3 ; * etc/EGLOT-NEWS: Clarify scope of topmost section
131ec049db Eglot: unbreak eglot-extend-to-xref on w32
0622e1f29f Eglot: ensure server shutdown turns off eglot-inlay-hints...
59f66ea302 ; * lisp/emacs-lisp/package-vc.el: Remove completed item ...
d23dc3dd7e ; * lisp/emacs-lisp/package-vc.el (package-vc): Fix manua...
4508a024e8 ; Clarify documentation of 'cursor' text property
d2e82817a3 Add two typescript-ts-mode faces (bug#62429)
10918fc9d2 Fix scrolling window when point moves up
9b32bc134c Improve documentation of 'defcustom's :set keyword
ab4273056e Comp fix calls to redefined primtives with op-bytecode (b...
c98929c7e1 ; Fix last change
a14c3f62a6 ; Fix last change
09fece5722 Fix duplicate defcustom in eww.el
2093e010dc Fix cursor motion in character-only terminals
e45bd10a3d Fix indentation regression in 'C-h l'
46fd10a760 * doc/misc/tramp.texi (Remote shell setup): Clarify use o...
974e4f3333 Make get_medium_narrowing_begv/zv static
afc2c6c13c Improve accuracy of cursor motion commands in long lines
7e26a5c774 Remove labeled restrictions before calling Fwiden
85ed1c9ca6 Code cleanup for long line optimizations

# Conflicts:
#	etc/NEWS
This commit is contained in:
Eli Zaretskii 2023-05-13 06:36:25 -04:00
commit ea986a64b2
24 changed files with 494 additions and 248 deletions

View file

@ -82,7 +82,7 @@ done
# SKIP-BRANCH 58cc931e92ece70c3e64131ee12a799d65409100
## The list below is the exhaustive list of all commits between Dec 1
## 2016 and Feb 28 2023 on which building Emacs with the default
## 2016 and Apr 30 2023 on which building Emacs with the default
## options, on a GNU/Linux computer and with GCC, fails. It is
## possible (though unlikely) that building Emacs with non-default
## options, with other compilers, or on other platforms, would succeed
@ -1720,3 +1720,6 @@ $REAL_GIT bisect skip $(cat $0 | grep '^# SKIP-SINGLE ' | sed 's/^# SKIP-SINGLE
# SKIP-SINGLE 95692f6754c3a8f55a90df2d6f7ce62be55cdcfc
# SKIP-SINGLE a3edacd3f547195740304139cb68aaa94d7b18ee
# SKIP-SINGLE ae4ff4f25fbf704446f8f38d8e818f223b79042b
# SKIP-SINGLE 9686b015a0d71d08828afb0cfe6e477bbc4909ae
# SKIP-SINGLE 621e732ade0f3dc165498ebde4d55d5aacb05b56
# SKIP-SINGLE 200dbf7d302e659e618f74bde81c7b3ccd795639

View file

@ -160,7 +160,13 @@ current line by an @kbd{i} or @kbd{d} command
Mark all package with a newer available version for upgrading
(@code{package-menu-mark-upgrades}). This places an installation mark
on the new available versions, and a deletion mark on the old
installed versions (marked with status @samp{obsolete}).
installed versions (marked with status @samp{obsolete}). By default,
this won't mark built-in packages for which a newer version is
available, but customizing @code{package-install-upgrade-built-in} can
change that. @xref{Package Installation}. If you customize
@code{package-install-upgrade-built-in} to a non-@code{nil} value, be
sure to review all the built-in packages the @kbd{U} command marks, to
avoid updating built-in packages you don't want to overwrite.
@item x
@kindex x @r{(Package Menu)}
@ -258,7 +264,11 @@ This shows only the packages that have been marked to be installed or deleted.
@kindex / u @r{(Package Menu)}
@findex package-menu-filter-upgradable
Filter package list to show only packages for which there are
available upgrades (@code{package-menu-filter-upgradable}).
available upgrades (@code{package-menu-filter-upgradable}). By
default, this filter excludes the built-in packages for which a newer
version is available, but customizing
@code{package-install-upgrade-built-in} can change that.
@xref{Package Installation}.
@item / /
@kindex / / @r{(Package Menu)}
@ -286,9 +296,12 @@ the package archive.
The package is available for installation, but a newer version is also
available. Packages with this status are hidden by default.
@cindex built-in package
@item built-in
The package is included in Emacs by default. It cannot be deleted
through the package menu, and is not considered for upgrading.
through the package menu, and by default is not considered for
upgrading (but you can change that by customizing
@code{package-install-upgrade-built-in}, @pxref{Package Installation}).
@item dependency
The package was installed automatically to satisfy a dependency of
@ -339,6 +352,37 @@ if you want to upgrade a package, you can use the @kbd{M-x
package-upgrade} command, and if you want to upgrade all the packages,
you can use the @kbd{M-x package-upgrade-all} command.
@vindex package-install-upgrade-built-in
By default, @code{package-install} doesn't consider built-in
packages for which new versions are available from the archives. (A
package is built-in if it is included in the Emacs distribution.) In
particular, it will not show built-in packages in the list of
completion candidates when you type at its prompt. But if you invoke
@code{package-install} with a prefix argument, it will also consider
built-in packages that can be upgraded. You can make this behavior
the default by customizing the variable
@code{package-install-upgrade-built-in}: if its value is
non-@code{nil}, @code{package-install} will consider built-in packages
even when invoked without a prefix argument. Note that the
package-menu commands (@pxref{Package Menu}) are also affected by
@code{package-install-upgrade-built-in}.
By contrast, @code{package-upgrade} and @code{package-upgrade-all}
never consider built-in packages. If you want to use these commands
for upgrading some built-in packages, you need to upgrade each of
those packages, once, either via @kbd{C-u M-x package-install
@key{RET}}, or by customizing @code{package-install-upgrade-built-in}
to a non-@code{nil} value, and then upgrading the package once via the
package menu or by @code{package-install}.
If you customize @code{package-install-upgrade-built-in} to a
non-@code{nil} value, be very careful when using commands that update
many packages at once, like @code{package-upgrade-all} and @kbd{U} in
the package menu: those might overwrite built-in packages that you
didn't intent to replace with newer versions from the archives. Don't
use these bulk commands if you want to update only a small number of
built-in packages.
@cindex package requirements
A package may @dfn{require} certain other packages to be installed,
because it relies on functionality provided by them. When Emacs

View file

@ -1188,6 +1188,7 @@ saved bounds. In that case it is equivalent to
@end example
@cindex labeled narrowing
@cindex labeled restriction
When the optional argument @var{label}, a symbol, is present, the
narrowing is @dfn{labeled}. A labeled narrowing differs from a
non-labeled one in several ways:

View file

@ -31,7 +31,7 @@ General Public License for more details.
@finalout
@titlepage
@title Transient User and Developer Manual
@subtitle for version 0.3.7.50
@subtitle for version 0.4.0
@author Jonas Bernoulli
@page
@vskip 0pt plus 1filll
@ -74,7 +74,7 @@ that hurdle is Psionic K's interactive tutorial, available at
@end quotation
@noindent
This manual is for Transient version 0.3.7.50.
This manual is for Transient version 0.4.0.
@insertcopying
@end ifnottex

View file

@ -1906,6 +1906,13 @@ default, this is disabled; however, if 'package-install' is invoked
with a prefix argument, it will act as if this new option were
enabled.
In addition, when this option is non-nil, built-in packages for which
a new version is available in archives can be upgraded via the package
menu produced by 'M-x list-packages'. If you do set this option
non-nil, we recommend not to use the 'U' command, but instead to use
'/ u' to show the packages which can be upgraded, and then decide
which ones of them you actually want to update from the archives.
If you customize this option, we recommend you place its non-default
setting in your early-init file.

View file

@ -656,7 +656,20 @@ instead of just updating them with the new/changed autoloads."
(write-region (point-min) (point-max) loaddefs-file nil 'silent)
(byte-compile-info
(file-relative-name loaddefs-file (car (ensure-list dir)))
t "GEN")))))))
t "GEN")))))
;; If processing files without any autoloads, the above loop will
;; not generate any files. If the function was invoked with
;; EXTRA-DATA, we want to ensure that even if no autoloads were
;; found, that at least a file will have been generated containing
;; the contents of EXTRA-DATA:
(when (and extra-data (not (file-exists-p output-file)))
(with-temp-buffer
(insert (loaddefs-generate--rubric output-file nil t))
(search-backward "\f")
(insert extra-data)
(ensure-empty-lines 1)
(write-region (point-min) (point-max) output-file nil 'silent)))))
(defun loaddefs-generate--print-form (def)
"Print DEF in a format that makes sense for version control."

View file

@ -3740,7 +3740,7 @@ corresponding to the newer version."
;; ENTRY is (PKG-DESC [NAME VERSION STATUS DOC])
(let ((pkg-desc (car entry))
(status (aref (cadr entry) 2)))
(cond ((member status '("installed" "dependency" "unsigned" "external"))
(cond ((member status '("installed" "dependency" "unsigned" "external" "built-in"))
(push pkg-desc installed))
((member status '("available" "new"))
(setq available (package--append-to-alist pkg-desc available))))))
@ -3751,6 +3751,8 @@ corresponding to the newer version."
(and avail-pkg
(version-list-< (package-desc-priority-version pkg-desc)
(package-desc-priority-version avail-pkg))
(xor (not package-install-upgrade-built-in)
(package--active-built-in-p pkg-desc))
(push (cons name avail-pkg) upgrades))))
upgrades))

View file

@ -314,7 +314,9 @@ retried once before actually displaying the error report."
(when nntp-record-commands
(nntp-record-command "*** CALLED nntp-report ***"))
(nnheader-report 'nntp args)))
(nnheader-report 'nntp args)
(apply #'error args)))
(defsubst nntp-copy-to-buffer (buffer start end)
"Copy string from unibyte current buffer to multibyte buffer."

View file

@ -4018,7 +4018,7 @@ same LABEL argument.
"Helper function for `with-restriction', which see."
(save-restriction
(narrow-to-region start end)
(if label (internal--lock-narrowing label))
(if label (internal--label-restriction label))
(funcall body)))
(defmacro without-restriction (&rest rest)
@ -4040,7 +4040,7 @@ are lifted.
(defun internal--without-restriction (body &optional label)
"Helper function for `without-restriction', which see."
(save-restriction
(if label (internal--unlock-narrowing label))
(if label (internal--unlabel-restriction label))
(widen)
(funcall body)))

View file

@ -409,6 +409,8 @@ REPORT-FN is the callback function."
;;; Texinfo mode
(defvar fill-paragraph-separate nil)
;;;###autoload
(define-derived-mode texinfo-mode text-mode "Texinfo"
"Major mode for editing Texinfo files.
@ -482,6 +484,10 @@ value of `texinfo-mode-hook'."
"\\)\\>"))
(setq-local require-final-newline mode-require-final-newline)
(setq-local indent-tabs-mode nil)
;; This is used in 'texinfo--fill-paragraph'.
(setq-local fill-paragraph-separate (default-value 'paragraph-separate))
(setq-local paragraph-separate
(concat "@[a-zA-Z]*[ \n]\\|" paragraph-separate))
(setq-local paragraph-start (concat "@[a-zA-Z]*[ \n]\\|"
paragraph-start))
(setq-local fill-paragraph-function 'texinfo--fill-paragraph)
@ -536,7 +542,13 @@ value of `texinfo-mode-hook'."
(defun texinfo--fill-paragraph (justify)
"Function to fill a paragraph in `texinfo-mode'."
(let ((command-re "\\(@[a-zA-Z]+\\)[ \t\n]"))
(let ((command-re "\\(@[a-zA-Z]+\\)[ \t\n]")
;; Kludge alert: we override paragraph-separate here because
;; that is needed for filling @noindent and similar lines.
;; The default Texinfo-specific paragraph-separate value,
;; OTOH, is needed for auto-fill-mode, which doesn't call
;; mode-specific functions.
(paragraph-separate fill-paragraph-separate))
(catch 'no-fill
(save-restriction
;; First check whether we're on a command line that can be

View file

@ -6,7 +6,7 @@
;; URL: https://github.com/magit/transient
;; Keywords: extensions
;; Package-Version: 0.3.7.50
;; Package-Version: 0.4.0
;; Package-Requires: ((emacs "26.1"))
;; SPDX-License-Identifier: GPL-3.0-or-later
@ -3934,8 +3934,13 @@ search instead."
(defun transient-isearch-abort ()
"Like `isearch-abort' but adapted for `transient'."
(interactive)
(condition-case nil (isearch-abort) (quit))
(transient--isearch-exit))
(let ((around (lambda (fn)
(condition-case nil (funcall fn) (quit))
(transient--isearch-exit))))
(advice-add 'isearch-cancel :around around)
(unwind-protect
(isearch-abort)
(advice-remove 'isearch-cancel around))))
(defun transient--isearch-setup ()
(select-window transient--window)

View file

@ -499,7 +499,7 @@ With CHECK-AFTER non-nil, considers also the content after point, if needed."
(defmacro widget-specify-insert (&rest form)
"Execute FORM without inheriting any text properties."
(declare (debug body))
(declare (debug (body)))
`(save-restriction
(let ((inhibit-read-only t)
(inhibit-modification-hooks t))

View file

@ -2386,6 +2386,7 @@ Any narrowing restriction in effect (see `narrow-to-region') is removed,
so the buffer is truly empty after this. */)
(void)
{
labeled_restrictions_remove_in_current_buffer ();
Fwiden ();
del_range (BEG, Z);

View file

@ -1113,6 +1113,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
{
/* No need to save restrictions since we delete everything
anyway. */
labeled_restrictions_remove_in_current_buffer ();
Fwiden ();
del_range (BEG, Z);
}

View file

@ -1077,7 +1077,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
with long lines, however, NL might be far away, so
pretend that the buffer is smaller. */
if (current_buffer->long_line_optimizations_p)
endpos = get_closer_narrowed_begv (cmp_it->parent_it->w, charpos);
endpos = get_small_narrowing_begv (cmp_it->parent_it->w, charpos);
}
}
cmp_it->id = -1;
@ -1660,7 +1660,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
{
/* In buffers with very long lines, this function becomes very
slow. Pretend that the buffer is narrowed to make it fast. */
ptrdiff_t begv = get_closer_narrowed_begv (w, window_point (w));
ptrdiff_t begv = get_small_narrowing_begv (w, window_point (w));
if (pos > begv)
head = begv;
}

View file

@ -2334,21 +2334,20 @@ struct it
with which display_string was called. */
ptrdiff_t end_charpos;
/* Alternate begin position of the buffer that may be used to
optimize display (see the SET_WITH_NARROWED_BEGV macro). */
ptrdiff_t narrowed_begv;
/* Alternate begin and end positions of the buffer that are used to
optimize display of buffers with long lines. These two fields
hold the return value of the 'get_medium_narrowing_begv' and
'get_medium_narrowing_zv' functions. */
ptrdiff_t medium_narrowing_begv;
ptrdiff_t medium_narrowing_zv;
/* Alternate end position of the buffer that may be used to
optimize display. */
ptrdiff_t narrowed_zv;
/* Begin position of the buffer for the locked narrowing around
low-level hooks. */
ptrdiff_t locked_narrowing_begv;
/* End position of the buffer for the locked narrowing around
low-level hooks. */
ptrdiff_t locked_narrowing_zv;
/* Alternate begin and end positions of the buffer that are used for
labeled narrowings around low-level hooks in buffers with long
lines. These two fields hold the return value of the
'get_large_narrowing_begv' and 'get_large_narrowing_zv'
functions. */
ptrdiff_t large_narrowing_begv;
ptrdiff_t large_narrowing_zv;
/* C string to iterate over. Non-null means get characters from
this string, otherwise characters are read from current_buffer
@ -3410,11 +3409,9 @@ void mark_window_display_accurate (Lisp_Object, bool);
void redisplay_preserve_echo_area (int);
void init_iterator (struct it *, struct window *, ptrdiff_t,
ptrdiff_t, struct glyph_row *, enum face_id);
ptrdiff_t get_narrowed_begv (struct window *, ptrdiff_t);
ptrdiff_t get_narrowed_zv (struct window *, ptrdiff_t);
ptrdiff_t get_closer_narrowed_begv (struct window *, ptrdiff_t);
ptrdiff_t get_locked_narrowing_begv (ptrdiff_t);
ptrdiff_t get_locked_narrowing_zv (ptrdiff_t);
ptrdiff_t get_small_narrowing_begv (struct window *, ptrdiff_t);
ptrdiff_t get_large_narrowing_begv (ptrdiff_t);
ptrdiff_t get_large_narrowing_zv (ptrdiff_t);
void init_iterator_to_row_start (struct it *, struct window *,
struct glyph_row *);
void start_display (struct it *, struct window *, struct text_pos);

View file

@ -2653,182 +2653,203 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
return del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1);
}
/* Alist of buffers in which locked narrowing is used. The car of
each list element is a buffer, the cdr is a list of triplets (tag
begv-marker zv-marker). The last element of that list always uses
the (uninterned) Qoutermost_narrowing tag and records the narrowing
bounds that were set by the user and that are visible on display.
This alist is used internally by narrow-to-region, widen,
internal--lock-narrowing, internal--unlock-narrowing and
save-restriction. For efficiency reasons, an alist is used instead
of a buffer-local variable: otherwise reset_outermost_narrowings,
which is called during each redisplay cycle, would have to loop
through all live buffers. */
static Lisp_Object narrowing_locks;
/* Alist of buffers in which labeled restrictions are used. The car
of each list element is a buffer, the cdr is a list of triplets
(label begv-marker zv-marker). The last triplet of that list
always uses the (uninterned) Qoutermost_restriction label, and
records the restriction bounds that were current when the first
labeled restriction was entered (which may be a narrowing that was
set by the user and is visible on display). This alist is used
internally by narrow-to-region, widen, internal--label-restriction,
internal--unlabel-restriction and save-restriction. For efficiency
reasons, an alist is used instead of a buffer-local variable:
otherwise reset_outermost_restrictions, which is called during each
redisplay cycle, would have to loop through all live buffers. */
static Lisp_Object labeled_restrictions;
/* Add BUF with its LOCKS in the narrowing_locks alist. */
/* Add BUF with its list of labeled RESTRICTIONS in the
labeled_restrictions alist. */
static void
narrowing_locks_add (Lisp_Object buf, Lisp_Object locks)
labeled_restrictions_add (Lisp_Object buf, Lisp_Object restrictions)
{
narrowing_locks = nconc2 (list1 (list2 (buf, locks)), narrowing_locks);
labeled_restrictions = nconc2 (list1 (list2 (buf, restrictions)),
labeled_restrictions);
}
/* Remove BUF and its locks from the narrowing_locks alist. Do
nothing if BUF is not present in narrowing_locks. */
/* Remove BUF and its list of labeled restrictions from the
labeled_restrictions alist. Do nothing if BUF is not present in
labeled_restrictions. */
static void
narrowing_locks_remove (Lisp_Object buf)
labeled_restrictions_remove (Lisp_Object buf)
{
narrowing_locks = Fdelq (Fassoc (buf, narrowing_locks, Qnil),
narrowing_locks);
labeled_restrictions = Fdelq (Fassoc (buf, labeled_restrictions, Qnil),
labeled_restrictions);
}
/* Retrieve one of the BEGV/ZV bounds of a narrowing in BUF from the
narrowing_locks alist, as a pointer to a struct Lisp_Marker, or
NULL if BUF is not in narrowing_locks or is a killed buffer. When
OUTERMOST is true, the bounds that were set by the user and that
are visible on display are returned. Otherwise the innermost
locked narrowing bounds are returned. */
static struct Lisp_Marker *
narrowing_lock_get_bound (Lisp_Object buf, bool begv, bool outermost)
/* Retrieve one of the labeled restriction bounds in BUF from the
labeled_restrictions alist, as a marker, or return nil if BUF is
not in labeled_restrictions or is a killed buffer. When OUTERMOST
is true, the restriction bounds that were current when the first
labeled restriction was entered are returned. Otherwise the bounds
of the innermost labeled restriction are returned. */
static Lisp_Object
labeled_restrictions_get_bound (Lisp_Object buf, bool begv, bool outermost)
{
if (NILP (Fbuffer_live_p (buf)))
return NULL;
Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks);
if (NILP (buffer_locks))
return NULL;
buffer_locks = XCAR (XCDR (buffer_locks));
return Qnil;
Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
if (NILP (restrictions))
return Qnil;
restrictions = XCAR (XCDR (restrictions));
Lisp_Object bounds
= outermost
? XCDR (assq_no_quit (Qoutermost_narrowing, buffer_locks))
: XCDR (XCAR (buffer_locks));
? XCDR (assq_no_quit (Qoutermost_restriction, restrictions))
: XCDR (XCAR (restrictions));
eassert (! NILP (bounds));
Lisp_Object marker = begv ? XCAR (bounds) : XCAR (XCDR (bounds));
eassert (EQ (Fmarker_buffer (marker), buf));
return XMARKER (marker);
return marker;
}
/* Retrieve the tag of the innermost narrowing in BUF. Return nil if
BUF is not in narrowing_locks or is a killed buffer. */
/* Retrieve the label of the innermost labeled restriction in BUF.
Return nil if BUF is not in labeled_restrictions or is a killed
buffer. */
static Lisp_Object
narrowing_lock_peek_tag (Lisp_Object buf)
labeled_restrictions_peek_label (Lisp_Object buf)
{
if (NILP (Fbuffer_live_p (buf)))
return Qnil;
Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks);
if (NILP (buffer_locks))
Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
if (NILP (restrictions))
return Qnil;
Lisp_Object tag = XCAR (XCAR (XCAR (XCDR (buffer_locks))));
eassert (! NILP (tag));
return tag;
Lisp_Object label = XCAR (XCAR (XCAR (XCDR (restrictions))));
eassert (! NILP (label));
return label;
}
/* Add a LOCK for BUF in the narrowing_locks alist. */
/* Add a labeled RESTRICTION for BUF in the labeled_restrictions
alist. */
static void
narrowing_lock_push (Lisp_Object buf, Lisp_Object lock)
labeled_restrictions_push (Lisp_Object buf, Lisp_Object restriction)
{
Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks);
if (NILP (buffer_locks))
narrowing_locks_add (buf, list1 (lock));
Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
if (NILP (restrictions))
labeled_restrictions_add (buf, list1 (restriction));
else
XSETCDR (buffer_locks, list1 (nconc2 (list1 (lock),
XCAR (XCDR (buffer_locks)))));
XSETCDR (restrictions, list1 (nconc2 (list1 (restriction),
XCAR (XCDR (restrictions)))));
}
/* Remove the innermost lock in BUF from the narrowing_locks alist.
Do nothing if BUF is not present in narrowing_locks. */
/* Remove the innermost labeled restriction in BUF from the
labeled_restrictions alist. Do nothing if BUF is not present in
labeled_restrictions. */
static void
narrowing_lock_pop (Lisp_Object buf)
labeled_restrictions_pop (Lisp_Object buf)
{
Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks);
if (NILP (buffer_locks))
Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
if (NILP (restrictions))
return;
if (EQ (narrowing_lock_peek_tag (buf), Qoutermost_narrowing))
narrowing_locks_remove (buf);
if (EQ (labeled_restrictions_peek_label (buf), Qoutermost_restriction))
labeled_restrictions_remove (buf);
else
XSETCDR (buffer_locks, list1 (XCDR (XCAR (XCDR (buffer_locks)))));
XSETCDR (restrictions, list1 (XCDR (XCAR (XCDR (restrictions)))));
}
/* Unconditionally remove all labeled restrictions in current_buffer. */
void
labeled_restrictions_remove_in_current_buffer (void)
{
labeled_restrictions_remove (Fcurrent_buffer ());
}
static void
unwind_reset_outermost_narrowing (Lisp_Object buf)
unwind_reset_outermost_restriction (Lisp_Object buf)
{
struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false);
struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false);
if (begv != NULL && zv != NULL)
Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
if (! NILP (begv) && ! NILP (zv))
{
SET_BUF_BEGV_BOTH (XBUFFER (buf), begv->charpos, begv->bytepos);
SET_BUF_ZV_BOTH (XBUFFER (buf), zv->charpos, zv->bytepos);
SET_BUF_BEGV_BOTH (XBUFFER (buf),
marker_position (begv), marker_byte_position (begv));
SET_BUF_ZV_BOTH (XBUFFER (buf),
marker_position (zv), marker_byte_position (zv));
}
else
narrowing_locks_remove (buf);
labeled_restrictions_remove (buf);
}
/* Restore the narrowing bounds that were set by the user, and restore
the bounds of the locked narrowing upon return.
/* Restore the restriction bounds that were current when the first
labeled restriction was entered, and restore the bounds of the
innermost labeled restriction upon return.
In particular, this function is called when redisplay starts, so
that if a Lisp function executed during redisplay calls (redisplay)
while a locked narrowing is in effect, the locked narrowing will
not be visible on display.
while labeled restrictions are in effect, these restrictions will
not become visible on display.
See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#140 and
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#254 for example
recipes that demonstrate why this is necessary. */
void
reset_outermost_narrowings (void)
reset_outermost_restrictions (void)
{
Lisp_Object val, buf;
for (val = narrowing_locks; CONSP (val); val = XCDR (val))
for (val = labeled_restrictions; CONSP (val); val = XCDR (val))
{
buf = XCAR (XCAR (val));
eassert (BUFFERP (buf));
struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, true);
struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, true);
if (begv != NULL && zv != NULL)
Lisp_Object begv = labeled_restrictions_get_bound (buf, true, true);
Lisp_Object zv = labeled_restrictions_get_bound (buf, false, true);
if (! NILP (begv) && ! NILP (zv))
{
SET_BUF_BEGV_BOTH (XBUFFER (buf), begv->charpos, begv->bytepos);
SET_BUF_ZV_BOTH (XBUFFER (buf), zv->charpos, zv->bytepos);
record_unwind_protect (unwind_reset_outermost_narrowing, buf);
SET_BUF_BEGV_BOTH (XBUFFER (buf),
marker_position (begv), marker_byte_position (begv));
SET_BUF_ZV_BOTH (XBUFFER (buf),
marker_position (zv), marker_byte_position (zv));
record_unwind_protect (unwind_reset_outermost_restriction, buf);
}
else
narrowing_locks_remove (buf);
labeled_restrictions_remove (buf);
}
}
/* Helper functions to save and restore the narrowing locks of the
current buffer in Fsave_restriction. */
/* Helper functions to save and restore the labeled restrictions of
the current buffer in Fsave_restriction. */
static Lisp_Object
narrowing_locks_save (void)
labeled_restrictions_save (void)
{
Lisp_Object buf = Fcurrent_buffer ();
Lisp_Object locks = assq_no_quit (buf, narrowing_locks);
if (!NILP (locks))
locks = XCAR (XCDR (locks));
return Fcons (buf, Fcopy_sequence (locks));
Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
if (! NILP (restrictions))
restrictions = XCAR (XCDR (restrictions));
return Fcons (buf, Fcopy_sequence (restrictions));
}
static void
narrowing_locks_restore (Lisp_Object buf_and_saved_locks)
labeled_restrictions_restore (Lisp_Object buf_and_restrictions)
{
Lisp_Object buf = XCAR (buf_and_saved_locks);
Lisp_Object saved_locks = XCDR (buf_and_saved_locks);
narrowing_locks_remove (buf);
if (!NILP (saved_locks))
narrowing_locks_add (buf, saved_locks);
Lisp_Object buf = XCAR (buf_and_restrictions);
Lisp_Object restrictions = XCDR (buf_and_restrictions);
labeled_restrictions_remove (buf);
if (! NILP (restrictions))
labeled_restrictions_add (buf, restrictions);
}
static void
unwind_narrow_to_region_locked (Lisp_Object tag)
unwind_labeled_narrow_to_region (Lisp_Object label)
{
Finternal__unlock_narrowing (tag);
Finternal__unlabel_restriction (label);
Fwiden ();
}
/* Narrow current_buffer to BEGV-ZV with a narrowing locked with TAG. */
/* Narrow current_buffer to BEGV-ZV with a restriction labeled with
LABEL. */
void
narrow_to_region_locked (Lisp_Object begv, Lisp_Object zv, Lisp_Object tag)
labeled_narrow_to_region (Lisp_Object begv, Lisp_Object zv,
Lisp_Object label)
{
Fnarrow_to_region (begv, zv);
Finternal__lock_narrowing (tag);
Finternal__label_restriction (label);
record_unwind_protect (restore_point_unwind, Fpoint_marker ());
record_unwind_protect (unwind_narrow_to_region_locked, tag);
record_unwind_protect (unwind_labeled_narrow_to_region, label);
}
DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
@ -2842,11 +2863,11 @@ To gain access to other portions of the buffer, use
`without-restriction' with the same label. */)
(void)
{
Fset (Qoutermost_narrowing, Qnil);
Fset (Qoutermost_restriction, Qnil);
Lisp_Object buf = Fcurrent_buffer ();
Lisp_Object tag = narrowing_lock_peek_tag (buf);
Lisp_Object label = labeled_restrictions_peek_label (buf);
if (NILP (tag))
if (NILP (label))
{
if (BEG != BEGV || Z != ZV)
current_buffer->clip_changed = 1;
@ -2856,19 +2877,23 @@ To gain access to other portions of the buffer, use
}
else
{
struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false);
struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false);
eassert (begv != NULL && zv != NULL);
if (begv->charpos != BEGV || zv->charpos != ZV)
Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
eassert (! NILP (begv) && ! NILP (zv));
ptrdiff_t begv_charpos = marker_position (begv);
ptrdiff_t zv_charpos = marker_position (zv);
if (begv_charpos != BEGV || zv_charpos != ZV)
current_buffer->clip_changed = 1;
SET_BUF_BEGV_BOTH (current_buffer, begv->charpos, begv->bytepos);
SET_BUF_ZV_BOTH (current_buffer, zv->charpos, zv->bytepos);
/* If the only remaining bounds in narrowing_locks for
SET_BUF_BEGV_BOTH (current_buffer,
begv_charpos, marker_byte_position (begv));
SET_BUF_ZV_BOTH (current_buffer,
zv_charpos, marker_byte_position (zv));
/* If the only remaining bounds in labeled_restrictions for
current_buffer are the bounds that were set by the user, no
locked narrowing is in effect in current_buffer anymore:
remove it from the narrowing_locks alist. */
if (EQ (tag, Qoutermost_narrowing))
narrowing_lock_pop (buf);
labeled restriction is in effect in current_buffer anymore:
remove it from the labeled_restrictions alist. */
if (EQ (label, Qoutermost_restriction))
labeled_restrictions_pop (buf);
}
/* Changing the buffer bounds invalidates any recorded current column. */
invalidate_current_column ();
@ -2905,25 +2930,27 @@ argument. To gain access to other portions of the buffer, use
args_out_of_range (start, end);
Lisp_Object buf = Fcurrent_buffer ();
if (! NILP (narrowing_lock_peek_tag (buf)))
if (! NILP (labeled_restrictions_peek_label (buf)))
{
struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false);
struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false);
eassert (begv != NULL && zv != NULL);
/* Limit the start and end positions to those of the locked
narrowing. */
if (s < begv->charpos) s = begv->charpos;
if (s > zv->charpos) s = zv->charpos;
if (e < begv->charpos) e = begv->charpos;
if (e > zv->charpos) e = zv->charpos;
/* Limit the start and end positions to those of the innermost
labeled restriction. */
Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
eassert (! NILP (begv) && ! NILP (zv));
ptrdiff_t begv_charpos = marker_position (begv);
ptrdiff_t zv_charpos = marker_position (zv);
if (s < begv_charpos) s = begv_charpos;
if (s > zv_charpos) s = zv_charpos;
if (e < begv_charpos) e = begv_charpos;
if (e > zv_charpos) e = zv_charpos;
}
/* Record the accessible range of the buffer when narrow-to-region
is called, that is, before applying the narrowing. It is used
only by internal--lock-narrowing. */
Fset (Qoutermost_narrowing, list3 (Qoutermost_narrowing,
Fpoint_min_marker (),
Fpoint_max_marker ()));
is called, that is, before applying the narrowing. That
information is used only by internal--label-restriction. */
Fset (Qoutermost_restriction, list3 (Qoutermost_restriction,
Fpoint_min_marker (),
Fpoint_max_marker ()));
if (BEGV != s || ZV != e)
current_buffer->clip_changed = 1;
@ -2940,38 +2967,38 @@ argument. To gain access to other portions of the buffer, use
return Qnil;
}
DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing,
Sinternal__lock_narrowing, 1, 1, 0,
doc: /* Lock the current narrowing with LABEL.
DEFUN ("internal--label-restriction", Finternal__label_restriction,
Sinternal__label_restriction, 1, 1, 0,
doc: /* Label the current restriction with LABEL.
This is an internal function used by `with-restriction'. */)
(Lisp_Object tag)
(Lisp_Object label)
{
Lisp_Object buf = Fcurrent_buffer ();
Lisp_Object outermost_narrowing
= buffer_local_value (Qoutermost_narrowing, buf);
/* If internal--lock-narrowing is ever called without being preceded
by narrow-to-region, do nothing. */
if (NILP (outermost_narrowing))
Lisp_Object outermost_restriction
= buffer_local_value (Qoutermost_restriction, buf);
/* If internal--label-restriction is ever called without being
preceded by narrow-to-region, do nothing. */
if (NILP (outermost_restriction))
return Qnil;
if (NILP (narrowing_lock_peek_tag (buf)))
narrowing_lock_push (buf, outermost_narrowing);
narrowing_lock_push (buf, list3 (tag,
Fpoint_min_marker (),
Fpoint_max_marker ()));
if (NILP (labeled_restrictions_peek_label (buf)))
labeled_restrictions_push (buf, outermost_restriction);
labeled_restrictions_push (buf, list3 (label,
Fpoint_min_marker (),
Fpoint_max_marker ()));
return Qnil;
}
DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing,
Sinternal__unlock_narrowing, 1, 1, 0,
doc: /* Unlock a narrowing locked with LABEL.
DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction,
Sinternal__unlabel_restriction, 1, 1, 0,
doc: /* If the current restriction is labeled with LABEL, remove its label.
This is an internal function used by `without-restriction'. */)
(Lisp_Object tag)
(Lisp_Object label)
{
Lisp_Object buf = Fcurrent_buffer ();
if (EQ (narrowing_lock_peek_tag (buf), tag))
narrowing_lock_pop (buf);
if (EQ (labeled_restrictions_peek_label (buf), label))
labeled_restrictions_pop (buf);
return Qnil;
}
@ -3071,15 +3098,15 @@ save_restriction_restore_1 (Lisp_Object data)
Lisp_Object
save_restriction_save (void)
{
Lisp_Object restr = save_restriction_save_1 ();
Lisp_Object locks = narrowing_locks_save ();
return Fcons (restr, locks);
Lisp_Object restriction = save_restriction_save_1 ();
Lisp_Object labeled_restrictions = labeled_restrictions_save ();
return Fcons (restriction, labeled_restrictions);
}
void
save_restriction_restore (Lisp_Object data)
{
narrowing_locks_restore (XCDR (data));
labeled_restrictions_restore (XCDR (data));
save_restriction_restore_1 (XCAR (data));
}
@ -4748,7 +4775,7 @@ syms_of_editfns (void)
DEFSYM (Qwall, "wall");
DEFSYM (Qpropertize, "propertize");
staticpro (&narrowing_locks);
staticpro (&labeled_restrictions);
DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion,
doc: /* Non-nil means text motion commands don't notice fields. */);
@ -4809,12 +4836,12 @@ This variable is experimental; email 32252@debbugs.gnu.org if you need
it to be non-nil. */);
binary_as_unsigned = false;
DEFVAR_LISP ("outermost-narrowing", Voutermost_narrowing,
DEFVAR_LISP ("outermost-restriction", Voutermost_restriction,
doc: /* Outermost narrowing bounds, if any. Internal use only. */);
Voutermost_narrowing = Qnil;
Fmake_variable_buffer_local (Qoutermost_narrowing);
DEFSYM (Qoutermost_narrowing, "outermost-narrowing");
Funintern (Qoutermost_narrowing, Qnil);
Voutermost_restriction = Qnil;
Fmake_variable_buffer_local (Qoutermost_restriction);
DEFSYM (Qoutermost_restriction, "outermost-restriction");
Funintern (Qoutermost_restriction, Qnil);
defsubr (&Spropertize);
defsubr (&Schar_equal);
@ -4907,8 +4934,8 @@ it to be non-nil. */);
defsubr (&Sdelete_and_extract_region);
defsubr (&Swiden);
defsubr (&Snarrow_to_region);
defsubr (&Sinternal__lock_narrowing);
defsubr (&Sinternal__unlock_narrowing);
defsubr (&Sinternal__label_restriction);
defsubr (&Sinternal__unlabel_restriction);
defsubr (&Ssave_restriction);
defsubr (&Stranspose_regions);
}

View file

@ -5246,6 +5246,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
}
record_unwind_protect (save_restriction_restore, save_restriction_save ());
labeled_restrictions_remove_in_current_buffer ();
/* Special kludge to simplify auto-saving. */
if (NILP (start))

View file

@ -590,7 +590,6 @@ ftcrfont_draw (struct glyph_string *s,
GREEN_FROM_ULONG (col) / 255.0,
BLUE_FROM_ULONG (col) / 255.0);
#endif
s->background_filled_p = 1;
cairo_rectangle (cr, x, y - FONT_BASE (s->font),
s->width, FONT_HEIGHT (s->font));
cairo_fill (cr);

View file

@ -2065,6 +2065,7 @@ line_number_display_width (struct window *w, int *width, int *pixel_width)
{
record_unwind_protect (save_restriction_restore,
save_restriction_save ());
labeled_restrictions_remove_in_current_buffer ();
Fwiden ();
saved_restriction = true;
}

View file

@ -318,6 +318,8 @@ static Lisp_Object command_loop (void);
static void echo_now (void);
static ptrdiff_t echo_length (void);
static void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
/* Incremented whenever a timer is run. */
unsigned timers_run;
@ -1909,7 +1911,7 @@ safe_run_hooks (Lisp_Object hook)
unbind_to (count, Qnil);
}
void
static void
safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
{
specpdl_ref count = SPECPDL_INDEX ();
@ -1919,11 +1921,11 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
if (current_buffer->long_line_optimizations_p
&& long_line_optimizations_region_size > 0)
{
ptrdiff_t begv = get_locked_narrowing_begv (PT);
ptrdiff_t zv = get_locked_narrowing_zv (PT);
ptrdiff_t begv = get_large_narrowing_begv (PT);
ptrdiff_t zv = get_large_narrowing_zv (PT);
if (begv != BEG || zv != Z)
narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv),
Qlong_line_optimizations_in_command_hooks);
labeled_narrow_to_region (make_fixnum (begv), make_fixnum (zv),
Qlong_line_optimizations_in_command_hooks);
}
run_hook_with_args (2, ((Lisp_Object []) {hook, hook}),

View file

@ -4680,8 +4680,9 @@ extern void save_restriction_restore (Lisp_Object);
extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t, bool);
extern void narrow_to_region_locked (Lisp_Object, Lisp_Object, Lisp_Object);
extern void reset_outermost_narrowings (void);
extern void labeled_narrow_to_region (Lisp_Object, Lisp_Object, Lisp_Object);
extern void reset_outermost_restrictions (void);
extern void labeled_restrictions_remove_in_current_buffer (void);
extern void init_editfns (void);
extern void syms_of_editfns (void);
@ -4850,7 +4851,6 @@ extern bool detect_input_pending (void);
extern bool detect_input_pending_ignore_squeezables (void);
extern bool detect_input_pending_run_timers (bool);
extern void safe_run_hooks (Lisp_Object);
extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
extern void safe_run_hooks_2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern void cmd_error_internal (Lisp_Object, const char *);
extern Lisp_Object command_loop_2 (Lisp_Object);

View file

@ -2255,6 +2255,7 @@ readevalloop (Lisp_Object readcharfun,
record_unwind_protect_excursion ();
/* Save ZV in it. */
record_unwind_protect (save_restriction_restore, save_restriction_save ());
labeled_restrictions_remove_in_current_buffer ();
/* Those get unbound after we read one expression. */
/* Set point and ZV around stuff to be read. */

View file

@ -3482,7 +3482,7 @@ init_iterator (struct it *it, struct window *w,
/* This is set only when long_line_optimizations_p is non-zero
for the current buffer. */
it->narrowed_begv = 0;
it->medium_narrowing_begv = 0;
/* Compute faces etc. */
reseat (it, it->current.pos, true);
@ -3491,17 +3491,104 @@ init_iterator (struct it *it, struct window *w,
CHECK_IT (it);
}
/* Compute a suitable alternate value for BEGV and ZV that may be used
temporarily to optimize display if the buffer in window W contains
long lines. */
/* How Emacs deals with long lines.
(1) When a buffer is about to be (re)displayed, 'redisplay_window'
detects, with a heuristic, whether it contains long lines.
This happens in 'redisplay_window' because it is only displaying
buffers with long lines that is problematic. In other words, none
of the optimizations described below is ever used in buffers that
are never displayed.
This happens with a heuristic, which checks whether a buffer
contains long lines, each time its contents have changed "enough"
between two redisplay cycles, because a buffer without long lines
can become a buffer with long lines at any time, for example after
a yank command, or after a replace command, or while the output of
an external process is inserted in a buffer.
When Emacs has detected that a buffer contains long lines, the
buffer-local variable 'long_line_optimizations_p' (in 'struct
buffer') is set, and Emacs does not try to detect whether the
buffer does or does not contain long lines anymore.
What a long line is depends on the variable 'long-line-threshold',
whose default value is 50000 (characters).
(2) When a buffer with long lines is (re)displayed, the amount of
data that the display routines consider is, in a few well-chosen
places, limited with a temporary restriction, whose bounds are
calculated with the functions below.
(2.1) 'get_small_narrowing_begv' is used to create a restriction
which starts a few hundred characters before point. The exact
number of characters depends on the width of the window in which
the buffer is displayed.
There is no corresponding 'get_small_narrowing_zv' function,
because it is not necessary to set the end limit of that
restriction.
This restriction is used in four places, namely:
'back_to_previous_line_start' and 'move_it_vertically_backward'
(with the 'SET_WITH_NARROWED_BEGV' macro), and in
'composition_compute_stop_pos' and 'find_automatic_composition' (in
a conditional statement depending on 'long_line_optimizations_p').
(2.2) 'get_medium_narrowing_begv' is used to create a restriction
which starts a few thousand characters before point. The exact
number of characters depends on the size (width and height) of the
window in which the buffer is displayed. For performance reasons,
the return value of that function is cached in 'struct it', in the
'medium_narrowing_begv' field.
The corresponding function 'get_medium_narrowing_zv' (and
'medium_narrowing_zv' field in 'struct it') is not used to set the
end limit of the restriction, which is again unnecessary, but to
determine, in 'reseat', whether the iterator has moved far enough
from its original position, and whether the start position of the
restriction must be computed anew.
This restriction is used in a single place:
'get_visually_first_element', with the 'SET_WITH_NARROWED_BEGV'
macro.
(2.3) 'get_large_narrowing_begv' and 'get_large_narrowing_zv' are
used to create a restriction which starts a few hundred thousand
characters before point and ends a few hundred thousand characters
after point. The size of that restriction depends on the variable
'long-line-optimizations-region-size', whose default value is
500000 (characters); it can be adjusted by a few hundred characters
depending on 'long-line-optimizations-bol-search-limit', whose
default value is 128 (characters).
For performance reasons again, the return values of these functions
are stored in the 'large_narrowing_begv' and 'large_narrowing_zv'
fields in 'struct it'.
The restriction defined by these values is used around three
low-level hooks: around 'fontification-functions', in
'handle_fontified_prop', and around 'pre-command-hook' and
'post-command-hook', in 'safe_run_hooks_maybe_narrowed', which is
called in 'command_loop_1'. These restrictions are set around
these hooks with 'labeled_narrow_to_region'; the restrictions are
labeled, and cannot be removed with a call to 'widen', but can be
removed with 'without-restriction' with a :label argument.
*/
static int
get_narrowed_width (struct window *w)
{
/* In a character-only terminal, only one font size is used, so we
can use a smaller factor. */
int fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3;
int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS);
int fact = FRAME_WINDOW_P (XFRAME (w->frame)) ? 3 : 2;
/* If the window has no fringes (in a character-only terminal or in
a GUI frame without fringes), subtract 1 from the width for the
'\' line wrapping character. */
int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS)
- ((WINDOW_RIGHT_FRINGE_WIDTH (w) == 0
|| WINDOW_LEFT_FRINGE_WIDTH (w) == 0) ? 1 : 0);
return fact * max (1, width);
}
@ -3512,29 +3599,63 @@ get_narrowed_len (struct window *w)
return get_narrowed_width (w) * max (1, height);
}
ptrdiff_t
get_narrowed_begv (struct window *w, ptrdiff_t pos)
static ptrdiff_t
get_medium_narrowing_begv (struct window *w, ptrdiff_t pos)
{
int len = get_narrowed_len (w);
return max ((pos / len - 1) * len, BEGV);
}
ptrdiff_t
get_narrowed_zv (struct window *w, ptrdiff_t pos)
static ptrdiff_t
get_medium_narrowing_zv (struct window *w, ptrdiff_t pos)
{
int len = get_narrowed_len (w);
return min ((pos / len + 1) * len, ZV);
}
ptrdiff_t
get_closer_narrowed_begv (struct window *w, ptrdiff_t pos)
/* Find the position of the last BOL before POS, unless it is too far
away. The buffer portion in which the search occurs is gradually
enlarged: [POS-500..POS], [POS-5500..POS-500],
[POS-55500..POS-5500], and finally [POS-555500..POS-55500]. Return
BEGV-1 if no BOL was found in [POS-555500..POS]. */
static ptrdiff_t
get_nearby_bol_pos (ptrdiff_t pos)
{
int len = get_narrowed_width (w);
return max ((pos / len - 1) * len, BEGV);
ptrdiff_t start, pos_bytepos, cur, next, found, bol = BEGV - 1, init_pos = pos;
int dist;
for (dist = 500; dist <= 500000; dist *= 10)
{
pos_bytepos = pos == BEGV ? BEGV_BYTE : CHAR_TO_BYTE (pos);
start = pos - dist < BEGV ? BEGV : pos - dist;
for (cur = start; cur < pos; cur = next)
{
next = find_newline1 (cur, CHAR_TO_BYTE (cur),
pos, pos_bytepos,
1, &found, NULL, false);
if (found)
bol = next;
else
break;
}
if (bol >= BEGV || start == BEGV)
break;
else
pos = pos - dist < BEGV ? BEGV : pos - dist;
}
eassert (bol <= init_pos);
return bol;
}
ptrdiff_t
get_locked_narrowing_begv (ptrdiff_t pos)
get_small_narrowing_begv (struct window *w, ptrdiff_t pos)
{
int len = get_narrowed_width (w);
ptrdiff_t bol_pos = max (get_nearby_bol_pos (pos), BEGV);
return max (bol_pos + ((pos - bol_pos) / len - 1) * len, BEGV);
}
ptrdiff_t
get_large_narrowing_begv (ptrdiff_t pos)
{
if (long_line_optimizations_region_size <= 0)
return BEGV;
@ -3552,7 +3673,7 @@ get_locked_narrowing_begv (ptrdiff_t pos)
}
ptrdiff_t
get_locked_narrowing_zv (ptrdiff_t pos)
get_large_narrowing_zv (ptrdiff_t pos)
{
if (long_line_optimizations_region_size <= 0)
return ZV;
@ -3571,7 +3692,7 @@ unwind_narrowed_begv (Lisp_Object point_min)
#define SET_WITH_NARROWED_BEGV(IT,DST,EXPR,BV) \
do { \
if (IT->narrowed_begv) \
if (IT->medium_narrowing_begv) \
{ \
specpdl_ref count = SPECPDL_INDEX (); \
record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); \
@ -4410,17 +4531,17 @@ handle_fontified_prop (struct it *it)
if (current_buffer->long_line_optimizations_p
&& long_line_optimizations_region_size > 0)
{
ptrdiff_t begv = it->locked_narrowing_begv;
ptrdiff_t zv = it->locked_narrowing_zv;
ptrdiff_t begv = it->large_narrowing_begv;
ptrdiff_t zv = it->large_narrowing_zv;
ptrdiff_t charpos = IT_CHARPOS (*it);
if (charpos < begv || charpos > zv)
{
begv = get_locked_narrowing_begv (charpos);
zv = get_locked_narrowing_zv (charpos);
begv = get_large_narrowing_begv (charpos);
zv = get_large_narrowing_zv (charpos);
}
if (begv != BEG || zv != Z)
narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv),
Qlong_line_optimizations_in_fontification_functions);
labeled_narrow_to_region (make_fixnum (begv), make_fixnum (zv),
Qlong_line_optimizations_in_fontification_functions);
}
/* Don't allow Lisp that runs from 'fontification-functions'
@ -7055,7 +7176,7 @@ back_to_previous_line_start (struct it *it)
dec_both (&cp, &bp);
SET_WITH_NARROWED_BEGV (it, IT_CHARPOS (*it),
find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)),
get_closer_narrowed_begv (it->w, IT_CHARPOS (*it)));
get_small_narrowing_begv (it->w, IT_CHARPOS (*it)));
}
/* Find in the current buffer the first display or overlay string
@ -7359,7 +7480,7 @@ back_to_previous_visible_line_start (struct it *it)
it->continuation_lines_width = 0;
eassert (IT_CHARPOS (*it) >= BEGV);
eassert (it->narrowed_begv > 0 /* long-line optimizations: all bets off */
eassert (it->medium_narrowing_begv > 0 /* long-line optimizations: all bets off */
|| IT_CHARPOS (*it) == BEGV
|| FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
CHECK_IT (it);
@ -7477,24 +7598,29 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
if (current_buffer->long_line_optimizations_p)
{
if (!it->narrowed_begv)
if (!it->medium_narrowing_begv)
{
it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w));
it->narrowed_zv = get_narrowed_zv (it->w, window_point (it->w));
it->locked_narrowing_begv
= get_locked_narrowing_begv (window_point (it->w));
it->locked_narrowing_zv
= get_locked_narrowing_zv (window_point (it->w));
it->medium_narrowing_begv
= get_medium_narrowing_begv (it->w, window_point (it->w));
it->medium_narrowing_zv
= get_medium_narrowing_zv (it->w, window_point (it->w));
it->large_narrowing_begv
= get_large_narrowing_begv (window_point (it->w));
it->large_narrowing_zv
= get_large_narrowing_zv (window_point (it->w));
}
else if ((pos.charpos < it->narrowed_begv || pos.charpos > it->narrowed_zv)
else if ((pos.charpos < it->medium_narrowing_begv
|| pos.charpos > it->medium_narrowing_zv)
&& (!redisplaying_p || it->line_wrap == TRUNCATE))
{
it->narrowed_begv = get_narrowed_begv (it->w, pos.charpos);
it->narrowed_zv = get_narrowed_zv (it->w, pos.charpos);
it->locked_narrowing_begv
= get_locked_narrowing_begv (window_point (it->w));
it->locked_narrowing_zv
= get_locked_narrowing_zv (window_point (it->w));
it->medium_narrowing_begv
= get_medium_narrowing_begv (it->w, pos.charpos);
it->medium_narrowing_zv
= get_medium_narrowing_zv (it->w, pos.charpos);
it->large_narrowing_begv
= get_large_narrowing_begv (window_point (it->w));
it->large_narrowing_zv
= get_large_narrowing_zv (window_point (it->w));
}
}
@ -8804,7 +8930,7 @@ get_visually_first_element (struct it *it)
SET_WITH_NARROWED_BEGV (it, bob,
string_p ? 0 :
IT_CHARPOS (*it) < BEGV ? obegv : BEGV,
it->narrowed_begv);
it->medium_narrowing_begv);
if (STRINGP (it->string))
{
@ -8848,7 +8974,7 @@ get_visually_first_element (struct it *it)
find_newline_no_quit (IT_CHARPOS (*it),
IT_BYTEPOS (*it), -1,
&it->bidi_it.bytepos),
it->narrowed_begv);
it->medium_narrowing_begv);
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
do
{
@ -10737,7 +10863,7 @@ move_it_vertically_backward (struct it *it, int dy)
dec_both (&cp, &bp);
SET_WITH_NARROWED_BEGV (it, cp,
find_newline_no_quit (cp, bp, -1, NULL),
get_closer_narrowed_begv (it->w, IT_CHARPOS (*it)));
get_small_narrowing_begv (it->w, IT_CHARPOS (*it)));
move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
}
bidi_unshelve_cache (it3data, true);
@ -16417,7 +16543,7 @@ redisplay_internal (void)
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->already_hscrolled_p = false;
reset_outermost_narrowings ();
reset_outermost_restrictions ();
retry:
/* Remember the currently selected window. */
@ -24144,6 +24270,7 @@ display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
ptrdiff_t val;
specpdl_ref pdl_count = SPECPDL_INDEX ();
record_unwind_protect (save_restriction_restore, save_restriction_save ());
labeled_restrictions_remove_in_current_buffer ();
Fwiden ();
val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
unbind_to (pdl_count, Qnil);