From 2fe4523518db061067b62b004e619e91653bb36a Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 7 May 2022 17:01:44 +0800 Subject: [PATCH 0001/1028] Cache color lookup failures as well * src/xterm.c (x_parse_color): Cache color lookup failures too. * src/xterm.h (struct color_name_cache_entry): New field `valid'. --- src/xterm.c | 59 ++++++++++++++++++++++++++++++++--------------------- src/xterm.h | 7 +++++++ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 2141964c747..c841240a72b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6933,11 +6933,12 @@ x_parse_color (struct frame *f, const char *color_name, XColor *color) { unsigned short r, g, b; - Display *dpy = FRAME_X_DISPLAY (f); - Colormap cmap = FRAME_X_COLORMAP (f); + Display *dpy; + Colormap cmap; struct x_display_info *dpyinfo; struct color_name_cache_entry *cache_entry; unsigned int hash, idx; + int rc; /* Don't pass #RGB strings directly to XParseColor, because that follows the X convention of zero-extending each channel @@ -6949,37 +6950,49 @@ x_parse_color (struct frame *f, const char *color_name, color->red = r; color->green = g; color->blue = b; + return 1; } - dpyinfo = FRAME_DISPLAY_INFO (f); - hash = x_hash_string_ignore_case (color_name); - idx = hash % dpyinfo->color_names_size; - - for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names[idx]; - cache_entry; cache_entry = cache_entry->next) - { - if (!xstrcasecmp (cache_entry->name, color_name)) - { - *color = cache_entry->rgb; - return 1; - } - } - /* Some X servers send BadValue on empty color names. */ if (!strlen (color_name)) return 0; - if (XParseColor (dpy, cmap, color_name, color) == 0) - /* No caching of negative results, currently. */ - return 0; + cmap = FRAME_X_COLORMAP (f); + dpy = FRAME_X_DISPLAY (f); + dpyinfo = FRAME_DISPLAY_INFO (f); + + hash = x_hash_string_ignore_case (color_name); + idx = hash % dpyinfo->color_names_size; + + for (cache_entry = dpyinfo->color_names[idx]; + cache_entry; cache_entry = cache_entry->next) + { + if (!xstrcasecmp (cache_entry->name, color_name)) + { + if (cache_entry->valid) + *color = cache_entry->rgb; + + return cache_entry->valid; + } + } + + block_input (); + rc = XParseColor (dpy, cmap, color_name, color); + unblock_input (); cache_entry = xzalloc (sizeof *cache_entry); - cache_entry->rgb = *color; + + if (rc) + cache_entry->rgb = *color; + + cache_entry->valid = rc; cache_entry->name = xstrdup (color_name); - cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names[idx]; - FRAME_DISPLAY_INFO (f)->color_names[idx] = cache_entry; - return 1; + cache_entry->next = dpyinfo->color_names[idx]; + + dpyinfo->color_names[idx] = cache_entry; + + return rc; } diff --git a/src/xterm.h b/src/xterm.h index 3e06564bee9..66c4b178234 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -196,8 +196,15 @@ extern cairo_pattern_t *x_bitmap_stipple (struct frame *, Pixmap); struct color_name_cache_entry { struct color_name_cache_entry *next; + + /* The color values of the cached color entry. */ XColor rgb; + + /* The name of the cached color. */ char *name; + + /* Whether or not RGB is valid (i.e. the color actually exists). */ + bool_bf valid : 1; }; #ifdef HAVE_XINPUT2 From e8488bcc9cbbeafe6307a73b2386ced986327618 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 12:05:48 +0200 Subject: [PATCH 0002/1028] Avoid having font locking triggering unnecessary auto-saving * lisp/subr.el (with-silent-modifications): Use it to restore the ticks (bug#11303). * src/buffer.c (Finternal__set_buffer_modified_tick): New function. --- etc/NEWS | 9 +++++++++ lisp/subr.el | 7 ++++++- src/buffer.c | 13 +++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index f7dddd36de1..b595eae7e10 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1507,6 +1507,15 @@ Emacs buffers, like indentation and the like. The new ert function * Incompatible Lisp Changes in Emacs 29.1 +--- +** 'with-silent-modifications' also restores buffer modification ticks. +'with-silent-modifications' is a macro meant to be used by the font +locking machinery to allow applying text properties without changing +the modification status of the buffer. However, it didn't restore the +buffer modification ticks, so applying font locking to a modified +buffer that had already been auto-saved would trigger another +auto-saving. This is no longer the case. + --- ** 'prin1' doesn't always escape "." and "?" in symbols any more. Previously, symbols like 'foo.bar' would be printed by 'prin1' as diff --git a/lisp/subr.el b/lisp/subr.el index 5af802fa18d..01549cc6f74 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4594,14 +4594,19 @@ like `buffer-modified-p', checking whether the file is locked by someone else, running buffer modification hooks, and other things of that nature." (declare (debug t) (indent 0)) - (let ((modified (make-symbol "modified"))) + (let ((modified (make-symbol "modified")) + (tick (make-symbol "tick"))) `(let* ((,modified (buffer-modified-p)) + (,tick (buffer-modified-tick)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn ,@body) + ;; We restore the buffer tick count, too, because otherwise + ;; we'll trigger a new auto-save. + (internal--set-buffer-modified-tick ,tick) (unless ,modified (restore-buffer-modified-p nil)))))) diff --git a/src/buffer.c b/src/buffer.c index f8a7a4f5109..6334e197f0e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1499,6 +1499,18 @@ use current buffer as BUFFER. */) return modiff_to_integer (BUF_MODIFF (decode_buffer (buffer))); } +DEFUN ("internal--set-buffer-modified-tick", + Finternal__set_buffer_modified_tick, Sinternal__set_buffer_modified_tick, + 1, 2, 0, + doc: /* Set BUFFER's tick counter to TICK. +No argument or nil as argument means use current buffer as BUFFER. */) + (Lisp_Object tick, Lisp_Object buffer) +{ + CHECK_FIXNUM (tick); + BUF_MODIFF (decode_buffer (buffer)) = XFIXNUM (tick); + return Qnil; +} + DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick, Sbuffer_chars_modified_tick, 0, 1, 0, doc: /* Return BUFFER's character-change tick counter. @@ -6418,6 +6430,7 @@ will run for `clone-indirect-buffer' calls as well. */); defsubr (&Sforce_mode_line_update); defsubr (&Sset_buffer_modified_p); defsubr (&Sbuffer_modified_tick); + defsubr (&Sinternal__set_buffer_modified_tick); defsubr (&Sbuffer_chars_modified_tick); defsubr (&Srename_buffer); defsubr (&Sother_buffer); From e13744780fea9c11a4fed3de08bd0384ce2de8e8 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 12:15:30 +0200 Subject: [PATCH 0003/1028] Make the icomplete-in-buffer doc string document more * lisp/icomplete.el (icomplete-in-buffer): Note what this variable does and doesn't do (bug#45768). --- lisp/icomplete.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index ee1a131a6ee..a0f105a628d 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -139,7 +139,9 @@ See `icomplete-delay-completions-threshold'." :type 'integer) (defvar icomplete-in-buffer nil - "If non-nil, also use Icomplete when completing in non-mini buffers.") + "If non-nil, also use Icomplete when completing in non-mini buffers. +This affects commands like `complete-in-region', but not commands +like `dabbrev-completion', which uses its own completion setup.") (defcustom icomplete-minibuffer-setup-hook nil "Icomplete-specific customization of minibuffer setup. From ea58276462d93f24c75473c69154ef7a4a47b63c Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 12:46:55 +0200 Subject: [PATCH 0004/1028] Allow inhibiting linkification in *Help* buffers * doc/lispref/help.texi (Keys in Documentation): Document it. lisp/help-mode.el (help-make-xrefs): Implement a new \+ syntax to inhibit buttonification. --- doc/lispref/help.texi | 4 ++++ etc/NEWS | 9 ++++++++ lisp/help-mode.el | 42 +++++++++++++++++++----------------- test/lisp/help-mode-tests.el | 2 +- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index d53bfad8e9e..f029a1c97cc 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -362,6 +362,10 @@ depending on the value of @code{text-quoting-style}. quotes the following character and is discarded; thus, @samp{\=`} puts @samp{`} into the output, @samp{\=\[} puts @samp{\[} into the output, and @samp{\=\=} puts @samp{\=} into the output. + +@item \+ +This indicates that the symbol directly following should not be marked +as link in the @file{*Help*} buffer. @end table @strong{Please note:} Each @samp{\} must be doubled when written in a diff --git a/etc/NEWS b/etc/NEWS index b595eae7e10..a2f7f038524 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -461,6 +461,15 @@ This allows you to enter emoji using short strings, eg :face_palm: or ** Help ++++ +*** New doc string syntax to indicate that symbols shouldn't be links. +When displaying doc strings in *Help* buffers, strings that are +"`like-this'" are made into links (if they point to a bound +function/variable). This can lead to false positives when talking +about values that are symbols that happen to have the same names as +functions/variables. To inhibit this buttonification, the new +"\\+`like-this'" syntax can be used. + +++ *** New user option 'help-window-keep-selected'. If non-nil, commands to show the info manual and the source will reuse diff --git a/lisp/help-mode.el b/lisp/help-mode.el index a0a587cd810..4a65f40507b 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -452,6 +452,7 @@ Commands: "\\(symbol\\|program\\|property\\)\\|" ; Don't link "\\(source \\(?:code \\)?\\(?:of\\|for\\)\\)\\)" "[ \t\n]+\\)?" + "\\(\\\\\\+\\)?" "['`‘]\\(\\(?:\\sw\\|\\s_\\)+\\|`\\)['’]")) "Regexp matching doc string references to symbols. @@ -628,27 +629,28 @@ that." ;; Quoted symbols (save-excursion (while (re-search-forward help-xref-symbol-regexp nil t) - (let* ((data (match-string 8)) - (sym (intern-soft data))) - (if sym - (cond - ((match-string 3) ; `variable' &c - (and (or (boundp sym) ; `variable' doesn't ensure + (when-let ((sym (intern-soft (match-string 9)))) + (if (match-string 8) + (delete-region (match-beginning 8) + (match-end 8)) + (cond + ((match-string 3) ; `variable' &c + (and (or (boundp sym) ; `variable' doesn't ensure ; it's actually bound - (get sym 'variable-documentation)) - (help-xref-button 8 'help-variable sym))) - ((match-string 4) ; `function' &c - (and (fboundp sym) ; similarly - (help-xref-button 8 'help-function sym))) - ((match-string 5) ; `face' - (and (facep sym) - (help-xref-button 8 'help-face sym))) - ((match-string 6)) ; nothing for `symbol' - ((match-string 7) - (help-xref-button 8 'help-function-def sym)) - ((cl-some (lambda (x) (funcall (nth 1 x) sym)) - describe-symbol-backends) - (help-xref-button 8 'help-symbol sym))))))) + (get sym 'variable-documentation)) + (help-xref-button 9 'help-variable sym))) + ((match-string 4) ; `function' &c + (and (fboundp sym) ; similarly + (help-xref-button 9 'help-function sym))) + ((match-string 5) ; `face' + (and (facep sym) + (help-xref-button 9 'help-face sym))) + ((match-string 6)) ; nothing for `symbol' + ((match-string 7) + (help-xref-button 9 'help-function-def sym)) + ((cl-some (lambda (x) (funcall (nth 1 x) sym)) + describe-symbol-backends) + (help-xref-button 9 'help-symbol sym))))))) ;; An obvious case of a key substitution: (save-excursion (while (re-search-forward diff --git a/test/lisp/help-mode-tests.el b/test/lisp/help-mode-tests.el index c0c1cf8b530..b5bdf6b8d49 100644 --- a/test/lisp/help-mode-tests.el +++ b/test/lisp/help-mode-tests.el @@ -81,7 +81,7 @@ Lisp concepts such as car, cdr, cons cell and list.") (insert (format fmt fn)) (goto-char (point-min)) (re-search-forward help-xref-symbol-regexp) - (help-xref-button 8 'help-function) + (help-xref-button 9 'help-function) (should-not (button-at (1- beg))) (should-not (button-at (+ beg (length (symbol-name fn))))) (should (eq (button-type (button-at beg)) 'help-function)))))) From d632c3d7db62f5de3dea68324e6f3937827be385 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 7 May 2022 19:00:04 +0800 Subject: [PATCH 0005/1028] Fix mouse face dismissal in some widget popups * src/xterm.c (handle_one_xevent): Accept XINotifyUngrab as well. --- src/xterm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xterm.c b/src/xterm.c index c841240a72b..848389ce965 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16909,7 +16909,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #ifdef USE_X_TOOLKIT if (popup_activated () - && leave->mode == XINotifyPassiveUngrab) + && (leave->mode == XINotifyPassiveUngrab + || leave->mode == XINotifyUngrab)) any = x_any_window_to_frame (dpyinfo, leave->event); #endif From 8df69384f3951356dfb539e2cf72d905f82d00ae Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 13:19:49 +0200 Subject: [PATCH 0006/1028] Allow dabbrev to ignore binary buffers * doc/emacs/abbrevs.texi (Dynamic Abbrevs): Document it. * lisp/dabbrev.el (dabbrev-ignored-buffer-names) (dabbrev-ignored-buffer-regexps): Link to it. (dabbrev-ignored-buffer-modes): New user option (bug#19392). (dabbrev--filter-buffer-modes): New function. (dabbrev--select-buffers, dabbrev--make-friend-buffer-list): Use it. --- doc/emacs/abbrevs.texi | 5 ++++- etc/NEWS | 7 +++++++ lisp/dabbrev.el | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/doc/emacs/abbrevs.texi b/doc/emacs/abbrevs.texi index 9f339a03577..07f66ec10ac 100644 --- a/doc/emacs/abbrevs.texi +++ b/doc/emacs/abbrevs.texi @@ -411,10 +411,13 @@ away in the buffer to search for an expansion. @vindex dabbrev-check-all-buffers @vindex dabbrev-check-other-buffers +@vindex dabbrev-ignored-buffer-modes After scanning the current buffer, @kbd{M-/} normally searches other buffers. The variables @code{dabbrev-check-all-buffers} and @code{dabbrev-check-other-buffers} can be used to determine which -other buffers, if any, are searched. +other buffers, if any, are searched. Buffers that have major modes +derived from any of the modes in @code{dabbrev-ignored-buffer-modes} +are ignored. @vindex dabbrev-ignored-buffer-names @vindex dabbrev-ignored-buffer-regexps diff --git a/etc/NEWS b/etc/NEWS index a2f7f038524..2e7a1d86386 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -734,6 +734,13 @@ script that was used in ancient South Asia. A new input method, * Changes in Specialized Modes and Packages in Emacs 29.1 +** dabbrev + ++++ +*** New user option 'dabbrev-ignored-buffer-modes'. +Buffers with major modes in this list will be ignored. By default, +this includes "binary" buffers like 'archive-mode' and 'image-mode'. + ** Package +++ diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index 220a2f52e92..adbfca01a30 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -225,18 +225,28 @@ or matched by `dabbrev-ignored-buffer-regexps'." (defcustom dabbrev-ignored-buffer-names '("*Messages*" "*Buffer List*") "List of buffer names that dabbrev should not check. -See also `dabbrev-ignored-buffer-regexps'." +See also `dabbrev-ignored-buffer-regexps' and +`dabbrev-ignored-buffer-modes'." :type '(repeat (string :tag "Buffer name")) :group 'dabbrev :version "20.3") (defcustom dabbrev-ignored-buffer-regexps nil "List of regexps matching names of buffers that dabbrev should not check. -See also `dabbrev-ignored-buffer-names'." +See also `dabbrev-ignored-buffer-names' and +`dabbrev-ignored-buffer-modes'." :type '(repeat regexp) :group 'dabbrev :version "21.1") +(defcustom dabbrev-ignored-buffer-modes + '(archive-mode image-mode tar-mode) + "Inhibit looking for abbreviations in buffers derived from these modes. +See also `dabbrev-ignored-buffer-names' and +`dabbrev-ignored-buffer-regexps'." + :type '(repeat symbol) + :version "29.1") + (defcustom dabbrev-check-other-buffers t "Should \\[dabbrev-expand] look in other buffers? nil: Don't look in other buffers. @@ -632,19 +642,29 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." "Return a list of other buffers to search for a possible abbrev. The current buffer is not included in the list. -This function makes a list of all the buffers returned by `buffer-list', -then discards buffers whose names match `dabbrev-ignored-buffer-names' -or `dabbrev-ignored-buffer-regexps'. It also discards buffers for which -`dabbrev-friend-buffer-function', if it is bound, returns nil when called -with the buffer as argument. -It returns the list of the buffers that are not discarded." +This function makes a list of all the buffers returned by +`buffer-list', then discards buffers whose names match +`dabbrev-ignored-buffer-names' or +`dabbrev-ignored-buffer-regexps', and major modes that match +`dabbrev-ignored-buffer-modes'. It also discards buffers for +which `dabbrev-friend-buffer-function', if it is bound, returns +nil when called with the buffer as argument. It returns the list +of the buffers that are not discarded." (dabbrev-filter-elements - buffer (buffer-list) + buffer (dabbrev--filter-buffer-modes) (and (not (eq (current-buffer) buffer)) (not (dabbrev--ignore-buffer-p buffer)) (boundp 'dabbrev-friend-buffer-function) (funcall dabbrev-friend-buffer-function buffer)))) +(defun dabbrev--filter-buffer-modes () + (seq-filter (lambda (buffer) + (not (apply + #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + dabbrev-ignored-buffer-modes))) + (buffer-list))) + (defun dabbrev--try-find (abbrev reverse n ignore-case) "Search for ABBREV, backwards if REVERSE, N times. If IGNORE-CASE is non-nil, ignore case while searching. @@ -779,7 +799,7 @@ of the start of the occurrence." (setq list (append list (dabbrev-filter-elements - buffer (buffer-list) + buffer (dabbrev--filter-buffer-modes) (and (not (memq buffer list)) (not (dabbrev--ignore-buffer-p buffer))))))) ;; Remove the current buffer. From 7952dcc23363b18f74203124d023b063bef359cf Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 13:45:35 +0200 Subject: [PATCH 0007/1028] Fix compilation warnings in newer subr tests * test/lisp/subr-tests.el (test-local-set-state): Fix compilation warnings. --- test/lisp/subr-tests.el | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 8f3ee66e00d..89803e5ce2e 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -1058,20 +1058,21 @@ final or penultimate step during initialization.")) (should (equal (kbd "C-x ( C-d C-x )") "")) (should (equal (kbd "C-x ( C-x )") ""))) +(defvar subr-test--global) (ert-deftest test-local-set-state () - (setq global 1) + (setq subr-test--global 1) (with-temp-buffer - (setq-local local 2) - (let ((state (buffer-local-set-state global 10 - local 20 - unexist 30))) - (should (= global 10)) - (should (= local 20)) - (should (= unexist 30)) + (setq-local subr-test--local 2) + (let ((state (buffer-local-set-state subr-test--global 10 + subr-test--local 20 + subr-test--unexist 30))) + (should (= subr-test--global 10)) + (should (= subr-test--local 20)) + (should (= subr-test--unexist 30)) (buffer-local-restore-state state) - (should (= global 1)) - (should (= local 2)) - (should-not (boundp 'unexist))))) + (should (= subr-test--global 1)) + (should (= subr-test--local 2)) + (should-not (boundp 'subr-test--unexist))))) (provide 'subr-tests) ;;; subr-tests.el ends here From ccec59f2b2c5344b10fa4b006bb5dc1c59555fb1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 13:56:19 +0200 Subject: [PATCH 0008/1028] Improve inferior-python-mode scroll behaviour * lisp/progmodes/python.el (inferior-python-mode): Use scroll-convervatively instead of trying to do this with a comint filter (which produces flickering) (bug#31115). --- lisp/progmodes/python.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 11ed732d282..825e94572a7 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2646,6 +2646,7 @@ banner and the initial prompt are received separately." (defun python-comint-postoutput-scroll-to-bottom (output) "Faster version of `comint-postoutput-scroll-to-bottom'. Avoids `recenter' calls until OUTPUT is completely sent." + (declare (obsolete nil "29.1")) ; Not used. (when (and (not (string= "" output)) (python-shell-comint-end-of-output-p (ansi-color-filter-apply output))) @@ -2951,11 +2952,11 @@ variable. (setq-local comint-output-filter-functions '(ansi-color-process-output python-shell-comint-watch-for-first-prompt-output-filter - python-comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt)) (setq-local comint-highlight-input nil) (setq-local compilation-error-regexp-alist python-shell-compilation-regexp-alist) + (setq-local scroll-conservatively 1) (add-hook 'completion-at-point-functions #'python-shell-completion-at-point nil 'local) (define-key inferior-python-mode-map "\t" From c56070beb6cb7bc383c7f39215c915e1f43fd578 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 14:31:42 +0200 Subject: [PATCH 0009/1028] Make `x' in package-menu-mode more DWIM * lisp/emacs-lisp/package.el (package-menu-mode): Make the doc string more helpful. (package-menu-execute): Make `x' when no files are installed DWIM. --- etc/NEWS | 4 ++++ lisp/emacs-lisp/package.el | 31 +++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 2e7a1d86386..5dd87e3e9e8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -748,6 +748,10 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'. This command allows you to upgrade packages without using 'M-x list-packages'. +*** New DWIM action on 'x'. +If no packages are marked, 'x' will install the package under point if +it isn't already, and remove it if it is installed. + ** Miscellaneous +++ diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 58c1349e1c2..c1e14a4acb5 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2885,7 +2885,13 @@ either a full name or nil, and EMAIL is a valid email address." (define-derived-mode package-menu-mode tabulated-list-mode "Package Menu" "Major mode for browsing a list of packages. -Letters do not insert themselves; instead, they are commands. +The most useful commands here are: + + `x': Install the package under point if it isn't already installed, + and delete it if it's already installed, + `i': mark a package for installation, and + `d': mark a package for deletion. Use the `x' command to perform the + actions on the marked files. \\ \\{package-menu-mode-map}" :interactive nil @@ -3632,8 +3638,13 @@ packages list, respectively." (defun package-menu-execute (&optional noquery) "Perform marked Package Menu actions. Packages marked for installation are downloaded and installed, -packages marked for deletion are removed, -and packages marked for upgrading are downloaded and upgraded. +packages marked for deletion are removed, and packages marked for +upgrading are downloaded and upgraded. + +If no packages are marked, the action taken depends on the state +of the package under point. If it's not already installed, this +command will install the package, and if it's installed, it will +delete the package. Optional argument NOQUERY non-nil means do not ask the user to confirm." (interactive nil package-menu-mode) @@ -3651,8 +3662,20 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." ((eq cmd ?I) (push pkg-desc install-list)))) (forward-line))) + ;; Nothing marked. (unless (or delete-list install-list) - (user-error "No operations specified")) + ;; Not on a package line. + (unless (tabulated-list-get-id) + (user-error "No operations specified")) + (let* ((id (tabulated-list-get-id)) + (status (package-menu-get-status))) + (cond + ((member status '("installed")) + (push id delete-list)) + ((member status '("available" "avail-obso" "new" "dependency")) + (push id install-list)) + (t (user-error "No default action available for status: %s" + status))))) (let-alist (package-menu--partition-transaction install-list delete-list) (when (or noquery (package-menu--prompt-transaction-p .delete .install .upgrade)) From c2a84365d8c24ad2ebbb95ac8526c279aefa678c Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 14:35:15 +0200 Subject: [PATCH 0010/1028] Remove tar-mode dabbrev-ignored-buffer-modes * lisp/dabbrev.el (dabbrev-ignored-buffer-modes): Remove tar-mode from the default, because it isn't really a binary mode. --- lisp/dabbrev.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index adbfca01a30..06a8ead8340 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -239,8 +239,7 @@ See also `dabbrev-ignored-buffer-names' and :group 'dabbrev :version "21.1") -(defcustom dabbrev-ignored-buffer-modes - '(archive-mode image-mode tar-mode) +(defcustom dabbrev-ignored-buffer-modes '(archive-mode image-mode) "Inhibit looking for abbreviations in buffers derived from these modes. See also `dabbrev-ignored-buffer-names' and `dabbrev-ignored-buffer-regexps'." From 5ac6af4e886e630e039d282bb6f3965d7367c461 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 14:42:18 +0200 Subject: [PATCH 0011/1028] Document the `x' DWIM action in the manual * doc/emacs/package.texi (Package Menu): Mention the DWIM action of the `x' command. --- doc/emacs/package.texi | 10 +++++++++- etc/NEWS | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index bd3ae2aa6ad..fc2a093ec42 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -89,6 +89,11 @@ list of available packages from package archive servers. If the network is unavailable, it falls back on the most recently retrieved list. +The main command to use in the package list buffer is the @key{x} +command. If the package under point isn't installed already, this +command will install it. If the package under point is already +installed, this command will delete it. + The following commands are available in the package menu: @table @kbd @@ -162,7 +167,10 @@ installed versions (marked with status @samp{obsolete}). @findex package-menu-execute Download and install all packages marked with @kbd{i}, and their dependencies; also, delete all packages marked with @kbd{d} -(@code{package-menu-execute}). This also removes the marks. +(@code{package-menu-execute}). This also removes the marks. If no +packages are marked, this command will install the package under point +(if it isn't installed already), or delete the package under point (if +it's already installed). @item g @item r diff --git a/etc/NEWS b/etc/NEWS index 5dd87e3e9e8..de3f093864f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -748,6 +748,7 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'. This command allows you to upgrade packages without using 'M-x list-packages'. ++++ *** New DWIM action on 'x'. If no packages are marked, 'x' will install the package under point if it isn't already, and remove it if it is installed. From f7c56a0d739d1397b5fb2b1beeeea6b74a1d5886 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 15:05:45 +0200 Subject: [PATCH 0012/1028] Explain better what the interactive prefix does in scroll-down/up * lisp/window.el (scroll-up-command, scroll-down-command): * lisp/image-mode.el (image-scroll-up, image-scroll-down): Actually explain what the interactive prefix does (bug#44503). --- lisp/image-mode.el | 26 ++++++++++++++++++++------ lisp/window.el | 10 ++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 721f2f2bbd8..ea5d7ff0f35 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -282,10 +282,17 @@ Stop if the top edge of the image is reached." (defun image-scroll-up (&optional n) "Scroll image in current window upward by N lines. Stop if the bottom edge of the image is reached. -If ARG is omitted or nil, scroll upward by a near full screen. + +Interactively, giving this command a numerical prefix will scroll +up by that many lines (and down by that many lines if the number +is negative). Without a prefix, scroll up by a full screen. +If given a `C-u -' prefix, scroll a full page down instead. + +If N is omitted or nil, scroll upward by a near full screen. A near full screen is `next-screen-context-lines' less than a full screen. -Negative ARG means scroll downward. -If ARG is the atom `-', scroll downward by nearly full screen. +A negative N means scroll downward. + +If N is the atom `-', scroll downward by nearly full screen. When calling from a program, supply as argument a number, nil, or `-'." (interactive "P") (cond ((null n) @@ -303,10 +310,17 @@ When calling from a program, supply as argument a number, nil, or `-'." (defun image-scroll-down (&optional n) "Scroll image in current window downward by N lines. Stop if the top edge of the image is reached. -If ARG is omitted or nil, scroll downward by a near full screen. + +Interactively, giving this command a numerical prefix will scroll +down by that many lines (and up by that many lines if the number +is negative). Without a prefix, scroll down by a full screen. +If given a `C-u -' prefix, scroll a full page up instead. + +If N is omitted or nil, scroll downward by a near full screen. A near full screen is `next-screen-context-lines' less than a full screen. -Negative ARG means scroll upward. -If ARG is the atom `-', scroll upward by nearly full screen. +A negative N means scroll upward. + +If N is the atom `-', scroll upward by nearly full screen. When calling from a program, supply as argument a number, nil, or `-'." (interactive "P") (cond ((null n) diff --git a/lisp/window.el b/lisp/window.el index 9f787846124..52003f7b7b4 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -10031,6 +10031,11 @@ When point is already on that position, then signal an error." (defun scroll-up-command (&optional arg) "Scroll text of selected window upward ARG lines; or near full screen if no ARG. +Interactively, giving this command a numerical prefix will scroll +up by that many lines (and down by that many lines if the number +is negative). Without a prefix, scroll up by a full screen. +If given a `C-u -' prefix, scroll a full page down instead. + If `scroll-error-top-bottom' is non-nil and `scroll-up' cannot scroll window further, move cursor to the bottom line. When point is already on that position, then signal an error. @@ -10063,6 +10068,11 @@ If ARG is the atom `-', scroll downward by nearly full screen." (defun scroll-down-command (&optional arg) "Scroll text of selected window down ARG lines; or near full screen if no ARG. +Interactively, giving this command a numerical prefix will scroll +down by that many lines (and up by that many lines if the number +is negative). Without a prefix, scroll down by a full screen. +If given a `C-u -' prefix, scroll a full page up instead. + If `scroll-error-top-bottom' is non-nil and `scroll-down' cannot scroll window further, move cursor to the top line. When point is already on that position, then signal an error. From 987a212eb17b32cabcf46640417768bcccb2be5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=B8=E0=A4=AE=E0=A5=80=E0=A4=B0=20=E0=A4=B8=E0=A4=BF?= =?UTF-8?q?=E0=A4=82=E0=A4=B9=20Sameer=20Singh?= Date: Sat, 7 May 2022 17:55:25 +0530 Subject: [PATCH 0013/1028] Add support for the Kaithi script * lisp/language/indian.el ("Kaithi"): New language environment. Add composition rules for Kaithi. Add sample text and input method. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Support Kaithi. * lisp/leim/quail/indian.el ("kaithi"): New input method. * etc/HELLO: Add a Kaithi greeting. * etc/NEWS: Announce the new language environment and its input method. --- etc/HELLO | 2 + etc/NEWS | 6 ++ lisp/international/fontset.el | 2 + lisp/language/indian.el | 38 +++++++++++++ lisp/leim/quail/indian.el | 101 ++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+) diff --git a/etc/HELLO b/etc/HELLO index dbbcc0493bf..ac0cb823eae 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -59,6 +59,8 @@ Hindi (हिंदी) नमस्ते / नमस्कार । Inuktitut (ᐃᓄᒃᑎᑐᑦ) ᐊᐃ Italian (italiano) Ciao / Buon giorno Javanese (ꦧꦱꦗꦮꦶ) console.log("ꦲꦭꦺꦴ"); + +Kaithi (𑂍𑂶𑂟𑂲) 𑂩𑂰𑂧𑂩𑂰𑂧 Kannada (ಕನ್ನಡ) ನಮಸ್ಕಾರ Khmer (ភាសាខ្មែរ) ជំរាបសួរ Lakota (Lakȟotiyapi) Taŋyáŋ yahí! diff --git a/etc/NEWS b/etc/NEWS index de3f093864f..671c30772eb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -731,6 +731,12 @@ This language environment supports Brahmi, which is a historical script that was used in ancient South Asia. A new input method, 'brahmi', is provided to type text in this script. +*** New language environment "Kaithi". +This language environment supports Kaithi or Kayasthi, which was +an important writing system of the past mainly used for administrative +purposes. A new input method, 'kaithi', is provided to type text in +this script. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 883f08905e9..66f5068cf76 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -232,6 +232,7 @@ (elymaic #x10FE0) (old-uyghur #x10F70) (brahmi #x11013 #x11045 #x11052 #x11065) + (kaithi #x1108D #x110B0 #x110BD) (mahajani #x11150) (khojki #x11200) (khudawadi #x112B0) @@ -772,6 +773,7 @@ elymaic old-uyghur brahmi + kaithi makasar dives-akuru cuneiform diff --git a/lisp/language/indian.el b/lisp/language/indian.el index c3d59b6f770..0031405182c 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -136,6 +136,17 @@ South Indian language Malayalam is supported in this language environment.")) The ancient Brahmi script is supported in this language environment.")) '("Indian")) ; Should we have an "Old" category? +(set-language-info-alist + "Kaithi" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "kaithi") + (sample-text . "Kaithi (𑂍𑂶𑂟𑂲) 𑂩𑂰𑂧𑂩𑂰𑂧") + (documentation . "\ +Languages such as Awadhi, Bhojpuri, Magahi and Maithili +which used the Kaithi script are supported in this language environment.")) + '("Indian")) + ;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is ;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING). @@ -421,6 +432,33 @@ The ancient Brahmi script is supported in this language environment.")) (concat multiplier number-joiner numeral) 1 'font-shape-gstring)))) +;; Kaithi composition rules +(let ((consonant "[\x1108D-\x110AF]") + (nukta "\x110BA") + (vowel "[\x1108D-\x110C2]") + (anusvara-candrabindu "[\x11080\x11081]") + (virama "\x110B9") + (number-sign "\x110BD") + (number-sign-above "\x110CD") + (numerals "[\x966-\x96F]+") + (zwj "\x200D")) + (set-char-table-range composition-function-table + '(#x110B0 . #x110BA) + (list (vector + (concat consonant nukta "?\\(?:" virama zwj "?" consonant nukta "?\\)*\\(?:" + virama zwj "?\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") + 1 'font-shape-gstring))) + (set-char-table-range composition-function-table + '(#x110BD . #x110BD) + (list (vector + (concat number-sign numerals) + 0 'font-shape-gstring))) + (set-char-table-range composition-function-table + '(#x110CD . #x110CD) + (list (vector + (concat number-sign-above numerals) + 0 'font-shape-gstring)))) + (provide 'indian) ;;; indian.el ends here diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index f2d5f9bad4a..a52d44bc083 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -835,5 +835,106 @@ Full key sequences are listed below:") ("`/" ?𑁿) ) +(quail-define-package + "kaithi" "Kaithi" "𑂍𑂶" t "Kaithi phonetic input method. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules +("``" ?₹) +("1" ?१) +("`1" ?1) +("2" ?२) +("`2" ?2) +("3" ?३) +("`3" ?3) +("4" ?४) +("`4" ?4) +("5" ?५) +("`5" ?5) +("6" ?६) +("`6" ?6) +("7" ?७) +("`7" ?7) +("8" ?८) +("`8" ?8) +("9" ?९) +("0" ?०) +("`0" ?0) +("`\)" ?𑂻) +("`\\" ?𑃀) +("`|" ?𑃁) +("`" ?𑂗) +("q" ?𑂗) +("Q" ?𑂘) +("w" ?𑂙) +("W" ?𑂛) +("`w" ?𑂚) +("`W" ?𑂜) +("e" ?𑂵) +("E" ?𑂶) +("`e" ?𑂉) +("`E" ?𑂊) +("r" ?𑂩) +("R" ?𑃂) +("t" ?𑂞) +("T" ?𑂟) +("y" ?𑂨) +("Y" ?⸱) +("u" ?𑂳) +("U" ?𑂴) +("`u" ?𑂇) +("`U" ?𑂈) +("i" ?𑂱) +("I" ?𑂲) +("`i" ?𑂅) +("`I" ?𑂆) +("o" ?𑂷) +("O" ?𑂸) +("`o" ?𑂋) +("`O" ?𑂌) +("p" ?𑂣) +("P" ?𑂤) +("a" ?𑂰) +("A" ?𑂄) +("`a" ?𑂃) +("s" ?𑂮) +("S" ?𑂬) +("d" ?𑂠) +("D" ?𑂡) +("`d" ?𑂼) +("`D" #x110BD) ; Kaithi Number Sign +("f" ?𑂹) +("F" #x110CD) ; Kaithi Number Sign Above +("`f" ?𑂾) +("`F" ?𑂿) +("g" ?𑂏) +("G" ?𑂐) +("h" ?𑂯) +("H" ?𑂂) +("j" ?𑂔) +("J" ?𑂕) +("k" ?𑂍) +("K" ?𑂎) +("l" ?𑂪) +("z" ?𑂖) +("Z" ?𑂑) +("x" ?𑂭) +("X" ?𑂺) +("c" ?𑂒) +("C" ?𑂓) +("`c" #x200C) ; ZWNJ +("`C" #x200D) ; ZWJ +("v" ?𑂫) +("b" ?𑂥) +("B" ?𑂦) +("n" ?𑂢) +("N" ?𑂝) +("m" ?𑂧) +("M" ?𑂁) +("`m" ?𑂀) +) + ;;; indian.el ends here From 7e97b33aa62c39111f33a94c487f0a174d06346d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 7 May 2022 13:38:42 +0000 Subject: [PATCH 0014/1028] Clean up some variables in the Haiku code * src/haikuterm.c: Add comments to some variables and clean up initializers. * src/haikuterm.h (haiku_frame_param_handlers): Move here instead. --- src/haikuterm.c | 13 ++++++++++--- src/haikuterm.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index ced16d9f09b..f08fe681871 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -43,17 +43,24 @@ along with GNU Emacs. If not, see . */ /* Minimum and maximum values used for Haiku scroll bars. */ #define BE_SB_MAX 12000000 -struct haiku_display_info *x_display_list = NULL; -extern frame_parm_handler haiku_frame_parm_handlers[]; +/* The single Haiku display (if any). */ +struct haiku_display_info *x_display_list; /* This is used to determine when to evict the font lookup cache, which we do every 50 updates. */ static int up_to_date_count; +/* List of defined fringe bitmaps. */ static void **fringe_bmps; -static int max_fringe_bmp = 0; +/* The amount of fringe bitmaps in that list. */ +static int max_fringe_bmp; + +/* Alist of resources to their values. */ static Lisp_Object rdb; + +/* Non-zero means that a HELP_EVENT has been generated since Emacs + start. */ static bool any_help_event_p; char * diff --git a/src/haikuterm.h b/src/haikuterm.h index 30b474b1e1d..1bff03ae39e 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -205,6 +205,8 @@ extern struct font_driver const haikufont_driver; extern Lisp_Object tip_frame; extern struct frame *haiku_dnd_frame; +extern frame_parm_handler haiku_frame_parm_handlers[]; + struct scroll_bar { /* These fields are shared by all vectors. */ From 19d1b9275e7565fb67fd9e0587f08837ba8a3220 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 7 May 2022 10:21:26 -0400 Subject: [PATCH 0015/1028] (dabbrev-completion): Fix bug#45768 Make `dabbrev-completion` go through `completion-at-point` so that it interacts correctly with Icomplete. Export a new `completion-capf` function while we're at it, since it can be useful elsewhere. * lisp/dabbrev.el (dabbrev-capf): New function, extracted from `dabbrev-completion`. (dabbrev-completion): Use it. --- etc/NEWS | 3 +++ lisp/dabbrev.el | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 671c30772eb..6a60231b3aa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -742,6 +742,9 @@ this script. ** dabbrev +--- +*** New function 'dabbrev-capf' for use on 'completion-at-point-functions' + +++ *** New user option 'dabbrev-ignored-buffer-modes'. Buffers with major modes in this list will be ignored. By default, diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index 06a8ead8340..b04128cf677 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -392,6 +392,14 @@ If the prefix argument is 16 (which comes from \\[universal-argument] \\[univers then it searches *all* buffers." (interactive "*P") (dabbrev--reset-global-variables) + (setq dabbrev--check-other-buffers (and arg t)) + (setq dabbrev--check-all-buffers + (and arg (= (prefix-numeric-value arg) 16))) + (let ((completion-at-point-functions '(dabbrev-capf))) + (completion-at-point))) + +(defun dabbrev-capf () + "Dabbrev completion function for `completion-at-point-functions'." (let* ((abbrev (dabbrev--abbrev-at-point)) (beg (progn (search-backward abbrev) (point))) (end (progn (search-forward abbrev) (point))) @@ -429,10 +437,7 @@ then it searches *all* buffers." (t (mapcar #'downcase completion-list))))))) (complete-with-action a list s p))))) - (setq dabbrev--check-other-buffers (and arg t)) - (setq dabbrev--check-all-buffers - (and arg (= (prefix-numeric-value arg) 16))) - (completion-in-region beg end table))) + (list beg end table))) ;;;###autoload (defun dabbrev-expand (arg) From e59c42950f622b0e3b463cb8e37f504f6b347843 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 7 May 2022 17:54:19 +0300 Subject: [PATCH 0016/1028] Improve Devanagari character composition rules * lisp/language/indian.el (devanagari-composable-pattern): Add rules for Vedic accents. Suggested by Madhu . --- lisp/language/indian.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 0031405182c..b240403b0a1 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -169,6 +169,8 @@ which used the Kaithi script are supported in this language environment.")) ("H" . "\u094D") ; HALANT ("s" . "[\u0951\u0952]") ; stress sign ("t" . "[\u0953\u0954]") ; accent + ("1" . "\u0967") ; numeral 1 + ("3" . "\u0969") ; numeral 3 ("N" . "\u200C") ; ZWNJ ("J" . "\u200D") ; ZWJ ("X" . "[\u0900-\u097F]")))) ; all coverage @@ -180,6 +182,8 @@ which used the Kaithi script are supported in this language environment.")) "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?a?s?t?A?\\)\\|" ;; special consonant form, or "JHR\\|" + ;; vedic accents with numerals, or + "1ss\\|3ss\\|s3ss\\|" ;; any other singleton characters "X") table)) From 2e461ab2dcb407c868a38d833f38815c17a28c5a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 7 May 2022 18:10:42 +0300 Subject: [PATCH 0017/1028] ; Fix last change of Devanagari composition rules. --- lisp/language/indian.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index b240403b0a1..a7205e28b65 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -183,7 +183,7 @@ which used the Kaithi script are supported in this language environment.")) ;; special consonant form, or "JHR\\|" ;; vedic accents with numerals, or - "1ss\\|3ss\\|s3ss\\|" + "1ss?\\|3ss\\|s3ss\\|" ;; any other singleton characters "X") table)) From fc0bd6057c676b9945aa739dd9365a350ca5acef Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 7 May 2022 18:21:29 +0200 Subject: [PATCH 0018/1028] Make 'delete-process' into a command * doc/lispref/processes.texi (Deleting Processes): Document missing PROCESS value. * src/process.c (Fdelete_process): Allow calling interactively (bug#10107). --- doc/lispref/processes.texi | 14 ++++++++------ etc/NEWS | 7 +++++++ src/process.c | 18 ++++++++++++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 18f446735bb..668a577870a 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1011,16 +1011,18 @@ terminated (due to calling @code{exit} or to a signal). If it is they exit. @end defopt -@defun delete-process process +@defun delete-process &optional process This function deletes a process, killing it with a @code{SIGKILL} signal if the process was running a program. The argument may be a process, the name of a process, a buffer, or the name of a buffer. (A buffer or buffer-name stands for the process that -@code{get-buffer-process} returns.) Calling @code{delete-process} on -a running process terminates it, updates the process status, and runs -the sentinel immediately. If the process has already terminated, -calling @code{delete-process} has no effect on its status, or on the -running of its sentinel (which will happen sooner or later). +@code{get-buffer-process} returns, and a missing or @code{nil} +@var{process} means that the current buffer's process should be +killed.) Calling @code{delete-process} on a running process +terminates it, updates the process status, and runs the sentinel +immediately. If the process has already terminated, calling +@code{delete-process} has no effect on its status, or on the running +of its sentinel (which will happen sooner or later). If the process object represents a network, serial, or pipe connection, its status changes to @code{closed}; otherwise, it changes diff --git a/etc/NEWS b/etc/NEWS index 6a60231b3aa..ee7a127af0e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -248,6 +248,13 @@ removed some time after that. * Changes in Emacs 29.1 +--- +** 'delete-process' is now a command. +When called interactively, it will kill the process running in the +current buffer (if any). This can be useful if you have runaway +output in the current buffer (from a process or a network connection), +and want to stop it. + +++ ** New command 'restart-emacs'. This is like 'save-buffers-kill-emacs', but instead of just killing diff --git a/src/process.c b/src/process.c index 08a02ad9423..2f8863aef25 100644 --- a/src/process.c +++ b/src/process.c @@ -1071,13 +1071,24 @@ record_deleted_pid (pid_t pid, Lisp_Object filename) } -DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, +DEFUN ("delete-process", Fdelete_process, Sdelete_process, 0, 1, + "(list 'message)", doc: /* Delete PROCESS: kill it and forget about it immediately. PROCESS may be a process, a buffer, the name of a process or buffer, or -nil, indicating the current buffer's process. */) +nil, indicating the current buffer's process. + +Interactively, it will kill the current buffer's process. */) (register Lisp_Object process) { register struct Lisp_Process *p; + bool mess = false; + + /* We use this to see whether we were called interactively. */ + if (EQ (process, Qmessage)) + { + mess = true; + process = Qnil; + } process = get_process (process); p = XPROCESS (process); @@ -1131,6 +1142,8 @@ nil, indicating the current buffer's process. */) } } remove_process (process); + if (mess) + message ("Deleted process"); return Qnil; } @@ -8637,6 +8650,7 @@ sentinel or a process filter function has an error. */); DEFSYM (Qnull, "null"); DEFSYM (Qpipe_process_p, "pipe-process-p"); + DEFSYM (Qmessage, "message"); defsubr (&Sprocessp); defsubr (&Sget_process); From 97dd99c6f750021233baa90e0974378631d31b62 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 7 May 2022 19:34:53 +0300 Subject: [PATCH 0019/1028] Fix Bengali composition rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/language/indian.el (bengali-composable-pattern): Fix composition rules for U+09F0 and U+09FE. Patch from समीर सिंह Sameer Singh . (Bug#55303) --- lisp/language/indian.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index a7205e28b65..ce46d325494 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -194,14 +194,15 @@ which used the Kaithi script are supported in this language environment.")) '(("a" . "\u0981") ; SIGN CANDRABINDU ("A" . "[\u0982\u0983]") ; SIGN ANUSVARA .. VISARGA ("V" . "[\u0985-\u0994\u09E0\u09E1]") ; independent vowel - ("C" . "[\u0995-\u09B9\u09DC-\u09DF\u09F1]") ; consonant + ("C" . "[\u0995-\u09B9\u09DC-\u09DF\u09F0\u09F1]") ; consonant ("B" . "[\u09AC\u09AF\u09B0\u09F0]") ; BA, YA, RA ("R" . "[\u09B0\u09F0]") ; RA ("n" . "\u09BC") ; NUKTA ("v" . "[\u09BE-\u09CC\u09D7\u09E2\u09E3]") ; vowel sign ("H" . "\u09CD") ; HALANT ("T" . "\u09CE") ; KHANDA TA - ("N" . "\u200C") ; ZWNJ + ("S" . "\u09FE") ; SANDHI MARK + ("N" . "\u200C") ; ZWNJ ("J" . "\u200D") ; ZWJ ("X" . "[\u0980-\u09FF]")))) ; all coverage (indian-compose-regexp @@ -209,7 +210,7 @@ which used the Kaithi script are supported in this language environment.")) ;; syllables with an independent vowel, or "\\(?:RH\\)?Vn?\\(?:J?HB\\)?v*n?a?A?\\|" ;; consonant-based syllables, or - "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*[NJ]?v?a?A?\\)\\|" + "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*[NJ]?v?a?A?S?\\)\\|" ;; another syllables with an independent vowel, or "\\(?:RH\\)?T\\|" ;; special consonant form, or From 090d5f4446e89df4bc5ad9a043294b711493c7ac Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 7 May 2022 09:48:27 -0700 Subject: [PATCH 0020/1028] * src/fns.c: Fix IDs in comments to match code. --- src/fns.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/fns.c b/src/fns.c index 4673fde28c7..2c206c62b22 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4113,7 +4113,7 @@ hash_table_user_defined_call (ptrdiff_t nargs, Lisp_Object *args, return unbind_to (count, Ffuncall (nargs, args)); } -/* Ignore HT and compare KEY1 and KEY2 using 'eql'. +/* Ignore H and compare KEY1 and KEY2 using 'eql'. Value is true if KEY1 and KEY2 are the same. */ static Lisp_Object @@ -4122,7 +4122,7 @@ cmpfn_eql (Lisp_Object key1, Lisp_Object key2, struct Lisp_Hash_Table *h) return Feql (key1, key2); } -/* Ignore HT and compare KEY1 and KEY2 using 'equal'. +/* Ignore H and compare KEY1 and KEY2 using 'equal'. Value is true if KEY1 and KEY2 are the same. */ static Lisp_Object @@ -4132,7 +4132,7 @@ cmpfn_equal (Lisp_Object key1, Lisp_Object key2, struct Lisp_Hash_Table *h) } -/* Given HT, compare KEY1 and KEY2 using HT->user_cmp_function. +/* Given H, compare KEY1 and KEY2 using H->user_cmp_function. Value is true if KEY1 and KEY2 are the same. */ static Lisp_Object @@ -4143,8 +4143,7 @@ cmpfn_user_defined (Lisp_Object key1, Lisp_Object key2, return hash_table_user_defined_call (ARRAYELTS (args), args, h); } -/* Ignore HT and return a hash code for KEY which uses 'eq' to compare - keys. */ +/* Ignore H and return a hash code for KEY which uses 'eq' to compare keys. */ static Lisp_Object hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h) @@ -4154,7 +4153,7 @@ hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h) return make_ufixnum (XHASH (key) ^ XTYPE (key)); } -/* Ignore HT and return a hash code for KEY which uses 'equal' to compare keys. +/* Ignore H and return a hash code for KEY which uses 'equal' to compare keys. The hash code is at most INTMASK. */ static Lisp_Object @@ -4163,7 +4162,7 @@ hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h) return make_ufixnum (sxhash (key)); } -/* Ignore HT and return a hash code for KEY which uses 'eql' to compare keys. +/* Ignore H and return a hash code for KEY which uses 'eql' to compare keys. The hash code is at most INTMASK. */ static Lisp_Object @@ -4172,7 +4171,7 @@ hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h) return (FLOATP (key) || BIGNUMP (key) ? hashfn_equal : hashfn_eq) (key, h); } -/* Given HT, return a hash code for KEY which uses a user-defined +/* Given H, return a hash code for KEY which uses a user-defined function to compare keys. */ Lisp_Object From ca3e3c947192e97f2c494ac12a26ff0d259f0459 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Sat, 7 May 2022 20:17:23 +0300 Subject: [PATCH 0021/1028] ; Pacify some --without-x byte-compiler warnings. --- lisp/term/haiku-win.el | 1 + test/src/image-tests.el | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 5f020877325..6396779d60d 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -99,6 +99,7 @@ for more details on the structure of the associations.") "B_LINK_VISITED_COLOR" "B_LINK_ACTIVE_COLOR" "B_STATUS_BAR_COLOR" "B_SUCCESS_COLOR" "B_FAILURE_COLOR"]) +(defvar x-colors) ;; Also update `x-colors' to take that into account. (setq x-colors (append haiku-allowed-ui-colors x-colors)) diff --git a/test/src/image-tests.el b/test/src/image-tests.el index 3885981e0b2..f710aadea74 100644 --- a/test/src/image-tests.el +++ b/test/src/image-tests.el @@ -53,6 +53,8 @@ ;;;; image-test-size +(declare-function image-size "image.c" (spec &optional pixels frame)) + (ert-deftest image-tests-image-size/gif () (image-skip-unless 'gif) (pcase (image-size (create-image (cdr (assq 'gif image-tests--images)))) @@ -126,6 +128,8 @@ ;;;; image-mask-p +(declare-function image-mask-p "image.c" (spec &optional frame)) + (ert-deftest image-tests-image-mask-p/gif () (image-skip-unless 'gif) (should-not (image-mask-p (create-image @@ -176,6 +180,8 @@ ;;;; image-metadata +(declare-function image-metadata "image.c" (spec &optional frame)) + ;; TODO: These tests could be expanded with files that actually ;; contain metadata. @@ -238,6 +244,7 @@ (ert-deftest image-tests-init-image-library () (skip-unless (fboundp 'init-image-library)) + (declare-function init-image-library "image.c" (type)) (should (init-image-library 'pbm)) ; built-in (should-not (init-image-library 'invalid-image-type))) From 672a296d3b353249ed829a7164c3db55ee204e47 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 09:06:40 +0800 Subject: [PATCH 0022/1028] Use correct event structures to fetch time on XI2 * src/xterm.c (handle_one_xevent): Don't use generic `xi_event' to access the event time. --- src/xterm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 848389ce965..2fc4c559a9c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16807,7 +16807,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, ev.window = enter->event; ev.time = enter->time; - x_display_set_last_user_time (dpyinfo, xi_event->time); + x_display_set_last_user_time (dpyinfo, enter->time); #ifdef USE_MOTIF use_copy = true; @@ -16955,7 +16955,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, leave->deviceid, false); #endif - x_display_set_last_user_time (dpyinfo, xi_event->time); + x_display_set_last_user_time (dpyinfo, leave->time); #ifdef HAVE_XWIDGETS { @@ -17572,7 +17572,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { #ifndef USE_TOOLKIT_SCROLL_BARS struct scroll_bar *bar - = x_window_to_scroll_bar (xi_event->display, xev->event, 2); + = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2); if (bar) x_scroll_bar_note_movement (bar, &ev); @@ -19149,7 +19149,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, device = xi_device_from_id (dpyinfo, pev->deviceid); source = xi_device_from_id (dpyinfo, pev->sourceid); - x_display_set_last_user_time (dpyinfo, xi_event->time); + x_display_set_last_user_time (dpyinfo, pev->time); if (!device) goto XI_OTHER; From faa342c794dec66d6b77ccf550361d58455a4454 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 03:08:42 +0000 Subject: [PATCH 0023/1028] Implement bitmap loading for faces on Haiku Stipples don't completely work yet. * lisp/faces.el (face-valid-attribute-values): Enable `:stipple' on Haiku. * src/haiku_draw_support.cc (BView_DrawBitmap) (BView_DrawBitmapWithEraseOp, BView_DrawMask): Don't push and pop states. (BView_DrawBitmapTiled): New function. * src/haiku_support.cc (BBitmap_import_mono_bits): Delete function. * src/haiku_support.h: Update prototypes. * src/haikuterm.c (get_string_resource): Fix coding style. (haiku_get_bitmap, haiku_draw_stipple_background): Implement partially. (haiku_set_scroll_bar_default_width) (haiku_set_scroll_bar_default_height, haiku_scroll_bar_create) (haiku_set_horizontal_scroll_bar, haiku_set_vertical_scroll_bar) (haiku_create_terminal, haiku_scroll_bar_remove): Fix coding style. * src/image.c (image_create_bitmap_from_data) (image_create_bitmap_from_file): Implement on Haiku. --- lisp/faces.el | 2 +- src/haiku_draw_support.cc | 46 +++++++++++++---- src/haiku_support.cc | 11 ---- src/haiku_support.h | 4 +- src/haikuterm.c | 106 +++++++++++++++++++++++++------------- src/image.c | 82 +++++++++++++++++++++++++++-- 6 files changed, 188 insertions(+), 63 deletions(-) diff --git a/lisp/faces.el b/lisp/faces.el index 12a386c8f63..395ea315bae 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1202,7 +1202,7 @@ an integer value." (:height 'integerp) (:stipple - (and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32 or haiku + (and (memq (window-system frame) '(x ns pgtk haiku)) ; No stipple on w32 (mapcar #'list (apply #'nconc (mapcar (lambda (dir) diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc index a8d46d000a3..551af51d7c1 100644 --- a/src/haiku_draw_support.cc +++ b/src/haiku_draw_support.cc @@ -285,11 +285,32 @@ BView_DrawBitmap (void *view, void *bitmap, int x, int y, BView *vw = get_view (view); BBitmap *bm = (BBitmap *) bitmap; - vw->PushState (); vw->SetDrawingMode (B_OP_OVER); vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1), BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1)); - vw->PopState (); + vw->SetDrawingMode (B_OP_COPY); +} + +void +BView_DrawBitmapTiled (void *view, void *bitmap, int x, int y, + int width, int height, int vx, int vy, + int vwidth, int vheight) +{ + BView *vw = get_view (view); + BBitmap *bm = (BBitmap *) bitmap; + BRect bounds = bm->Bounds (); + + if (width == -1) + width = BE_RECT_WIDTH (bounds); + + if (height == -1) + height = BE_RECT_HEIGHT (bounds); + + vw->SetDrawingMode (B_OP_OVER); + vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1), + BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1), + B_TILE_BITMAP); + vw->SetDrawingMode (B_OP_COPY); } void @@ -300,17 +321,22 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x, BBitmap *bm = (BBitmap *) bitmap; BBitmap bc (bm->Bounds (), B_RGBA32); BRect rect (x, y, x + width - 1, y + height - 1); + uint32_t *bits; + size_t stride; + rgb_color low_color; + BRect bounds; if (bc.InitCheck () != B_OK || bc.ImportBits (bm) != B_OK) return; - uint32_t *bits = (uint32_t *) bc.Bits (); - size_t stride = bc.BytesPerRow (); + bits = (uint32_t *) bc.Bits (); + stride = bc.BytesPerRow (); if (bm->ColorSpace () == B_GRAY1) { - rgb_color low_color = vw->LowColor (); - BRect bounds = bc.Bounds (); + low_color = vw->LowColor (); + bounds = bc.Bounds (); + for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y) { for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x) @@ -323,10 +349,11 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x, } } - vw->PushState (); - vw->SetDrawingMode (bm->ColorSpace () == B_GRAY1 ? B_OP_OVER : B_OP_ERASE); + vw->SetDrawingMode ((bm->ColorSpace () + == B_GRAY1) + ? B_OP_OVER : B_OP_ERASE); vw->DrawBitmap (&bc, rect); - vw->PopState (); + vw->SetDrawingMode (B_OP_COPY); } void @@ -357,6 +384,7 @@ BView_DrawMask (void *src, void *view, vw->SetDrawingMode (B_OP_OVER); vw->DrawBitmap (&bm, BRect (x, y, x + width - 1, y + height - 1), BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1)); + vw->SetDrawingMode (B_OP_COPY); } static BBitmap * diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 5dfb25d6dd7..27a676dd31c 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -3599,17 +3599,6 @@ BBitmap_import_fringe_bitmap (void *bitmap, unsigned short *bits, int wd, int h) } } -void -BBitmap_import_mono_bits (void *bitmap, void *bits, int wd, int h) -{ - BBitmap *bmp = (BBitmap *) bitmap; - - if (wd % 8) - wd += 8 - (wd % 8); - - bmp->ImportBits (bits, wd / 8 * h, wd / 8, 0, B_GRAY1); -} - /* Make a scrollbar at X, Y known to the view VIEW. */ void BView_publish_scroll_bar (void *view, int x, int y, int width, int height) diff --git a/src/haiku_support.h b/src/haiku_support.h index 5ded9300d8a..eaca7a9bad7 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -541,6 +541,8 @@ extern void BView_DrawBitmap (void *, void *, int, int, int, int, int, int, extern void BView_DrawBitmapWithEraseOp (void *, void *, int, int, int, int); extern void BView_DrawMask (void *, void *, int, int, int, int, int, int, int, int, uint32_t); +extern void BView_DrawBitmapTiled (void *, void *, int, int, + int, int, int, int, int, int); extern void BView_resize_to (void *, int, int); extern void BView_set_view_cursor (void *, void *); @@ -570,9 +572,7 @@ extern void BView_invalidate (void *); extern void BView_draw_lock (void *, bool, int, int, int, int); extern void BView_invalidate_region (void *, int, int, int, int); extern void BView_draw_unlock (void *); - extern void BBitmap_import_fringe_bitmap (void *, unsigned short *, int, int); -extern void BBitmap_import_mono_bits (void *, void *, int, int); extern void haiku_font_pattern_free (struct haiku_font_pattern *); diff --git a/src/haikuterm.c b/src/haikuterm.c index f08fe681871..46ea5f90277 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -122,7 +122,8 @@ haiku_delete_terminal (struct terminal *terminal) } static const char * -get_string_resource (void *ignored, const char *name, const char *class) +haiku_get_string_resource (void *ignored, const char *name, + const char *class) { const char *native; @@ -990,10 +991,28 @@ haiku_draw_plain_background (struct glyph_string *s, struct face *face, s->height - 2 * box_line_hwidth); } +static void * +haiku_get_bitmap (struct frame *f, ptrdiff_t id) +{ + return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].img; +} + static void haiku_draw_stipple_background (struct glyph_string *s, struct face *face, int box_line_hwidth, int box_line_vwidth) { + void *view; + + view = FRAME_HAIKU_VIEW (s->f); + BView_StartClip (view); + haiku_clip_to_string (s); + BView_ClipToRect (view, s->x, s->y + box_line_hwidth, + s->background_width, + s->height - 2 * box_line_hwidth); + BView_DrawBitmapTiled (view, haiku_get_bitmap (s->f, face->stipple), + 0, 0, -1, -1, 0, 0, FRAME_PIXEL_WIDTH (s->f), + FRAME_PIXEL_HEIGHT (s->f)); + BView_EndClip (view); } static void @@ -2079,19 +2098,25 @@ haiku_draw_vertical_window_border (struct window *w, static void haiku_set_scroll_bar_default_width (struct frame *f) { - int unit = FRAME_COLUMN_WIDTH (f); - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = BScrollBar_default_size (0) + 1; - FRAME_CONFIG_SCROLL_BAR_COLS (f) = - (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit; + int unit, size; + + unit = FRAME_COLUMN_WIDTH (f); + size = BScrollBar_default_size (0) + 1; + + FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = size; + FRAME_CONFIG_SCROLL_BAR_COLS (f) = (size + unit - 1) / unit; } static void haiku_set_scroll_bar_default_height (struct frame *f) { - int height = FRAME_LINE_HEIGHT (f); - FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = BScrollBar_default_size (1) + 1; - FRAME_CONFIG_SCROLL_BAR_LINES (f) = - (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height; + int height, size; + + height = FRAME_LINE_HEIGHT (f); + size = BScrollBar_default_size (true) + 1; + + FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = size; + FRAME_CONFIG_SCROLL_BAR_LINES (f) = (size + height - 1) / height; } static void @@ -2273,15 +2298,17 @@ static struct scroll_bar * haiku_scroll_bar_create (struct window *w, int left, int top, int width, int height, bool horizontal_p) { - struct frame *f = XFRAME (WINDOW_FRAME (w)); + struct frame *f; Lisp_Object barobj; + struct scroll_bar *bar; + void *scroll_bar; + void *view; - void *sb = NULL; - void *vw = FRAME_HAIKU_VIEW (f); + f = XFRAME (WINDOW_FRAME (w)); + view = FRAME_HAIKU_VIEW (f); block_input (); - struct scroll_bar *bar - = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER); + bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER); XSETWINDOW (bar->window, w); bar->top = top; @@ -2294,15 +2321,14 @@ haiku_scroll_bar_create (struct window *w, int left, int top, bar->update = -1; bar->horizontal = horizontal_p; - sb = BScrollBar_make_for_view (vw, horizontal_p, - left, top, left + width - 1, - top + height - 1, bar); - - BView_publish_scroll_bar (vw, left, top, width, height); + scroll_bar = BScrollBar_make_for_view (view, horizontal_p, + left, top, left + width - 1, + top + height - 1, bar); + BView_publish_scroll_bar (view, left, top, width, height); bar->next = FRAME_SCROLL_BARS (f); bar->prev = Qnil; - bar->scroll_bar = sb; + bar->scroll_bar = scroll_bar; XSETVECTOR (barobj, bar); fset_scroll_bars (f, barobj); @@ -2316,18 +2342,20 @@ haiku_scroll_bar_create (struct window *w, int left, int top, static void haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int position) { - eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)); Lisp_Object barobj; struct scroll_bar *bar; int top, height, left, width; int window_x, window_width; + void *view; + eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)); /* Get window dimensions. */ window_box (w, ANY_AREA, &window_x, 0, &window_width, 0); left = window_x; width = window_width; top = WINDOW_SCROLL_BAR_AREA_Y (w); height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w); + view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w)); block_input (); @@ -2342,15 +2370,15 @@ haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int p { bar = XSCROLL_BAR (w->horizontal_scroll_bar); - if (bar->left != left || bar->top != top || - bar->width != width || bar->height != height) + if (bar->left != left || bar->top != top + || bar->width != width || bar->height != height) { - void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w)); BView_forget_scroll_bar (view, bar->left, bar->top, bar->width, bar->height); BView_move_frame (bar->scroll_bar, left, top, left + width - 1, top + height - 1); BView_publish_scroll_bar (view, left, top, width, height); + bar->left = left; bar->top = top; bar->width = width; @@ -2367,14 +2395,15 @@ haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int p } static void -haiku_set_vertical_scroll_bar (struct window *w, - int portion, int whole, int position) +haiku_set_vertical_scroll_bar (struct window *w, int portion, int whole, int position) { - eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)); Lisp_Object barobj; struct scroll_bar *bar; int top, height, left, width; int window_y, window_height; + void *view; + + eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)); /* Get window dimensions. */ window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); @@ -2384,8 +2413,10 @@ haiku_set_vertical_scroll_bar (struct window *w, /* Compute the left edge and the width of the scroll bar area. */ left = WINDOW_SCROLL_BAR_AREA_X (w); width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); - block_input (); + view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w)); + + block_input (); if (NILP (w->vertical_scroll_bar)) { bar = haiku_scroll_bar_create (w, left, top, width, height, false); @@ -2396,15 +2427,15 @@ haiku_set_vertical_scroll_bar (struct window *w, { bar = XSCROLL_BAR (w->vertical_scroll_bar); - if (bar->left != left || bar->top != top || - bar->width != width || bar->height != height) + if (bar->left != left || bar->top != top + || bar->width != width || bar->height != height) { - void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w)); BView_forget_scroll_bar (view, bar->left, bar->top, bar->width, bar->height); BView_move_frame (bar->scroll_bar, left, top, left + width - 1, top + height - 1); BView_publish_scroll_bar (view, left, top, width, height); + bar->left = left; bar->top = top; bar->width = width; @@ -3880,7 +3911,7 @@ haiku_create_terminal (struct haiku_display_info *dpyinfo) terminal->frame_visible_invisible_hook = haiku_set_frame_visible_invisible; terminal->set_frame_offset_hook = haiku_set_offset; terminal->delete_terminal_hook = haiku_delete_terminal; - terminal->get_string_resource_hook = get_string_resource; + terminal->get_string_resource_hook = haiku_get_string_resource; terminal->set_new_font_hook = haiku_new_font; terminal->defined_color_hook = haiku_defined_color; terminal->set_window_size_hook = haiku_set_window_size; @@ -4089,9 +4120,15 @@ mark_haiku_display (void) void haiku_scroll_bar_remove (struct scroll_bar *bar) { + void *view; + struct frame *f; + + f = WINDOW_XFRAME (XWINDOW (bar->window)); + view = FRAME_HAIKU_VIEW (f); + block_input (); - void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (XWINDOW (bar->window))); - BView_forget_scroll_bar (view, bar->left, bar->top, bar->width, bar->height); + BView_forget_scroll_bar (view, bar->left, bar->top, + bar->width, bar->height); BScrollBar_delete (bar->scroll_bar); expose_frame (WINDOW_XFRAME (XWINDOW (bar->window)), bar->left, bar->top, bar->width, bar->height); @@ -4100,7 +4137,6 @@ haiku_scroll_bar_remove (struct scroll_bar *bar) wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil); else wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); - unblock_input (); }; diff --git a/src/image.c b/src/image.c index e4b56e29cff..757e1250066 100644 --- a/src/image.c +++ b/src/image.c @@ -542,12 +542,22 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_PGTK */ #ifdef HAVE_HAIKU - void *bitmap = BBitmap_new (width, height, 1); + void *bitmap; + int bytes_per_line, x, y; + + bitmap = BBitmap_new (width, height, 1); if (!bitmap) return -1; - BBitmap_import_mono_bits (bitmap, bits, width, height); + bytes_per_line = (width + 7) / 8; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + PUT_PIXEL (bitmap, x, y, (bits[8] >> (x % 8)) & 1); + bits += bytes_per_line; + } #endif id = image_allocate_bitmap_record (f); @@ -592,12 +602,19 @@ image_create_bitmap_from_data (struct frame *f, char *bits, return id; } +#ifdef HAVE_HAIKU +static char *slurp_file (int, ptrdiff_t *); +static Lisp_Object image_find_image_fd (Lisp_Object, int *); +static bool xbm_read_bitmap_data (struct frame *, char *, char *, + int *, int *, char **, bool); +#endif + /* Create bitmap from file FILE for frame F. */ ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) || defined (HAVE_HAIKU) +#if defined (HAVE_NTGUI) return -1; /* W32_TODO : bitmap support */ #else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); @@ -610,7 +627,6 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) if (!bitmap) return -1; - id = image_allocate_bitmap_record (f); dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].refcount = 1; @@ -637,7 +653,6 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].refcount = 1; dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); - //dpyinfo->bitmaps[id - 1].depth = 1; dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap); dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap); dpyinfo->bitmaps[id - 1].pattern @@ -692,6 +707,63 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) return id; #endif /* HAVE_X_WINDOWS */ + +#ifdef HAVE_HAIKU + ptrdiff_t id, size; + int fd, width, height, rc, bytes_per_line, x, y; + char *contents, *data, *tmp; + void *bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + bitmap = BBitmap_new (width, height, 1); + + if (!bitmap) + { + xfree (contents); + xfree (data); + return -1; + } + + id = image_allocate_bitmap_record (f); + + dpyinfo->bitmaps[id - 1].img = bitmap; + dpyinfo->bitmaps[id - 1].depth = 1; + dpyinfo->bitmaps[id - 1].file = NULL; + dpyinfo->bitmaps[id - 1].height = height; + dpyinfo->bitmaps[id - 1].width = width; + dpyinfo->bitmaps[id - 1].refcount = 1; + + bytes_per_line = (width + 7) / 8; + tmp = data; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + PUT_PIXEL (bitmap, x, y, (tmp[x / 8] >> (x % 8)) & 1); + + tmp += bytes_per_line; + } + + xfree (contents); + xfree (data); + return id; +#endif } /* Free bitmap B. */ From b205d67f8c92593f8e170419d677a70e535a3a19 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 04:42:11 +0000 Subject: [PATCH 0024/1028] Fully implement stipples for text on Haiku * src/haikufont.c (haikufont_draw): Use `haiku_draw_background_rect' instead. * src/haikuterm.c (haiku_draw_plain_background): Change arguments to accept rect manually. (haiku_get_bitmap): Delete function. (haiku_get_bitmap_rec): New function. (haiku_draw_stipple_background): Accept rect instead of box sizes. (haiku_draw_background_rect): New function. (haiku_maybe_draw_background): Use that instead. (haiku_draw_image_glyph_string): Add notice. (haiku_draw_glyph_string): Set `stippled_p' correctly. * src/haikuterm.h (struct haiku_bitmap_record): New fields for keeping track of stipple state. * src/image.c (image_create_bitmap_from_data) (image_create_bitmap_from_file, free_bitmap_record): Free and set them accordingly. --- src/haikufont.c | 4 +- src/haikuterm.c | 111 ++++++++++++++++++++++++++++++++---------------- src/haikuterm.h | 7 +++ src/image.c | 30 ++++++++++--- 4 files changed, 107 insertions(+), 45 deletions(-) diff --git a/src/haikufont.c b/src/haikufont.c index e0db086aa00..54f11c6e413 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -1084,8 +1084,8 @@ haikufont_draw (struct glyph_string *s, int from, int to, s->first_glyph->slice.glyphless.lower_yoff - s->first_glyph->slice.glyphless.upper_yoff; - BView_SetHighColor (view, background); - BView_FillRectangle (view, x, y - ascent, s->width, height); + haiku_draw_background_rect (s, s->face, x, y - ascent, + s->width, height); s->background_filled_p = 1; } diff --git a/src/haikuterm.c b/src/haikuterm.c index 46ea5f90277..93af5c8e435 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -971,10 +971,11 @@ haiku_draw_string_box (struct glyph_string *s) static void haiku_draw_plain_background (struct glyph_string *s, struct face *face, - int box_line_hwidth, int box_line_vwidth) + int x, int y, int width, int height) { void *view = FRAME_HAIKU_VIEW (s->f); unsigned long cursor_color; + if (s->hl == DRAW_CURSOR) { haiku_merge_cursor_foreground (s, NULL, &cursor_color); @@ -983,38 +984,86 @@ haiku_draw_plain_background (struct glyph_string *s, struct face *face, else BView_SetHighColor (view, face->background_defaulted_p ? FRAME_BACKGROUND_PIXEL (s->f) : - face->background); + face->background); - BView_FillRectangle (view, s->x, - s->y + box_line_hwidth, - s->background_width, - s->height - 2 * box_line_hwidth); + BView_FillRectangle (view, x, y, width, height); } -static void * -haiku_get_bitmap (struct frame *f, ptrdiff_t id) +static struct haiku_bitmap_record * +haiku_get_bitmap_rec (struct frame *f, ptrdiff_t id) { - return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].img; + return &FRAME_DISPLAY_INFO (f)->bitmaps[id - 1]; +} + +static void +haiku_update_bitmap_rec (struct haiku_bitmap_record *rec, + uint32_t new_foreground, + uint32_t new_background) +{ + char *bits; + int x, y, bytes_per_line; + + if (new_foreground == rec->stipple_foreground + && new_background == rec->stipple_background) + return; + + bits = rec->stipple_bits; + bytes_per_line = (rec->width + 7) / 8; + + for (y = 0; y < rec->height; y++) + { + for (x = 0; x < rec->width; x++) + haiku_put_pixel (rec->img, x, y, + ((bits[x / 8] >> (x % 8)) & 1 + ? new_foreground : new_background)); + + bits += bytes_per_line; + } + + rec->stipple_foreground = new_foreground; + rec->stipple_background = new_background; } static void haiku_draw_stipple_background (struct glyph_string *s, struct face *face, - int box_line_hwidth, int box_line_vwidth) + int x, int y, int width, int height) { + struct haiku_bitmap_record *rec; + unsigned long foreground, background; void *view; view = FRAME_HAIKU_VIEW (s->f); + rec = haiku_get_bitmap_rec (s->f, s->face->stipple); + + if (s->hl == DRAW_CURSOR) + haiku_merge_cursor_foreground (s, &foreground, &background); + else + { + foreground = s->face->foreground; + background = s->face->background; + } + + haiku_update_bitmap_rec (rec, foreground, background); + BView_StartClip (view); haiku_clip_to_string (s); - BView_ClipToRect (view, s->x, s->y + box_line_hwidth, - s->background_width, - s->height - 2 * box_line_hwidth); - BView_DrawBitmapTiled (view, haiku_get_bitmap (s->f, face->stipple), - 0, 0, -1, -1, 0, 0, FRAME_PIXEL_WIDTH (s->f), + BView_ClipToRect (view, x, y, width, height); + BView_DrawBitmapTiled (view, rec->img, 0, 0, -1, -1, + 0, 0, FRAME_PIXEL_WIDTH (s->f), FRAME_PIXEL_HEIGHT (s->f)); BView_EndClip (view); } +void +haiku_draw_background_rect (struct glyph_string *s, struct face *face, + int x, int y, int width, int height) +{ + if (!s->stippled_p) + haiku_draw_plain_background (s, face, x, y, width, height); + else + haiku_draw_stipple_background (s, face, x, y, width, height); +} + static void haiku_maybe_draw_background (struct glyph_string *s, int force_p) { @@ -1028,12 +1077,10 @@ haiku_maybe_draw_background (struct glyph_string *s, int force_p) || FONT_TOO_HIGH (s->font) || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) { - if (!face->stipple) - haiku_draw_plain_background (s, face, box_line_width, - box_vline_width); - else - haiku_draw_stipple_background (s, face, box_line_width, - box_vline_width); + haiku_draw_background_rect (s, s->face, s->x, s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); + s->background_filled_p = 1; } } @@ -1286,17 +1333,8 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s) } if (background_width > 0) - { - void *view = FRAME_HAIKU_VIEW (s->f); - unsigned long bkg; - if (s->hl == DRAW_CURSOR) - haiku_merge_cursor_foreground (s, NULL, &bkg); - else - bkg = s->face->background; - - BView_SetHighColor (view, bkg); - BView_FillRectangle (view, x, s->y, background_width, s->height); - } + haiku_draw_background_rect (s, s->face, s->y, + background_width, s->height); } s->background_filled_p = 1; } @@ -1566,6 +1604,7 @@ haiku_draw_image_glyph_string (struct glyph_string *s) void *view = FRAME_HAIKU_VIEW (s->f); void *bitmap = s->img->pixmap; + /* TODO: implement stipples for images with masks. */ s->stippled_p = face->stipple != 0; BView_SetHighColor (view, face->background); @@ -1648,16 +1687,14 @@ haiku_draw_image_glyph_string (struct glyph_string *s) static void haiku_draw_glyph_string (struct glyph_string *s) { - void *view; + void *view = FRAME_HAIKU_VIEW (s->f);; + struct face *face = s->face; block_input (); - view = FRAME_HAIKU_VIEW (s->f); BView_draw_lock (view, false, 0, 0, 0, 0); prepare_face_for_display (s->f, s->face); - struct face *face = s->face; - if (face != s->face) - prepare_face_for_display (s->f, face); + s->stippled_p = s->hl != DRAW_CURSOR && face->stipple; if (s->next && s->right_overhang && !s->for_overlaps) { diff --git a/src/haikuterm.h b/src/haikuterm.h index 1bff03ae39e..cc032d03892 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -52,6 +52,10 @@ struct haiku_bitmap_record char *file; int refcount; int height, width, depth; + + uint32_t stipple_foreground; + uint32_t stipple_background; + void *stipple_bits; }; struct haiku_display_info @@ -325,6 +329,9 @@ extern int haiku_load_image (struct frame *, struct image *, extern void syms_of_haikuimage (void); #endif +extern void haiku_draw_background_rect (struct glyph_string *, struct face *, + int, int, int, int); + #ifdef USE_BE_CAIRO extern cairo_t *haiku_begin_cr_clip (struct frame *, struct glyph_string *); diff --git a/src/image.c b/src/image.c index 757e1250066..f3b47f7cccb 100644 --- a/src/image.c +++ b/src/image.c @@ -542,20 +542,24 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_PGTK */ #ifdef HAVE_HAIKU - void *bitmap; + void *bitmap, *stipple; int bytes_per_line, x, y; - bitmap = BBitmap_new (width, height, 1); + bitmap = BBitmap_new (width, height, false); if (!bitmap) return -1; bytes_per_line = (width + 7) / 8; + stipple = xmalloc (height * bytes_per_line); + memcpy (stipple, bits, height * bytes_per_line); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - PUT_PIXEL (bitmap, x, y, (bits[8] >> (x % 8)) & 1); + PUT_PIXEL (bitmap, x, y, ((bits[8] >> (x % 8)) & 1 + ? f->foreground_pixel + : f->background_pixel)); bits += bytes_per_line; } #endif @@ -577,6 +581,11 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_HAIKU dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].depth = 1; + dpyinfo->bitmaps[id - 1].stipple_bits = stipple; + dpyinfo->bitmaps[id - 1].stipple_foreground + = f->foreground_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_background + = f->background_pixel & 0xffffffff; #endif dpyinfo->bitmaps[id - 1].file = NULL; @@ -731,7 +740,7 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) return -1; } - bitmap = BBitmap_new (width, height, 1); + bitmap = BBitmap_new (width, height, false); if (!bitmap) { @@ -748,6 +757,11 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].height = height; dpyinfo->bitmaps[id - 1].width = width; dpyinfo->bitmaps[id - 1].refcount = 1; + dpyinfo->bitmaps[id - 1].stipple_foreground + = f->foreground_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_background + = f->background_pixel & 0xffffffff; + dpyinfo->bitmaps[id - 1].stipple_bits = data; bytes_per_line = (width + 7) / 8; tmp = data; @@ -755,13 +769,14 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - PUT_PIXEL (bitmap, x, y, (tmp[x / 8] >> (x % 8)) & 1); + PUT_PIXEL (bitmap, x, y, ((tmp[x / 8] >> (x % 8)) & 1 + ? f->foreground_pixel + : f->background_pixel)); tmp += bytes_per_line; } xfree (contents); - xfree (data); return id; #endif } @@ -796,6 +811,9 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) #ifdef HAVE_HAIKU BBitmap_free (bm->img); + + if (bm->stipple_bits) + xfree (bm->stipple_bits); #endif if (bm->file) From 5eeca488b9a5f1cad328f9b031be588526a0ef1e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 05:09:24 +0000 Subject: [PATCH 0025/1028] Implement stipples for stretch glyphs * src/haikuterm.c (haiku_draw_stipple_background): Accept new arguments for specifying the color explicitly. All callers changed. (haiku_draw_stretch_glyph_string): Draw stipple correctly. (haiku_draw_glyph_string): Handle stipple correctly when drawing neighbors. --- src/haikuterm.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index 93af5c8e435..7c1115e0278 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -1026,7 +1026,10 @@ haiku_update_bitmap_rec (struct haiku_bitmap_record *rec, static void haiku_draw_stipple_background (struct glyph_string *s, struct face *face, - int x, int y, int width, int height) + int x, int y, int width, int height, + bool explicit_colors_p, + uint32 explicit_background, + uint32 explicit_foreground) { struct haiku_bitmap_record *rec; unsigned long foreground, background; @@ -1035,7 +1038,12 @@ haiku_draw_stipple_background (struct glyph_string *s, struct face *face, view = FRAME_HAIKU_VIEW (s->f); rec = haiku_get_bitmap_rec (s->f, s->face->stipple); - if (s->hl == DRAW_CURSOR) + if (explicit_colors_p) + { + background = explicit_background; + foreground = explicit_foreground; + } + else if (s->hl == DRAW_CURSOR) haiku_merge_cursor_foreground (s, &foreground, &background); else { @@ -1061,7 +1069,8 @@ haiku_draw_background_rect (struct glyph_string *s, struct face *face, if (!s->stippled_p) haiku_draw_plain_background (s, face, x, y, width, height); else - haiku_draw_stipple_background (s, face, x, y, width, height); + haiku_draw_stipple_background (s, face, x, y, width, height, + false, 0, 0); } static void @@ -1255,9 +1264,8 @@ haiku_draw_glyphless_glyph_string_foreground (struct glyph_string *s) static void haiku_draw_stretch_glyph_string (struct glyph_string *s) { - eassert (s->first_glyph->type == STRETCH_GLYPH); - struct face *face = s->face; + uint32_t bkg; if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p) { @@ -1305,9 +1313,11 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s) int y = s->y; int w = background_width - width, h = s->height; + /* Draw stipples manually because we want the background + part of a stretch glyph to have a stipple even if the + cursor is visible on top. */ if (!face->stipple) { - uint32_t bkg; if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w)) haiku_mouse_face_colors (s, NULL, &bkg); else @@ -1316,6 +1326,16 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s) BView_SetHighColor (view, bkg); BView_FillRectangle (view, x, y, w, h); } + else + { + if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w)) + haiku_mouse_face_colors (s, NULL, &bkg); + else + bkg = face->background; + + haiku_draw_stipple_background (s, s->face, x, y, w, h, + true, bkg, face->foreground); + } } } else if (!s->background_filled_p) @@ -1333,7 +1353,7 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s) } if (background_width > 0) - haiku_draw_background_rect (s, s->face, s->y, + haiku_draw_background_rect (s, s->face, s->x, s->y, background_width, s->height); } s->background_filled_p = 1; @@ -1706,13 +1726,16 @@ haiku_draw_glyph_string (struct glyph_string *s) width += next->width, next = next->next) if (next->first_glyph->type != IMAGE_GLYPH) { - prepare_face_for_display (s->f, s->next->face); - haiku_start_clip (s->next); - haiku_clip_to_string (s->next); + prepare_face_for_display (s->f, next->face); + next->stippled_p + = next->hl != DRAW_CURSOR && next->face->stipple; + + haiku_start_clip (next); + haiku_clip_to_string (next); if (next->first_glyph->type != STRETCH_GLYPH) - haiku_maybe_draw_background (s->next, 1); + haiku_maybe_draw_background (next, true); else - haiku_draw_stretch_glyph_string (s->next); + haiku_draw_stretch_glyph_string (next); haiku_end_clip (s); } } From 7474b55e2812ec11f55817429b5e8815710e5112 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 05:28:11 +0000 Subject: [PATCH 0026/1028] Fix setting stipple via `set-face-stipple' * lisp/faces.el (face-valid-attribute-values): Return results for `:stipple' in correct format. --- lisp/faces.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/faces.el b/lisp/faces.el index 395ea315bae..1ada05a7b8b 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1203,7 +1203,8 @@ an integer value." 'integerp) (:stipple (and (memq (window-system frame) '(x ns pgtk haiku)) ; No stipple on w32 - (mapcar #'list + (mapcar (lambda (item) + (cons item item)) (apply #'nconc (mapcar (lambda (dir) (and (file-readable-p dir) From 48c422e255095658ea8ff20a59a6d306910281c5 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 13:44:28 +0800 Subject: [PATCH 0027/1028] Fix display of hollow box cursor on NS * src/nsterm.m (ns_draw_window_cursor): Fix verbatim translations from X. --- src/nsterm.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nsterm.m b/src/nsterm.m index fef7f0dc6c8..82062033335 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3079,7 +3079,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. break; case HOLLOW_BOX_CURSOR: draw_phys_cursor_glyph (w, glyph_row, DRAW_NORMAL_TEXT); - [NSBezierPath strokeRect: r]; + + /* This works like it does in PostScript, not X Windows. */ + [NSBezierPath strokeRect: NSInsetRect (r, 0.5, 0.5)]; break; case HBAR_CURSOR: NSRectFill (r); From a85e30516e543081d0197b9975fa9ba143426b6f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 8 May 2022 09:24:29 +0300 Subject: [PATCH 0028/1028] Fix selection dialog display on MS-Windows * src/w32fns.c (w32_wnd_proc) : Update the frame from the back buffer when double-buffering is in effect and a selection dialog is open. (w32_dialog_in_progress): Indicate to 'w32_wnd_proc' that a selection dialog is open. (Bug#55208) --- src/w32fns.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/w32fns.c b/src/w32fns.c index 0f25c1a594a..e5becb5d64f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -247,6 +247,8 @@ static HWND w32_visible_system_caret_hwnd; static int w32_unicode_gui; +static bool w32_selection_dialog_open; + /* From w32menu.c */ int menubar_in_use = 0; @@ -4184,6 +4186,16 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) update_rect.left, update_rect.top, update_rect.right, update_rect.bottom)); #endif + /* Under double-buffering, update the frame from the back + buffer, to prevent a "ghost" of the selection dialog to + be left on display while the user selects in the dialog. */ + if (w32_selection_dialog_open + && !w32_disable_double_buffering + && FRAME_OUTPUT_DATA (f)->paint_dc) + BitBlt (FRAME_OUTPUT_DATA (f)->paint_buffer_handle, + 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), + FRAME_OUTPUT_DATA (f)->paint_dc, 0, 0, SRCCOPY); + EndPaint (hwnd, &paintStruct); leave_crit (); @@ -7755,6 +7767,15 @@ w32_dialog_in_progress (Lisp_Object in_progress) { Lisp_Object frames, frame; + /* Indicate to w32_wnd_proc that the selection dialog is about to be + open (or was closed, if IN_PROGRESS is nil). */ + if (!w32_disable_double_buffering) + { + enter_crit (); + w32_selection_dialog_open = !NILP (in_progress); + leave_crit (); + } + /* Don't let frames in `above' z-group obscure dialog windows. */ FOR_EACH_FRAME (frames, frame) { From 144e9f9b6a376ec0349557ef10a6c133228cda26 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 14:27:13 +0800 Subject: [PATCH 0029/1028] Fix file-based stipple on NS * src/image.c (image_create_bitmap_from_file) [HAVE_NS]: Fix loading XBM data from file. --- src/image.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/image.c b/src/image.c index f3b47f7cccb..6cd0aa48cfc 100644 --- a/src/image.c +++ b/src/image.c @@ -611,7 +611,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, return id; } -#ifdef HAVE_HAIKU +#if defined HAVE_HAIKU || defined HAVE_NS static char *slurp_file (int, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, int *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -630,11 +630,36 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) #endif #ifdef HAVE_NS - ptrdiff_t id; - void *bitmap = ns_image_from_file (file); + ptrdiff_t id, size; + int fd, width, height, rc; + char *contents, *data; + void *bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + bitmap = ns_image_from_XBM (data, width, height, 0, 0); if (!bitmap) + { + xfree (contents); + xfree (data); return -1; + } id = image_allocate_bitmap_record (f); dpyinfo->bitmaps[id - 1].img = bitmap; @@ -643,6 +668,9 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].depth = 1; dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); + + xfree (contents); + xfree (data); return id; #endif From 1a988d9ff55c098ddee0c79afcccbdc63e7c680e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 14:33:34 +0800 Subject: [PATCH 0030/1028] Improve handling of invisible cursor alloc failures * src/xterm.c (x_toggle_visible_pointer): Use Xfixes if cursor allocation really fails. This happens when the X server has a limit on the number of cursors that can be created. --- src/xterm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/xterm.c b/src/xterm.c index 2fc4c559a9c..a7f0f3d7efa 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9452,8 +9452,21 @@ x_toggle_visible_pointer (struct frame *f, bool invisible) if (dpyinfo->invisible_cursor == None) dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo); +#ifndef HAVE_XFIXES if (dpyinfo->invisible_cursor == None) invisible = false; +#else + /* But if Xfixes is available, try using it instead. */ + if (x_probe_xfixes_extension (dpyinfo)) + { + dpyinfo->fixes_pointer_blanking = true; + xfixes_toggle_visible_pointer (f, invisible); + + return; + } + else + invisible = false; +#endif if (invisible) XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f), From e683b08b3fbbc1692e0053699c5cf2b7cbc803f6 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sun, 8 May 2022 11:43:19 +0200 Subject: [PATCH 0031/1028] Handle changed scp protocol in Tramp, don't merge * lisp/net/tramp-sh.el (tramp-scp-force-scp-protocol): New defvar. (tramp-scp-force-scp-protocol): New defun. (tramp-do-copy-or-rename-file-out-of-band): Use it. (tramp-methods) : Use "%y". * lisp/net/tramp.el (tramp-methods): Adapt docstring. --- lisp/net/tramp-sh.el | 43 ++++++++++++++++++++++++++++++++++++++++--- lisp/net/tramp.el | 2 ++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 67f5519bbfe..c4fbe4673b9 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -134,6 +134,15 @@ be auto-detected by Tramp. The string is used in `tramp-methods'.") +(defvar tramp-scp-force-scp-protocol nil + "Force scp protocol. + +It is the string \"-O\" if supported by the local scp (since +release 8.6), otherwise the string \"\". If it is nil, it will +be auto-detected by Tramp. + +The string is used in `tramp-methods'.") + ;; Initialize `tramp-methods' with the supported methods. ;;;###tramp-autoload (tramp--with-startup @@ -170,7 +179,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") - ("%x") ("-q") ("-r") ("%c"))) + ("%x") ("%y") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -186,7 +195,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") - ("%x") ("-q") ("-r") ("%c"))) + ("%x") ("%y") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -2311,7 +2320,8 @@ The method used must be an out-of-band method." ?h (or host "") ?u (or user "") ?p (or port "") ?r listener ?c options ?k (if keep-date " " "") ?n (concat "2>" (tramp-get-remote-null-device v)) - ?x (tramp-scp-strict-file-name-checking v)) + ?x (tramp-scp-strict-file-name-checking v) + ?y (tramp-scp-force-scp-protocol v)) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) @@ -4818,6 +4828,33 @@ Goes through the list `tramp-inline-compress-commands'." (setq tramp-scp-strict-file-name-checking "-T"))))))) tramp-scp-strict-file-name-checking))) +(defun tramp-scp-force-scp-protocol (vec) + "Return the force scp protocol argument of the local scp." + (cond + ;; No options to be computed. + ((null (assoc "%y" (tramp-get-method-parameter vec 'tramp-copy-args))) + "") + + ;; There is already a value to be used. + ((stringp tramp-scp-force-scp-protocol) + tramp-scp-force-scp-protocol) + + ;; Determine the options. + (t (setq tramp-scp-force-scp-protocol "") + (let ((case-fold-search t)) + (ignore-errors + (when (executable-find "scp") + (with-tramp-progress-reporter + vec 4 "Computing force scp protocol argument" + (with-temp-buffer + (tramp-call-process vec "scp" nil t nil "-O") + (goto-char (point-min)) + (unless + (search-forward-regexp + "\\(illegal\\|unknown\\) option -- O" nil t) + (setq tramp-scp-force-scp-protocol "-O"))))))) + tramp-scp-force-scp-protocol))) + (defun tramp-timeout-session (vec) "Close the connection VEC after a session timeout. If there is just some editing, retry it after 5 seconds." diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 8baf72464dc..63ea8a283c6 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -255,6 +255,8 @@ pair of the form (KEY VALUE). The following KEYs are defined: - \"%n\" expands to \"2>/dev/null\". - \"%x\" is replaced by the `tramp-scp-strict-file-name-checking' argument if it is supported. + - \"%y\" is replaced by the `tramp-scp-force-scp-protocol' + argument if it is supported. The existence of `tramp-login-args', combined with the absence of `tramp-copy-args', is an indication that the From ccbdae840d21100520d191afa7001c4cd53a48a8 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sun, 8 May 2022 11:51:59 +0200 Subject: [PATCH 0032/1028] Handle changed scp protocol in Tramp * lisp/net/tramp-sh.el (tramp-scp-force-scp-protocol): New defvar. (tramp-scp-force-scp-protocol): New defun. (tramp-do-copy-or-rename-file-out-of-band): Use it. (tramp-scp-direct-remote-copying, tramp-methods) : Use "%z". * lisp/net/tramp.el (tramp-methods): Adapt docstring. --- lisp/net/tramp-sh.el | 49 +++++++++++++++++++++++++++++++++++++++----- lisp/net/tramp.el | 4 +++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index ba4cdb0ab52..74155d1722e 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -137,6 +137,15 @@ be auto-detected by Tramp. The string is used in `tramp-methods'.") +(defvar tramp-scp-force-scp-protocol nil + "Force scp protocol. + +It is the string \"-O\" if supported by the local scp (since +release 8.6), otherwise the string \"\". If it is nil, it will +be auto-detected by Tramp. + +The string is used in `tramp-methods'.") + (defcustom tramp-use-scp-direct-remote-copying nil "Whether to use direct copying between two remote hosts." :group 'tramp @@ -179,7 +188,8 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") - ("%x") ("%y") ("-q") ("-r") ("%c"))) + ("%x") ("%y") ("%z") + ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -195,7 +205,8 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") - ("%x") ("%y") ("-q") ("-r") ("%c"))) + ("%x") ("%y") ("%z") + ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -2347,7 +2358,8 @@ The method used must be an out-of-band method." ?r listener ?c options ?k (if keep-date " " "") ?n (concat "2>" (tramp-get-remote-null-device v)) ?x (tramp-scp-strict-file-name-checking v) - ?y (tramp-scp-direct-remote-copying v1 v2)) + ?y (tramp-scp-force-scp-protocol v) + ?z (tramp-scp-direct-remote-copying v1 v2)) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) @@ -4810,14 +4822,41 @@ Goes through the list `tramp-inline-compress-commands'." (setq tramp-scp-strict-file-name-checking "-T"))))))) tramp-scp-strict-file-name-checking))) +(defun tramp-scp-force-scp-protocol (vec) + "Return the force scp protocol argument of the local scp." + (cond + ;; No options to be computed. + ((null (assoc "%y" (tramp-get-method-parameter vec 'tramp-copy-args))) + "") + + ;; There is already a value to be used. + ((stringp tramp-scp-force-scp-protocol) + tramp-scp-force-scp-protocol) + + ;; Determine the options. + (t (setq tramp-scp-force-scp-protocol "") + (let ((case-fold-search t)) + (ignore-errors + (when (executable-find "scp") + (with-tramp-progress-reporter + vec 4 "Computing force scp protocol argument" + (with-temp-buffer + (tramp-call-process vec "scp" nil t nil "-O") + (goto-char (point-min)) + (unless + (search-forward-regexp + "\\(illegal\\|unknown\\) option -- O" nil t) + (setq tramp-scp-force-scp-protocol "-O"))))))) + tramp-scp-force-scp-protocol))) + (defun tramp-scp-direct-remote-copying (vec1 vec2) "Return the direct remote copying argument of the local scp." (cond ((or (not tramp-use-scp-direct-remote-copying) (null vec1) (null vec2) (not (tramp-get-process vec1)) (not (equal (tramp-file-name-port vec1) (tramp-file-name-port vec2))) - (null (assoc "%y" (tramp-get-method-parameter vec1 'tramp-copy-args))) - (null (assoc "%y" (tramp-get-method-parameter vec2 'tramp-copy-args)))) + (null (assoc "%z" (tramp-get-method-parameter vec1 'tramp-copy-args))) + (null (assoc "%z" (tramp-get-method-parameter vec2 'tramp-copy-args)))) "") ((let ((case-fold-search t)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 34f256147ba..fec4ea68ec6 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -255,7 +255,9 @@ pair of the form (KEY VALUE). The following KEYs are defined: - \"%n\" expands to \"2>/dev/null\". - \"%x\" is replaced by the `tramp-scp-strict-file-name-checking' argument if it is supported. - - \"%y\" is replaced by the `tramp-scp-direct-remote-copying' + - \"%y\" is replaced by the `tramp-scp-force-scp-protocol' + argument if it is supported. + - \"%z\" is replaced by the `tramp-scp-direct-remote-copying' argument if it is supported. The existence of `tramp-login-args', combined with the From be60e9e947cc441abc3373d321ff7869b607628e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 19:02:06 +0800 Subject: [PATCH 0033/1028] Fix bug in `pixel-scroll-precision-mode' on nonselected windows * src/window.c (Fset_window_vscroll): Mark window for redisplay. (bug#55299) --- src/window.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/window.c b/src/window.c index 15d6cf94b0e..72d10f9da23 100644 --- a/src/window.c +++ b/src/window.c @@ -7980,6 +7980,9 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */) /* Prevent redisplay shortcuts. */ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true; + + /* Mark W for redisplay. (bug#55299) */ + wset_redisplay (w); } } From 461ac0815c153778c41f3074e8d7748754ff7dd9 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 19:14:57 +0800 Subject: [PATCH 0034/1028] Fix crashes on ordinary menus on macOS * src/nsmenu.m ([EmacsMenu runMenuAt:forFrame:keymaps:]): Fix coding style. ([EmacsMenu menu:willHighlightItem:]): Ignore if this is a context menu. --- src/nsmenu.m | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/nsmenu.m b/src/nsmenu.m index b0ab12bb87d..34864f94087 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -741,15 +741,15 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f /* p = [view convertPoint:p fromView: nil]; */ p.y = NSHeight ([view frame]) - p.y; e = [[view window] currentEvent]; - event = [NSEvent mouseEventWithType: NSEventTypeRightMouseDown - location: p - modifierFlags: 0 - timestamp: [e timestamp] - windowNumber: [[view window] windowNumber] - context: nil - eventNumber: 0 /* [e eventNumber] */ - clickCount: 1 - pressure: 0]; + event = [NSEvent mouseEventWithType: NSEventTypeRightMouseDown + location: p + modifierFlags: 0 + timestamp: [e timestamp] + windowNumber: [[view window] windowNumber] + context: nil + eventNumber: 0 /* [e eventNumber] */ + clickCount: 1 + pressure: 0]; context_menu_value = -1; [NSMenu popUpContextMenu: self withEvent: event forView: view]; @@ -767,6 +767,10 @@ - (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item Lisp_Object vec = f->menu_bar_vector; Lisp_Object help, frame; + /* This isn't a menubar, ignore. */ + if (context_menu_value == -1) + return; + if (idx >= ASIZE (vec)) return; From 4c505203f9171886f47638779326e257a95a1d79 Mon Sep 17 00:00:00 2001 From: Visuwesh Date: Sun, 8 May 2022 13:17:34 +0200 Subject: [PATCH 0035/1028] dired-do-query-replace-regexp doc string fix * lisp/dired-aux.el (dired-do-query-replace-regexp): Refer 'fileloop-continue' instead of the obsolete command 'tags-loop-continue'. --- lisp/dired-aux.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 64cdab28f9a..d2bac5c467c 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3293,7 +3293,7 @@ type \\[help-command] at that time. Third arg DELIMITED (prefix arg) means replace only word-delimited matches. If you exit the query-replace loop (\\[keyboard-quit], RET or q), you can -resume the query replace with the command \\[tags-loop-continue]." +resume the query replace with the command \\[fileloop-continue]." (interactive (let ((common (query-replace-read-args From 1d012e0a621f9cf99048f57130144275b9025d1c Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sun, 8 May 2022 11:39:45 +0000 Subject: [PATCH 0036/1028] Linux console: don't translate ESC TAB to `backtab' in input-decode-map. This translation happened after the terminfo entry for TAB in the linux section was changed to kcbt=\E^I in ncurses version 6.3. * lisp/term/linux.el (terminal-init-linux): Add a define-key form to remove the entry for "\e\t" from input-decode-map. * etc/PROBLEMS: Add a new section under "character terminals" about S-TAB wrongly doing the same thing as M-TAB, giving tips about amending the Linux keyboard layout. --- etc/PROBLEMS | 27 +++++++++++++++++++++++++++ lisp/term/linux.el | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 2a26dfaec4d..8a260c3177c 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1736,6 +1736,33 @@ this, you can remove the X resource or put this in your init file: (xterm-remove-modify-other-keys) +** The shift TAB key combination works as meta TAB on a Linux console. + +This happens because on your keyboard layout, S-TAB produces the same +keycodes as typing ESC TAB individually. The best way to solve this +is to modify your keyboard layout to produce different codes, and tell +Emacs what these new codes mean. + +The current keyboard layout will probably be a .map.gz file somewhere +under /usr/share/keymaps. Identify this file, possibly from a system +initialization file such as /etc/conf.d/keymaps. Run gunzip on it to +decompress it, and amend the entries for keycode 15 to look something +like this: + +keycode 15 = Tab + alt keycode 15 = Meta_Tab + shift keycode 15 = F219 +string F219 = "\033[4}\011" # Shift+ + +After possibly saving this file under a different name, compress it +again using gzip. Amend /etc/conf.d/keyamps, etc., if needed. +Further details can be found in the man page for loadkeys. + +Then add the following line near the start of your site-start.el or +.emacs or init.el file: + +(define-key input-decode-map "\e[4}\t" 'backtab) + ** Emacs spontaneously displays "I-search: " at the bottom of the screen. This means that Control-S/Control-Q (XON/XOFF) "flow control" is being diff --git a/lisp/term/linux.el b/lisp/term/linux.el index 6d43e477ac9..ab5a6d8698f 100644 --- a/lisp/term/linux.el +++ b/lisp/term/linux.el @@ -17,6 +17,10 @@ (ignore-errors (when gpm-mouse-mode (require 't-mouse) (gpm-mouse-enable))) + ;; Don't translate ESC TAB to backtab as directed + ;; by ncurses-6.3. + (define-key input-decode-map "\e\t" nil) + ;; Make Latin-1 input characters work, too. ;; Meta will continue to work, because the kernel ;; turns that into Escape. From 2f1410562ea36f1143c9d7b2e1341cef93ae1c19 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 20:48:42 +0800 Subject: [PATCH 0037/1028] Disable scrolling optimizations when a stipple is present * src/dispextern.h (struct glyph_row): New field `stippled_p'. We cannot just use the contents of the glyph row, since it has to be set in `gui_clear_end_of_line' and is more convenient to set inside the various draw_glyph_string functions. * src/dispnew.c (scrolling_window): Disable if a row in the current matrix has the stipple_p flag set. * src/xdisp.c (gui_clear_end_of_line): * src/xterm.c (x_draw_image_glyph_string) (x_draw_stretch_glyph_string, x_draw_glyph_string): Set `stipple_p' if a stipple pattern was drawn. --- src/dispextern.h | 3 +++ src/dispnew.c | 19 ++++++++++++++++++- src/xdisp.c | 7 ++++++- src/xterm.c | 20 +++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/dispextern.h b/src/dispextern.h index e9b19a7f135..a7f478acdf8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1075,6 +1075,9 @@ struct glyph_row right-to-left paragraph. */ bool_bf reversed_p : 1; + /* Whether or not a stipple was drawn in this row at some point. */ + bool_bf stipple_p : 1; + /* Continuation lines width at the start of the row. */ int continuation_lines_width; diff --git a/src/dispnew.c b/src/dispnew.c index 1dd64be4ead..c49c38cba86 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -4392,7 +4392,6 @@ add_row_entry (struct glyph_row *row) return entry; } - /* Try to reuse part of the current display of W by scrolling lines. HEADER_LINE_P means W has a header line. @@ -4438,6 +4437,14 @@ scrolling_window (struct window *w, int tab_line_p) struct glyph_row *d = MATRIX_ROW (desired_matrix, i); struct glyph_row *c = MATRIX_ROW (current_matrix, i); + /* If there is a row with a stipple currently on the glass, give + up. Stipples look different depending on where on the + display they are drawn, so scrolling the display will produce + incorrect results. */ + + if (c->stipple_p) + return 0; + if (c->enabled_p && d->enabled_p && !d->redraw_fringe_bitmaps_p @@ -4467,6 +4474,16 @@ scrolling_window (struct window *w, int tab_line_p) first_old = first_new = i; + while (i < current_matrix->nrows - 1) + { + /* If there is a stipple after the first change, give up as + well. */ + if (MATRIX_ROW (current_matrix, i)->stipple_p) + return 0; + + ++i; + } + /* Set last_new to the index + 1 of the row that reaches the bottom boundary in the desired matrix. Give up if we find a disabled row before we reach the bottom boundary. */ diff --git a/src/xdisp.c b/src/xdisp.c index 50efa50c55b..f09f209b2e3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -32015,14 +32015,16 @@ gui_insert_glyphs (struct window *w, struct glyph_row *updated_row, void gui_clear_end_of_line (struct window *w, struct glyph_row *updated_row, - enum glyph_row_area updated_area, int to_x) + enum glyph_row_area updated_area, int to_x) { struct frame *f; int max_x, min_y, max_y; int from_x, from_y, to_y; + struct face *face; eassert (updated_row); f = XFRAME (w->frame); + face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); if (updated_row->full_width_p) max_x = (WINDOW_PIXEL_WIDTH (w) @@ -32074,6 +32076,9 @@ gui_clear_end_of_line (struct window *w, struct glyph_row *updated_row, block_input (); FRAME_RIF (f)->clear_frame_area (f, from_x, from_y, to_x - from_x, to_y - from_y); + + if (face && !updated_row->stipple_p) + updated_row->stipple_p = face->stipple; unblock_input (); } } diff --git a/src/xterm.c b/src/xterm.c index a7f0f3d7efa..fe9531bdb4e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8052,6 +8052,9 @@ x_draw_image_glyph_string (struct glyph_string *s) || s->img->pixmap == 0 || s->width != s->background_width) { + if (s->stippled_p) + s->row->stipple_p = true; + #ifndef USE_CAIRO if (s->img->mask) { @@ -8232,6 +8235,8 @@ x_draw_stretch_glyph_string (struct glyph_string *s) XSetFillStyle (display, gc, FillOpaqueStippled); x_fill_rectangle (s->f, gc, x, y, w, h, true); XSetFillStyle (display, gc, FillSolid); + + s->row->stipple_p = true; } else { @@ -8258,8 +8263,13 @@ x_draw_stretch_glyph_string (struct glyph_string *s) background_width -= text_left_x - x; x = text_left_x; } + + if (!s->row->stipple_p) + s->row->stipple_p = s->stippled_p; + if (background_width > 0) - x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); + x_draw_glyph_string_bg_rect (s, x, s->y, + background_width, s->height); } s->background_filled_p = true; @@ -8708,6 +8718,14 @@ x_draw_glyph_string (struct glyph_string *s) /* Reset clipping. */ x_reset_clip_rectangles (s->f, s->gc); s->num_clips = 0; + + /* Set the stippled flag that tells redisplay whether or not a + stipple was actually draw. */ + + if (s->first_glyph->type != STRETCH_GLYPH + && s->first_glyph->type != IMAGE_GLYPH + && !s->row->stipple_p) + s->row->stipple_p = s->stippled_p; } /* Shift display to make room for inserted glyphs. */ From 4b20ae908bc82d1f0d9e5bc9740a32572ed15018 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 13:02:00 +0000 Subject: [PATCH 0038/1028] Set stipple flags on Haiku as well * src/haikuterm.c (haiku_draw_glyph_string): Set stipple flag where stipples are actually drawn. (This is different from X.) --- src/haikuterm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/haikuterm.c b/src/haikuterm.c index 7c1115e0278..16e732fa0da 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -1860,8 +1860,21 @@ haiku_draw_glyph_string (struct glyph_string *s) } } } + haiku_end_clip (s); BView_draw_unlock (view); + + /* Set the stipple_p flag indicating whether or not a stipple was + drawn in s->row. That is the case either when s is a stretch + glyph string and s->face->stipple is not NULL, or when + s->face->stipple exists and s->hl is not DRAW_CURSOR, and s is + not an image. This is different from X. */ + if (s->first_glyph->type != IMAGE_GLYPH + && s->face->stipple + && (s->first_glyph->type == STRETCH_GLYPH + || s->hl != DRAW_CURSOR)) + s->row->stipple_p = true; + unblock_input (); } From 33141b51c3121b93f625c76b996b17ec8de97419 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 8 May 2022 15:03:59 +0200 Subject: [PATCH 0039/1028] Allow term-mode to send function keys to the underlying shell * lisp/term.el (term-bind-function-keys): New user option. (term-raw-map): Bind f keys. (term-send-function-key): Send the function key to the underlying shell (bug#29920). --- etc/NEWS | 5 +++++ lisp/term.el | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index ee7a127af0e..5c13b72c29b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1137,6 +1137,11 @@ filters and displayed with the specified color. ** term-mode +--- +*** New user option 'term-bind-function-keys'. +If non-nil, 'term-mode' will pass the function keys on to the +underlying shell instead of using the normal Emacs bindings. + --- *** Support for ANSI 256-color and 24-bit colors, italic and other fonts. Term-mode can now display 256-color and 24-bit color codes. It can diff --git a/lisp/term.el b/lisp/term.el index 3e05d529cd7..640478b59a2 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -918,6 +918,13 @@ is buffer-local." :type 'integer :version "27.1") +(defcustom term-bind-function-keys nil + "If nil, don't alter , and so on. +If non-nil, bind these keys in `term-mode' and send them to the +underlying shell." + :type 'boolean + :version "29.1") + ;; Set up term-raw-map, etc. @@ -958,6 +965,10 @@ is buffer-local." (define-key map [next] 'term-send-next) (define-key map [xterm-paste] #'term--xterm-paste) (define-key map [?\C-/] #'term-send-C-_) + + (when term-bind-function-keys + (dotimes (key 21) + (keymap-set map (format "" key) #'term-send-function-key))) map) "Keyboard map for sending characters directly to the inferior process.") @@ -1411,6 +1422,26 @@ Entry to this mode runs the hooks on `term-mode-hook'." (defun term-send-del () (interactive) (term-send-raw-string "\e[3~")) (defun term-send-backspace () (interactive) (term-send-raw-string "\C-?")) (defun term-send-C-_ () (interactive) (term-send-raw-string "\C-_")) + +(defun term-send-function-key () + "If bound to a function key, this will send that key to the underlying shell." + (interactive) + (let ((key (this-command-keys-vector))) + (when (and (= (length key) 1) + (symbolp (elt key 0))) + (let ((name (symbol-name (elt key 0)))) + (when (string-match "\\`f\\([0-9]++\\)\\'" name) + (let* ((num (string-to-number (match-string 1 name))) + (ansi + (cond + ((<= num 5) (+ num 10)) + ((<= num 10) (+ num 11)) + ((<= num 14) (+ num 12)) + ((<= num 16) (+ num 13)) + ((<= num 20) (+ num 14))))) + (when ansi + (term-send-raw-string (format "\e[%d~" ansi))))))))) + (defun term-char-mode () "Switch to char (\"raw\") sub-mode of term mode. From c7bd76a3f02d0a426c85035fd37b0d1a8b6ea5d9 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 21:07:44 +0800 Subject: [PATCH 0040/1028] Set stipple flag on PGTK as well * pgtkterm.c (pgtk_draw_glyph_string_background): (pgtk_draw_glyph_string): Set stipple flag on string row. (pgtk_draw_fringe_bitmap): (pgtk_defined_color): Fix coding style. --- src/pgtkterm.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/pgtkterm.c b/src/pgtkterm.c index c8c8bd0d85e..4d6221d8034 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -1333,9 +1333,7 @@ pgtk_draw_glyph_string_background (struct glyph_string *s, bool force_p) if (s->stippled_p) { /* Fill background with a stipple pattern. */ - - fill_background (s, - s->x, s->y + box_line_width, + fill_background (s, s->x, s->y + box_line_width, s->background_width, s->height - 2 * box_line_width); s->background_filled_p = true; @@ -2501,9 +2499,7 @@ pgtk_draw_glyph_string (struct glyph_string *s) if (s->face->underline_defaulted_p) pgtk_draw_underwave (s, s->xgcv.foreground); else - { - pgtk_draw_underwave (s, s->face->underline_color); - } + pgtk_draw_underwave (s, s->face->underline_color); } else if (s->face->underline == FACE_UNDER_LINE) { @@ -2670,6 +2666,11 @@ pgtk_draw_glyph_string (struct glyph_string *s) } } + /* TODO: figure out in which cases the stipple is actually drawn on + PGTK. */ + if (!s->row->stipple_p) + s->row->stipple_p = s->face->stipple; + /* Reset clipping. */ pgtk_end_cr_clip (s->f); s->num_clips = 0; @@ -3505,9 +3506,7 @@ pgtk_draw_fringe_bitmap (struct window *w, struct glyph_row *row, mono-displays, the fill style may have been changed to FillSolid in pgtk_draw_glyph_string_background. */ if (face->stipple) - { - fill_background_by_face (f, face, p->bx, p->by, p->nx, p->ny); - } + fill_background_by_face (f, face, p->bx, p->by, p->nx, p->ny); else { pgtk_set_cr_source_with_color (f, face->background, true); @@ -6608,9 +6607,9 @@ pgtk_xlfd_to_fontname (const char *xlfd) } bool -pgtk_defined_color (struct frame *f, - const char *name, - Emacs_Color * color_def, bool alloc, bool makeIndex) +pgtk_defined_color (struct frame *f, const char *name, + Emacs_Color *color_def, bool alloc, + bool makeIndex) /* -------------------------------------------------------------------------- Return true if named color found, and set color_def rgb accordingly. If makeIndex and alloc are nonzero put the color in the color_table, From f93c94996c7a8062878e1b7e0e7dba74bf5b98cd Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sun, 8 May 2022 13:14:14 +0000 Subject: [PATCH 0041/1028] CC Mode: Fix bug in c-parse-state. Fixes bug #55181. * lisp/progmodes/cc-engine.el (c-state-cache-lower-good-pos): When in a literal, return the start of that literal as a "good pos", not the parameter POS. --- lisp/progmodes/cc-engine.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index b2fa9e06911..ae68bf989a7 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -3422,7 +3422,9 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and ;; Return a good pos (in the sense of `c-state-cache-good-pos') at the ;; lowest[*] position between POS and HERE which is syntactically equivalent ;; to HERE. This position may be HERE itself. POS is before HERE in the - ;; buffer. + ;; buffer. If POS and HERE are both in the same literal, return the start + ;; of the literal. STATE is the parsing state at POS. + ;; ;; [*] We don't actually always determine this exact position, since this ;; would require a disproportionate amount of work, given that this function ;; deals only with a corner condition, and POS and HERE are typically on @@ -3438,7 +3440,7 @@ initializing CC Mode. Currently (2020-06) these are `js-mode' and (setq pos (point) state s))) (if (eq (point) here) ; HERE is in the same literal as POS - pos + (nth 8 state) ; A valid good pos cannot be in a literal. (setq s (parse-partial-sexp pos here (1+ (car state)) nil state nil)) (cond ((> (car s) (car state)) ; Moved into a paren between POS and HERE From 4d8527e5802e41573ee8c9f2a41659a1ba388dde Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 13:20:43 +0000 Subject: [PATCH 0042/1028] Fix display of fringes with stipples on Haiku * haikuterm.c (haiku_after_update_window_line): Fix coding style. (haiku_draw_fringe_bitmap): Handle display of stipples if present. --- src/haikuterm.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index 16e732fa0da..265d3fbf5e6 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -1910,8 +1910,9 @@ haiku_after_update_window_line (struct window *w, void *view = FRAME_HAIKU_VIEW (f); BView_draw_lock (view, false, 0, 0, 0, 0); BView_StartClip (view); - BView_SetHighColor (view, face->background_defaulted_p ? - FRAME_BACKGROUND_PIXEL (f) : face->background); + BView_SetHighColor (view, (face->background_defaulted_p + ? FRAME_BACKGROUND_PIXEL (f) + : face->background)); BView_FillRectangle (view, 0, y, width, height); BView_FillRectangle (view, FRAME_PIXEL_WIDTH (f) - width, y, width, height); @@ -2529,25 +2530,50 @@ static void haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p) { - void *view = FRAME_HAIKU_VIEW (XFRAME (WINDOW_FRAME (w))); - struct face *face = p->face; + struct face *face; + struct frame *f; + struct haiku_bitmap_record *rec; + void *view, *bitmap; + uint32 col; + + f = XFRAME (WINDOW_FRAME (w)); + view = FRAME_HAIKU_VIEW (f); + face = p->face; block_input (); BView_draw_lock (view, true, p->x, p->y, p->wd, p->h); BView_StartClip (view); haiku_clip_to_row (w, row, ANY_AREA); + if (p->bx >= 0 && !p->overlay_p) { - BView_SetHighColor (view, face->background); - BView_FillRectangle (view, p->bx, p->by, p->nx, p->ny); + if (!face->stipple) + { + BView_SetHighColor (view, face->background); + BView_FillRectangle (view, p->bx, p->by, p->nx, p->ny); + } + else + { + rec = haiku_get_bitmap_rec (f, face->stipple); + haiku_update_bitmap_rec (rec, face->foreground, + face->background); + + BView_StartClip (view); + haiku_clip_to_row (w, row, ANY_AREA); + BView_ClipToRect (view, p->bx, p->by, p->nx, p->ny); + BView_DrawBitmapTiled (view, rec->img, 0, 0, -1, -1, + 0, 0, FRAME_PIXEL_WIDTH (f), + FRAME_PIXEL_HEIGHT (f)); + BView_EndClip (view); + } } if (p->which && p->which < max_fringe_bmp && p->which < max_used_fringe_bitmap) { - void *bitmap = fringe_bmps[p->which]; + bitmap = fringe_bmps[p->which]; if (!bitmap) { @@ -2561,8 +2587,6 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row, bitmap = fringe_bmps[p->which]; } - uint32_t col; - if (!p->cursor_p) col = face->foreground; else if (p->overlay_p) From d6e316db729718f93772cec2e5166f54a920c0e3 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 8 May 2022 21:28:28 +0800 Subject: [PATCH 0043/1028] Fix display of fringes with stipples on X * src/xterm.c (x_draw_fringe_bitmap): Set fill style and use fill function correctly. --- src/xterm.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index fe9531bdb4e..d32bdea843a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5762,15 +5762,19 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring mono-displays, the fill style may have been changed to FillSolid in x_draw_glyph_string_background. */ if (face->stipple) - XSetFillStyle (display, face->gc, FillOpaqueStippled); + { + XSetFillStyle (display, face->gc, FillOpaqueStippled); + x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny, + true); + XSetFillStyle (display, face->gc, FillSolid); + } else - XSetBackground (display, face->gc, face->background); - - x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny, - true); - - if (!face->stipple) - XSetForeground (display, face->gc, face->foreground); + { + XSetBackground (display, face->gc, face->background); + x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny, + true); + XSetForeground (display, face->gc, face->foreground); + } } #ifdef USE_CAIRO From d24ea263e2193016c353d20e6388ef91597cf082 Mon Sep 17 00:00:00 2001 From: Visuwesh Date: Sun, 8 May 2022 13:17:34 +0200 Subject: [PATCH 0044/1028] dired-do-query-replace-regexp doc string fix * lisp/dired-aux.el (dired-do-query-replace-regexp): Refer 'fileloop-continue' instead of the obsolete command 'tags-loop-continue'. (Bug#55311) (cherry picked from commit 4c505203f9171886f47638779326e257a95a1d79) --- lisp/dired-aux.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index e00910cfe8d..d47bcf04279 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3179,7 +3179,7 @@ type \\[help-command] at that time. Third arg DELIMITED (prefix arg) means replace only word-delimited matches. If you exit the query-replace loop (\\[keyboard-quit], RET or q), you can -resume the query replace with the command \\[tags-loop-continue]." +resume the query replace with the command \\[fileloop-continue]." (interactive (let ((common (query-replace-read-args From 7546179a011452c304022349d034a03303a11ebb Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 8 May 2022 15:41:46 +0200 Subject: [PATCH 0045/1028] Don't hang on trying to rename FIFOs between file systems * src/fileio.c (Frename_file): Don't hang on trying to move FIFOs (bug#34069). --- src/fileio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/fileio.c b/src/fileio.c index c418036fc6e..0610f7235a5 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2718,6 +2718,20 @@ This is what happens in interactive use with M-x. */) : Qnil); if (!NILP (symlink_target)) Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists); + else if (S_ISFIFO (file_st.st_mode)) + { + /* If it's a FIFO, calling `copy-file' will hang if it's a + inter-file system move, so do it here. (It will signal + an error in that case, but it won't hang in any case.) */ + if (!NILP (ok_if_already_exists)) + barf_or_query_if_file_exists (newname, false, + "rename to it", + FIXNUMP (ok_if_already_exists), + false); + if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) != 0) + report_file_errno ("Renaming", list2 (file, newname), errno); + return Qnil; + } else Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt); } From b03d6265cd9427e11c5bfd4a56822b4475c8e8cd Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 8 May 2022 10:33:49 -0400 Subject: [PATCH 0046/1028] * lisp/emacs-lisp/oclosure.el (oclosure-define): Fix empty case --- lisp/emacs-lisp/oclosure.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/oclosure.el b/lisp/emacs-lisp/oclosure.el index cb8c59b05a2..9775e8cc656 100644 --- a/lisp/emacs-lisp/oclosure.el +++ b/lisp/emacs-lisp/oclosure.el @@ -223,7 +223,7 @@ list of slot properties. The currently known properties are the following: `:mutable': A non-nil value mean the slot can be mutated. `:type': Specifies the type of the values expected to appear in the slot." (declare (doc-string 2) (indent 1)) - (unless (stringp docstring) + (unless (or (stringp docstring) (null docstring)) (push docstring slots) (setq docstring nil)) (let* ((options (when (consp name) From 82f1f198c6b473c5f1169983d998f0779958d087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=B8=E0=A4=AE=E0=A5=80=E0=A4=B0=20=E0=A4=B8=E0=A4=BF?= =?UTF-8?q?=E0=A4=82=E0=A4=B9=20Sameer=20Singh?= Date: Sun, 8 May 2022 17:42:35 +0530 Subject: [PATCH 0047/1028] Add support for the Tirhuta script * lisp/language/indian.el ("Tirhuta"): New language environment. Add composition rules for Tirhuta. Add sample text and input method. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Support Tirhuta. * lisp/leim/quail/indian.el ("tirhuta"): New input method. * etc/HELLO: Add a Tirhuta greeting. * etc/NEWS: Announce the new language environment and its input method. --- etc/HELLO | 2 + etc/NEWS | 5 ++ lisp/international/fontset.el | 3 +- lisp/language/indian.el | 24 ++++++++ lisp/leim/quail/indian.el | 107 ++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) diff --git a/etc/HELLO b/etc/HELLO index ac0cb823eae..bd33c32b7a9 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -86,6 +86,8 @@ TaiViet (ꪁꪫꪱꪣ ꪼꪕ) ꪅꪰꪙꫂ ꪨꪮꫂ ꪁꪫꪱ / ꪅꪽ ꪨꪷ Thai (ภาษาไทย) สวัสดีครับ / สวัสดีค่ะ Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ Tigrigna (ትግርኛ) ሰላማት + +Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧 / 𑒮𑒲𑒞𑒰𑒩𑒰𑒧 Turkish (Türkçe) Merhaba Ukrainian (українська) Вітаю Vietnamese (tiếng Việt) Chào bạn diff --git a/etc/NEWS b/etc/NEWS index 5c13b72c29b..5d2b5e12cfa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -744,6 +744,11 @@ an important writing system of the past mainly used for administrative purposes. A new input method, 'kaithi', is provided to type text in this script. +*** New language environment "Tirhuta". +This language environment supports Tirhuta or Mithilaakshar, which is +used to write the Maithili language. A new input method, 'tirhuta', +is provided to type text in this script. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 66f5068cf76..2d417d632f8 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -238,7 +238,7 @@ (khudawadi #x112B0) (grantha #x11305) (newa #x11400) - (tirhuta #x11481) + (tirhuta #x11481 #x1148F #x114D0) (siddham #x11580) (modi #x11600) (takri #x11680) @@ -774,6 +774,7 @@ old-uyghur brahmi kaithi + tirhuta makasar dives-akuru cuneiform diff --git a/lisp/language/indian.el b/lisp/language/indian.el index ce46d325494..922061c3b6a 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -147,6 +147,17 @@ Languages such as Awadhi, Bhojpuri, Magahi and Maithili which used the Kaithi script are supported in this language environment.")) '("Indian")) +(set-language-info-alist + "Tirhuta" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "tirhuta") + (sample-text . "Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧") + (documentation . "\ +Maithili language and its script Tirhuta is supported in this +language environment.")) + '("Indian")) + ;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is ;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING). @@ -466,4 +477,17 @@ which used the Kaithi script are supported in this language environment.")) (provide 'indian) +;; Tirhuta composition rules +(let ((consonant "[\x1148F-\x114AF]") + (nukta "\x114C3") + (vowel "[\x114B0-\x114BE]") + (anusvara-candrabindu "[\x114BF\x114C0]") + (virama "\x114C2")) + (set-char-table-range composition-function-table + '(#x114B0 . #x114C3) + (list (vector + (concat consonant nukta "?\\(?:" virama consonant nukta "?\\)*\\(?:" + virama "\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") + 1 'font-shape-gstring)))) + ;;; indian.el ends here diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index a52d44bc083..f730a5ca0f1 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -860,6 +860,7 @@ Full key sequences are listed below:") ("8" ?८) ("`8" ?8) ("9" ?९) +("`9" ?9) ("0" ?०) ("`0" ?0) ("`\)" ?𑂻) @@ -936,5 +937,111 @@ Full key sequences are listed below:") ("`m" ?𑂀) ) +(quail-define-package + "tirhuta" "Tirhuta" "𑒞𑒱" t "Tirhuta phonetic input method. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules +("``" ?₹) +("1" ?𑓑) +("`1" ?1) +("2" ?𑓒) +("`2" ?2) +("3" ?𑓓) +("`3" ?3) +("4" ?𑓔) +("`4" ?4) +("5" ?𑓕) +("`5" ?5) +("6" ?𑓖) +("`6" ?6) +("7" ?𑓗) +("`7" ?7) +("8" ?𑓘) +("`8" ?8) +("9" ?𑓙) +("`9" ?9) +("0" ?𑓐) +("`0" ?0) +("`\)" ?𑓆) +("`\\" ?।) +("`|" ?॥) +("`" ?𑒙) +("q" ?𑒙) +("Q" ?𑒚) +("w" ?𑒛) +("W" ?𑒜) +("e" ?𑒺) +("E" ?𑒹) +("`e" ?𑒋) +("r" ?𑒩) +("R" ?𑒵) +("`r" ?𑒇) +("t" ?𑒞) +("T" ?𑒟) +("y" ?𑒨) +("Y" ?𑒻) +("`y" ?𑒌) +("u" ?𑒳) +("U" ?𑒴) +("`u" ?𑒅) +("`U" ?𑒆) +("i" ?𑒱) +("I" ?𑒲) +("`i" ?𑒃) +("`I" ?𑒄) +("o" ?𑒽) +("O" ?𑒼) +("`o" ?𑒍) +("p" ?𑒣) +("P" ?𑒤) +("a" ?𑒰) +("A" ?𑒂) +("`a" ?𑒁) +("s" ?𑒮) +("S" ?𑒬) +("d" ?𑒠) +("D" ?𑒡) +("f" ?𑓂) +("F" ?𑒶) +("`f" ?𑒈) +("g" ?𑒑) +("G" ?𑒒) +("h" ?𑒯) +("H" ?𑓁) +("j" ?𑒖) +("J" ?𑒗) +("k" ?𑒏) +("K" ?𑒐) +("l" ?𑒪) +("L" ?𑒷) +("`l" ?𑒉) +("z" ?𑒘) +("Z" ?𑒓) +("`z" ?𑒸) +("`Z" ?𑒊) +("x" ?𑒭) +("X" ?𑓃) +("c" ?𑒔) +("C" ?𑒕) +("`c" #x200C) ; ZWNJ +("v" ?𑒫) +("V" ?𑒾) +("`v" ?𑒎) +("b" ?𑒥) +("B" ?𑒦) +("`b" ?𑒀) +("`B" ?𑓄) +("n" ?𑒢) +("N" ?𑒝) +("`n" ?𑓇) +("`N" ?𑓅) +("m" ?𑒧) +("M" ?𑓀) +("`m" ?𑒿) +) + ;;; indian.el ends here From e8ed4317e879683872d956cc919d0957fff18531 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 8 May 2022 17:37:32 +0300 Subject: [PATCH 0048/1028] ; * etc/HELLO: Remove empty line. --- etc/HELLO | 1 - 1 file changed, 1 deletion(-) diff --git a/etc/HELLO b/etc/HELLO index bd33c32b7a9..f5e2adae940 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -86,7 +86,6 @@ TaiViet (ꪁꪫꪱꪣ ꪼꪕ) ꪅꪰꪙꫂ ꪨꪮꫂ ꪁꪫꪱ / ꪅꪽ ꪨꪷ Thai (ภาษาไทย) สวัสดีครับ / สวัสดีค่ะ Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ Tigrigna (ትግርኛ) ሰላማት - Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧 / 𑒮𑒲𑒞𑒰𑒩𑒰𑒧 Turkish (Türkçe) Merhaba Ukrainian (українська) Вітаю From fad31cebe174cc35738de943eae8e34038f11b1a Mon Sep 17 00:00:00 2001 From: Protesilaos Stavrou Date: Sun, 8 May 2022 17:27:48 +0300 Subject: [PATCH 0049/1028] Add Greek translation of the tutorial * etc/tutorials/TUTORIAL.el_GR: Add tutorial in Greek. It is a faithful translation of the TUTORIAL. * etc/tutorials/TUTORIAL.translators (Author): Mention myself as the author and the maintainer. * etc/NEWS: Announce it. (Bug#55314) * lisp/language/greek.el (set-language-info-alist): Link to the tutorial and include sample text. --- etc/NEWS | 7 +- etc/tutorials/TUTORIAL.el_GR | 1268 ++++++++++++++++++++++++++++ etc/tutorials/TUTORIAL.translators | 4 + lisp/language/greek.el | 4 +- 4 files changed, 1281 insertions(+), 2 deletions(-) create mode 100644 etc/tutorials/TUTORIAL.el_GR diff --git a/etc/NEWS b/etc/NEWS index 5d2b5e12cfa..234aa819be1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -719,7 +719,7 @@ The options 'mouse-wheel-down-alternate-event', and 'mouse-wheel-right-alternate-event' have been added to better support systems where two kinds of wheel events can be received. -** Editing complex text layout (CTL) scripts +** Internationalization changes *** The function key now allows deleting the entire composed sequence. For the details, see the item about the 'delete-forward-char' command @@ -749,6 +749,11 @@ This language environment supports Tirhuta or Mithilaakshar, which is used to write the Maithili language. A new input method, 'tirhuta', is provided to type text in this script. +--- +*** New Greek translation of the Emacs tutorial. +Type 'C-u C-h t' to select it in case your language setup does not do +so automatically. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/etc/tutorials/TUTORIAL.el_GR b/etc/tutorials/TUTORIAL.el_GR new file mode 100644 index 00000000000..e001cc6cce6 --- /dev/null +++ b/etc/tutorials/TUTORIAL.el_GR @@ -0,0 +1,1268 @@ +Εκμάθηση του Emacs. Δες το τέλος για όρους αντιγραφής. + +Στο Emacs οι εντολές γενικά περιλαμβάνουν το πλήκτρο CONTROL (συχνά +αναγράφεται ως Ctrl) ή το πλήκτρο META (συνήθως επισημαίνεται ως ALT). +Αντί να γράφουμε το πλήρες όνομα κάθε φορά, θα χρησιμοποιούμε τις εξής +συντομογραφίες: + + C-<χαρ> σημαίνει κράτα πατημένο το πλήκτρο CONTROL καθώς + πληκτρολογείς τον χαρακτήρα <χάρ>. Συνεπώς, C-f είναι: + κράτα πατημένο το CONTROL και πληκτρολόγησε το f. + M-<χαρ> σημαίνει κράτα πατημένο το πλήκτρο META ή ALT καθώς + πληκτρολογείς τον χαρακτήρα <χάρ>. Σε περίπτωση που δεν + υπάρχει πλήκτρο META ή ALT, πληκτρολόγησε και απελευθέρωσε + το πλήκτρο ESC και κατόπιν πληκτρολόγησε τον <χάρ>. + Γράφουμε για το πλήκτρο ESC. + +Σημαντική σημείωση: για να τερματίσεις το Emacs, πληκτρολόγησε C-x +C-c. (Δύο χαρακτήρες.) Για να ακυρώσεις μια μερικώς πληκτρολογημένη +εντολή, πληκτρολόγησε C-g. +Για να σταματήσεις την εκμάθηση, πληκτρολόγησε C-x k, κατόπιν +στην προτροπή. +Οι χαρακτήρες ">>" στο αριστερό περιθώριο δείχνουν οδηγίες για να +δοκιμάσεις μια εντολή. Για παράδειγμα: +<> +[Το μέσο της σελίδας παραμένει κενό για διδακτικούς σκοπούς. Το +κείμενο συνεχίζεται παρακάτω.] + +>> Τώρα πληκτρολόγησε C-v (δες επόμενη οθόνη) ώστε να κυλήσεις πιο + κάτω στην παρούσα εκμάθηση. (Κάνε το, κρατώντας πατημένο το + πλήκτρο CONTROL και πληκτρολογώντας v.) Από εδώ και στο εξής, + παρακαλώ κάνε αυτό όποτε φτάνεις στο τέλος της οθόνης. + +Σημείωσε πως υπάρχει επικάλυψη δύο γραμμών όταν κυλάς μια πλήρη οθόνη: +αυτή σου προσφέρει κάποια συνέχεια ώστε να συνεχίσεις να διαβάζεις το +κείμενο. + +Αυτό είναι αντίγραφο του κειμένου εκμάθησης του Emacs, ελαφρά +τροποποιημένο για εσένα. Παρακάτω θα σου αναθέσουμε να δοκιμάσεις +μερικές εντολές που τροποποιούν το εν λόγω κείμενο. Μην ανησυχείς αν +τροποποιήσεις αυτό το κείμενο πριν σου το ζητήσουμε· η πράξη αυτή +αναφέρεται ως «επεξεργασία» και το Emacs χρησιμοποιείται για αυτόν τον +σκοπό. + +Το πρώτο πράγμα που πρέπει να γνωρίζεις είναι πως να κινείσαι από το +ένα σημείο σε άλλο σημείο του κειμένου. Ήδη ξέρεις πως να πηγαίνεις +μια οθόνη προς τα κάτω με το C-v. Για να κινηθείς αντίστροφα, +πληκτρολόγησε M-v (κράτα πατημένο το META και πληκτρολόγησε το v, ή +πληκτρολόγησε v εάν δεν έχει πλήκτρο META ή ALT). + +>> Δοκίμασε να πληκτρολογήσεις M-v και μετά C-v μερικές φορές. + +Είναι αποδεκτό να κυλήσεις το κείμενο με άλλους τρόπους, αν τους +ξέρεις. + +* ΣΥΝΟΨΗ +-------- + +Οι εξής εντολές είναι χρήσιμες για να βλέπεις πλήρης οθόνες: + + C-v Κινήσου μπροστά/κάτω μια πλήρη οθόνη + M-v Κινήσου πίσω/πάνω μια πλήρη οθόνη + + C-l Καθάρισε την οθόνη επανεμφανίζοντας το κείμενο της και + μεταφέροντας τον δείκτη (κέρσορα) στο κέντρο της. + (Αυτό είναι CONTROL-L, όχι CONTROL-1.) + +>> Εντόπισε τον δείκτη και σημείωσε το κείμενο πέριξ του. Μετά + πληκτρολόγησε C-l. Ξαναβρές τον δείκτη και παρατήρησε το κείμενο + δίπλα του, αλλά τώρα πρόσεξε πως βρίσκεται στο κέντρο της οθόνης. + Εάν πατήσεις C-l πάλι, το κείμενο αυτό θα μετατοπιστεί στο πάνω + μέρος της οθόνης. Πάτα το C-l ξανά και θα πάει στο κάτω μέρος. + +Μπορείς επίσης να χρησιμοποιήσεις τα πλήκτρα PageUp και PageDn για να +κινηθείς ανά πλήρη οθόνη, εάν ο ακροδέκτης (τερματικό) σου τα έχει, +ωστόσο είναι πιο αποτελεσματικό να χρησιμοποιείς τα C-v και M-v. + + +* ΒΑΣΙΚΟΣ ΕΛΕΓΧΟΣ ΤΟΥ ΔΕΙΚΤΗ +---------------------------- + +Η κίνηση ανά πλήρη οθόνη είναι χρήσιμη, αλλά πως θα πας σε +συγκεκριμένο σημείο εντός του κειμένου της οθόνης; + +Υπάρχουν πολλοί τρόποι να το επιτύχεις αυτό. Μπορείς να +χρησιμοποιήσεις τα πλήκτρα με τα βέλη, αλλά είναι πιο αποτελεσματικό +να κρατήσεις τα χέρια σου στην κανονική θέση και να χρησιμοποιήσεις +τις εντολές C-p, C-b, C-f, και C-n. Οι χαρακτήρες αυτοί είναι το +αντίστοιχο των τεσσάρων πλήκτρων με τα βέλη, κατά αυτόν τον τρόπο: + + Προηγούμενη γραμμή, C-p + : + : + Πίσω, C-b .... Παρούσα θέση του δείκτη .... Εμπρός, C-f + : + : + Επόμενη γραμμή, C-n + +>> Μετακίνησε τον δείκτη στη μέση του διαγράμματος αυτού + χρησιμοποιώντας C-n ή C-p. Μετά πληκτρολόγησε C-l για να δεις το + όλο διάγραμμα στο κέντρο της οθόνης. + +Θα σου είναι ευκολότερο να θυμάσαι αυτά τα γράμματα από τις λέξεις τις +οποίες αναφέρουν στην Αγγλική: P για προηγούμενο (previous), N για +επόμενο (next), B για πίσω (backward), και F για εμπρός (forward). Θα +χρησιμοποιείς διαρκώς αυτές τις βασικές εντολές για την τοποθέτηση του +δείκτη. + +>> Κάνε μερικά C-n μέχρι να φέρεις τον δείκτη σε αυτή την γραμμή. + +>> Κινήσου εντός της γραμμής με μερικά C-f και μετά πάνω με κάποια + C-p. Δες τι κάνει το C-p όταν βρίσκεται στην μέση της γραμμής. + +Κάθε γραμμή κειμένου τελειώνει με τον χαρακτήρα νέας γραμμής, που +επιτελεί τον σκοπό του διαχωρισμού της μίας γραμμής από την άλλη. +(Συνήθως η τελευταία γραμμή σε ένα αρχείο τελειώνει με τον χαρακτήρα +νέας γραμμής, ωστόσο το Emacs δεν απαιτεί κάτι τέτοιο.) + +>> Δοκίμασε το C-b στην αρχή της γραμμής. Θα μετακινήσει τον δείκτη + στο τέλος της προηγούμενης γραμμής. Διότι κινείται προς τα πίσω + προσπερνώντας τον χαρακτήρα νέας γραμμής. + +Το C-f έχει την ίδια συμπεριφορά με το C-b. + +>> Κάνε μερικά ακόμα C-b, ώστε να εντοπίσεις τον δείκτη. Κατόπιν + κάνε C-f για να γυρίσεις στο τέλος της γραμμής. Μετά ένα ακόμα C-f + για να κινηθείς στην αρχή της επόμενης γραμμής. + +Όταν κινείσαι πέρα από το πάνω ή κάτω μέρος της οθόνης, το κείμενο +πέραν της άκρης μετατοπίζεται εντός της οθόνης. Αυτό ονομάζεται +«κύλιση». Επιτρέπει στο Emacs να φέρει τον δείκτη στο ορισμένο +σημείο του κειμένου χωρίς να κινηθεί εκτός της οθόνης. + +>> Δοκίμασε να κινήσεις τον δείκτη πέρα από το κάτω μέρος της οθόνης + με το C-n και δες τι συμβαίνει. + +Εάν η κίνηση ανά χαρακτήρα είναι πολύ αργή, μπορείς να κινηθείς ανά +λέξη. Το M-f (META-f) πάει μπροστά μια λέξη και M-b πίσω μια λέξη. + +>> Πληκτρολόγησε μερικά M-f και M-b. + +Όταν βρίσκεσαι στο μέσο μιας λέξης, το M-f πηγαίνει στο τέλος της. +Όταν βρίσκεσαι σε κενό μεταξύ λέξεων, το M-f κινείται στο τέλος της +ακόλουθης λέξης. Το M-b λειτουργεί αναλόγως προς την αντίθετη +κατεύθυνση. + +>> Πληκτρολόγησε M-f και M-b μερικές φορές, με C-f και C-b μεταξύ τους + ώστε να παρατηρήσεις την δράση των M-f και M-b σε διάφορα σημεία + εντός και μεταξύ λέξεων. + +Παρατήρησε την παράλληλο μεταξύ C-f και C-b από την μία, και M-f και +M-b από την άλλη. Πολύ συχνά οι Meta χαρακτήρες χρησιμοποιούνται για +πράξεις που σχετίζονται με μονάδες που ορίζει η εκάστοτε γλώσσα +(λέξεις, προτάσεις, παραγράφους), ενώ οι Control χαρακτήρες επιδρούν +σε βασικά στοιχεία που είναι ανεξάρτητα του τι επεξεργάζεσαι +(χαρακτήρες, γραμμές, κτλ.). + +Αυτή η παράλληλος ισχύει μεταξύ γραμμών και προτάσεων. C-a και C-e +πηγαίνουν στην αρχή και το τέλος της γραμμής, ενώ M-a και M-e +πηγαίνουν στην αρχή και το τέλος της πρότασης. + +>> Δοκίμασε δύο C-a και ύστερα δύο C-e. + Δοκίμασε δύο M-a και ύστερα δύο M-e. + +Παρατήρησε πως αλλεπάλληλα C-a δεν κάνουν τίποτα, ενώ επανειλημμένα +M-a συνεχίζουν να κινούνται ανά μία πρόταση. Παρότι δεν είναι +ανάλογα, το καθένα φαντάζει φυσικό. + +Η θέση του δείκτη εντός του κειμένου ονομάζεται «σημείο» (point). Με +άλλα λόγια, ο δείκτης δείχνει που βρίσκεται το σημείο εντός του +κειμένου στην οθόνη. + +Ιδού μία σύνοψη των απλών κινήσεων του δείκτη, συμπεριλαμβανομένων +των εντολών για κίνηση ανά λέξη και πρόταση: + + C-f Κινήσου εμπρός ένα χαρακτήρα + C-b Κινήσου πίσω ένα χαρακτήρα + + M-f Κινήσου εμπρός μία λέξη + M-b Κινήσου πίσω μία λέξη + + C-n Κινήσου στην επόμενη γραμμή + C-p Κινήσου στην προηγούμενη γραμμή + + C-a Κινήσου στην αρχή της γραμμής + C-e Κινήσου στο τέλος της γραμμής + + M-a Κινήσου πίσω στην αρχή της πρότασης + M-e Κινήσου εμπρός στο τέλος της πρότασης + +>> Δοκίμασε όλες αυτές τις εντολές μερικές φορές για εξάσκηση. Αυτές + είναι οι πιο συνηθισμένες εντολές. + +Δύο άλλες σημαντικές κινήσεις του δείκτη είναι το M-< (META +Μικρότερο), που κινείται στην αρχή ολόκληρου του κειμένου, και M-> +(META Μεγαλύτερο) που κινείται στο τέλος ολόκληρου του κειμένου. + +Στους πλείστους ακροδέκτες (τερματικά), το '<' είναι στο ίδιο πλήκτρο +με το κόμμα, οπότε πρέπει να κρατάς πατημένο το shift για να το +πληκτρολογήσεις. Σε αυτούς τους ακροδέκτες πρέπει να χρησιμοποιήσεις +το shift και για το M-<, αλλιώς θα πατάς M-κόμμα. + +>> Δοκίμασε το M-< τώρα για να κινηθείς στην αρχή αυτής της εκμάθησης. + Κατόπιν χρησιμοποίησε το C-v επανειλημμένα για να επιστρέψεις εδώ. + +>> Τώρα δοκίμασε το M-> για να κινηθείς στο τέλος αυτής της εκμάθησης. + Κατόπιν χρησιμοποίησε το M-v επανειλημμένα για να επιστρέψεις εδώ. + +Μπορείς επίσης να χρησιμοποιήσεις τα πλήκτρα με τα βέλη, εάν ο +ακροδέκτης σου τα υποστηρίζει. Προτείνουμε να μάθεις τα C-b, C-f, C-n +και C-p για τρεις λόγους. Πρώτον, δουλεύουν σε όλων των ειδών τους +ακροδέκτες. Δεύτερον, όταν αποκτήσεις εμπειρία στην χρήση του Emacs, +θα διαπιστώσεις πως αυτοί οι χαρακτήρες του Control είναι πιο γρήγοροι +στην χρήση παρά τα βέλη (διότι δεν απομακρύνεις τα χέρια σου από την +θέση πληκτρολόγησης δια αφής). Τρίτον, εφόσον διαμορφώσεις την +συνήθεια να χρησιμοποιείς τις εντολές με τους Control χαρακτήρες, +μπορείς πιο εύκολα να μάθεις πιο προηγμένες εντολές κίνησης. + +Οι πλείστες εντολές του Emacs δέχονται αριθμητική παράμετρο: για τις +περισσότερες εντολές αυτή λειτουργεί ως μετρητής επανάληψης. Ο τρόπος +που δίνεις σε μια εντολή αριθμητική παράμετρο γίνεται πληκτρολογώντας +το C-u και μετά τα ψηφία προτού πληκτρολογήσεις την εντολή. Εάν έχεις +το πλήκτρο META (ή ALT), υπάρχει άλλος εναλλακτικός τρόπος εισαγωγής +αριθμητικής παραμέτρου: πληκτρολόγησε τα ψηφία κρατώντας πατημένο το +πλήκτρο META. Συνιστούμε να μάθεις την μέθοδο του C-u γιατί ισχύει σε +όλους τους ακροδέκτες. Η αριθμητική παράμετρος ονομάζεται επίσης +«προθεματική παράμετρος», καθώς πληκτρολογείς την παράμετρο πριν την +εντολή στην οποία δίνεται. + +Για παράδειγμα, C-u 8 C-f κινείται εμπρός οκτώ χαρακτήρες. + +>> Δοκίμασε να χρησιμοποιήσεις το C-n ή C-p με αριθμητική παράμετρο + για να κινήσεις τον δείκτη σε μια γραμμή κοντά σε αυτή με μόνο μία + εντολή. + +Οι πλείστες εντολές χρησιμοποιούν την αριθμητική παράμετρο ως μετρητή +επανάληψης, αλλά μερικές εντολές την χρησιμοποιούν με διαφορετικό +τρόπο. Αρκετές εντολές (αλλά καμία από αυτές που έμαθες έως τώρα) την +χρησιμοποιούν ως ένδειξη--η παρουσία προθεματικής παραμέτρου, +ανεξαρτήτως της αξίας της, κάνει την εντολή να εκτελέσει κάτι +διαφορετικό. + +Τα C-v και M-v συνιστούν άλλο ένα είδος εξαίρεσης. Όταν τους δοθεί +παράμετρος, κυλούν το κείμενο πάνω ή κάτω κατά τόσες γραμμές, αντί για +πλήρη οθόνη. Για παράδειγμα, C-u 8 C-v κυλάει πάνω κατά 8 γραμμές. + +>> Δοκίμασε να πληκτρολογήσεις C-u 8 C-v τώρα. + +Αυτό πρέπει να κύλησε το κείμενο πάνω κατά 8 γραμμές. Αν θέλεις να το +φέρεις κάτω πάλι δοκίμασε την ίδια αριθμητική παράμετρο με το M-v. + +Εάν χρησιμοποιείς γραφική προβολή, όπως το X ή MS-Windows, θα πρέπει +να υπάρχει μια ψηλή, ορθογώνια επιφάνεια σε πλευρά του παραθύρου του +Emacs που είναι γνωστή και ως η μπάρα κύλισης (scroll bar). Μπορείς +να κυλήσεις το κείμενο πατώντας με το ποντίκι πάνω στην μπάρα κύλισης. + +Αν το ποντίκι σου έχει ροδέλα, μπορείς να την χρησιμοποιήσεις για +κύλιση. + + +* ΑΝ ΤΟ EMACS ΠΑΨΕΙ ΝΑ ΑΝΤΑΠΟΚΡΙΝΕΤΑΙ +------------------------------------- + +Αν το Emacs πάψει να ανταποκρίνεται στις εντολές σου, μπορείς να το +σταματήσεις με ασφάλεια πληκτρολογώντας C-g. Μπορείς να +χρησιμοποιήσεις το C-g για να σταματήσεις μια εντολή που παίρνει πολύ +χρόνο να εκτελεστεί. + +Μπορείς επίσης να χρησιμοποιήσεις το C-g για να καταργήσεις μια +αριθμητική παράμετρο ή την αρχή μιας εντολής που δεν θέλεις να +ολοκληρώσεις. + +>> Πληκτρολόγησε C-u 100 για να φτιάξεις μια αριθμητική παράμετρο του + 100, μετά πληκτρολόγησε C-g. Τώρα πληκτρολόγησε C-f. Θα πρέπει να + κινηθεί μόνο ένα χαρακτήρα, διότι ακύρωσες την παράμετρο με το C-g. + +Σε περίπτωση που έχεις πληκτρολογήσει το κατά λάθος, μπορείς να +το ξεφορτωθείς με το C-g. + + +* ΑΠΕΝΕΡΓΟΠΟΙΗΜΕΝΕΣ ΕΝΤΟΛΕΣ +--------------------------- + +Κάποιες εντολές του Emacs είναι «απενεργοποιημένες» ώστε νέοι χρήστες +να μην τις χρησιμοποιήσουν κατά λάθος. + +Αν πληκτρολογήσεις μία από αυτές τις απενεργοποιημένες εντολές, το +Emacs παρουσιάζει μήνυμα που αναφέρει ποια είναι η εντολή και σου ζητά +αν θέλεις να την εκτελέσεις. + +Εάν πράγματι θες να δοκιμάσεις την εντολή, πληκτρολόγησε (το +κενό) ως απάντηση στην ερώτηση. Κανονικά, αν δεν θέλεις να εκτελέσεις +την απενεργοποιημένη εντολή απαντάς με το «n». + +>> Πληκτρολόγησε C-x C-l (που είναι απενεργοποιημένη εντολή) και μετά + πληκτρολόγησε n ως απάντηση. + + +* ΠΑΡΑΘΥΡΑ +---------- + +Το Emacs μπορεί να έχει πολλά «παράθυρα», με το καθένα να δείχνει το +δικό του κείμενο. Θα εξηγήσουμε παρακάτω πως να χρησιμοποιείς πολλά +παράθυρα. Για την ώρα θέλουμε να εξηγήσουμε πως θα ξεφορτωθείς +πλεονάζοντα παράθυρα για να επιστρέψεις στην βασική επεξεργασία εντός +ενός παραθύρου. Είναι απλό: + + C-x 1 Ένα παράθυρο (δηλαδή εξαφάνισε όλα τα άλλα παράθυρα) + +Αυτό πρόκειται για το CONTROL-x που ακολουθείται από το ψηφίο 1. Το +C-x 1 μεγιστοποιεί το παράθυρο που περιέχει τον δείκτη. Διαγράφει τα +άλλα παράθυρα. + +>> Φέρε τον δείκτη σε αυτή την γραμμή και πληκτρολόγησε C-u 0 C-l. +>> Πληκτρολόγησε C-h k C-f. + Δες πως το παράθυρο συρρικνώνεται, καθώς ένα νέο εμφανίζεται για να + παρουσιάσει την καταγραφή της εντολής C-f. + +>> Πληκτρολόγησε C-x 1 και δες πως το παράθυρο της καταγραφής + εξαφανίζεται. + +Υπάρχει σειρά εντολών που ξεκινούν με το CONTROL-x· πολλές εξ αυτών +έχουν να κάνουν με παράθυρα (windows), αρχεία (files), αποσβεστήρες +(buffers), και τα σχετικά. Αυτές οι εντολές είναι δύο, τρία ή τέσσερα +γράμματα μάκρος. + + +* ΕΙΣΑΓΟΝΤΑΣ ΚΑΙ ΔΙΑΓΡΑΦΟΝΤΑΣ +----------------------------- + +Αν θέλεις να εισάγεις κείμενο, απλά πληκτρολόγησε το. Κοινοί +χαρακτήρες, όπως το Α, 7, *, κτλ. εισάγονται καθώς τους πληκτρολογείς. +Για να εισάγεις τον χαρακτήρα νέας γραμμής, πληκτρολόγησε +(αυτό είναι το πλήκτρο που μερικές φορές αναγράφεται ως «Enter»). + +Για να διαγράψεις τον χαρακτήρα ακριβώς πριν από το τωρινό σημείο του +δείκτη, πληκτρολόγησε . Αυτό είναι το πλήκτρο που συνήθως +αναγράφεται στο πληκτρολόγιο ως «Backspace»--το ίδιο θα +χρησιμοποιούσες κανονικά κι εκτός Emacs για να διαγράψεις τον +τελευταίο χαρακτήρα που εισήγαγες. + +Συνήθως υπάρχει άλλο ένα πλήκτρο που αναγράφεται ως , αλλά +αυτό είναι διαφορετικό από αυτό που προαναφέραμε και που εννοούμε με +το του Emacs. + +>> Κάνε αυτό τώρα--πληκτρολόγησε μερικούς χαρακτήρες, μετά διάγραψε + τους πατώντας το μερικές φορές. Μην ανησυχείς για την + τροποποίηση αυτού του αρχείου: δεν τροποποιείς το κύριο κείμενο + εκμάθησης. Αυτό είναι το προσωπικό σου αντίγραφο. + +Όταν η γραμμή του κειμένου γίνεται πολύ μεγάλη για μια γραμμή της +οθόνης, η γραμμή του κειμένου «συνεχίζεται» σε δεύτερη γραμμή οθόνης. +Εάν χρησιμοποιείς γραφική προβολή, καμπυλωτά βελάκια θα εμφανιστούν +στα στενά πλαίσια που βρίσκονται στα άκρα της επιφάνειας του κειμένου +(οι «παρυφές» αριστερά και δεξιά), για να επισημάνουν που συνεχίζεται +η γραμμή. Εάν χρησιμοποιείται προβολή κειμένου, η συνεχιζόμενη γραμμή +παρουσιάζεται με την αντίστροφη κάθετο ('\') στην δεξιότερη στήλη της +οθόνης. + +>> Εισήγαγε κείμενο μέχρις ότου φτάσεις στο δεξί περιθώριο και + συνέχισε να προσθέτεις. Θα δεις να εμφανίζεται η γραμμή συνέχειας. + +>> Πάτα επανειλημμένα για να διαγράψεις το κείμενο μέχρι που η + γραμμή να χωράει ξανά στην οθόνη. Η γραμμή συνέχειας θα χαθεί. + +Μπορείς να διαγράψεις τον χαρακτήρα νέας γραμμής όπως κάθε άλλο +χαρακτήρα. Διαγράφοντας τον χαρακτήρα νέας γραμμής μεταξύ δύο γραμμών +έχει σαν αποτέλεσμα την συνένωση τους σε μία γραμμή. Εάν σαν +αποτέλεσμα η γραμμή είναι πολύ μεγάλη, θα παρουσιαστεί με την γραμμή +συνέχειας. + +>> Μετακίνησε τον δείκτη στην αρχή της γραμμής και πληκτρολόγησε + . Αυτό θα συνενώσει την γραμμή με την από πάνω της. + +>> Πληκτρολόγησε για να επανεισάγεις τον χαρακτήρα νέας + γραμμής που μόλις διέγραψες. + +Το πλήκτρο είναι ειδικό, καθώς πληκτρολογώντας το μπορεί να +κάνει περισσότερα πράγματα πέραν της εισαγωγής του χαρακτήρα νέας +γραμμής. Ανάλογα με το περιβάλλων κείμενο, μπορεί να προσθέσει κενό +μετά τον χαρακτήρα νέας γραμμής, ώστε όταν αρχίσεις να γράφεις στην +νέα γραμμή, το κείμενο να στοιχίζεται με την προηγούμενη γραμμή. +Ονομάζουμε αυτή την συμπεριφορά (όπου το πάτημα ενός πλήκτρου κάνει +κάτι παραπάνω από την εισαγωγή του σχετικού χαρακτήρα) «ηλεκτρική». + +>> Ιδού ένα παράδειγμα της ηλεκτρικότητας του . + Πληκτρολόγησε στο τέλος αυτής της γραμμής. + +Κανονικά θα δεις πως μετά την εισαγωγή του χαρακτήρα νέας γραμμής, το +Emacs εισάγει κενά ώστε ο δείκτης να βρίσκεται ακριβώς κάτω από το +«Π» του «Πληκτρολόγησε». + +Θυμήσου πως οι πλείστες εντολές του Emacs δέχονται μετρητή επανάληψης· +αυτό περιλαμβάνει την εισαγωγή κειμένου. Επαναλαμβάνοντας ένα +χαρακτήρα κειμένου τον εισάγει πολλές φορές. + +>> Δοκίμασε το τώρα -- πληκτρολόγησε C-u 8 * για να εισάγεις ********. + +Έχεις ήδη μάθει τους πιο βασικούς τρόπους για την πληκτρολόγηση +κειμένου στο Emacs και την διόρθωση των λαθών. Μπορείς επίσης να +διαγράψεις λέξεις και γραμμές. Ιδού η σύνοψη των πράξεων διαγραφής: + + Διάγραψε τον χαρακτήρα ακριβώς πριν τον δείκτη + C-d Διάγραψε τον χαρακτήρα ακριβώς μετά τον δείκτη + + M- Εξαφάνισε την λέξη ακριβώς πριν τον δείκτη + M-d Εξαφάνισε την λέξη μετά τον δείκτη + + C-k Εξαφάνισε από το σημείο του δείκτη ως το τέλος της γραμμής + M-k Εξαφάνισε ως το τέλος της παρούσας πρότασης + +Πρόσεξε πως το και C-d σε σύγκριση με M- και M-d +προεκτείνουν την παράλληλο που άρχισε με το C-f και M-f (κατ'ακρίβεια, +το δεν είναι χαρακτήρας control, αλλά ας μην ανησυχούμε για +αυτό). Τα C-k και M-k είναι κατά τρόπο όπως το C-e και M-e καθώς οι +γραμμές ταιριάζουν με τις προτάσεις. + +Μπορείς επίσης να εξαφανίσεις ένα μέρος κειμένου με ενιαίο τρόπο. +Κινήσου σε μία άκρη του και πληκτρολόγησε C-. ( είναι το +πλήκτρο του κενού.) Κατόπιν, μετακίνησε τον δείκτη στην άλλη άκρη του +κειμένου που θέλεις να εξαφανίσεις. Καθώς το κάνεις αυτό, το Emacs +επισημαίνει το κείμενο μεταξύ των δύο άκρων του δείκτη και του σημείου +όπου πληκτρολόγησες C-. Τέλος, πληκτρολόγησε C-w. Αυτό +εξαφανίζει το κείμενο μεταξύ των δύο σημείων. + +>> Μετακίνησε τον δείκτη στο γράμμα Μ στην αρχή της προηγούμενης + παραγράφου. +>> Πληκτρολόγησε C-. Το Emacs θα σου γράψει μήνυμα στο κάτω + μέρος της οθόνης πως τέθηκε σημάδι («Mark set»). +>> Μετακίνησε τον δείκτη στο κ της λέξης «άκρη» στην δεύτερη γραμμή + της παραγράφου. +>> Πληκτρολόγησε C-w. Αυτό θα εξαφανίσει το κείμενο που άρχιζε με Μ + και τελειώνει ακριβώς πριν το κ. + +Η διαφορά μεταξύ της «εξαφάνισης» και της «διαγραφής» είναι πως το +«εξαφανισμένο» κείμενο μπορεί να επανεισαχθεί (σε οποιαδήποτε θέση), +ενώ τα «διαγραμμένα» πράγματα δεν μπορούν να επανεισαχθούν κατά αυτόν +τον τρόπο (μπορείς, ωστόσο, να αναιρέσεις την διαγραφή--δες παρακάτω). +Επανεισαγωγή εξαφανισμένου κειμένου ονομάζεται «τράβηγμα» («yanking»). +(Φαντάσου πως τραβάς κάτι πίσω το οποίο είχε αφαιρεθεί.) Γενικά, οι +εντολές που αφαιρούν πολύ κείμενο το εξαφανίζουν, ενώ οι εντολές που +αφαιρούν απλά ένα χαρακτήρα, ή μόνο κενές γραμμές ή κενά, κάνουν +διαγραφή (οπότε δεν μπορείς να τα τραβήξεις πίσω). και C-d +κάνουν διαγραφή στην απλή περίπτωση, χωρίς παράμετρο. Αν τους δοθεί +παράμετρος, τότε κάνουν εξαφάνιση. + +>> Μετακίνησε τον δείκτη στην αρχή μιας γραμμής που δεν είναι κενή. + Κατόπιν πληκτρολόγησε C-k για να εξαφανίσεις το κείμενο ως το τέλος + της γραμμής. +>> Πληκτρολόγησε C-k δεύτερη φορά. Θα δεις πως εξαφανίζει τον + χαρακτήρα νέας γραμμής που ακολουθεί εκείνη την γραμμή. + +Σημείωσε πως ένα C-k εξαφανίζει το περιεχόμενο της γραμμής, ενώ +δεύτερο C-k εξαφανίζει την ίδια την γραμμή και κάνει όλες τις +ακόλουθες γραμμές να μετατοπιστούν προς τα πάνω. Το C-k ερμηνεύει την +αριθμητική παράμετρο με ειδικό τρόπο: εξαφανίζει τις γραμμές ΚΑΙ το +περιεχόμενο τους. Αυτό δεν πρόκειται για απλή επανάληψη. C-u 2 C-k +εξαφανίζει δύο γραμμές και τους αντίστοιχους χαρακτήρες νέας γραμμής· +ενώ πληκτρολογώντας το C-k δύο φορές δεν θα το έκανε αυτό. + +Μπορείς να τραβήξεις εξαφανισμένο κείμενο στο ίδιο σημείο από όπου +εξαφανίστηκε, ή σε κάποιο άλλο σημείο που επεξεργάζεσαι, ή ακόμα σε +άλλο αρχείο. Μπορείς να τραβήξεις το ίδιο κείμενο πολλές φορές· αυτό +δημιουργεί πολλαπλά αντίγραφα του. Άλλοι κειμενογράφοι ονομάζουν την +εξαφάνιση και το τράβηγμα «αποκοπή» και «επικόλληση» (δες το γλωσσάριο +στο εγχειρίδιο του Emacs). + +Η εντολή για τράβηγμα είναι C-y. Εισάγει το τελευταίο εξαφανισμένο +κείμενο στην τρέχουσα θέση του δείκτη. + +>> Δοκίμασε το· πληκτρολόγησε C-y για τα τραβήξεις το κείμενο πίσω. + +Εάν κάνεις πολλά C-k στην σειρά, όλο το εξαφανισμένο κείμενο +αποθηκεύεται μαζί, ώστε ένα C-y τραβάει όλες τις γραμμές συλλήβδην. + +>> Κάνε το τώρα· πληκτρολόγησε C-k αρκετές φορές. + +Τώρα ανάκτησε το εξαφανισμένο κείμενο: + +>> Πληκτρολόγησε C-y. Κατόπιν μετακίνησε τον δείκτη κάτω μερικές + γραμμές και πληκτρολόγησε C-y ξανά. Τώρα βλέπεις πως να + αντιγράψεις ορισμένο κείμενο. + +Τι κάνει εάν έχεις κείμενο που θέλεις να τραβήξεις πίσω και μετά να +εξαφανίσεις κάτι άλλο; Το C-y θα τραβήξει την πιο πρόσφατη εξαφάνιση. +Αλλά η προηγούμενη της δεν έχει χαθεί. Μπορείς να επιστρέψεις σε αυτή +χρησιμοποιώντας την εντολή M-y. Αφού έχεις κάνει C-y για να πάρεις +την πιο πρόσφατη εξαφάνιση, πληκτρολογώντας το M-y αντικαθιστά το +τραβηγμένο κείμενο με το λιγότερο πρόσφατο εξαφανισμένο κείμενο. +Πληκτρολογώντας M-y ξανά και ξανά επαναφέρει ολοένα και παλαιότερες +εξαφανίσεις. Όταν βρεις το κείμενο που ψάχνεις, δεν χρειάζεται να +κάνεις κάτι άλλο για να το κρατήσεις. Απλά συνέχισε την επεξεργασία, +αφήνοντας το τραβηγμένο κείμενο εκεί που είναι. + +Εάν χρησιμοποιήσεις το M-y αρκετές φορές, θα επιστρέψεις στο αρχικό +σημείο (την πιο πρόσφατη εξαφάνιση). + +>> Εξαφάνισε μια γραμμή, κινήσου κάπου αλλού, εξαφάνισε άλλη γραμμή. + Μετά πάτα C-y για να επαναφέρεις την δεύτερη εξαφανισμένη γραμμή. + Μετά κάνε M-y κι αυτή θα αντικατασταθεί με την πρώτη εξαφανισμένη + γραμμή. Κάνε κι άλλα M-y να δεις τι θα σου βγάλει. Συνέχισε ώσπου + να σου δώσει πάλι την δεύτερη εξαφανισμένη γραμμή. Αν θέλεις + μπορείς να περάσεις στο M-y θετικές ή αρνητικές παραμέτρους. + + +* ΑΝΑΙΡΕΣΗ +---------- + +Εάν κάνεις αλλαγή στο κείμενο κι ύστερα κρίνεις πως ήταν λάθος, +μπορείς να την αναιρέσεις με την εντολή αναίρεσης C-/. + +Κανονικά, το C-/ αναιρεί τις αλλαγές που επέφερε μία εντολή. Αν +επαναλάβεις το C-/ πολλές φορές στη σειρά, κάθε επανάληψη αναιρεί +ακόμα μία εντολή. + +Ωστόσο υπάρχουν δύο εξαιρέσεις: εντολές που δεν τροποποιούν κείμενο +δεν μετρούν (όπως εντολές που κινούν τον δείκτη ή κυλούν το κείμενο) +και χαρακτήρες που αυτό-εισάγονται συνήθως κρίνονται ως ομάδες έως 20 +μέλη. (Αυτό είναι για να περιορίσει τον αριθμό των C-/ που +απαιτούνται για την αναίρεση εισαγωγής κειμένου.) + +>> Εξαφάνισε αυτή την γραμμή με C-k και πληκτρολόγησε C-/ ώστε να + επανεμφανιστεί. + +Το C-_ είναι εναλλακτική εντολή αναίρεσης που λειτουργεί το ίδιο με το +C-/. Σε ορισμένους ακροδέκτες κειμένου, ενδέχεται να μην χρειάζεται +το shift για να εισάγεις το C-_. Σε ορισμένους ακροδέκτες κειμένου, +το C-/ στέλνει το σήμα του C-_ στο Emacs. Εναλλακτικά, το C-x u +λειτουργεί ακριβώς όπως το C-/, αλλά είναι λίγο πιο δύσκολο να το +πληκτρολογήσεις. + +Η αριθμητική παράμετρος στα C-/, C-_, C-x u δρα ως μετρητής +επανάληψης. + +Μπορείς να αναιρέσεις την διαγραφή κειμένου κατά τον ίδιο τρόπο που +αναιρείς την εξαφάνιση κειμένου. Ο διαχωρισμός μεταξύ εξαφάνισης και +διαγραφής έχει σημασία μόνο όταν θες να τραβήξεις κάτι πίσω με το C-y: +δεν έχει καμιά διαφορά για τους σκοπούς της αναίρεσης. + + +* ΑΡΧΕΙΑ +-------- + +Για να καταστήσεις μόνιμο το κείμενο που επεξεργάζεσαι, πρέπει να το +βάλεις σε αρχείο. Αλλιώς θα χαθεί όταν κλείσεις το Emacs. Για να +βάλεις κείμενο σε αρχείο, πρέπει να το «βρεις» πριν εισάγεις το +κείμενο. (Η πράξη αυτή ονομάζεται επίσης ως «επίσκεψη» στην τοποθεσία +του αρχείου.) + +Εξεύρεση του αρχείο σημαίνει πως βλέπεις το περιεχόμενο του εντός του +Emacs. Κατά πολλούς τρόπους, είναι σαν να επεξεργάζεσαι το αρχείο +απευθείας. Ωστόσο, οι αλλαγές που κάνεις καθίστανται μόνιμες μόνο +αφού «αποθηκεύσεις» το αρχείο. Αυτό γίνεται ώστε να μην μένουν +μισοτελειωμένα αρχεία στο σύστημα ενάντια στην θέληση σου. Ακόμα κι +αν αποθηκεύσεις τις αλλαγές, το Emacs διατηρεί αντίγραφο του γνησίου +αρχείου υπό ελαφρώς τροποποιημένο όνομα, ώστε να μπορείς να το +επαναφέρεις σε περίπτωση που συνέβη κάποιο λάθος. + +Αν κοιτάξεις προς το κάτω μέρος της οθόνης θα δεις μια γραμμή που +αρχίζει με παύλες και αναφέρει « -:--- TUTORIAL.el_GR» ή κάπως έτσι. +Αυτό το μέρος της οθόνης συνήθως δείχνει το όνομα του αρχείου που +επισκέπτεσαι. Τώρα επισκέπτεσαι το προσωπικό σου αντίγραφο του +κειμένου εκμάθησης του Emacs, που ονομάζεται «TUTORIAL.el_GR». Όταν +βρίσκεις ένα αρχείο με το Emacs, το όνομα του θα εμφανιστεί σε εκείνο +ακριβώς το σημείο. + +Μια ειδική πτυχή της εντολής για εξεύρεση αρχείου είναι πως πρέπει να +προσδιορίσεις ποιο αρχείο θέλεις. Λέμε πως η εντολή «διαβάζει την +παράμετρο» (στην προκειμένη περίπτωση αυτή είναι το όνομα του +αρχείου). Αφού πληκτρολογήσεις την εντολή + + C-x C-f Βρες ένα αρχείο + +το Emacs θα σου ζητήσει να πληκτρολογήσεις το όνομα του. Το όνομα +του αρχείου που εισάγεις εμφανίζεται στο κάτω μέρος της οθόνης. Η +τελευταία γραμμή ονομάζεται μικροαποσβεστήρας (minibuffer) όταν +χρησιμοποιείται για τέτοιους σκοπούς εισαγωγής εντολής. Μπορείς να +χρησιμοποιήσεις τις κοινές εντολές του Emacs για επεξεργασία κειμένου +καθώς γράφεις το όνομα του αρχείου. + +Ενόσω δακτυλογραφείς το όνομα του αρχείο (ή κάθε άλλο κείμενο στον +μικροαποσβεστήρα), μπορείς να ακυρώσεις την εντολή με το C-g. + +>> Πληκτρολόγησε C-x C-f και μετά C-g. Αυτό ακυρώνει τον + μικροαποσβεστήρα και την εντολή C-x C-f που τον χρησιμοποιούσε. + Συνεπώς δεν θα βρεις κανένα αρχείο. + +Όταν ολοκληρώσεις την εισαγωγή του ονόματος ενός αρχείου, πάτα + για να την επικυρώσεις. Ο μικροαποσβεστήρας εξαφανίζεται +καθώς το C-x C-f αναλαμβάνει δράση για να βρει το αρχείο που του +όρισες. + +Το περιεχόμενο του αρχείου τώρα εμφανίζεται στην οθόνη και μπορείς να +το επεξεργαστείς. Όταν θέλεις να μονιμοποιήσεις τις αλλαγές που +έκανες, χρησιμοποίησε την εντολή + + C-x C-s Αποθήκευσε το αρχείο + +Αυτή αντιγράφει το κείμενο που βρίσκεται στο Emacs στο εν λόγω αρχείο. +Την πρώτη φορά που το κάνεις αυτό, το Emacs μετονομάζει το γνήσιο ώστε +να μην χαθεί. Το νέο όνομα περιέχει το σύμβολο «~» ως κατάληξη του +αρχικού ονόματος. Όταν ολοκληρωθεί η αποθήκευση, το Emacs παρουσιάζει +το όνομα του αρχείου όπου γράφτηκαν οι αλλαγές. + +>> Πληκτρολόγησε C-x C-s TUTORIAL.el_GR . + Αυτό θα αποθηκεύσει αυτό το κείμενο σε αρχείο με το όνομα + TUTORIAL.el_GR και θα αναφέρει πως έγραψε σε αυτό στο κάτω μέρος + της οθόνης. + +Μπορείς να βρεις υφιστάμενο αρχείο είτε για να το δεις ή να το +επεξεργαστείς. Μπορείς επίσης να βρεις αρχείο το οποίο δεν +προϋπάρχει. Έτσι το Emacs θα δημιουργήσει το αρχείο: θα βρεις το νέο +αρχείο, το οποίο είναι κενό, και κατόπιν θα εισάγεις κείμενο σε αυτό. +Όταν επιχειρήσεις να το αποθηκεύσεις, το Emacs θα δημιουργήσει το +αρχείο αυτό με το περιεχόμενο που του έδωσες. Από εκεί και πέρα +θεώρησε πως επεξεργάζεσαι ένα υφιστάμενο αρχείο. + + +* ΑΠΟΣΒΕΣΤΗΡΕΣ +-------------- + +Εάν βρεις δεύτερο αρχείο με το C-x C-f, το πρώτο παραμένει εντός του +Emacs. Μπορείς να επανέλθεις σε αυτό αν το ξαναβρείς με το C-x C-f. +Έτσι δύναται να έχεις πολλά αρχεία ανοιχτά εντός του Emacs. + +Το Emacs αποθηκεύει το περιεχόμενο του κάθε αρχείου σε αντικείμενο το +οποίο ονομάζεται «αποσβεστήρας» (buffer). Η εξεύρεση αρχείου +δημιουργεί νέο αποσβεστήρα εντός του Emacs. Για να δεις την λίστα με +όλους τους υφιστάμενους αποσβεστήρες, πληκτρολόγησε + + C-x C-b Παράθεσε αποσβεστήρες + +>> Δοκίμασε το C-x C-b τώρα. + +Παρατήρησε πως κάθε αποσβεστήρας έχει όνομα ενώ δύναται να έχει επίσης +κι όνομα αρχείου του οποίο το περιεχόμενο κρατεί. ΟΤΙΔΗΠΟΤΕ βλέπεις +σε παράθυρο Emacs πάντα είναι μέρος ενός αποσβεστήρα. + +>> Πληκτρολόγησε C-x 1 για να εξαφανίσεις το παράθυρο που παραθέτει + τους αποσβεστήρες. + +Όταν έχεις πολλούς αποσβεστήρες, μόνο ένας είναι ο «τρέχον» σε κάθε +στιγμή. Πρόκειται για τον αποσβεστήρα που επεξεργάζεσαι. Εάν θες να +επεξεργαστείς κάποιον άλλο αποσβεστήρα, πρέπει να «μεταβείς» σε αυτόν. +Αν θα μεταβείς σε αποσβεστήρας που επισκέπτεται αρχείο, μπορείς να το +κάνεις με το C-x C-f προσδιορίζοντας το όνομα του αρχείου. Αλλά +υπάρχει ευκολότερος τρόπος: χρησιμοποίησε την εντολή C-x b. Σε αυτή +την εντολή, πρέπει να εισάγεις το όνομα του αποσβεστήρα. + +>> Δημιούργησε αρχείο ονόματι «foo»: γράψε C-x C-f foo . + Μετά πληκτρολόγησε C-x b TUTORIAL.el_GR για να επιστρέψεις + σε αυτό το κείμενο εκμάθησης του Emacs. + +Συνήθως, το όνομα του αποσβεστήρα αντιστοιχεί σε αυτό του αρχείου +(χωρίς το μέρος του αρχείου που αναφέρει τον κατάλογο/φάκελο στον +οποίο βρίσκεται). Ωστόσο αυτό δεν ισχύει πάντοτε. Η παράθεση +αποσβεστήρων που φτιάχνει το C-x C-b δείχνει τόσο το όνομα του +αποσβεστήρα όσο κι αυτό του αρχείου. + +Κάποιοι αποσβεστήρες δεν ανταποκρίνονται σε αρχεία. Ο αποσβεστήρας +ονόματι «*Buffer List*», που περιέχει τα στοιχεία του C-x C-b, δεν +έχει κάποιο υποκείμενο αρχείο. Ο αποσβεστήρας αυτού του +TUTORIAL.el_GR αρχικά δεν είχε κάποιο αρχείο, αλλά τώρα έχει, καθώς +στην προηγούμενη ενότητα χρησιμοποίησες το C-x C-s για να τον +αποθηκεύσεις σε αρχείο. + +Ο αποσβεστήρας με το όνομα «*Messages*» επίσης δεν έχει αρχείο. Αυτός +περιέχει όλα τα μηνύματα που εμφανίζονται στο κάτω μέρος της οθόνης +κατά την λειτουργία του Emacs. + +>> Πληκτρολόγησε C-x b *Messages* για να δεις τον αποσβεστήρα + με τα μηνύματα. Μετά πληκτρολόγησε C-x b TUTORIAL.el_GR + για να επανέλθεις εδώ. + +Εάν κάνεις αλλαγές στο κείμενο ενός αρχείου, μετά βρεις κάποιο άλλο +αρχείο, η πράξη αυτή δεν αποθηκεύει τις αλλαγές που έκανες στο πρώτο +αρχείο. Οι αλλαγές παραμένουν εντός του Emacs, στον αποσβεστήρα που +ανταποκρίνεται σε εκείνο το αρχείο. Η δημιουργία ή επεξεργασία του +δεύτερου αρχείου δεν επηρεάζει το πρώτο. Αυτό είναι πολύ χρήσιμο, +ωστόσο σημαίνει πως χρειάζεσαι έναν βολικό τρόπο να αποθηκεύεις +αλλαγές σε πολλούς αποσβεστήρες. Το να πρέπει να επιστρέψεις στο +πρώτο αρχείο απλά και μόνο για να το αποθηκεύσεις είναι ενοχλητικό. +Οπότε έχουμε + + C-x s Αποθήκευσε ορισμένους αποσβεστήρες στα αρχεία τους + +Το C-x s ρωτά για κάθε αποσβεστήρα που επισκέπτεται αρχείο και που +κρατά αλλαγές οι οποίες δεν έχουν αποθηκευτεί. Σε ρωτά για κάθε +αποσβεστήρα κατά πόσον να αποθηκευτούν οι αλλαγές του στο αρχείο. + +>> Εισήγαγε μια γραμμή κειμένου και πληκτρολόγησε C-x s. + Θα σε ρωτήσει κατά πόσον θες να αποθηκεύσεις τον αποσβεστήρα με + όνομα TUTORIAL.el_GR. Απάντα καταφατικά με το «y» (yes). + + +* ΕΠΕΚΤΕΙΝΟΝΤΑΣ ΤΟ ΣΥΝΟΛΟ ΕΝΤΟΛΩΝ +--------------------------------- + +Υπάρχουν πάρα πολλές εντολές του Emacs που δεν μπορούν να χωρέσουν σε +όλους τους control και meta χαρακτήρες. Το Emacs ξεπερνά αυτό το +εμπόδιο με την εντολή επέκτασης (eXtend). Αυτή έχει δύο μορφές: + + C-x Χαρακτήρος επέκταση. Ακολουθείται από τον χαρακτήρα. + M-x Ονόματος επέκταση. Ακολουθείται από όνομα. + +Αυτές είναι εντολές που είναι χρήσιμες εν γένει αλλά χρησιμοποιούνται +σχετικά λιγότερο από αυτές που έμαθες έως τώρα. Έχεις ήδη δει εντολές +επέκτασης, όπως το C-x C-f και το C-x C-s. Άλλο παράδειγμα είναι η +εντολή που κλείνει το Emacs--αυτή είναι C-x C-c. (Μην ανησυχείς για +απώλεια αλλαγών που έκανες· το C-x C-c ρωτά να αποθηκεύσει αλλαγές σε +κάθε αρχείο πριν τερματίσει το Emacs.) + +Εάν χρησιμοποιείς γραφική προβολή, δεν χρειάζεσαι κάποια ειδική εντολή +για να μεταβείς από το Emacs σε κάποια άλλη εφαρμογή. Μπορείς να το +κάνεις με το ποντίκι ή τις εντολές του διαχειριστή παραθύρων. Αν όμως +χρησιμοποιείς ακροδέκτη κειμένου ο οποίος προβάλει μόνο μία εφαρμογή, +τότε πρέπει να «αναστείλεις» το Emacs για να επιλέξεις οποιαδήποτε +άλλη εφαρμογή. + +C-z είναι η εντολή της *προσωρινής* εξόδου από το Emacs--μπορείς να +επιστρέψεις στην ίδια συνεδρία υστερότερα. Όταν το Emacs λειτουργεί +εντός ακροδέκτη κειμένου, το C-z «αναστέλλει» το Emacs· δηλαδή +επιστρέφει στο περίβλημα (shell) χωρίς να καταστρέψει την εργασία του +Emacs. Στα πλείστα περιβλήματα, μπορείς να επαναφέρεις το Emacs με +την εντολή «fg» ή την «%emacs». + +Χρησιμοποιείς το C-x C-c όταν θες να αποσυνδεθείς πλήρως. Είναι η +σωστή πράξη για έξοδο από το Emacs, παράδειγμα για περιπτώσεις ταχείας +επεξεργασίας κειμένου όπως στην διαχείριση ηλεκτρονικού ταχυδρομείου. + +Υπάρχουν πολλές εντολές του τύπου C-x. Παραθέτουμε αυτές που έμαθες: + + C-x C-f Εξεύρεση αρχείου + C-x C-s Αποθήκευση αποσβεστήρα σε αρχείο + C-x s Αποθήκευση μερικών αποσβεστήρων στα αρχεία τους + C-x C-b Παράθεση αποσβεστήρων + C-x b Μετάβαση σε αποσβεστήρα + C-x C-c Έξοδος από το Emacs + C-x 1 Διαγραφή όλων πλην ενός παραθύρου + C-x u Αναίρεση + +Επώνυμες εκτεταμένες εντολές είναι αυτές που χρησιμοποιούνται με +λιγότερη συχνότητα, ή εντολές που χρησιμοποιούνται μόνο σε +συγκεκριμένες λειτουργίες. Ως παράδειγμα έχουμε την εντολή +replace-string, η οποία αντικαθιστά μια σειρά (αλληλουχία) χαρακτήρων +με μια άλλη εντός του αποσβεστήρα. Όταν πληκτρολογείς M-x, το Emacs +σε προτρέπει στο κάτω μέρος της οθόνης για το όνομα της εντολής· +«replace-string» σε αυτή την περίπτωση. Απλά να πληκτρολογήσεις το +«repl s» και το Emacs θα ολοκληρώσει το όνομα. ( αναφέρεται +στο πλήκτρο Tab, που συνήθως βρίσκεται πάνω από το Caps Lock ή το +Shift στην αριστερή πλευρά του πληκτρολογίου.) Κατάθεσε το όνομα της +εντολής με το . + +Η εντολή replace-string απαιτεί δύο παραμέτρους--την σειρά χαρακτήρων +προς αντικατάσταση και αυτή που θα την αντικαταστήσει. Κάθε +παράμετρος τελειώνει με το . + +>> Μετακίνησε τον δείκτη στην κενή γραμμή δύο γραμμές κάτω από αυτήν. + Πληκτρολόγησε M-x repl sαλλάξειμετατραπεί + + Πρόσεξε πως αυτή η γραμμή έχει αλλάξει: αντικατέστησες την λέξη + «αλλάξει» με την «μετατραπεί» όπου αυτή υπήρχε μετά την αρχική θέση + του δείκτη. + + +* ΑΥΤΟΜΑΤΗ ΑΠΟΘΗΚΕΥΣΗ +--------------------- + +Όταν έχεις κάνει αλλαγές σε ένα αρχείο, αλλά δεν τις έχεις αποθηκεύσει +ακόμα, ενδέχεται να χαθούν αν ο υπολογιστής κλείσει. Για να σε +προστατέψει από αυτό το ενδεχόμενο, το Emacs κατά διαστήματα γράφει σε +ένα αρχείο «αυτόματης αποθήκευσης» κάθε αρχείο που επεξεργάζεσαι. Το +όνομα αυτού του αρχείου έχει ένα # στην αρχή κι ένα στο τέλος· για +παράδειγμα, αν το αρχείο σου ονομάζεται «hello.c», η αυτόματη +αποθήκευση γίνεται στο «#hello.c#». Όταν αποθηκεύσεις το αρχείο με +τον φυσιολογικό τρόπο, το Emacs διαγράφει το αρχείο αυτόματης +αποθήκευσης. + +Εάν ο υπολογιστής κλείσει αναπάντεχα μπορείς να ανακτήσεις αυτό που +επεξεργαζόσουν με το να βρεις το αρχείο (το κανονικό αρχείο, όχι αυτό +της αυτόματης αντιγραφής του) και να πληκτρολογήσεις M-x +recover-this-file . Όταν σου ζητηθεί επιβεβαίωση, +πληκτρολόγησε yes για την ανάκτηση των δεδομένων. + + +* ΤΟΠΟΣ ΑΝΤΗΧΗΣΗΣ +----------------- + +Αν το Emacs διακρίνει πως πληκτρολογείς τους χαρακτήρες μιας +μακροσκελούς εντολής με σχετικά αργό ρυθμό, θα σου τους δείξει στο +κάτω μέρος της οθόνης σε αυτό που ονομάζεται «τόπος αντήχησης». Ο +τόπος αντήχησης περιλαμβάνει την τελευταία γραμμή της οθόνης. + + +* ΓΡΑΜΜΗ ΚΑΤΑΣΤΑΣΗΣ +------------------- + +Η γραμμή ακριβώς πάνω από τον τόπο αντήχησης ονομάζεται «γραμμή +κατάστασης». Αυτή αναφέρει πληροφορίες όπως: + + -:**- TUTORIAL.el_GR 63% L800 (Fundamental) + +Αυτή η γραμμή έχει χρήσιμες πληροφορίες για την κατάσταση του Emacs +και του κειμένου που επεξεργάζεσαι. + +Ήδη γνωρίζεις τι σημαίνει το πεδίο ονόματος του αρχείου--αναφέρει το +αρχείο που έχεις επισκεφθεί. Το ΝΝ% δείχνει την τρέχουσα θέση σου +στον αποσβεστήρα του κειμένου: σημαίνει πως ΝΝ επί τις εκατό του +αποσβεστήρα βρίσκεται πέρα από το πάνω μέρος της οθόνης. Εάν το πάνω +μέρος περιέχει όλο το προηγούμενο κείμενο, τότε θα γράφει «Top» αντί +για «0%». Αν είναι στο κάτω μέρος του αποσβεστήρα, τότε θα αναγράφει +«Bot». Αν ο αποσβεστήρας είναι μικρός ώστε όλο το περιεχόμενο του να +χωράει στην οθόνη, τότε η γραμμή κατάστασης θα γράφει «All». + +Το L και τα ψηφία δείχνουν την θέση με άλλο τρόπο: τον αριθμό της +γραμμής όπου βρίσκεται το σημείο. + +Οι αστερίσκοι κοντά στην αρχή δείχνουν πως έχουν υπάρξει τροποποιήσεις +στο κείμενο. Μόλις επισκεφθείς ή αποθηκεύσεις ένα αρχείο, εκείνο το +τμήμα δεν δείχνει αστερίσκους παρά μόνο παύλες. + +Το τμήμα της γραμμής κατάστασης εντός παρενθέσεων αναφέρει τις +λειτουργίες επεξεργασίας που ισχύουν. Η βασική λειτουργία ονομάζεται +Fundamental κι είναι αυτή που χρησιμοποιείς τώρα. Πρόκειται για +παράδειγμα «αξιωματικής λειτουργίας» (major mode). + +Το Emacs έχει πολλές αξιωματικές λειτουργίες. Κάποιες αφορούν την +επεξεργασία κειμένου σε διάφορες γλώσσες προγραμματισμού ή για διάφορα +ήδη κειμένου, όπως Lisp mode, Text mode, κτλ. Μόνο μια αξιωματική +λειτουργία γίνεται να είναι σε ισχύ, και το όνομα της βρίσκεται στην +γραμμή κατάστασης όπου τώρα υπάρχει το «Fundamental». + +Κάθε αξιωματική λειτουργία κάνει κάποιες εντολές να συμπεριφέρονται με +διαφορετικό τρόπο. Για παράδειγμα, υπάρχουν εντολές για την +δημιουργία σχολίων σε ένα πρόγραμμα, και καθώς κάθε γλώσσα έχει τις +δικές τις ιδέες για το τι συνιστά σχόλιο, η εκάστοτε αξιωματική +λειτουργία εισάγει σχόλια ιδιοτρόπως. + +Κάθε αξιωματική λειτουργία φέρει το όνομα μιας εκτεταμένης εντολής, +που είναι ένας τρόπος να αλλάξεις σε αυτή. Για παράδειγμα, M-x +fundamental-mode είναι η εντολή που θέτει σε ισχύ το Fundamental mode. + +Αν θα επεξεργάζεσαι κείμενο σε ανθρώπινη γλώσσα, όπως αυτό το αρχείο, +μάλλον θες να χρησιμοποιήσεις το Text mode. + +>> Πληκτρολόγησε M-x text-mode . + +Μην ανησυχείς, καθώς καμία από τις εντολές που έχεις μάθει δεν αλλάζει +με ουσιαστικό τρόπο. Ωστόσο θα διαπιστώσεις πως M-f και M-b τώρα +θεωρούν τα εισαγωγικά ως μέρος της λέξης. Πριν, στο Fundamental mode, +M-f και M-b διάβαζαν τα εισαγωγικά ως διαχωριστικά λέξεων. + +Αξιωματικές λειτουργίες κάνουν τέτοιες εκλεπτυσμένες αλλαγές: οι +πλείστες εντολές «διεκπεραιώνουν το ίδιο έργο» σε κάθε αξιωματική +λειτουργία, αλλά ίσως το επιτυγχάνουν με ελαφρώς διαφορετικό τρόπο. + +Για να μάθεις περισσότερα σχετικά με την τρέχουσα αξιωματική +λειτουργία, πληκτρολόγησε C-h m. + +>> Μετακίνησε τον δείκτη στην γραμμή μετά από αυτήν. +>> Πληκτρολόγησε C-l C-l ώστε να έρθει αυτή η γραμμή στο πάνω μέρος + της οθόνης. +>> Πληκτρολόγησε C-h m για να διαβάσεις πως διαφέρει το Text mode από + το Fundamental mode. +>> Πληκτρολόγησε C-x 1 για να αφαιρέσεις την καταγραφή από την οθόνη. + +Οι αξιωματικές λειτουργίες ονομάζονται έτσι διότι υπάρχουν και οι +ελάσσονες λειτουργίες (minor modes). Ελάσσονες λειτουργίες δεν +υποκαθιστούν τις αξιωματικές λειτουργίες, παρά μόνο επί μέρους πτυχές +τους. Κάθε ελάσσων λειτουργία μπορεί να ενεργοποιηθεί ή +απενεργοποιηθεί αυτοτελώς, ανεξάρτητα από άλλες ελάσσονες λειτουργίες +ή οποιονδήποτε συνδυασμό τους. + +Μια ελάσσων λειτουργία που είναι πολύ χρήσιμη, ειδικά για την +επεξεργασία κειμένου ανθρώπινης γλώσσας, είναι η Auto Fill mode. Όταν +αυτή η λειτουργία ενεργοποιηθεί, το Emacs αυτόματα διαχωρίζει τις +γραμμές μεταξύ των λέξεων όταν αυτές γίνονται πολύ πλατιές. + +Το Auto Fill mode ενεργοποιείται με M-x auto-fill-mode . Όταν +η λειτουργία είναι σε ισχύ, μπορεί να απενεργοποιηθεί πάλι με M-x +auto-fill-mode . Αν είναι απενεργοποιημένη, τότε η εντολή +αυτή την ενεργοποιεί, και το αντίστροφο. Λέμε πως η εντολή +«εναλλάσσει την λειτουργία». + +>> Πληκτρολόγησε M-x auto-fill-mode τώρα. Κατόπιν + πληκτρολόγησε μια γραμμή με «ασδφ » πολλές φορές ως που να δεις ότι + διαιρείται σε δύο γραμμές. Πρέπει να έχει κενά μεταξύ των + χαρακτήρων, διότι μόνο με βάση αυτά λειτουργεί το Auto Fill (δεν + κόβει λέξεις). + +Το μήκος συνήθως ορίζεται στους 70 χαρακτήρες, αλλά μπορείς να το +αλλάξεις με την εντολή C-x f. Όρισε τον αριθμό που επιθυμείς ως +αριθμητική παράμετρο. + +>> Πληκτρολόγησε C-x f με παράμετρο το 20. (C-u 2 0 C-x f). Κατόπιν + πληκτρολόγησε τυχαίο κείμενο με κενά και πρόσεξε πως το Emacs + συμπληρώνει τις γραμμές έως τους 20 χαρακτήρες. Μετά θέσε πάλι το + μήκος τους 70 χαρακτήρες χρησιμοποιώντας C-x f με αριθμητική + παράμετρο. + +Αν κάνεις αλλαγές στην μέση της παραγράφου, το Auto Fill mode δεν +επανασυμπληρώνει για χάρη σου. +Για να επανασυμπληρώσεις μια παράγραφο χειροκίνητα, πληκτρολόγησε M-q +(META-q) με τον δείκτη εντός της παραγράφου εκείνης. + +>> Μετακίνησε τον δείκτη στην προηγούμενη παράγραφο και πληκτρολόγησε + M-q. + + +* ΑΝΑΖΗΤΗΣΗ +----------- + +Το Emacs μπορεί να αναζητήσει σειρές (σειρά (string) είναι αλληλουχία +χαρακτήρων) είτε προς τα εμπρός είτε ανάποδα. Αναζήτηση σειράς +συνιστά κίνηση του δείκτη· μετακινεί τον δείκτη όπου εμφανίζεται η +σειρά. + +Η εντολή αναζήτησης του Emacs είναι «τμηματική». Αυτό σημαίνει πως η +αναζήτηση γίνεται ενόσω δακτυλογραφείς τους χαρακτήρες της σειράς που +αναζητείς. + +Η εντολή προς εκκίνηση αναζήτησης είναι C-s για κίνηση προς τα εμπρός +και C-r και κίνηση όπισθεν. ΑΛΛΑ ΠΕΡΙΜΕΝΕ! Μην τις δοκιμάσεις ακόμα. + +Όταν πληκτρολογείς C-s θα δεις πως η σειρά «I-search» εμφανίζεται ως +προτροπή στον τόπο αντήχησης. Αυτό σου λέει πως το Emacs βρίσκεται σε +αυτό που ονομάζεται «τμηματική αναζήτηση» και περιμένει να +πληκτρολογήσεις αυτό το οποίο ψάχνεις. ολοκληρώνει την +αναζήτηση. + +>> Τώρα πληκτρολόγησε C-s για να αρχίσεις την αναζήτηση. ΑΡΓΑ, ένα + γράμμα τη φορά, γράψε «δείκτη», κάνοντας παύση αφού εισάγεις τον + κάθε χαρακτήρα για να δεις τι συμβαίνει με τον δείκτη. + Τώρα έχεις αναζητήσει για «δείκτη» μία φορά. +>> Πάτα πάλι C-s για να ψάξεις την επόμενη εμφάνιση του «δείκτη». +>> Τώρα πληκτρολόγησε τέσσερις φορές και δες πως κινείται ο + δείκτης. +>> Πληκτρολόγησε για να τερματίσεις την αναζήτηση. + +Είδες τι έγινε; Το Emacs, σε τμηματική αναζήτηση, προσπαθεί να +εντοπίσει την επόμενη εμφάνιση της σειράς χαρακτήρων που έγραψες. Για +να μεταφερθείς στην επόμενη εμφάνιση, πάτα C-s ξανά. Εάν δεν υπάρχει +άλλη, το Emacs θα σηματοδοτήσει «αποτυχία» (failing). Το C-g μπορεί +να τερματίσει την αναζήτηση. + +Κατά την διάρκεια μιας τμηματικής αναζήτησης εάν πατήσεις , η +αναζήτηση «υποχωρεί» σε πρότερο σημείο. Αν πατήσεις αμέσως +αφότου έχεις πληκτρολογήσει C-s για μετακίνηση στην επόμενη εμφάνιση +μιας σειράς χαρακτήρων, θα μεταβείς πίσω στην προηγούμενη εμφάνιση. +Εάν δεν υπάρχει προηγούμενη εμφάνιση, το διαγράφει τον τελευταίο +χαρακτήρα στην σειρά. Για παράδειγμα, φαντάσου πως έγραψες «δ» για να +βρεις την πρώτη εμφάνιση του. Τώρα αν προσθέσεις το «ε» θα πας στην +πρώτη εμφάνιση του «δε». Τώρα πάτα . Διαγράφει το «ε» από την +σειρά και μετακινεί τον δείκτη πίσω στην πρώτη εμφάνιση του «δ». + +Αν είσαι στο μέσον μιας αναζήτησης και πληκτρολογήσεις ένα χαρακτήρα +control ή meta (με κάποιες εξαιρέσεις--όπως C-s και C-r που έχουν +ειδική σημασία στην αναζήτηση), η αναζήτηση θα τερματιστεί. + +Το C-s ξεκινά αναζήτηση που ψάχνει για κάθε εμφάνιση της αναζητούμενης +σειράς ΑΠΟ την τρέχουσα θέση του δείκτη. Εάν θες να βρεις +προηγούμενες εμφανίσεις, χρησιμοποίησε το C-r. Όσα είπαμε για το C-s +ισχύουν για το C-r, με μόνη διαφορά την κατεύθυνση της αναζήτησης. + + +* ΠΟΛΛΑΠΛΑ ΠΑΡΑΘΥΡΑ +------------------- + +Ένα από τα καλά του Emacs είναι πως μπορείς να παρουσιάσεις πέραν του +ενός παραθύρου στην οθόνη. (Σημείωσε πως το Emacs χρησιμοποιεί τον +όρο «πλαίσιο» (frame)--επεξηγείται στην επόμενη ενότητα--για αυτό που +ορισμένες εφαρμογές αποκαλούν «παράθυρο» (window). Το εγχειρίδιο του +Emacs περιέχει γλωσσάριο με όλους τους όρους.) + +>> Φέρε τον δείκτη σε αυτή την γραμμή και πληκτρολόγησε C-l C-l. + +>> Τώρα πάτα C-x 2, που μοιράζει την οθόνη σε δύο παράθυρα. + Και τα δύο παράθυρα παρουσιάζουν αυτή την εκμάθηση. Ο δείκτης + επεξεργασίας παραμένει στο πάνω παράθυρο. + +>> Πληκτρολόγησε C-M-v για να κυλήσεις το κάτω παράθυρο. (Εάν δεν + έχεις META ή ALT πλήκτρο, τότε πληκτρολόγησε C-v.) + +>> Πληκτρολόγησε C-x o («o» είναι για το «άλλο» στην αγγλική (other)) + ώστε να επιλέξεις το έτερο παράθυρο. + +>> Χρησιμοποίησε C-v και M-v στο κάτω παράθυρο για να το κυλήσεις. + Συνέχισε να διαβάζεις αυτές τις οδηγίες στο πάνω παράθυρο. + +>> Πάτα C-x o και πάλι ώστε να φέρεις τον δείκτη πίσω στο πάνω + παράθυρο. Ο δείκτης στο πάνω παράθυρο είναι εκεί που ήταν και + πριν. + +Μπορείς να συνεχίσεις να χρησιμοποιείς C-x o για εναλλαγή μεταξύ των +παραθύρων. Το «επιλεγμένο παράθυρο», όπου γίνεται η επεξεργασία, +είναι αυτό που έχει ένα φανερό δείκτη που αναβοσβήνει καθώς γράφεις. +Τα άλλα παράθυρα έχουν τις δικές τους θέσεις για τον δείκτη· αν +χρησιμοποιείς γραφική προβολή του Emacs, αυτοί οι δείκτες +παρουσιάζονται ως άδεια κουτιά που δεν αναβοσβήνουν. + +Η εντολή C-M-v είναι πολύ χρήσιμη όταν επεξεργάζεται κείμενο σε ένα +παράθυρο και χρησιμοποιείς το έτερο παράθυρο για αναφορά. Χωρίς να +φύγεις από το επιλεγμένο παράθυρο, μπορείς να κυλήσεις το παράθυρο με +C-M-v. + +Το C-M-v αποτελεί παράδειγμα CONTROL-META χαρακτήρα. Αν έχεις META (ή +ALT) πλήκτρο, πληκτρολογείς C-M-v κρατώντας πατημένα τόσο το CONTROL +όσο και το META και πληκτρολογώντας v. Δεν έχει σημασία αν το CONTROL +ή το META «έρχεται πρώτο», καθώς αμφότερα μεταβάλουν τον χαρακτήρα που +εισάγεις. + +Αν δεν έχεις το πλήκτρο META (ή ALT), και χρησιμοποιείς το , τότε +η σειρά έχει σημασία: πρώτα πατάς κι αφήνεις το κι ακολουθείς με +CONTROL-v, διότι CONTROL--v δεν θα δουλέψει. Αυτό γιατί το +είναι χαρακτήρας από μόνο του, κι όχι πλήκτρο μετατροπής χαρακτήρων. + +>> Πληκτρολόγησε C-x 1 στο πάνω παράθυρο για να κλείσεις το κάτω + παράθυρο. + +(Άν πατούσες C-x 1 στο κάτω παράθυρο, θα έκλεινες το πάνω. Φαντάσου +πως αυτή η εντολή λέει «κράτα ένα παράθυρο--αυτό που έχω επιλεγμένο.») + +Δεν είναι απαραίτητο να παρουσιάζεις τον ίδιο αποσβεστήρα σε πολλά +παράθυρα. Αν χρησιμοποιήσεις το C-x C-f για να βρεις ένα αρχείο στο +ένα παράθυρο, το έτερο παράθυρο δεν αλλάζει. Μπορείς να βρεις ένα +αρχείο σε κάθε παράθυρο ανεξάρτητα από τα άλλα. + +Ιδού άλλος ένα τρόπος για να χρησιμοποιείς δύο παράθυρα που δείχνουν +διαφορετικά πράγματα: + +>> Πληκτρολόγησε C-x 4 C-f και δώσε όνομα αρχείου στην σχετική + προτροπή που εμφανίζεται στο κάτω μέρος της οθόνης. Επικύρωσε την + επιλογή σου με το . Δες πως το επιλεγμένο αρχείο + εμφανίζεται στο κάτω παράθυρο. Ο δείκτης πάει κι αυτός εκεί. + +>> Πληκτρολόγησε C-x o για να επιστρέψεις στο πάνω παράθυρο και μετά + C-x 1 για να κλείσεις το κάτω παράθυρο. + + +* ΠΟΛΛΑΠΛΑ ΠΛΑΙΣΙΑ +------------------ + +Το Emacs μπορεί επίσης να δημιουργήσει πολλά «πλαίσια». Πλαίσιο +ονομάζουμε αυτό που περιέχει ένα ή περισσότερα παράθυρα, μαζί με τα +μενού, μπάρες κύλισης, τόπο αντήχησης, κτλ. Σε γραφικές προβολές, +αυτό που το Emacs αποκαλεί «πλαίσιο» είναι το ίδιο που άλλες εφαρμογές +ονομάζουν «παράθυρο». Πολλά γραφικά πλαίσια μπορούν να εμφανίζονται +στην οθόνη ταυτόχρονα. Σε ακροδέκτη κειμένου, μόνο ένα πλαίσιο μπορεί +να παρουσιάζεται κάθε φορά. + +>> Πληκτρολόγησε C-x 5 2. + Δες ένα νέο πλαίσιο που εμφανίστηκε στην οθόνη. + +Μπορείς να κάνεις όσα έκανες στο αρχικό πλαίσιο και στο νέο πλαίσιο. +Δεν υπάρχει τίποτα το ειδικό για το ένα ή το άλλο. + +>> Πληκτρολόγησε C-x 5 0. + Αυτό αφαιρεί το επιλεγμένο πλαίσιο. + +Μπορείς πάντοτε να αφαιρέσεις ένα πλαίσιο με τον κοινό τρόπο που +προσφέρει το σύστημα γραφικών (συνήθως πατάς με το ποντίκι πάνω σε ένα +εικονίδιο «X» σε ένα από τα πάνω άκρα του πλαισίου). Αν αφαιρέσεις το +τελευταίο πλαίσιο της λειτουργίας του Emacs κατά αυτόν τον τρόπο, τότε +κλείνει το Emacs. + + +* ΕΠΙΠΕΔΑ ΑΝΑΔΡΟΜΙΚΗΣ ΕΠΕΞΕΡΓΑΣΙΑΣ +---------------------------------- + +Κάποιες φορές θα βρεθείς σε αυτό που ονομάζουμε «επίπεδο αναδρομικής +επεξεργασίας». Αυτό επισημαίνεται από αγκύλες στην γραμμή κατάστασης +που περιβάλλουν τις παρενθέσεις γύρω από την αξιωματική λειτουργία. +Για παράδειγμα, ίσως δεις [(Fundamental)] αντί για (Fundamental). + +Για να βγεις από επίπεδο αναδρομικής επεξεργασίας, πληκτρολόγησε + . Αυτή είναι η γενική εντολή εξόδου. Μπορείς να την +χρησιμοποιήσεις για να κλείσεις όλα τα έτερα παράθυρα και για να βγεις +από τον μικροαποσβεστήρα. + +>> Πληκτρολόγησε M-x για να μπεις στον μικροαποσβεστήρα· κατόπιν πάτα + για να εξέλθεις. + +Δεν μπορείς να χρησιμοποιήσεις C-g για να βγεις από επίπεδο +αναδρομικής επεξεργασίας. Αυτό είναι έτσι γιατί το C-g ακυρώνει +εντολές ή τις παραμέτρους αυτών ΕΝΤΟΣ του τρέχοντος επιπέδου +αναδρομικής επεξεργασίας. + + +* ΠΕΡΙΣΣΟΤΕΡΗ ΒΟΗΘΕΙΑ +--------------------- + +Σε αυτό τον οδηγό προσπαθήσαμε να προσφέρουμε βασικές γνώσεις για να +αρχίσεις να χρησιμοποιείς το Emacs. Υπάρχουν τόσα πολλά στο Emacs που +θα ήταν αδύνατο να τα εξηγήσουμε όλα εδώ. Ωστόσο, μάλλον θα θέλεις να +μάθεις περισσότερα για τις διάφορες δυνατότητες που παρέχει το Emacs. +Προς αυτόν τον σκοπό, το Emacs προσφέρει εντολές για την εξεύρεση κι +ανάγνωση οδηγιών. Αυτές οι εντολές «βοήθειας» (help) όλες αρχίζουν με +τον χαρακτήρα CONTROL-h, που αποκαλείται «ο χαρακτήρας βοηθείας». + +Για να χρησιμοποιήσεις τις υπηρεσίες βοηθείας, πληκτρολόγησε C-h, και +μετά ένα χαρακτήρα που ανταποκρίνεται στο είδος της βοήθειας που +επιζητείς. Αν είσαι σε ΠΡΑΓΜΑΤΙΚΑ δύσκολη θέση, πάτα C-h ? και το +Emacs θα σου πει τι είδη βοηθείας υπάρχουν. Αν έχεις ήδη πατήσει C-h +και αποφάσισες πως δεν θέλεις καμία βοήθεια, απλά ακύρωσε το με C-g. + +(Αν το C-h δεν προβάλει μήνυμα για βοήθεια στο κάτω μέρος της οθόνης, +δοκίμασε το πλήκτρο F1, αλλιώς M-x help .) + +Η πιο βασική βοήθεια προσφέρεται από το C-h c. Πληκτρολόγησε C-h, +ύστερα το c, και μετά τον χαρακτήρα ή αλληλουχία χαρακτήρων +οποιασδήποτε εντολής: το Emacs θα εμφανίσει μια σύντομη περιγραφή της +εντολής. + +>> Πληκτρολόγησε C-h c C-p + +Το μήνυμα θα είναι κάπως έτσι: + + C-p εκτελεί την εντολή previous-line + +Αυτό σου λέει το «όνομα της συνάρτησης». Καθώς οι συναρτήσεις έχουν +ονόματα που φανερώνουν την λειτουργία τους, μπορούν να ερμηνευθούν κι +ως πολύ σύντομες περιγραφές--επαρκείς για να σου υπενθυμίσουν κάτι που +ήδη έχεις μάθει. + +Εντολές με πολλούς χαρακτήρες, όπως C-x C-s ή v (αντί του M-v για +όσους δεν έχουν πλήκτρο META ή ALT) μπορούν κι αυτές να δοθούν μετά το +C-h c. + +Για περισσότερες πληροφορίες αναφορικά με μια εντολή, χρησιμοποίησε το +C-h k αντί του C-h c. + +>> Πληκτρολόγησε C-h k C-p. + +Αυτό δείχνει την πλήρη καταγραφή της συνάρτησης, καθώς και το όνομα +της, σε νέο παράθυρο του Emacs. Όταν το διαβάσεις, πάτα C-x 1 για να +κλείσεις εκείνο το παράθυρο. Δεν χρειάζεται να το κάνεις αυτό αμέσως. +Ίσως θες πρώτα να επεξεργαστείς κάτι καθώς αναφέρεσαι στο κείμενο +βοηθείας και μετά να πληκτρολογήσεις C-x 1. + +Ιδού άλλες χρήσιμες επιλογές με το C-h: + + C-h x Περιέγραψε μια εντολή. Ζητά το όνομα της εντολής. + +>> Προσπάθησε C-h x previous-line . + Δείχνει όλες τις πληροφορίες που έχει το Emacs σχετικά με την + συνάρτηση που δίνει την εντολή C-p. + +Παρόμοια εντολή είναι αυτή του C-h v που δείχνει την καταγραφή μιας +μεταβλητής, συμπεριλαμβανομένων αυτών που μπορείς να τροποποιήσεις για +να αλλάξεις την συμπεριφορά του Emacs. Πρέπει να γράψεις το όνομα της +μεταβλητής στην σχετική προτροπή. + + C-h a Συναφή εντολών (command apropos). Γράψε μια + λέξη-κλειδί και το Emacs θα παραθέσει όλες τις εντολές + των οποίων το όνομα περιέχει αυτήν την λέξη. Όλες + αυτές οι εντολές μπορούν να κληθούν με το META-x. Για + ορισμένες εντολές, τα συναφή εντολών περιέχουν και την + σχετική αλληλουχία χαρακτήρων που εκτελεί την εντολή. + +>> Πληκτρολόγησε C-h a file . + +Αυτό παραθέτει σε έτερο παράθυρο όλες τις εντολές M-x που περιέχουν +τον όρο «file» στο όνομα τους. Θα δεις εντολές χαρακτήρος μεταξύ των +επονομαζομένων (όπως C-x C-f πέριξ του find-file). + +>> Πληκτρολόγησε C-M-v για να κυλήσεις το παράθυρο βοηθείας. Κάνε το + μερικές φορές. + +>> Πληκτρολόγησε C-x 1 για να κλείσεις το παράθυρο βοηθείας. + + C-h i Διάβασε τα εγχειρίδια (Info manuals). Αυτή η εντολή + σε βάζει σε ειδικό αποσβεστήρα που ονομάζεται «*info*» + όπου μπορείς να διαβάσεις εγχειρίδια για τις + συσκευασίες που είναι εγκατεστημένες στο σύστημα σου. + Πληκτρολόγησε m emacs για να διαβάσεις το + εγχειρίδιο του Emacs. Αν δεν έχεις χρησιμοποιήσει το + Info ποτέ, πληκτρολόγησε h και το Emacs θα σου δείξει + τις σχετικές λειτουργίες. Αφού ολοκληρώσεις αυτή την + εκμάθηση, να αναφέρεσε στο εγχειρίδιο του Emacs ως την + κύρια πηγή όλων των καταγραφών. + + +* ΑΛΛΕΣ ΛΕΙΤΟΥΡΓΙΕΣ +------------------- + +Μπορείς να μάθεις περισσότερα για το Emacs διαβάζοντας το εγχειρίδιο +του, είτε ως έντυπο βιβλίο, είτε εντός του Emacs (χρησιμοποίησε τον +κατάλογο βοηθείας ή πληκτρολόγησε C-h r). Δύο λειτουργίες που ίσως να +σου φανούν χρήσιμες είναι η «ολοκλήρωση», που εξοικονομεί στην +δακτυλογράφηση, και το Dired, που απλοποιεί την διαχείριση αρχείων. + +Η ολοκλήρωση είναι τρόπος αποφυγής αχρείαστης πληκτρολόγησης. Για +παράδειγμα, αν θες να μεταβείς στον αποσβεστήρα *Messages*, +πληκτρολογείς C-x b *M και το Emacs θα συμπληρώσει το υπόλοιπο +του ονόματος ως εκεί που μπορεί να κρίνει αντιστοιχία με αυτό που +έχεις ήδη γράψει. Η ολοκλήρωση δουλεύει επίσης για ονόματα εντολών κι +αρχείων. Στο εγχειρίδιο καταγράφεται στην ενότητα «Completion». + +Το Dired σου επιτρέπει να παραθέτεις κατάλογο αρχείων (και προαιρετικά +υποκαταλόγους), να επιλέγεις, επισκέπτεσαι, μετονομάζεις, διαγράφεις, +ή γενικά να επιδράς πάνω σε αρχεία. Το Dired καταγράφεται στο +εγχειρίδιο στην ενότητα «Dired». + +Το εγχειρίδιο καταγράφει πολλές άλλες λειτουργίες του Emacs. + + +* ΕΓΚΑΤΑΣΤΑΣΗ ΣΥΣΚΕΥΑΣΙΩΝ +------------------------- + +Υπάρχει πλούσιος όγκος συσκευασιών (packages) του Emacs που έχουν +παρασκευαστεί από την κοινότητα των χρηστών του, που επεκτείνουν τις +δυνατότητες του Emacs. Αυτές οι συσκευασίες περιλαμβάνουν υποστήριξη +για νέες γλώσσες, πρόσθετα θέματα χρωμάτων, προεκτάσεις για εξωτερικές +εφαρμογές, και άλλα πολλά. + +Για παράθεση των διαθέσιμων συσκευασιών, πληκτρολόγησε M-x +list-packages. Στη σχετική λίστα, μπορείς να εγκαταστήσεις ή +απεγκαταστήσεις συσκευασίες, καθώς και να διαβάσεις τις περιγραφές +τους. Για περισσότερες πληροφορίες περί διαχείρισης συσκευασιών, δες +το εγχειρίδιο του Emacs. + + +* ΚΑΤΑΛΗΚΤΙΚΑ +------------- + +Για έξοδο από το Emacs, χρησιμοποίησε C-x C-c. + +Αυτή η εκμάθηση γράφτηκε για να είναι κατανοητή σε όλους τους νέους +χρήστες. Αν λοιπόν κάτι παραμένει ασαφές, μην κάτσεις εκεί να +κατηγορείς τον εαυτό σου - πες μας για το πρόβλημα σου! + + +* ΑΝΤΙΓΡΑΦΗ +----------- + +Αυτό το κείμενο εκμάθησης είναι συνέχεια μιας μακράς γραμμής κειμένων +εκμάθησης του Emacs, αρχής γενομένης αυτού του Stuart Cracraft για το +αρχικό Emacs. + +Αυτή η έκδοση της εκμάθησης είναι μέρος του GNU Emacs. Έχει +πνευματικά δικαιώματα και δίνεται με την άδεια διανομής αντιγράφων υπό +κάποιους όρους. + + Πνευματικά Δικαιώματα (C) 1985, 1996, 1998, 2001-2022 Free Software + Foundation, Inc. + + Αυτό το αρχείο είναι μέρος του GNU Emacs. + + Το GNU Emacs είναι ελεύθερο λογισμικό: μπορείτε να το αναδιανέμετε + ή/και να το τροποποιήσετε σύμφωνα με τους όρους της GNU Γενική + Δημόσια Άδεια (GNU General Public License) όπως δημοσιεύθηκε από το + Ίδρυμα Ελεύθερου Λογισμικού (Free Software Foundation), είτε την + έκδοση 3 της άδειας, είτε (κατά την επιλογή σας) οποιαδήποτε + μεταγενέστερη έκδοση. + + Το GNU Emacs διανέμεται με την ελπίδα πως θα είναι χρήσιμο, αλλά + ΧΩΡΙΣ ΚΑΜΙΑ ΕΓΓΥΗΣΗ· χωρίς καν την συνεπαγόμενη εγγύηση της + ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ή ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ. Δείτε την + GNU Γενική Δημόσια Άδεια (GNU General Public License) για + περισσότερες λεπτομέρειες. + + Οφείλατε να λάβετε αντίγραφο της GNU Γενικής Δημόσιας Άδειας (GNU + General Public License) μαζί με το GNU Emacs. Εάν όχι, δείτε + . + +Παρακαλώ όπως διαβάσετε το αρχείο COPYING και δώσετε αντίγραφα του GNU +Emacs στους φίλους σας. Βοηθήστε στην καταπολέμηση του περιορισμού +(«ιδιοκτησία») του λογισμικού δια της χρήσης, γραφής, και κοινοποίησης +ελεύθερου λογισμικού! diff --git a/etc/tutorials/TUTORIAL.translators b/etc/tutorials/TUTORIAL.translators index b6b95787068..891b6a16824 100644 --- a/etc/tutorials/TUTORIAL.translators +++ b/etc/tutorials/TUTORIAL.translators @@ -26,6 +26,10 @@ Maintainer: Dale Gulledge Author: Rafael Sepúlveda Maintainer: Rafael Sepúlveda +* TUTORIAL.el_GR: +Author: Protesilaos Stavrou +Maintainer: Protesilaos Stavrou + * TUTORIAL.fr: Author: Éric Jacoboni Maintainer: Éric Jacoboni diff --git a/lisp/language/greek.el b/lisp/language/greek.el index 58f4fe6fc49..920cf67d871 100644 --- a/lisp/language/greek.el +++ b/lisp/language/greek.el @@ -79,7 +79,9 @@ (coding-priority greek-iso-8bit) (nonascii-translation . iso-8859-7) (input-method . "greek") - (documentation . t))) + (documentation . "Support for Greek ISO-8859-7 using the greek input method.") + (sample-text . "Greek (ελληνικά) Γειά σας") + (tutorial . "TUTORIAL.el_GR"))) (provide 'greek) From 278b18a460caf34e422847d10ac3f0b62bef4996 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 8 May 2022 19:08:34 +0300 Subject: [PATCH 0050/1028] ; Fix typos and wording in a doc string * lisp/textmodes/pixel-fill.el (pixel-fill-width): Fix doc string. (Bug#55318) --- lisp/textmodes/pixel-fill.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/textmodes/pixel-fill.el b/lisp/textmodes/pixel-fill.el index 418d6a37c97..e47653e734a 100644 --- a/lisp/textmodes/pixel-fill.el +++ b/lisp/textmodes/pixel-fill.el @@ -45,9 +45,9 @@ of a line or the end of a line." (defun pixel-fill-width (&optional columns window) "Return the pixel width corresponding to COLUMNS in WINDOW. -If COLUMNS in nil, use the enture window width. +If COLUMNS is nil or omitted, use the entire window width. -If WINDOW is nil, this defaults to the current window." +If WINDOW is nil or omitted, this defaults to the selected window." (unless window (setq window (selected-window))) (let ((frame (window-frame window))) From 21ef29d4b1ea85c4b94232f028b3aa29a4a1a81b Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sun, 8 May 2022 21:01:34 +0300 Subject: [PATCH 0051/1028] Minor documentation improvements for completions commands and options * doc/emacs/mini.texi (Completion Commands): Mention prefix argument of choose-completion. (Completion Options): Improve documentation of completions-format and completions-sort. --- doc/emacs/mini.texi | 44 ++++++++++++++++++++++++-------------------- etc/NEWS | 2 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index a899fea7e39..ad5701670eb 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -381,16 +381,16 @@ used with the completion list: @vindex minibuffer-completion-auto-choose @item M-@key{DOWN} @itemx M-@key{UP} -These keys will navigate through the completions displayed in the -completions buffer. When @code{minibuffer-completion-auto-choose} is -non-@code{nil} (which is the default), using these commands will -automatically insert the current completion candidate in the -minibuffer. If this user option is @code{nil}, the keys will navigate -the same way as before, but won't automatically insert the candidate -in the minibuffer. Instead you have to use the @kbd{M-@key{RET}} command to -do that. With a prefix argument, @kbd{C-u M-@key{RET}} inserts the -currently active candidate to the minibuffer, but doesn't exit the -minibuffer. +While in the minibuffer, these keys will navigate through the +completions displayed in the completions buffer. When +@code{minibuffer-completion-auto-choose} is non-@code{nil} (which is +the default), using these commands will automatically insert the +current completion candidate in the minibuffer. If this user option +is @code{nil}, the keys will navigate the same way as before, but +won't automatically insert the candidate in the minibuffer. Instead +you have to use the @kbd{M-@key{RET}} command to do that. With +a prefix argument, @kbd{C-u M-@key{RET}} inserts the currently active +candidate to the minibuffer, but doesn't exit the minibuffer. @findex switch-to-completions @item M-v @@ -407,7 +407,9 @@ ways (@pxref{Windows}). @itemx mouse-1 @itemx mouse-2 While in the completion list buffer, this chooses the completion at -point (@code{choose-completion}). +point (@code{choose-completion}). With a prefix argument, @kbd{C-u +@key{RET}} inserts the completion at point to the minibuffer, but +doesn't exit the minibuffer. @findex next-completion @item @key{TAB} @@ -682,17 +684,19 @@ behavior only when there are @var{n} or fewer alternatives. @vindex completions-format When displaying completions, Emacs will normally pop up a new buffer -to display the completions. The completions will (by default) be -sorted in columns horizontally in alphabetical order, but this can be -changed by changing the @code{completions-format} user option. If -@code{vertical}, sort the completions vertically in columns instead, -and if @code{one-column}, just use a single column. +to display the completions. The completions will by default be sorted +in rows horizontally, but this can be changed by customizing the +@code{completions-format} user option. If @code{vertical}, sort the +completions vertically in columns instead, and if @code{one-column}, +just use a single column. @vindex completions-sort - This user option controls how completions are sorted in the -@samp{*Completions*} buffer. The default is @code{alphabetical}, but -it can also be a function which will be called with the list of -completions, and should return the list in the desired order. + The @code{completions-sort} user option controls how completions are +sorted in the @samp{*Completions*} buffer. The default is +@code{alphabetical} that sorts in alphabetical order. The value +@code{nil} disables sorting. It can also be a function which will be +called with the list of completions, and should return the list in the +desired order. @vindex completions-max-height When @code{completions-max-height} is non-@code{nil}, it limits the diff --git a/etc/NEWS b/etc/NEWS index 234aa819be1..dbdc161a416 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -892,7 +892,7 @@ When this user option names a face, the current candidate in the "*Completions*" buffer is highlighted with that face. The nil value disables this highlighting. ---- ++++ *** Choosing a completion with a prefix argument doesn't exit the minibuffer. This means that typing 'C-u RET' on a completion candidate in the "*Completions*" buffer inserts the completion to the minibuffer, From 8d788a195f68bf7451635f7d4dfe86a6dc2bbda5 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Sun, 8 May 2022 13:45:35 -0700 Subject: [PATCH 0052/1028] remember-notes: Use pop-to-buffer-same-window not switch-to-buffer * lisp/textmodes/remember.el (remember-notes): Use pop-to-buffer-same-window rather than switch-to-buffer, to allow customization via display-buffer-alist. --- lisp/textmodes/remember.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index d65aea62862..e72f86f7db6 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -653,7 +653,7 @@ to turn the *scratch* buffer into your notes buffer." (remember-notes-mode 1) (current-buffer))))) (when switch-to - (switch-to-buffer buf)) + (pop-to-buffer-same-window buf)) buf)) (defun remember-notes--kill-buffer-query () From 3d846efb857c0ace95d6fe026522fcdbffe04dc3 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 09:17:28 +0800 Subject: [PATCH 0053/1028] Fix race conditions in handling of unsupported drops on X * lisp/x-dnd.el (x-dnd-handle-unsupported-drop): Adjust for new parameters. * src/keyboard.c (kbd_buffer, kbd_fetch_ptr, kbd_store_ptr): Export variables. (kbd_buffer_get_event): Ignore already handled unsupported drops. * src/keyboard.h: Update prototypes. * src/termhooks.h (enum event_kind): Document meaning of `modifiers' in UNSUPPORTED_DROP_EVENTs. * src/xterm.c (x_dnd_send_unsupported_drop): Set event modifiers to current level. (x_toggle_visible_pointer): Fix fixes fallback. (x_dnd_begin_drag_and_drop): Handle UNSUPPORTED_DROP_EVENTs already in the keyboard buffer before starting DND. (syms_of_xterm): Give timestamp to unsupported drop function. * src/xterm.h: Update prototypes. --- lisp/x-dnd.el | 2 +- src/keyboard.c | 18 +++++---- src/keyboard.h | 9 +++++ src/termhooks.h | 5 +++ src/xterm.c | 100 ++++++++++++++++++++++++++++++++++++++++-------- src/xterm.h | 1 + 6 files changed, 110 insertions(+), 25 deletions(-) diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index 47d8ae14cfc..c2498a57a13 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -783,7 +783,7 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." ;;; Handling drops. -(defun x-dnd-handle-unsupported-drop (targets _x _y action _window-id _frame) +(defun x-dnd-handle-unsupported-drop (targets _x _y action _window-id _frame _time) "Return non-nil if the drop described by TARGETS and ACTION should not proceeed." (not (and (or (eq action 'XdndActionCopy) (eq action 'XdndActionMove)) diff --git a/src/keyboard.c b/src/keyboard.c index 70908120cb0..e8f51f8a6fe 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -95,8 +95,6 @@ volatile int interrupt_input_blocked; The maybe_quit function checks this. */ volatile bool pending_signals; -enum { KBD_BUFFER_SIZE = 4096 }; - KBOARD *initial_kboard; KBOARD *current_kboard; static KBOARD *all_kboards; @@ -290,14 +288,14 @@ bool input_was_pending; /* Circular buffer for pre-read keyboard input. */ -static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; +union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; /* Pointer to next available character in kbd_buffer. If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. */ -static union buffered_input_event *kbd_fetch_ptr; +union buffered_input_event *kbd_fetch_ptr; /* Pointer to next place to store character in kbd_buffer. */ -static union buffered_input_event *kbd_store_ptr; +union buffered_input_event *kbd_store_ptr; /* The above pair of variables forms a "queue empty" flag. When we enqueue a non-hook event, we increment kbd_store_ptr. When we @@ -4022,6 +4020,11 @@ kbd_buffer_get_event (KBOARD **kbp, kbd_fetch_ptr = next_kbd_event (event); input_pending = readable_events (0); + /* This means this event was already handled in + `x_dnd_begin_drag_and_drop'. */ + if (event->ie.modifiers < x_dnd_unsupported_event_level) + break; + f = XFRAME (event->ie.frame_or_window); if (!FRAME_LIVE_P (f)) @@ -4029,11 +4032,12 @@ kbd_buffer_get_event (KBOARD **kbp, if (!NILP (Vx_dnd_unsupported_drop_function)) { - if (!NILP (call6 (Vx_dnd_unsupported_drop_function, + if (!NILP (call7 (Vx_dnd_unsupported_drop_function, XCAR (XCDR (event->ie.arg)), event->ie.x, event->ie.y, XCAR (XCDR (XCDR (event->ie.arg))), make_uint (event->ie.code), - event->ie.frame_or_window))) + event->ie.frame_or_window, + make_int (event->ie.timestamp)))) break; } diff --git a/src/keyboard.h b/src/keyboard.h index cd5f677b963..a0b7204fa2b 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -358,6 +358,11 @@ enum menu_item_idx MENU_ITEMS_ITEM_LENGTH }; +enum + { + KBD_BUFFER_SIZE = 4096 + }; + extern void unuse_menu_items (void); /* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU @@ -419,6 +424,10 @@ extern void unuse_menu_items (void); happens. */ extern struct timespec *input_available_clear_time; +extern union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; +extern union buffered_input_event *kbd_fetch_ptr; +extern union buffered_input_event *kbd_store_ptr; + extern bool ignore_mouse_drag_p; extern Lisp_Object parse_modifiers (Lisp_Object); diff --git a/src/termhooks.h b/src/termhooks.h index 8c193914ba8..08bde0aec0d 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -223,6 +223,11 @@ enum event_kind gives the timestamp where the drop happened. + .modifiers gives a number that + determines if an event was already + handled by + `x_dnd_begin_drag_and_drop'. + .x and .y give the coordinates of the drop originating from the root window. */ diff --git a/src/xterm.c b/src/xterm.c index d32bdea843a..2bbc9f3d0c6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -868,6 +868,10 @@ static int x_filter_event (struct x_display_info *, XEvent *); /* Flag that indicates if a drag-and-drop operation is in progress. */ bool x_dnd_in_progress; +/* Number that indicates the last "generation" of + UNSUPPORTED_DROP_EVENTs handled. */ +unsigned x_dnd_unsupported_event_level; + /* The frame where the drag-and-drop operation originated. */ struct frame *x_dnd_frame; @@ -3070,6 +3074,7 @@ x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_windo ie.kind = UNSUPPORTED_DROP_EVENT; ie.code = (unsigned) target_window; + ie.modifiers = x_dnd_unsupported_event_level; ie.arg = list3 (assq_no_quit (QXdndSelection, dpyinfo->terminal->Vselection_alist), targets, arg); @@ -9479,15 +9484,18 @@ x_toggle_visible_pointer (struct frame *f, bool invisible) invisible = false; #else /* But if Xfixes is available, try using it instead. */ - if (x_probe_xfixes_extension (dpyinfo)) + if (dpyinfo->invisible_cursor == None) { - dpyinfo->fixes_pointer_blanking = true; - xfixes_toggle_visible_pointer (f, invisible); + if (x_probe_xfixes_extension (dpyinfo)) + { + dpyinfo->fixes_pointer_blanking = true; + xfixes_toggle_visible_pointer (f, invisible); - return; + return; + } + else + invisible = false; } - else - invisible = false; #endif if (invisible) @@ -9864,6 +9872,64 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, #ifndef USE_GTK struct x_display_info *event_display; #endif + union buffered_input_event *events, *event; + int n_events; + struct frame *event_frame; + + /* Before starting drag-and-drop, walk through the keyboard buffer + to see if there are any UNSUPPORTED_DROP_EVENTs, and run them now + if they exist, to prevent race conditions from happening due to + multiple unsupported drops running at once. */ + + block_input (); + events = alloca (sizeof *events * KBD_BUFFER_SIZE); + n_events = 0; + event = kbd_fetch_ptr; + + while (event != kbd_store_ptr) + { + if (event->ie.kind == UNSUPPORTED_DROP_EVENT + && event->ie.modifiers < x_dnd_unsupported_event_level) + events[n_events++] = *event; + + event = (event == kbd_buffer + KBD_BUFFER_SIZE - 1 + ? kbd_buffer : event + 1); + } + + x_dnd_unsupported_event_level += 1; + unblock_input (); + + for (i = 0; i < n_events; ++i) + { + maybe_quit (); + + event = &events[i]; + event_frame = XFRAME (event->ie.frame_or_window); + + if (!FRAME_LIVE_P (event_frame)) + continue; + + if (!NILP (Vx_dnd_unsupported_drop_function)) + { + if (!NILP (call7 (Vx_dnd_unsupported_drop_function, + XCAR (XCDR (event->ie.arg)), event->ie.x, + event->ie.y, XCAR (XCDR (XCDR (event->ie.arg))), + make_uint (event->ie.code), + event->ie.frame_or_window, + make_int (event->ie.timestamp)))) + continue; + } + + x_dnd_do_unsupported_drop (FRAME_DISPLAY_INFO (event_frame), + event->ie.frame_or_window, + XCAR (event->ie.arg), + XCAR (XCDR (event->ie.arg)), + (Window) event->ie.code, + XFIXNUM (event->ie.x), + XFIXNUM (event->ie.y), + event->ie.timestamp); + break; + } if (!FRAME_VISIBLE_P (f)) { @@ -24849,16 +24915,16 @@ mouse position list. */); DEFVAR_LISP ("x-dnd-unsupported-drop-function", Vx_dnd_unsupported_drop_function, doc: /* Function called when trying to drop on an unsupported window. -This function is called whenever the user tries to drop -something on a window that does not support either the XDND or -Motif protocols for drag-and-drop. It should return a non-nil -value if the drop was handled by the function, and nil if it was -not. It should accept several arguments TARGETS, X, Y, ACTION, -WINDOW-ID and FRAME, where TARGETS is the list of targets that -was passed to `x-begin-drag', WINDOW-ID is the numeric XID of -the window that is being dropped on, X and Y are the root -window-relative coordinates where the drop happened, ACTION -is the action that was passed to `x-begin-drag', and FRAME is -the frame which initiated the drag-and-drop operation. */); +This function is called whenever the user tries to drop something on a +window that does not support either the XDND or Motif protocols for +drag-and-drop. It should return a non-nil value if the drop was +handled by the function, and nil if it was not. It should accept +several arguments TARGETS, X, Y, ACTION, WINDOW-ID, FRAME and TIME, +where TARGETS is the list of targets that was passed to +`x-begin-drag', WINDOW-ID is the numeric XID of the window that is +being dropped on, X and Y are the root window-relative coordinates +where the drop happened, ACTION is the action that was passed to +`x-begin-drag', FRAME is the frame which initiated the drag-and-drop +operation, and TIME is the X server time when the drop happened. */); Vx_dnd_unsupported_drop_function = Qnil; } diff --git a/src/xterm.h b/src/xterm.h index 66c4b178234..16635053be4 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1586,6 +1586,7 @@ extern struct input_event xg_pending_quit_event; extern bool x_dnd_in_progress; extern struct frame *x_dnd_frame; +extern unsigned x_dnd_unsupported_event_level; #ifdef HAVE_XINPUT2 extern struct xi_device_t *xi_device_from_id (struct x_display_info *, int); From fd8eaa72a611d050e1fe9c38c466c7812c7795dd Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 09:37:58 +0800 Subject: [PATCH 0054/1028] Allow precision-scrolling nonselected windows when the minibuffer is resized * doc/lispref/windows.texi (Vertical Scrolling): Document new `preserve-vscroll-p' parameter of `set-window-vscroll'. * etc/NEWS: Announce new parameter. * lisp/pixel-scroll.el (pixel-scroll-precision-scroll-down-page) (pixel-scroll-precision-scroll-up-page): Use that parameter when setting the vscroll. * src/window.c (window_scroll_pixel_based, Fset_window_vscroll): Adjust for new parameter. * src/window.h (struct window): New flag `preserve_vscroll_p'. * src/xdisp.c (redisplay_window): Preserve the vscroll inside force_start on frozen windows with that flag set. (bug#55312) --- doc/lispref/windows.texi | 8 +++++++- etc/NEWS | 5 +++++ lisp/pixel-scroll.el | 6 +++--- src/window.c | 23 ++++++++++++++++------- src/window.h | 4 ++++ src/xdisp.c | 9 ++++++++- 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 97908bea001..57763c146da 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -5508,7 +5508,7 @@ pixels, rather than in units of the normal line height. @end example @end defun -@defun set-window-vscroll window lines &optional pixels-p +@defun set-window-vscroll window lines &optional pixels-p preserve-vscroll-p This function sets @var{window}'s vertical scroll position to @var{lines}. If @var{window} is @code{nil}, the selected window is used. The argument @var{lines} should be zero or positive; if not, it @@ -5530,6 +5530,12 @@ The return value is the result of this rounding. If @var{pixels-p} is non-@code{nil}, @var{lines} specifies a number of pixels. In this case, the return value is @var{lines}. + +Normally, the vscroll does not take effect on windows that aren't the +@code{minibuffer-scroll-window} or the selected window when the +mini-window is resized (@pxref{Minibuffer Windows}). This ``frozen'' +behavior is disabled when the @var{preserve-vscroll-p} parameter is +non-@code{nil}, which means to set the vscroll as usual. @end defun @defvar auto-window-vscroll diff --git a/etc/NEWS b/etc/NEWS index dbdc161a416..5860010f022 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2100,6 +2100,11 @@ dimensions. Specifying a cons as the FROM argument allows to start measuring text from a specified amount of pixels above or below a position. ++++ +** 'set-window-vscroll' now accepts a new argument PRESERVE-VSCROLL-P. +This means the vscroll will not be reset when set on a window that is +"frozen" due to a mini-window being resized. + ** XDG support --- diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index b0fe2f56c03..fc7e680c262 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -547,7 +547,7 @@ the height of the current window." (beginning-of-visual-line) (point))) t) - (set-window-vscroll nil desired-vscroll t))) + (set-window-vscroll nil desired-vscroll t t))) (defun pixel-scroll-precision-scroll-down (delta) "Scroll the current window down by DELTA pixels." @@ -586,7 +586,7 @@ the height of the current window." (goto-char up-point))) (let ((current-vscroll (window-vscroll nil t))) (setq delta (- delta current-vscroll)) - (set-window-vscroll nil 0 t) + (set-window-vscroll nil 0 t t) (when (> delta 0) (let* ((start (window-start)) (dims (window-text-pixel-size nil (cons start (- delta)) @@ -602,7 +602,7 @@ the height of the current window." (signal 'beginning-of-buffer nil)) (setq delta (- delta height)))) (when (< delta 0) - (set-window-vscroll nil (- delta) t))))) + (set-window-vscroll nil (- delta) t t))))) (defun pixel-scroll-precision-interpolate (delta &optional old-window) "Interpolate a scroll of DELTA pixels. diff --git a/src/window.c b/src/window.c index 72d10f9da23..47c008a643a 100644 --- a/src/window.c +++ b/src/window.c @@ -5636,7 +5636,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) if (w->vscroll < 0 && rtop > 0) { px = max (0, -w->vscroll - min (rtop, -dy)); - Fset_window_vscroll (window, make_fixnum (px), Qt); + Fset_window_vscroll (window, make_fixnum (px), Qt, + Qnil); return; } } @@ -5646,7 +5647,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) if (rbot > 0 && (w->vscroll < 0 || vpos == 0)) { px = max (0, -w->vscroll + min (rbot, dy)); - Fset_window_vscroll (window, make_fixnum (px), Qt); + Fset_window_vscroll (window, make_fixnum (px), Qt, + Qnil); return; } @@ -5655,7 +5657,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) { ptrdiff_t spos; - Fset_window_vscroll (window, make_fixnum (0), Qt); + Fset_window_vscroll (window, make_fixnum (0), Qt, + Qnil); /* If there are other text lines above the current row, move window start to current row. Else to next row. */ if (rbot > 0) @@ -5674,7 +5677,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) } } /* Cancel previous vscroll. */ - Fset_window_vscroll (window, make_fixnum (0), Qt); + Fset_window_vscroll (window, make_fixnum (0), Qt, Qnil); } itdata = bidi_shelve_cache (); @@ -7944,7 +7947,7 @@ optional second arg PIXELS-P means value is measured in pixels. */) DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll, - 2, 3, 0, + 2, 4, 0, doc: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL. This takes effect when displaying tall lines or images. @@ -7954,8 +7957,12 @@ optional third arg PIXELS-P non-nil means that VSCROLL is in pixels. If PIXELS-P is nil, VSCROLL may have to be rounded so that it corresponds to an integral number of pixels. The return value is the result of this rounding. -If PIXELS-P is non-nil, the return value is VSCROLL. */) - (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p) +If PIXELS-P is non-nil, the return value is VSCROLL. + +PRESERVE_VSCROLL_P makes setting the start of WINDOW preserve the +vscroll if its start is "frozen" due to a resized mini-window. */) + (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p, + Lisp_Object preserve_vscroll_p) { struct window *w = decode_live_window (window); struct frame *f = XFRAME (w->frame); @@ -7984,6 +7991,8 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */) /* Mark W for redisplay. (bug#55299) */ wset_redisplay (w); } + + w->preserve_vscroll_p = !NILP (preserve_vscroll_p); } return Fwindow_vscroll (window, pixels_p); diff --git a/src/window.h b/src/window.h index 387a3be36a9..7f7de588463 100644 --- a/src/window.h +++ b/src/window.h @@ -445,6 +445,10 @@ struct window window. */ bool_bf suspend_auto_hscroll : 1; + /* True if vscroll should be preserved while forcing the start due + to a frozen window. */ + bool_bf preserve_vscroll_p : 1; + /* Amount by which lines of this window are scrolled in y-direction (smooth scrolling). */ int vscroll; diff --git a/src/xdisp.c b/src/xdisp.c index f09f209b2e3..b9b3c6d1bf3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -19168,7 +19168,14 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) int new_vpos = -1; w->force_start = false; - w->vscroll = 0; + + /* The vscroll should be preserved in this case, since + `pixel-scroll-precision-mode' must continue working normally + when a mini-window is resized. (bug#55312) */ + if (!w->preserve_vscroll_p || !window_frozen_p (w)) + w->vscroll = 0; + + w->preserve_vscroll_p = false; w->window_end_valid = false; /* Forget any recorded base line for line number display. */ From 6ec29d0566042c65956d46fd1a30c6182ce0e537 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 10:13:43 +0800 Subject: [PATCH 0055/1028] Allow disabling Motif drag protocol * lisp/cus-start.el (standard): Add new variable. * src/xterm.c (x_dnd_update_state, handle_one_xevent): Respect new variable. (syms_of_xterm): New variable `x-dnd-disable-motif-drag'. --- lisp/cus-start.el | 3 +++ src/xterm.c | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 83ab61b28b5..d8c4b480359 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -832,6 +832,7 @@ since it could result in memory overflow and make Emacs crash." (scroll-bar-adjust-thumb-portion windows boolean "24.4") (x-scroll-event-delta-factor mouse float "29.1") (x-gtk-use-native-input keyboard boolean "29.1") + (x-dnd-disable-motif-drag dnd boolean "29.1") ;; xselect.c (x-select-enable-clipboard-manager killing boolean "24.1") ;; xsettings.c @@ -870,6 +871,8 @@ since it could result in memory overflow and make Emacs crash." ((or (equal "scroll-bar-adjust-thumb-portion" (symbol-name symbol)) (equal "x-scroll-event-delta-factor" + (symbol-name symbol)) + (equal "x-dnd-disable-motif-drag" (symbol-name symbol))) (featurep 'x)) ((string-match "\\`x-" (symbol-name symbol)) diff --git a/src/xterm.c b/src/xterm.c index 2bbc9f3d0c6..c9e26181912 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14053,6 +14053,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -14092,6 +14093,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -14117,7 +14119,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) if (target != None && x_dnd_last_protocol_version != -1) x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_protocol_version); - else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)) + else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -14148,7 +14151,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) 0 #endif ); - else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) + else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -15875,6 +15879,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -15914,6 +15919,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -15960,7 +15966,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (target != None && x_dnd_last_protocol_version != -1) x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_protocol_version); - else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)) + else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -15987,7 +15994,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_selection_timestamp, x_dnd_wanted_action, 0, event->xmotion.state); - else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) + else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -17454,6 +17462,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -17493,6 +17502,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); else if (x_dnd_last_seen_window != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)) { if (!x_dnd_motif_setup_p) @@ -17541,7 +17551,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (target != None && x_dnd_last_protocol_version != -1) x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_protocol_version); - else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)) + else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -17581,7 +17592,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_wanted_action, 0, dnd_state); } - else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None) + else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None + && !x_dnd_disable_motif_drag) { if (!x_dnd_motif_setup_p) xm_setup_drag_info (dpyinfo, x_dnd_frame); @@ -24906,6 +24918,13 @@ during a drag-and-drop session, to work around broken implementations of Motif. */); x_dnd_fix_motif_leave = true; + DEFVAR_BOOL ("x-dnd-disable-motif-drag", x_dnd_disable_motif_drag, + doc: /* Disable the Motif drag protocol during DND. +This reduces network usage, but also means you can no longer scroll +around inside the Motif window underneath the cursor during +drag-and-drop. */); + x_dnd_disable_motif_drag = false; + DEFVAR_LISP ("x-dnd-movement-function", Vx_dnd_movement_function, doc: /* Function called upon mouse movement on a frame during drag-and-drop. It should either be nil, or accept two arguments FRAME and POSITION, From d8a47823103da803b8274d790527f48d85a3f9b4 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 02:52:16 +0000 Subject: [PATCH 0056/1028] Fix stipple bitmap caching on Haiku * src/image.c (image_create_bitmap_from_file): Set file name on the bitmap rec on Haiku. --- src/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/image.c b/src/image.c index 6cd0aa48cfc..0c14173d833 100644 --- a/src/image.c +++ b/src/image.c @@ -781,7 +781,7 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].depth = 1; - dpyinfo->bitmaps[id - 1].file = NULL; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); dpyinfo->bitmaps[id - 1].height = height; dpyinfo->bitmaps[id - 1].width = width; dpyinfo->bitmaps[id - 1].refcount = 1; From 09866bb019d005ac5a8c475fe0b173fa35228d11 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 07:54:54 +0000 Subject: [PATCH 0057/1028] Use default external browser by default on Haiku * lisp/net/browse-url.el (browse-url-default-browser): Use that by default on Haiku. (browse-url-default-haiku-browser): New function. * src/haiku_support.cc (be_roster_launch): * src/haiku_support.h: New function. Update prototypes. * src/haikuselect.c (haiku_message_to_lisp): Encode and decode files correctly. (haiku_lisp_to_message): Encode and decode files correctly. (Fhaiku_roster_launch): New function. (syms_of_haikuselect): Update defsubrs. --- lisp/net/browse-url.el | 20 ++++++++++ src/haiku_support.cc | 34 +++++++++++++++++ src/haiku_support.h | 2 + src/haikuselect.c | 87 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 141 insertions(+), 2 deletions(-) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 66898d77073..c563a27ac85 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1019,6 +1019,8 @@ instead of `browse-url-new-window-flag'." 'browse-url-default-windows-browser) ((memq system-type '(darwin)) 'browse-url-default-macosx-browser) + ((featurep 'haiku) + 'browse-url-default-haiku-browser) ((browse-url-can-use-xdg-open) 'browse-url-xdg-open) ;;; ((executable-find browse-url-gnome-moz-program) 'browse-url-gnome-moz) ((executable-find browse-url-mozilla-program) 'browse-url-mozilla) @@ -1239,6 +1241,24 @@ The optional argument NEW-WINDOW is not used." (function-put 'browse-url-webpositive 'browse-url-browser-kind 'external) +(declare-function haiku-roster-launch "haikuselect.c") + +;;;###autoload +(defun browse-url-default-haiku-browser (url &optional _new-window) + "Browse URL with the system default browser. +Default to the URL around or before point." + (interactive (browse-url-interactive-arg "URL: ")) + (setq url (browse-url-encode-url url)) + (let* ((scheme (save-match-data + (if (string-match "\\(.+\\):/" url) + (match-string 1 url) + "http"))) + (mime (concat "application/x-vnd.Be.URL." scheme))) + (haiku-roster-launch mime (vector url)))) + +(function-put 'browse-url-default-haiku-browser + 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-emacs (url &optional same-window) "Ask Emacs to load URL into a buffer and show it in another window. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 27a676dd31c..6b4951e139a 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #include #include @@ -5071,3 +5072,36 @@ BWindow_set_sticky (void *window, bool sticky) w->UnlockLooper (); } } + +status_t +be_roster_launch (const char *type, const char *file, char **cargs, + ptrdiff_t nargs, void *message, team_id *team_id) +{ + BEntry entry; + entry_ref ref; + + if (type) + { + if (message) + return be_roster->Launch (type, (BMessage *) message, + team_id); + + return be_roster->Launch (type, (nargs > INT_MAX + ? INT_MAX : nargs), + cargs, team_id); + } + + if (entry.SetTo (file) != B_OK) + return B_ERROR; + + if (entry.GetRef (&ref) != B_OK) + return B_ERROR; + + if (message) + return be_roster->Launch (&ref, (BMessage *) message, + team_id); + + return be_roster->Launch (&ref, (nargs > INT_MAX + ? INT_MAX : nargs), + cargs, team_id); +} diff --git a/src/haiku_support.h b/src/haiku_support.h index eaca7a9bad7..416c717546f 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -690,6 +690,8 @@ extern bool be_select_font (void (*) (void), bool (*) (void), int *, bool, int, int, int); extern int be_find_font_indices (struct haiku_font_pattern *, int *, int *); +extern status_t be_roster_launch (const char *, const char *, char **, + ptrdiff_t, void *, team_id *); #ifdef __cplusplus } diff --git a/src/haikuselect.c b/src/haikuselect.c index a186acc66ff..6d62f395c16 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -275,7 +275,7 @@ haiku_message_to_lisp (void *message) if (!pbuf) memory_full (SIZE_MAX); - t1 = build_string (pbuf); + t1 = DECODE_FILE (build_string (pbuf)); free (pbuf); break; @@ -526,7 +526,8 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) case 'RREF': CHECK_STRING (data); - if (be_add_refs_data (message, SSDATA (name), SSDATA (data)) + if (be_add_refs_data (message, SSDATA (name), + SSDATA (ENCODE_FILE (data))) && haiku_signal_invalid_refs) signal_error ("Invalid file name", data); break; @@ -799,6 +800,87 @@ ignored if it is dropped on top of FRAME. */) return unbind_to (idx, Qnil); } +DEFUN ("haiku-roster-launch", Fhaiku_roster_launch, Shaiku_roster_launch, + 2, 2, 0, + doc: /* Launch an application associated with FILE-OR-TYPE. +Return the process ID of the application, or nil if no application was +launched. + +FILE-OR-TYPE can either be a string denoting a MIME type, or a list +with one argument FILE, denoting a file whose associated application +will be launched. + +ARGS can either be a vector of strings containing the arguments that +will be passed to the application, or a system message in the form +accepted by `haiku-drag-message' that will be sent to the application +after it starts. */) + (Lisp_Object file_or_type, Lisp_Object args) +{ + char **cargs; + char *type, *file; + team_id team_id; + status_t rc; + ptrdiff_t i, nargs; + Lisp_Object tem; + void *message; + specpdl_ref depth; + + type = NULL; + file = NULL; + cargs = NULL; + message = NULL; + nargs = 0; + depth = SPECPDL_INDEX (); + + USE_SAFE_ALLOCA; + + if (STRINGP (file_or_type)) + SAFE_ALLOCA_STRING (type, file_or_type); + else + { + CHECK_LIST (file_or_type); + tem = XCAR (file_or_type); + + CHECK_STRING (tem); + SAFE_ALLOCA_STRING (file, ENCODE_FILE (tem)); + CHECK_LIST_END (XCDR (file_or_type), file_or_type); + } + + if (VECTORP (args)) + { + nargs = ASIZE (args); + cargs = SAFE_ALLOCA (nargs * sizeof *cargs); + + for (i = 0; i < nargs; ++i) + { + tem = AREF (args, i); + CHECK_STRING (tem); + maybe_quit (); + + cargs[i] = SAFE_ALLOCA (SBYTES (tem) + 1); + memcpy (cargs[i], SDATA (tem), SBYTES (tem) + 1); + } + } + else + { + message = be_create_simple_message (); + + record_unwind_protect_ptr (BMessage_delete, message); + haiku_lisp_to_message (args, message); + } + + block_input (); + rc = be_roster_launch (type, file, cargs, nargs, message, + &team_id); + unblock_input (); + + if (rc == B_OK) + return SAFE_FREE_UNBIND_TO (depth, + make_uint (team_id)); + + return SAFE_FREE_UNBIND_TO (depth, Qnil); +} + static Lisp_Object haiku_note_drag_motion_1 (void *data) { @@ -860,6 +942,7 @@ used to retrieve the current position of the mouse. */); defsubr (&Shaiku_selection_put); defsubr (&Shaiku_selection_owner_p); defsubr (&Shaiku_drag_message); + defsubr (&Shaiku_roster_launch); haiku_dnd_frame = NULL; } From 52a27a67c1f501898bdb13841ce07609bbe4772e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 08:22:03 +0000 Subject: [PATCH 0058/1028] Fix file-based launching on Haiku * src/haikuselect.c (Fhaiku_roster_launch): Canonicalize file names before using them. --- src/haikuselect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/haikuselect.c b/src/haikuselect.c index 6d62f395c16..8ce71822983 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -821,7 +821,7 @@ after it starts. */) team_id team_id; status_t rc; ptrdiff_t i, nargs; - Lisp_Object tem; + Lisp_Object tem, canonical; void *message; specpdl_ref depth; @@ -840,9 +840,10 @@ after it starts. */) { CHECK_LIST (file_or_type); tem = XCAR (file_or_type); + canonical = Fexpand_file_name (tem, Qnil); CHECK_STRING (tem); - SAFE_ALLOCA_STRING (file, ENCODE_FILE (tem)); + SAFE_ALLOCA_STRING (file, ENCODE_FILE (canonical)); CHECK_LIST_END (XCDR (file_or_type), file_or_type); } From 74cc3b525ff9bd939875ce26c95b7a058426f5e7 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 9 May 2022 11:46:56 +0200 Subject: [PATCH 0059/1028] Fix doc string references to tags-loop-continue * lisp/vc/vc-dir.el (vc-dir-search, vc-dir-query-replace-regexp): Fix reference to obsolete tags-loop-continue (bug#55311). --- lisp/vc/vc-dir.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 18f5b07a7f4..9cf6422de00 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -924,7 +924,7 @@ system." "Search through all marked files for a match for REGEXP. For marked directories, use the files displayed from those directories. Stops when a match is found. -To continue searching for next match, use command \\[tags-loop-continue]." +To continue searching for next match, use command \\[fileloop-continue]." (interactive "sSearch marked files (regexp): ") (tags-search regexp (mapcar #'car (vc-dir-marked-only-files-and-states)))) @@ -940,7 +940,7 @@ DEL or `n' to skip and go to the next match. For more directions, type \\[help-command] at that time. If you exit (\\[keyboard-quit], RET or q), you can resume the query replace -with the command \\[tags-loop-continue]." +with the command \\[fileloop-continue]." ;; FIXME: this is almost a copy of `dired-do-query-replace-regexp'. This ;; should probably be made generic and used in both places instead of ;; duplicating it here. From 177718bc6df79ee93656e20c5b25b94923040dab Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 9 May 2022 11:57:46 +0200 Subject: [PATCH 0060/1028] Update string-to-number documentation to bignum Emacs * doc/lispref/strings.texi (String Conversion): string-to-number no longer converts integers to floating point numbers (bug#55334). --- doc/lispref/strings.texi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 6a6b756fbe5..2810f686eb7 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -853,9 +853,7 @@ between 2 and 16 (inclusive), and integers are converted in that base. If @var{base} is @code{nil}, then base ten is used. Floating-point conversion only works in base ten; we have not implemented other radices for floating-point numbers, because that would be much more -work and does not seem useful. If @var{string} looks like an integer -but its value is too large to fit into a Lisp integer, -@code{string-to-number} returns a floating-point result. +work and does not seem useful. The parsing skips spaces and tabs at the beginning of @var{string}, then reads as much of @var{string} as it can interpret as a number in From 6b6b2c11edc46517a3a1ac9f869bdd40adf8a3df Mon Sep 17 00:00:00 2001 From: Vladimir Nikishkin Date: Mon, 9 May 2022 12:03:33 +0200 Subject: [PATCH 0061/1028] Add new user option table-latex-environment * lisp/textmodes/table.el (table-latex-environment): New user option (bug#55333). (table--generate-source-prologue): Use it. --- etc/NEWS | 6 ++++++ lisp/textmodes/table.el | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 5860010f022..92a956c176d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2135,6 +2135,12 @@ This holds the value of the previous call to 'set-locale-environment'. This macro can be used to change the locale temporarily while executing code. +** table.el + +--- +*** New user option 'table-latex-environment'. +This allows switching between "table" and "tabular". + ** Tabulated List Mode +++ diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 2175900194c..5093a994423 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -753,6 +753,16 @@ the cell contents dynamically." :type 'string :group 'table) +(defcustom table-latex-environment "tabular" + "Which tabular-compatible environment to use when generating latex. +\"tabular\" and \"longtable\" are known to work." + :tag "Latex environment used to export tables" + :type '(choice + (const :tag "tabular" "tabular") + (const :tag "longtable" "longtable") + string) + :version "29.1") + (defcustom table-cals-thead-rows 1 "Number of top rows to become header rows in CALS table." :tag "CALS Header Rows" @@ -3025,7 +3035,8 @@ CALS (DocBook DTD): ""))) ((eq language 'latex) (insert (format "%% This LaTeX table template is generated by emacs %s\n" emacs-version) - "\\begin{tabular}{|" (apply #'concat (make-list (length col-list) "l|")) "}\n" + "\\begin{" table-latex-environment "}{|" + (apply #'concat (make-list (length col-list) "l|")) "}\n" "\\hline\n")) ((eq language 'cals) (insert (format "\n" emacs-version) @@ -3051,7 +3062,7 @@ CALS (DocBook DTD): ((eq language 'html) (insert "\n")) ((eq language 'latex) - (insert "\\end{tabular}\n")) + (insert "\\end{" table-latex-environment "}\n")) ((eq language 'cals) (set-marker-insertion-type (table-get-source-info 'colspec-marker) t) ;; insert before (save-excursion From d2a5631552cbe036c46111101c0570135e81fc56 Mon Sep 17 00:00:00 2001 From: Arash Esbati Date: Mon, 9 May 2022 12:10:10 +0200 Subject: [PATCH 0062/1028] Update AUCTeX FAQ entry * doc/misc/efaq-w32.texi (AUCTeX): AUCTeX project isn't providing pre-compiled versions for Windows anymore (bug#55330). --- doc/misc/efaq-w32.texi | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index 20dcb07ed76..3b48fb1453d 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -1754,10 +1754,9 @@ A number of implementations are listed on the AUCTeX is an Emacs package for writing LaTeX files, which also includes preview-latex, an Emacs mode for previewing the formatted -contents of LaTeX documents. Pre-compiled versions for Windows are -available from -@uref{https://www.gnu.org/software/auctex/download-for-windows.html, the -AUCTeX site}. +contents of LaTeX documents. AUCTeX is available from +@uref{https://elpa.gnu.org, GNU ELPA} and can be installed with the +command @kbd{M-x list-packages}. @node Spell check @section How do I perform spell checks? From 2e949031160d769bbac941c064b825a5c578afc5 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 9 May 2022 12:37:11 +0200 Subject: [PATCH 0063/1028] Add meta navigation keys to outline-minor-mode-cycle-map * lisp/outline.el (outline-minor-mode-cycle-map): Add meta navigate keys (bug#41129). --- lisp/outline.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/outline.el b/lisp/outline.el index 7fd43195cc0..81e312ee019 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -215,6 +215,10 @@ This option is only in effect when `outline-minor-mode-cycle' is non-nil." (let ((map (make-sparse-keymap))) (outline-minor-mode-cycle--bind map (kbd "TAB") #'outline-cycle) (outline-minor-mode-cycle--bind map (kbd "") #'outline-cycle-buffer) + (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-promote) + (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-demote) + (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-move-subtree-up) + (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-move-subtree-down) map) "Keymap used by `outline-minor-mode-cycle'.") From 5921e31c45e2d0b2b2ee4e03b21127abb3c30944 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 11:10:13 +0000 Subject: [PATCH 0064/1028] Respect display scale factor drawing underwaves on Haiku * src/haikuterm.c (haiku_get_scale_factor): New function. (haiku_draw_underwave): Apply said factor. --- src/haikuterm.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index 265d3fbf5e6..bfa6be225ac 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -723,22 +723,41 @@ haiku_draw_relief_rect (struct glyph_string *s, BView_EndClip (view); } +static void +haiku_get_scale_factor (int *scale_x, int *scale_y) +{ + struct haiku_display_info *dpyinfo = x_display_list; + + if (dpyinfo->resx > 96) + *scale_x = floor (dpyinfo->resx / 96); + if (dpyinfo->resy > 96) + *scale_y = floor (dpyinfo->resy / 96); +} + static void haiku_draw_underwave (struct glyph_string *s, int width, int x) { - int wave_height = 3, wave_length = 2; - int y, dx, dy, odd, xmax; + int wave_height, wave_length; + int y, dx, dy, odd, xmax, scale_x, scale_y; float ax, ay, bx, by; - void *view = FRAME_HAIKU_VIEW (s->f); + void *view; + + scale_x = 4; + scale_y = 4; + haiku_get_scale_factor (&scale_x, &scale_y); + wave_height = 3 * scale_y; + wave_length = 2 * scale_x; dx = wave_length; dy = wave_height - 1; y = s->ybase - wave_height + 3; xmax = x + width; + view = FRAME_HAIKU_VIEW (s->f); BView_StartClip (view); haiku_clip_to_string (s); BView_ClipToRect (view, x, y, width, wave_height); + ax = x - ((int) (x) % dx) + (float) 0.5; bx = ax + dx; odd = (int) (ax / dx) % 2; @@ -749,6 +768,8 @@ haiku_draw_underwave (struct glyph_string *s, int width, int x) else by += dy; + BView_SetPenSize (view, scale_y); + while (ax <= xmax) { BView_StrokeLine (view, ax, ay, bx, by); @@ -756,6 +777,8 @@ haiku_draw_underwave (struct glyph_string *s, int width, int x) bx += dx, by = y + 0.5 + odd * dy; odd = !odd; } + + BView_SetPenSize (view, 1); BView_EndClip (view); } From e195ac3df06cc4e805f3964f593234e5b5d70236 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 11:21:15 +0000 Subject: [PATCH 0065/1028] ; * src/haikuterm.c (haiku_draw_underwave): Fix default scale. --- src/haikuterm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index bfa6be225ac..747c8e4275f 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -742,8 +742,8 @@ haiku_draw_underwave (struct glyph_string *s, int width, int x) float ax, ay, bx, by; void *view; - scale_x = 4; - scale_y = 4; + scale_x = 1; + scale_y = 1; haiku_get_scale_factor (&scale_x, &scale_y); wave_height = 3 * scale_y; wave_length = 2 * scale_x; From 60a15fae0245e303e012408de49be87dc43af152 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 9 May 2022 13:38:40 +0200 Subject: [PATCH 0066/1028] Copy edits for the regexp sections in the manuals * doc/lispref/searching.texi (Regexp Backslash): * doc/emacs/search.texi (Regexps, Regexp Backslash): Copy edits from Jay Bingham (bug#41970). --- doc/emacs/search.texi | 56 +++++++++++++++++++------------------- doc/lispref/searching.texi | 32 +++++++++++----------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index c990f5d766a..81f4d26e033 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -1027,24 +1027,9 @@ you search for @samp{a.*?$} against the text @samp{abbab} followed by a newline, it matches the whole string. Since it @emph{can} match starting at the first @samp{a}, it does. -@item @kbd{\@{@var{n}\@}} -is a postfix operator specifying @var{n} repetitions---that is, the -preceding regular expression must match exactly @var{n} times in a -row. For example, @samp{x\@{4\@}} matches the string @samp{xxxx} and -nothing else. - -@item @kbd{\@{@var{n},@var{m}\@}} -is a postfix operator specifying between @var{n} and @var{m} -repetitions---that is, the preceding regular expression must match at -least @var{n} times, but no more than @var{m} times. If @var{m} is -omitted, then there is no upper limit, but the preceding regular -expression must match at least @var{n} times.@* @samp{\@{0,1\@}} is -equivalent to @samp{?}. @* @samp{\@{0,\@}} is equivalent to -@samp{*}. @* @samp{\@{1,\@}} is equivalent to @samp{+}. - @item @kbd{[ @dots{} ]} -is a @dfn{character set}, beginning with @samp{[} and terminated by -@samp{]}. +is a @dfn{a set of alternative characters}, beginning with @samp{[} +and terminated by @samp{]}. In the simplest case, the characters between the two brackets are what this set can match. Thus, @samp{[ad]} matches either one @samp{a} or @@ -1132,12 +1117,12 @@ to depend on this behavior; it is better to quote the special character anyway, regardless of where it appears. As a @samp{\} is not special inside a character alternative, it can -never remove the special meaning of @samp{-} or @samp{]}. So you -should not quote these characters when they have no special meaning -either. This would not clarify anything, since backslashes can -legitimately precede these characters where they @emph{have} special -meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string syntax), -which matches any single character except a backslash. +never remove the special meaning of @samp{-}, @samp{^} or @samp{]}. +So you should not quote these characters when they have no special +meaning either. This would not clarify anything, since backslashes +can legitimately precede these characters where they @emph{have} +special meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string +syntax), which matches any single character except a backslash. @node Regexp Backslash @section Backslash in Regular Expressions @@ -1202,11 +1187,11 @@ matches the same text that matched the @var{d}th occurrence of a @samp{\( @dots{} \)} construct. This is called a @dfn{back reference}. -After the end of a @samp{\( @dots{} \)} construct, the matcher remembers -the beginning and end of the text matched by that construct. Then, -later on in the regular expression, you can use @samp{\} followed by the -digit @var{d} to mean ``match the same text matched the @var{d}th time -by the @samp{\( @dots{} \)} construct''. +After the end of a @samp{\( @dots{} \)} construct, the matcher +remembers the beginning and end of the text matched by that construct. +Then, later on in the regular expression, you can use @samp{\} +followed by the digit @var{d} to mean ``match the same text matched +the @var{d}th @samp{\( @dots{} \)} construct''. The strings matching the first nine @samp{\( @dots{} \)} constructs appearing in a regular expression are assigned numbers 1 through 9 in @@ -1223,6 +1208,21 @@ If a particular @samp{\( @dots{} \)} construct matches more than once (which can easily happen if it is followed by @samp{*}), only the last match is recorded. +@item @kbd{\@{@var{m}\@}} +is a postfix operator specifying @var{m} repetitions---that is, the +preceding regular expression must match exactly @var{m} times in a +row. For example, @samp{x\@{4\@}} matches the string @samp{xxxx} and +nothing else. + +@item @kbd{\@{@var{m},@var{n}\@}} +is a postfix operator specifying between @var{m} and @var{n} +repetitions---that is, the preceding regular expression must match at +least @var{m} times, but no more than @var{n} times. If @var{n} is +omitted, then there is no upper limit, but the preceding regular +expression must match at least @var{m} times.@* @samp{\@{0,1\@}} is +equivalent to @samp{?}. @* @samp{\@{0,\@}} is equivalent to +@samp{*}. @* @samp{\@{1,\@}} is equivalent to @samp{+}. + @item \` matches the empty string, but only at the beginning of the string or buffer (or its accessible portion) being matched against. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index c9828f9c868..976f8b4b4bd 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -549,12 +549,12 @@ can act. It is poor practice to depend on this behavior; quote the special character anyway, regardless of where it appears. As a @samp{\} is not special inside a character alternative, it can -never remove the special meaning of @samp{-} or @samp{]}. So you -should not quote these characters when they have no special meaning -either. This would not clarify anything, since backslashes can -legitimately precede these characters where they @emph{have} special -meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string syntax), -which matches any single character except a backslash. +never remove the special meaning of @samp{-}, @samp{^} or @samp{]}. +So you should not quote these characters when they have no special +meaning either. This would not clarify anything, since backslashes +can legitimately precede these characters where they @emph{have} +special meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string +syntax), which matches any single character except a backslash. In practice, most @samp{]} that occur in regular expressions close a character alternative and hence are special. However, occasionally a @@ -823,21 +823,21 @@ the characters that stand for them. matches any character whose syntax is not @var{code}. @cindex category, regexp search for -@item \c@var{c} -matches any character whose category is @var{c}. Here @var{c} is a -character that represents a category: thus, @samp{c} for Chinese -characters or @samp{g} for Greek characters in the standard category -table. You can see the list of all the currently defined categories -with @kbd{M-x describe-categories @key{RET}}. You can also define -your own categories in addition to the standard ones using the +@item \c@var{code} +matches any character whose category is @var{code}. Here @var{code} +is a character that represents a category: thus, @samp{code} for +Chinese characters or @samp{g} for Greek characters in the standard +category table. You can see the list of all the currently defined +categories with @kbd{M-x describe-categories @key{RET}}. You can also +define your own categories in addition to the standard ones using the @code{define-category} function (@pxref{Categories}). -@item \C@var{c} -matches any character whose category is not @var{c}. +@item \C@var{code} +matches any character whose category is not @var{code}. @end table The following regular expression constructs match the empty string---that is, -they don't use up any characters---but whether they match depends on the +they don't consume any characters---but whether they match depends on the context. For all, the beginning and end of the accessible portion of the buffer are treated as if they were the actual beginning and end of the buffer. From d377b396432412b06647eef01f837126982f3e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Mon, 9 May 2022 12:29:59 +0100 Subject: [PATCH 0067/1028] Allow non-interactive use of eldoc-doc-buffer * lisp/emacs-lisp/eldoc.el (eldoc-doc-buffer): Allow non-interactive use. (Version): Bump minor. --- lisp/emacs-lisp/eldoc.el | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 74ffeb166d4..0b8078579cc 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -5,7 +5,7 @@ ;; Author: Noah Friedman ;; Keywords: extensions ;; Created: 1995-10-06 -;; Version: 1.11.1 +;; Version: 1.12.0 ;; Package-Requires: ((emacs "26.3")) ;; This is a GNU ELPA :core package. Avoid functionality that is not @@ -464,19 +464,22 @@ directly from the user or from ElDoc's automatic mechanisms'.") (defvar eldoc--doc-buffer-docs nil "Documentation items in `eldoc--doc-buffer'.") -(defun eldoc-doc-buffer () - "Display ElDoc documentation buffer. +(defun eldoc-doc-buffer (&optional interactive) + "Get or display ElDoc documentation buffer. -This holds the results of the last documentation request." - (interactive) +The buffer holds the results of the last documentation request. +If INTERACTIVE, display it. Else, return said buffer." + (interactive (list t)) (unless (buffer-live-p eldoc--doc-buffer) (user-error (format "ElDoc buffer doesn't exist, maybe `%s' to produce one." (substitute-command-keys "\\[eldoc]")))) (with-current-buffer eldoc--doc-buffer - (rename-buffer (replace-regexp-in-string "^ *" "" - (buffer-name))) - (display-buffer (current-buffer)))) + (cond (interactive + (rename-buffer (replace-regexp-in-string "^ *" "" + (buffer-name))) + (display-buffer (current-buffer))) + (t (current-buffer))))) (defun eldoc--format-doc-buffer (docs) "Ensure DOCS are displayed in an *eldoc* buffer." From 8a8b81c1e48a45ca187623f3c45d0c332bcd45ac Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 9 May 2022 14:06:24 +0200 Subject: [PATCH 0068/1028] Make ediff-show-diff-output work better on unsaved buffers * lisp/vc/ediff-util.el (ediff-show-diff-output): Make the `D' command work on unsaved buffers without a prefix (bug#45016). --- lisp/vc/ediff-util.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index b41def2aff3..f140f145593 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -3431,6 +3431,9 @@ Without an argument, it saves customized diff argument, if available )) (defun ediff-show-diff-output (arg) + "With prefix argument ARG, show plain diff output. +Without an argument, it saves customized diff argument, if available +(and plain output, if customized output was not generated)." (interactive "P") (ediff-barf-if-not-control-buffer) (ediff-compute-custom-diffs-maybe) @@ -3438,7 +3441,10 @@ Without an argument, it saves customized diff argument, if available (ediff-skip-unsuitable-frames ' ok-unsplittable)) (let ((buf (cond ((and arg (ediff-buffer-live-p ediff-diff-buffer)) ediff-diff-buffer) - ((ediff-buffer-live-p ediff-custom-diff-buffer) + ((and (ediff-buffer-live-p ediff-custom-diff-buffer) + ;; We may not have gotten a custom output if + ;; we're working on unsaved buffers. + (> (buffer-size ediff-custom-diff-buffer) 0)) ediff-custom-diff-buffer) ((ediff-buffer-live-p ediff-diff-buffer) ediff-diff-buffer) From 3eb82181fc328e6503b6cff5321f201322489d3f Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 20:15:41 +0800 Subject: [PATCH 0069/1028] Fix scroll optimizations being enabled for some rows with stipples * src/dispnew.c (update_text_area): New parameter `partial_p'. Set it if not enough glyphs were drawn to determine if a row doesn't have a stipple. (update_window_line): Preserve current_row->stipple_p in that case, after making the desired row current. * src/xterm.c (x_draw_fringe_bitmap): Set row->stipple. --- src/dispnew.c | 32 +++++++++++++++++++++++++++++--- src/xterm.c | 5 ++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/dispnew.c b/src/dispnew.c index c49c38cba86..795c928bc13 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3907,7 +3907,8 @@ update_marginal_area (struct window *w, struct glyph_row *updated_row, Value is true if display has changed. */ static bool -update_text_area (struct window *w, struct glyph_row *updated_row, int vpos) +update_text_area (struct window *w, struct glyph_row *updated_row, int vpos, + bool *partial_p) { struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); @@ -4013,6 +4014,13 @@ update_text_area (struct window *w, struct glyph_row *updated_row, int vpos) { x += desired_glyph->pixel_width; ++desired_glyph, ++current_glyph, ++i; + + /* Say that only a partial update was performed of + the current row (i.e. not all the glyphs were + drawn). This is used to preserve the stipple_p + flag of the current row inside + update_window_line. */ + *partial_p = true; } /* Consider the case that the current row contains "xxx @@ -4084,9 +4092,15 @@ update_text_area (struct window *w, struct glyph_row *updated_row, int vpos) rif->write_glyphs (w, updated_row, start, TEXT_AREA, i - start_hpos); changed_p = 1; + *partial_p = true; } } + /* This means we will draw from the start, so no partial update + is being performed. */ + if (!i) + *partial_p = false; + /* Write the rest. */ if (i < desired_row->used[TEXT_AREA]) { @@ -4159,7 +4173,9 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); - bool changed_p = 0; + + /* partial_p is true if not all of desired_row was drawn. */ + bool changed_p = 0, partial_p = 0, was_stipple; /* A row can be completely invisible in case a desired matrix was built with a vscroll and then make_cursor_line_fully_visible shifts @@ -4183,7 +4199,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) } /* Update the display of the text area. */ - if (update_text_area (w, desired_row, vpos)) + if (update_text_area (w, desired_row, vpos, &partial_p)) { changed_p = 1; if (current_row->mouse_face_p) @@ -4212,7 +4228,17 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) } /* Update current_row from desired_row. */ + was_stipple = current_row->stipple_p; make_current (w->desired_matrix, w->current_matrix, vpos); + + /* If only a partial update was performed, any stipple already + displayed in MATRIX_ROW (w->current_matrix, vpos) might still be + there, so don't hurry to clear that flag if it's not in + desired_row. */ + + if (partial_p && was_stipple) + current_row->stipple_p = true; + return changed_p; } diff --git a/src/xterm.c b/src/xterm.c index c9e26181912..10d268dc93f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5750,7 +5750,8 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row) } static void -x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p) +x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, + struct draw_fringe_bitmap_params *p) { struct frame *f = XFRAME (WINDOW_FRAME (w)); Display *display = FRAME_X_DISPLAY (f); @@ -5772,6 +5773,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny, true); XSetFillStyle (display, face->gc, FillSolid); + + row->stipple_p = true; } else { From 83e2e961b013fe086072fd8dbc7eb8d17cc586d1 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 20:23:20 +0800 Subject: [PATCH 0070/1028] Fix reading faces with a default value that is a symbol * lisp/faces.el (read-face-name): Don't try to intern face if it is already a symbol. --- lisp/faces.el | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lisp/faces.el b/lisp/faces.el index 1ada05a7b8b..2d4b7761be6 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1148,13 +1148,18 @@ returned. Otherwise, DEFAULT is returned verbatim." nil t nil 'face-name-history default)) ;; Ignore elements that are not faces ;; (for example, because DEFAULT was "all faces") - (if (facep face) (push (intern face) faces))) + (if (facep face) (push (if (stringp face) + (intern face) + face) + faces))) (nreverse faces)) (let ((face (completing-read prompt (completion-table-in-turn nonaliasfaces aliasfaces) nil t nil 'face-name-history defaults))) - (if (facep face) (intern face))))))) + (when (facep face) (if (stringp face) + (intern face) + face))))))) ;; Not defined without X, but behind window-system test. (defvar x-bitmap-file-path) From 825b5435826ff42dfe831ce5dae1d33dbbe82b15 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 9 May 2022 15:45:08 +0300 Subject: [PATCH 0071/1028] ; * lisp/vc/ediff-util.el (ediff-show-diff-output): Doc fix. --- lisp/vc/ediff-util.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index f140f145593..040a9a63c5a 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -3432,7 +3432,7 @@ Without an argument, it saves customized diff argument, if available (defun ediff-show-diff-output (arg) "With prefix argument ARG, show plain diff output. -Without an argument, it saves customized diff argument, if available +Without an argument, save the customized diff argument, if available (and plain output, if customized output was not generated)." (interactive "P") (ediff-barf-if-not-control-buffer) From f54a71fa279a87aa1d9e9a9894224305cbc330af Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 9 May 2022 12:45:05 +0000 Subject: [PATCH 0072/1028] * src/haikuterm.c (haiku_draw_fringe_bitmap): Set stipple flag. --- src/haikuterm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/haikuterm.c b/src/haikuterm.c index 747c8e4275f..802d7d2ac2f 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -2589,6 +2589,8 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); BView_EndClip (view); + + row->stipple_p = true; } } From 04b1f779f2e37cea854b40f0cc8e7f6221dcf6fd Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 9 May 2022 16:02:58 +0300 Subject: [PATCH 0073/1028] ; Fix recent changes in regexp documentation * doc/lispref/searching.texi (Regexp Backslash): * doc/emacs/search.texi (Regexps): Fix typo and wording. --- doc/emacs/search.texi | 15 +++++++++------ doc/lispref/searching.texi | 17 +++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index 81f4d26e033..b123ef83a16 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -1027,9 +1027,11 @@ you search for @samp{a.*?$} against the text @samp{abbab} followed by a newline, it matches the whole string. Since it @emph{can} match starting at the first @samp{a}, it does. +@cindex set of alternative characters, in regular expressions +@cindex character set, in regular expressions @item @kbd{[ @dots{} ]} -is a @dfn{a set of alternative characters}, beginning with @samp{[} -and terminated by @samp{]}. +is a @dfn{set of alternative characters}, or a @dfn{character set}, +beginning with @samp{[} and terminated by @samp{]}. In the simplest case, the characters between the two brackets are what this set can match. Thus, @samp{[ad]} matches either one @samp{a} or @@ -1046,9 +1048,10 @@ which matches any lower-case @acronym{ASCII} letter or @samp{$}, @samp{%} or period. As another example, @samp{[α-ωί]} matches all lower-case Greek letters. +@cindex character classes, in regular expressions You can also include certain special @dfn{character classes} in a character set. A @samp{[:} and balancing @samp{:]} enclose a -character class inside a character alternative. For instance, +character class inside a set of alternative characters. For instance, @samp{[[:alnum:]]} matches any letter or digit. @xref{Char Classes,,, elisp, The Emacs Lisp Reference Manual}, for a list of character classes. @@ -1116,10 +1119,10 @@ no preceding expression on which the @samp{*} can act. It is poor practice to depend on this behavior; it is better to quote the special character anyway, regardless of where it appears. -As a @samp{\} is not special inside a character alternative, it can +As a @samp{\} is not special inside a set of alternative characters, it can never remove the special meaning of @samp{-}, @samp{^} or @samp{]}. -So you should not quote these characters when they have no special -meaning either. This would not clarify anything, since backslashes +You should not quote these characters when they have no special +meaning. This would not clarify anything, since backslashes can legitimately precede these characters where they @emph{have} special meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string syntax), which matches any single character except a backslash. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index 976f8b4b4bd..21a2c6c51e4 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -550,8 +550,8 @@ special character anyway, regardless of where it appears. As a @samp{\} is not special inside a character alternative, it can never remove the special meaning of @samp{-}, @samp{^} or @samp{]}. -So you should not quote these characters when they have no special -meaning either. This would not clarify anything, since backslashes +You should not quote these characters when they have no special +meaning. This would not clarify anything, since backslashes can legitimately precede these characters where they @emph{have} special meaning, as in @samp{[^\]} (@code{"[^\\]"} for Lisp string syntax), which matches any single character except a backslash. @@ -825,12 +825,13 @@ matches any character whose syntax is not @var{code}. @cindex category, regexp search for @item \c@var{code} matches any character whose category is @var{code}. Here @var{code} -is a character that represents a category: thus, @samp{code} for -Chinese characters or @samp{g} for Greek characters in the standard -category table. You can see the list of all the currently defined -categories with @kbd{M-x describe-categories @key{RET}}. You can also -define your own categories in addition to the standard ones using the -@code{define-category} function (@pxref{Categories}). +is a character that represents a category: for example, in the standard +category table, @samp{c} stands for Chinese characters and @samp{g} +stands for Greek characters. You can see the list of all the +currently defined categories with @w{@kbd{M-x describe-categories +@key{RET}}}. You can also define your own categories in addition to +the standard ones using the @code{define-category} function +(@pxref{Categories}). @item \C@var{code} matches any character whose category is not @var{code}. From 0d32e33ed65c1f7884129e12fa75eaa5d3396c3b Mon Sep 17 00:00:00 2001 From: Protesilaos Stavrou Date: Mon, 9 May 2022 10:38:23 +0300 Subject: [PATCH 0074/1028] Shorten note about didactic space in TUTORIAL.el_GR (bug#55332) --- etc/tutorials/TUTORIAL.el_GR | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/etc/tutorials/TUTORIAL.el_GR b/etc/tutorials/TUTORIAL.el_GR index e001cc6cce6..b34fa5403c7 100644 --- a/etc/tutorials/TUTORIAL.el_GR +++ b/etc/tutorials/TUTORIAL.el_GR @@ -22,8 +22,7 @@ C-c. (Δύο χαρακτήρες.) Για να ακυρώσεις μια με Οι χαρακτήρες ">>" στο αριστερό περιθώριο δείχνουν οδηγίες για να δοκιμάσεις μια εντολή. Για παράδειγμα: <> -[Το μέσο της σελίδας παραμένει κενό για διδακτικούς σκοπούς. Το -κείμενο συνεχίζεται παρακάτω.] +[Κενό για διδακτικούς σκοπούς. Το κείμενο συνεχίζεται παρακάτω.] >> Τώρα πληκτρολόγησε C-v (δες επόμενη οθόνη) ώστε να κυλήσεις πιο κάτω στην παρούσα εκμάθηση. (Κάνε το, κρατώντας πατημένο το From c7bfb4841b684fdc92a1bb99e74a92ed4b515152 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 9 May 2022 16:08:10 +0300 Subject: [PATCH 0075/1028] ; * lisp/textmodes/table.el (table-latex-environment): Doc fix. --- lisp/textmodes/table.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 5093a994423..fc06c4c0da1 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -754,8 +754,10 @@ the cell contents dynamically." :group 'table) (defcustom table-latex-environment "tabular" - "Which tabular-compatible environment to use when generating latex. -\"tabular\" and \"longtable\" are known to work." + "Tabular-compatible environment to use when generating latex. +The value should be a string suitable for use as a LaTeX environment +that's compatible with the \"tabular\" protocol, such as \"tabular\" +and \"longtable\"." :tag "Latex environment used to export tables" :type '(choice (const :tag "tabular" "tabular") From 6fc54786c3bb797068675d7eb7b500fb990bd04a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 9 May 2022 16:28:22 +0300 Subject: [PATCH 0076/1028] ; Fix documentation of completion options * doc/emacs/mini.texi (Completion Commands, Completion Options): Improve and clarify the wording. --- doc/emacs/mini.texi | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index ad5701670eb..4e71793b66e 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -381,16 +381,16 @@ used with the completion list: @vindex minibuffer-completion-auto-choose @item M-@key{DOWN} @itemx M-@key{UP} -While in the minibuffer, these keys will navigate through the -completions displayed in the completions buffer. When +While in the minibuffer, these keys navigate through the completions +displayed in the completions buffer. When @code{minibuffer-completion-auto-choose} is non-@code{nil} (which is -the default), using these commands will automatically insert the -current completion candidate in the minibuffer. If this user option -is @code{nil}, the keys will navigate the same way as before, but -won't automatically insert the candidate in the minibuffer. Instead -you have to use the @kbd{M-@key{RET}} command to do that. With -a prefix argument, @kbd{C-u M-@key{RET}} inserts the currently active -candidate to the minibuffer, but doesn't exit the minibuffer. +the default), using these commands also inserts the current completion +candidate into the minibuffer. If +@code{minibuffer-completion-auto-choose} is @code{nil}, you can use +the @kbd{M-@key{RET}} command to insert the completion candidates into +the minibuffer. By default, that exits the minibuffer, but with a +prefix argument, @kbd{C-u M-@key{RET}} inserts the currently active +candidate without exiting the minibuffer. @findex switch-to-completions @item M-v @@ -408,8 +408,9 @@ ways (@pxref{Windows}). @itemx mouse-2 While in the completion list buffer, this chooses the completion at point (@code{choose-completion}). With a prefix argument, @kbd{C-u -@key{RET}} inserts the completion at point to the minibuffer, but -doesn't exit the minibuffer. +@key{RET}} inserts the completion at point into the minibuffer, but +doesn't exit the minibuffer---thus, you can change your mind and +choose another candidate. @findex next-completion @item @key{TAB} @@ -685,18 +686,19 @@ behavior only when there are @var{n} or fewer alternatives. @vindex completions-format When displaying completions, Emacs will normally pop up a new buffer to display the completions. The completions will by default be sorted -in rows horizontally, but this can be changed by customizing the -@code{completions-format} user option. If @code{vertical}, sort the -completions vertically in columns instead, and if @code{one-column}, -just use a single column. +horizontally, using as many columns as will fit in the window-width, +but this can be changed by customizing the @code{completions-format} +user option. If its value is @code{vertical}, Emacs will sort the +completions vertically instead, and if it's @code{one-column}, Emacs +will use just one column. @vindex completions-sort - The @code{completions-sort} user option controls how completions are -sorted in the @samp{*Completions*} buffer. The default is -@code{alphabetical} that sorts in alphabetical order. The value -@code{nil} disables sorting. It can also be a function which will be -called with the list of completions, and should return the list in the -desired order. + The @code{completions-sort} user option controls the order in which +the completions are sorted in the @samp{*Completions*} buffer. The +default is @code{alphabetical}, which sorts in alphabetical order. +The value @code{nil} disables sorting. The value can also be a +function, which will be called with the list of completions, and +should return the list in the desired order. @vindex completions-max-height When @code{completions-max-height} is non-@code{nil}, it limits the From 7b4bdf7b9b0f4c72dbd1b15f5d134d3176e53a8a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 9 May 2022 16:37:49 +0300 Subject: [PATCH 0077/1028] Remove the AUCTeX subsection from MS-Windows FAQ * doc/misc/efaq-w32.texi (AUCTeX): Remove the subsection, it is no longer useful. (Bug#55330) --- doc/misc/efaq-w32.texi | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index 3b48fb1453d..3a49f0a5da2 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -1742,22 +1742,6 @@ You will need an implementation of TeX for Windows. A number of implementations are listed on the @uref{http://www.tug.org/interest.html#free, TeX Users Group} website. -@menu -* AUCTeX:: -@end menu - -@node AUCTeX -@subsection AUCTeX -@cindex auctex, precompiled for Windows -@cindex latex -@cindex preview-latex - -AUCTeX is an Emacs package for writing LaTeX files, which also -includes preview-latex, an Emacs mode for previewing the formatted -contents of LaTeX documents. AUCTeX is available from -@uref{https://elpa.gnu.org, GNU ELPA} and can be installed with the -command @kbd{M-x list-packages}. - @node Spell check @section How do I perform spell checks? @cindex spell checking From 558286315c908a8be134bec0187c97ceac815b3e Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 9 May 2022 20:10:10 +0200 Subject: [PATCH 0078/1028] Improve Tramp tests * lisp/net/tramp-smb.el (tramp-smb-handle-copy-file): Handle compressed files. * lisp/net/tramp.el (tramp-skeleton-write-region): Handle encrypted VISIT file. (tramp-get-process-attributes): Add backward compatibility. * test/lisp/net/tramp-tests.el (with-connection-local-variables): Declare. (auto-save-file-name-transforms): Don't declare. (ert-resource-directory-format) (ert-resource-directory-trim-left-regexp) (ert-resource-directory-trim-right-regexp, ert-resource-directory) (ert-resource-file): Define if they don't exist. (tramp-test10-write-region-file-precious-flag) (tramp-test10-write-region-other-file-name-handler) (tramp-test31-interrupt-process, tramp-test31-signal-process) (tramp--test-async-shell-command) (tramp-test34-connection-local-variables) (tramp-test39-make-lock-file-name) (tramp-test39-detect-external-change): Extend tests. --- lisp/net/tramp-smb.el | 6 +- lisp/net/tramp.el | 11 ++-- test/lisp/net/tramp-tests.el | 106 +++++++++++++++++++++++++++++------ 3 files changed, 100 insertions(+), 23 deletions(-) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 968c1daccbf..8037c89829f 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -609,7 +609,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (if (tramp-tramp-file-p filename) filename newname)) 'file-missing filename)) - (if-let ((tmpfile (file-local-copy filename))) + ;; `file-local-copy' returns a file name also for a local file + ;; with `jka-compr-handler', so we cannot trust its result as + ;; indication for a remote file name. + (if-let ((tmpfile + (and (file-remote-p filename) (file-local-copy filename)))) ;; Remote filename. (condition-case err (rename-file tmpfile newname ok-if-already-exists) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index fec4ea68ec6..9413f7954f4 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3386,8 +3386,9 @@ BODY is the backend specific code." (lockname (file-truename (or ,lockname filename))) (handler (and (stringp ,visit) (let ((inhibit-file-name-handlers - (cons 'tramp-file-name-handler - inhibit-file-name-handlers)) + `(tramp-file-name-handler + tramp-crypt-file-name-handler + . inhibit-file-name-handlers)) (inhibit-file-name-operation 'write-region)) (find-file-name-handler ,visit 'write-region))))) (with-parsed-tramp-file-name filename nil @@ -4221,7 +4222,9 @@ Parsing the remote \"ps\" output is controlled by It is not guaranteed, that all process attributes as described in `process-attributes' are returned. The additional attribute `pid' shall be returned always." - (with-tramp-file-property vec "/" "process-attributes" + ;; Since Emacs 27.1. + (when (fboundp 'connection-local-criteria-for-default-directory) + (with-tramp-file-property vec "/" "process-attributes" (ignore-errors (with-temp-buffer (hack-connection-local-variables-apply @@ -4265,7 +4268,7 @@ It is not guaranteed, that all process attributes as described in (push (append res) result)) (forward-line)) ;; Return result. - result)))))) + result))))))) (defun tramp-handle-list-system-processes () "Like `list-system-processes' for Tramp files." diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 2d2bef732e0..643e19c1d2d 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -65,9 +65,6 @@ (declare-function tramp-method-out-of-band-p "tramp-sh") (declare-function tramp-smb-get-localname "tramp-smb") (defvar ange-ftp-make-backup-files) -(defvar auto-save-file-name-transforms) -(defvar lock-file-name-transforms) -(defvar remote-file-name-inhibit-locks) (defvar tramp-connection-properties) (defvar tramp-copy-size-limit) (defvar tramp-display-escape-sequence-regexp) @@ -77,12 +74,59 @@ (defvar tramp-remote-path) (defvar tramp-remote-process-environment) +;; Needed for Emacs 26. +(declare-function with-connection-local-variables "files-x") ;; Needed for Emacs 27. +(defvar lock-file-name-transforms) (defvar process-file-return-signal-string) +(defvar remote-file-name-inhibit-locks) (defvar shell-command-dont-erase-buffer) ;; Needed for Emacs 28. (defvar dired-copy-dereference) +;; `ert-resource-file' was introduced in Emacs 28.1. +(unless (macrop 'ert-resource-file) + (eval-and-compile + (defvar ert-resource-directory-format "%s-resources/" + "Format for `ert-resource-directory'.") + (defvar ert-resource-directory-trim-left-regexp "" + "Regexp for `string-trim' (left) used by `ert-resource-directory'.") + (defvar ert-resource-directory-trim-right-regexp "\\(-tests?\\)?\\.el" + "Regexp for `string-trim' (right) used by `ert-resource-directory'.") + + (defmacro ert-resource-directory () + "Return absolute file name of the resource directory for this file. + +The path to the resource directory is the \"resources\" directory +in the same directory as the test file. + +If that directory doesn't exist, use the directory named like the +test file but formatted by `ert-resource-directory-format' and trimmed +using `string-trim' with arguments +`ert-resource-directory-trim-left-regexp' and +`ert-resource-directory-trim-right-regexp'. The default values mean +that if called from a test file named \"foo-tests.el\", return +the absolute file name for \"foo-resources\"." + `(let* ((testfile ,(or (bound-and-true-p byte-compile-current-file) + (and load-in-progress load-file-name) + buffer-file-name)) + (default-directory (file-name-directory testfile))) + (file-truename + (if (file-accessible-directory-p "resources/") + (expand-file-name "resources/") + (expand-file-name + (format + ert-resource-directory-format + (string-trim testfile + ert-resource-directory-trim-left-regexp + ert-resource-directory-trim-right-regexp))))))) + + (defmacro ert-resource-file (file) + "Return file name of resource file named FILE. +A resource file is in the resource directory as per +`ert-resource-directory'." + `(expand-file-name ,file (ert-resource-directory))))) + ;; Beautify batch mode. (when noninteractive ;; Suppress nasty messages. @@ -2505,7 +2549,9 @@ This checks also `file-name-as-directory', `file-name-directory', (setq-local file-precious-flag t) (setq-local backup-inhibited t) (insert "bar") + (should (buffer-modified-p)) (should (null (save-buffer))) + (should (not (buffer-modified-p))) (should-not (cl-member tmp-name written-files :test #'string=))) ;; Cleanup. @@ -2518,6 +2564,8 @@ This checks also `file-name-as-directory', `file-name-directory', (skip-unless (tramp--test-enabled)) (skip-unless (not (tramp--test-ange-ftp-p))) (skip-unless (executable-find "gzip")) + ;; The function was introduced in Emacs 28.1. + (skip-unless (boundp 'tar-goto-file)) (let* ((default-directory tramp-test-temporary-file-directory) (archive (ert-resource-file "foo.tar.gz")) @@ -2531,20 +2579,26 @@ This checks also `file-name-as-directory', `file-name-directory', (copy-file archive tmp-file 'ok) ;; Read archive. Check contents of foo.txt, and modify it. Save. (with-current-buffer (setq buffer1 (find-file-noselect tmp-file)) - (should (tar-goto-file "foo.txt")) + ;; The function was introduced in Emacs 28.1. + (with-no-warnings (should (tar-goto-file "foo.txt"))) (save-current-buffer (setq buffer2 (tar-extract)) (should (string-equal (buffer-string) "foo\n")) (goto-char (point-max)) (insert "bar") - (should (null (save-buffer)))) - (should (null (save-buffer)))) + (should (buffer-modified-p)) + (should (null (save-buffer))) + (should-not (buffer-modified-p))) + (should (buffer-modified-p)) + (should (null (save-buffer))) + (should-not (buffer-modified-p))) (kill-buffer buffer1) (kill-buffer buffer2) ;; Read archive. Check contents of modified foo.txt. (with-current-buffer (setq buffer1 (find-file-noselect tmp-file)) - (should (tar-goto-file "foo.txt")) + ;; The function was introduced in Emacs 28.1. + (with-no-warnings (should (tar-goto-file "foo.txt"))) (save-current-buffer (setq buffer2 (tar-extract)) (should (string-equal (buffer-string) "foo\nbar\n"))))) @@ -5032,6 +5086,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-crypt-p))) + ;; Since Emacs 27.1. + (skip-unless (macrop 'with-connection-local-variables)) ;; We must use `file-truename' for the temporary directory, in ;; order to establish the connection prior running an asynchronous @@ -5072,6 +5128,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-crypt-p))) + ;; Since Emacs 27.1. + (skip-unless (macrop 'with-connection-local-variables)) ;; Since Emacs 29.1. (skip-unless (boundp 'signal-process-functions)) @@ -5117,10 +5175,12 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (should (equal (process-get proc 'remote-command) (with-connection-local-variables `(,shell-file-name ,shell-command-switch ,command)))) - (should - (zerop - (signal-process - (process-get proc 'remote-pid) sigcode default-directory))) + ;; `signal-process' has argument REMOTE since Emacs 29. + (with-no-warnings + (should + (zerop + (signal-process + (process-get proc 'remote-pid) sigcode default-directory)))) ;; Let the process accept the signal. (with-timeout (10 (tramp--test-timeout-handler)) (while (accept-process-output proc 0 nil t))) @@ -5181,9 +5241,11 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." INPUT, if non-nil, is a string sent to the process." (let ((proc (async-shell-command command output-buffer error-buffer)) (delete-exited-processes t)) - (should (equal (process-get proc 'remote-command) - (with-connection-local-variables - `(,shell-file-name ,shell-command-switch ,command)))) + ;; Since Emacs 27.1. + (when (macrop 'with-connection-local-variables) + (should (equal (process-get proc 'remote-command) + (with-connection-local-variables + `(,shell-file-name ,shell-command-switch ,command))))) (cl-letf (((symbol-function #'shell-command-sentinel) #'ignore)) (when (stringp input) (process-send-string proc input)) @@ -5567,7 +5629,7 @@ Use direct async.") :tags '(:expensive-test) (skip-unless (tramp--test-enabled)) ;; Since Emacs 27.1. - (skip-unless (fboundp 'with-connection-local-variables)) + (skip-unless (macrop 'with-connection-local-variables)) (let* ((default-directory tramp-test-temporary-file-directory) (tmp-name1 (tramp--test-make-temp-name)) @@ -5583,6 +5645,8 @@ Use direct async.") (should (file-directory-p tmp-name1)) ;; `local-variable' is buffer-local due to explicit setting. + ;; We need `with-no-warnings', because `defvar-local' is not + ;; called at toplevel. (with-no-warnings (defvar-local local-variable 'buffer)) (with-temp-buffer @@ -6163,7 +6227,9 @@ Use direct async.") (with-temp-buffer (set-visited-file-name tmp-name1) (insert "foo") - (save-buffer)) + (should (buffer-modified-p)) + (save-buffer) + (should-not (buffer-modified-p))) (should-not (with-no-warnings (file-locked-p tmp-name1))) (with-no-warnings (lock-file tmp-name1)) (should (eq (with-no-warnings (file-locked-p tmp-name1)) t)) @@ -6285,7 +6351,9 @@ Use direct async.") ;; buffer results in a prompt. (cl-letf (((symbol-function 'yes-or-no-p) (lambda (_) (ert-fail "Test failed unexpectedly")))) - (save-buffer)) + (should (buffer-modified-p)) + (save-buffer) + (should-not (buffer-modified-p))) (should-not (file-locked-p tmp-name)) ;; For local files, just changing the file @@ -6317,7 +6385,9 @@ Use direct async.") (cl-letf (((symbol-function 'yes-or-no-p) #'tramp--test-always) ((symbol-function 'read-char-choice) (lambda (&rest _) ?y))) - (save-buffer)) + (should (buffer-modified-p)) + (save-buffer) + (should-not (buffer-modified-p))) (should-not (file-locked-p tmp-name)))) ;; Cleanup. From 57b69ff39c1ec7aa74f2a19bd4c4de9f67a7df84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=B8=E0=A4=AE=E0=A5=80=E0=A4=B0=20=E0=A4=B8=E0=A4=BF?= =?UTF-8?q?=E0=A4=82=E0=A4=B9=20Sameer=20Singh?= Date: Mon, 9 May 2022 04:22:57 +0530 Subject: [PATCH 0079/1028] Add support for the Sharada script * lisp/language/indian.el ("Sharada"): New language environment. Add composition rules for Sharada. Add sample text and input method. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Support Sharada. * lisp/leim/quail/indian.el ("sharada"): New input method. * etc/HELLO: Add a Sharada greeting. * etc/NEWS: Announce the new language environment and its input method. (Bug#55328) --- etc/HELLO | 1 + etc/NEWS | 5 ++ lisp/international/fontset.el | 2 + lisp/language/indian.el | 43 ++++++++++++ lisp/leim/quail/indian.el | 119 ++++++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+) diff --git a/etc/HELLO b/etc/HELLO index f5e2adae940..b64aacfbe5b 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -75,6 +75,7 @@ Norwegian (norsk) Hei / God dag Oriya (ଓଡ଼ିଆ) ଶୁଣିବେ Polish (język polski) Dzień dobry! / Cześć! Russian (русский) Здра́вствуйте! +Sharada (𑆯𑆳𑆫𑆢𑆳) 𑆤𑆩𑆱𑇀𑆑𑆳𑆫 Sinhala (සිංහල) ආයුබෝවන් Slovak (slovenčina) Dobrý deň Slovenian (slovenščina) Pozdravljeni! diff --git a/etc/NEWS b/etc/NEWS index 92a956c176d..5cdc9a4b3ee 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -749,6 +749,11 @@ This language environment supports Tirhuta or Mithilaakshar, which is used to write the Maithili language. A new input method, 'tirhuta', is provided to type text in this script. +*** New language environment "Sharada". +This language environment supports the Sharada script. Named after the +goddess of learning, this script is used to write the Kashmiri language. +A new input method, 'sharada', is provided to type text in this script. + --- *** New Greek translation of the Emacs tutorial. Type 'C-u C-h t' to select it in case your language setup does not do diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 2d417d632f8..7fa390a34be 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -234,6 +234,7 @@ (brahmi #x11013 #x11045 #x11052 #x11065) (kaithi #x1108D #x110B0 #x110BD) (mahajani #x11150) + (sharada #x11191 #x111B3 #x111CD) (khojki #x11200) (khudawadi #x112B0) (grantha #x11305) @@ -774,6 +775,7 @@ old-uyghur brahmi kaithi + sharada tirhuta makasar dives-akuru diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 922061c3b6a..4b6c4744f1c 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -158,6 +158,17 @@ Maithili language and its script Tirhuta is supported in this language environment.")) '("Indian")) +(set-language-info-alist + "Sharada" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "sharada") + (sample-text . "Sharada (𑆯𑆳𑆫𑆢𑆳) 𑆤𑆩𑆱𑇀𑆑𑆳𑆫") + (documentation . "\ +Kashmiri language and its script Sharada is supported in this +language environment.")) + '("Indian")) + ;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is ;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING). @@ -461,17 +472,20 @@ language environment.")) (set-char-table-range composition-function-table '(#x110B0 . #x110BA) (list (vector + ;; Consonant based syllables (concat consonant nukta "?\\(?:" virama zwj "?" consonant nukta "?\\)*\\(?:" virama zwj "?\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") 1 'font-shape-gstring))) (set-char-table-range composition-function-table '(#x110BD . #x110BD) (list (vector + ;; Number sign (concat number-sign numerals) 0 'font-shape-gstring))) (set-char-table-range composition-function-table '(#x110CD . #x110CD) (list (vector + ;; Number sign above (concat number-sign-above numerals) 0 'font-shape-gstring)))) @@ -486,8 +500,37 @@ language environment.")) (set-char-table-range composition-function-table '(#x114B0 . #x114C3) (list (vector + ;; Consonant based syllables (concat consonant nukta "?\\(?:" virama consonant nukta "?\\)*\\(?:" virama "\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") 1 'font-shape-gstring)))) +;; Sharada composition rules +(let ((consonant "[\x11191-\x111B2]") + (nukta "\x111CA") + (vowel "[\x111B3-\x111BF\x111CE]") + (vowel-modifier "\x111CB") + (extra-short-vowel-mark "\x111CC") + (anusvara-candrabindu "[\x11181\x11180\x111CF]") + (virama "\x111C0") + (fricatives "[\x111C2\x111C3]") + (sandhi-mark "\x111C9") + (misc "[^\x11180-\x111C0\x111C2\x111C3\x111C9-\x111CC\x111CE-\x111CF]")) + (set-char-table-range composition-function-table + '(#x111B3 . #x111CF) + (list (vector + ;; Consonant based syllables + (concat consonant nukta "?" vowel-modifier "?\\(?:" virama + consonant nukta "?" vowel-modifier "?\\)*\\(?:" virama + "\\|" vowel "*" nukta "?" anusvara-candrabindu "?" + extra-short-vowel-mark "?" vowel-modifier "?" sandhi-mark + "?+" misc "?\\)") + 1 'font-shape-gstring))) + (set-char-table-range composition-function-table + '(#x111C2 . #x111C3) + (list (vector + ;; Fricatives with Consonants + (concat fricatives "?" consonant vowel "?") + 0 'font-shape-gstring)))) + ;;; indian.el ends here diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index f730a5ca0f1..b1e547a26ec 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -1043,5 +1043,124 @@ Full key sequences are listed below:") ("`m" ?𑒿) ) +(quail-define-package + "sharada" "Sharada" "𑆯𑆳" t "Sharada phonetic input method. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules +("``" ?₹) +("1" ?𑇑) +("`1" ?1) +("2" ?𑇒) +("`2" ?2) +("3" ?𑇓) +("`3" ?3) +("4" ?𑇔) +("`4" ?4) +("5" ?𑇕) +("`5" ?5) +("6" ?𑇖) +("`6" ?6) +("7" ?𑇗) +("`7" ?7) +("8" ?𑇘) +("`8" ?8) +("9" ?𑇙) +("`9" ?9) +("0" ?𑇐) +("`0" ?0) +("`\)" ?𑇇) +("`\\" ?𑇅) +("`|" ?𑇆) +("`" ?𑆛) +("q" ?𑆛) +("Q" ?𑆜) +("`q" ?𑇈) +("`Q" ?𑇉) +("w" ?𑆝) +("W" ?𑆞) +("`w" ?𑇋) +("`W" ?𑇍) +("e" ?𑆼) +("E" ?𑆽) +("`e" ?𑆍) +("`E" ?𑆎) +("r" ?𑆫) +("R" ?𑆸) +("`r" ?𑆉) +("`R" ?𑇎) +("t" ?𑆠) +("T" ?𑆡) +("y" ?𑆪) +("u" ?𑆶) +("U" ?𑆷) +("`u" ?𑆇) +("`U" ?𑆈) +("i" ?𑆴) +("I" ?𑆵) +("`i" ?𑆅) +("`I" ?𑆆) +("o" ?𑆾) +("O" ?𑆿) +("`o" ?𑆏) +("`O" ?𑆐) +("p" ?𑆥) +("P" ?𑆦) +("`p" ?𑇃) +("a" ?𑆳) +("A" ?𑆄) +("`a" ?𑆃) +("s" ?𑆱) +("S" ?𑆯) +("d" ?𑆢) +("D" ?𑆣) +("`d" ?𑇚) +("`D" ?𑇛) +("f" ?𑇀) +("F" ?𑆹) +("`f" ?𑆊) +("`F" ?𑇌) +("g" ?𑆓) +("G" ?𑆔) +("`g" ?𑇜) +("`G" ?𑇝) +("h" ?𑆲) +("H" ?𑆂) +("`h" ?𑇞) +("`H" ?𑇟) +("j" ?𑆘) +("J" ?𑆙) +("`j" ?᳘) +("`J" ?᳕) +("k" ?𑆑) +("K" ?𑆒) +("`k" ?𑇂) +("l" ?𑆬) +("L" ?𑆭) +("`l" ?𑆺) +("`L" ?𑆋) +("z" ?𑆚) +("Z" ?𑆕) +("`z" ?𑆻) +("`Z" ?𑆌) +("x" ?𑆰) +("X" ?𑇊) +("c" ?𑆖) +("C" ?𑆗) +("`c" #x200C) ; ZWNJ +("v" ?𑆮) +("b" ?𑆧) +("B" ?𑆨) +("n" ?𑆤) +("N" ?𑆟) +("`n" ?𑇄) +("`N" ?𑇁) +("m" ?𑆩) +("M" ?𑆁) +("`m" ?𑆀) +("`M" ?𑇏) +) ;;; indian.el ends here From 75f57e4c9e19441665fe5643f010e41d4895fd54 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Mon, 9 May 2022 21:56:42 +0100 Subject: [PATCH 0080/1028] ; * admin/MAINTAINERS: Remove myself as NS port maintainer. --- admin/MAINTAINERS | 8 -------- 1 file changed, 8 deletions(-) diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS index 092978f6d2c..2760a9a42b5 100644 --- a/admin/MAINTAINERS +++ b/admin/MAINTAINERS @@ -275,14 +275,6 @@ Vibhav Pant lisp/net/browse-url.el lisp/erc/* -Alan Third - The NS port: - nextstep/* - src/ns* - src/*.m - lisp/term/ns-win.el - doc/emacs/macos.texi - Amin Bandali Eshell lisp/eshell/* From b7167ba8d14ad722452c297e33ae5e496f17f72c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 08:48:36 +0800 Subject: [PATCH 0081/1028] ; * src/xdisp.c (mark_window_display_accurate_1): Clear vscroll flag. --- src/xdisp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xdisp.c b/src/xdisp.c index b9b3c6d1bf3..82a018485d3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -17006,6 +17006,7 @@ mark_window_display_accurate_1 (struct window *w, bool accurate_p) w->window_end_valid = true; w->update_mode_line = false; + w->preserve_vscroll_p = false; } w->redisplay = !accurate_p; From b299f173490f5c51476ad3c8436b19bb091c1b00 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 09:32:59 +0800 Subject: [PATCH 0082/1028] Update alpha frame parameter when the window manager changes it * src/xfns.c (x_set_alpha): New function. Set `alpha_identical_p' flag. (x_frame_parm_handlers): Use it to handle `alpha' instead. * src/xterm.c (x_set_frame_alpha): Make tests against current alpha safer. (handle_one_xevent): Set frame alpha when alpha property changes. * src/xterm.h (struct x_output): New flag `alpha_identical_p'. --- src/xfns.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/xterm.c | 48 +++++++++++++++++++++++++++++++++++++++++-- src/xterm.h | 4 ++++ 3 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/xfns.c b/src/xfns.c index dc8f02780ce..7dbf1e16c3a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -2372,6 +2372,63 @@ x_set_scroll_bar_default_height (struct frame *f) #endif } +static void +x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + double alpha = 1.0; + double newval[2]; + int i; + Lisp_Object item; + bool alpha_identical_p; + + alpha_identical_p = true; + + for (i = 0; i < 2; i++) + { + newval[i] = 1.0; + if (CONSP (arg)) + { + item = CAR (arg); + arg = CDR (arg); + + alpha_identical_p = false; + } + else + item = arg; + + if (NILP (item)) + alpha = - 1.0; + else if (FLOATP (item)) + { + alpha = XFLOAT_DATA (item); + if (! (0 <= alpha && alpha <= 1.0)) + args_out_of_range (make_float (0.0), make_float (1.0)); + } + else if (FIXNUMP (item)) + { + EMACS_INT ialpha = XFIXNUM (item); + if (! (0 <= ialpha && ialpha <= 100)) + args_out_of_range (make_fixnum (0), make_fixnum (100)); + alpha = ialpha / 100.0; + } + else + wrong_type_argument (Qnumberp, item); + newval[i] = alpha; + } + + for (i = 0; i < 2; i++) + f->alpha[i] = newval[i]; + + FRAME_X_OUTPUT (f)->alpha_identical_p = alpha_identical_p; + + if (FRAME_TERMINAL (f)->set_frame_alpha_hook) + { + block_input (); + FRAME_TERMINAL (f)->set_frame_alpha_hook (f); + unblock_input (); + } +} + /* Record in frame F the specified or default value according to ALIST of the parameter named PROP (a Lisp symbol). If no value is @@ -9368,7 +9425,7 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_wait_for_wm, gui_set_fullscreen, gui_set_font_backend, - gui_set_alpha, + x_set_alpha, x_set_sticky, x_set_tool_bar_position, #ifdef HAVE_XDBE diff --git a/src/xterm.c b/src/xterm.c index 10d268dc93f..de3129fd87c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5358,9 +5358,16 @@ x_set_frame_alpha (struct frame *f) &actual, &format, &n, &left, &data); - if (rc == Success && actual != None && data) + if (rc == Success && actual != None + && n && format == XA_CARDINAL && data) { unsigned long value = *(unsigned long *) data; + + /* Xlib sign-extends values greater than 0x7fffffff on 64-bit + machines. Get the low bits by ourself. */ + + value &= 0xffffffff; + if (value == opac) { x_uncatch_errors (); @@ -14746,7 +14753,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, unsigned long nitems, bytesafter; unsigned char *data = NULL; - if (event->xproperty.state == PropertyDelete) { if (!last) @@ -14835,6 +14841,44 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } + if (f && FRAME_X_OUTPUT (f)->alpha_identical_p + && (event->xproperty.atom + == dpyinfo->Xatom_net_wm_window_opacity)) + { + int rc, actual_format; + Atom actual; + unsigned char *tmp_data; + unsigned long n, left, opacity; + + tmp_data = NULL; + + if (event->xproperty.state == PropertyDelete) + { + f->alpha[0] = 1.0; + f->alpha[1] = 1.0; + } + else + { + rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f), + dpyinfo->Xatom_net_wm_window_opacity, + 0, 1, False, XA_CARDINAL, &actual, + &actual_format, &n, &left, &tmp_data); + + if (rc == Success && actual_format == 32 + && actual == XA_CARDINAL && n) + { + opacity = *(unsigned long *) tmp_data & OPAQUE; + f->alpha[0] = (double) opacity / (double) OPAQUE; + f->alpha[1] = (double) opacity / (double) OPAQUE; + + store_frame_param (f, Qalpha, make_float (f->alpha[0])); + } + } + + if (tmp_data) + XFree (tmp_data); + } + if (event->xproperty.window == dpyinfo->root_window && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop) diff --git a/src/xterm.h b/src/xterm.h index 16635053be4..98c4c5f01c6 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -932,6 +932,10 @@ struct x_output false, tell Xt not to wait. */ bool_bf wait_for_wm : 1; + /* True if this frame's alpha value is the same for both the active + and inactive states. */ + bool_bf alpha_identical_p : 1; + #ifdef HAVE_X_I18N /* Input context (currently, this means Compose key handler setup). */ XIC xic; From 0b2f550e3229c7a1b001fb1a09e7a5b4e3ecfb3e Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Mon, 9 May 2022 15:53:45 +0200 Subject: [PATCH 0083/1028] Fix syntax descriptor comparison in python-indent-region * lisp/progmodes/python.el (python-indent-region): Compare raw syntax descriptors with equal (bug#45328) (because comparing them with eq will always be false). --- lisp/progmodes/python.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 825e94572a7..cb4be10f5cc 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1297,7 +1297,7 @@ Called from a program, START and END specify the region to indent." ;; Don't mess with strings, unless it's the ;; enclosing set of quotes or a docstring. (or (not (python-syntax-context 'string)) - (eq + (equal (syntax-after (+ (1- (point)) (current-indentation) From 0bee4cda881f7db4113cba541b684c334e828c4a Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 03:38:01 +0200 Subject: [PATCH 0084/1028] Reimplement recent with-silent-modifications auto-save changes * doc/lispref/buffers.texi (Buffer Modification): Document buffer-modified-p returning `autosaved'. * lisp/subr.el (with-silent-modifications): Use restore-buffer-modified-p instead of altering the buffer modiff (since this has other side effects like not updating after async `display' changes. * src/buffer.c (Fbuffer_modified_p): Allow returning whether the buffer has been autosaved after changes. (Frestore_buffer_modified_p): Allow adjusting whether the buffer has been autosaved after changes. * src/fileio.c (Fdo_auto_save): Refill the doc string. --- doc/lispref/buffers.texi | 10 +++++---- lisp/subr.el | 12 ++++------ src/buffer.c | 47 +++++++++++++++++++++++++++++----------- src/fileio.c | 11 ++++++---- test/src/buffer-tests.el | 35 ++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 29 deletions(-) diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index d8cf3d7919b..3e3b0bd9f01 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -541,10 +541,12 @@ file formerly visited. @ref{Text}. @defun buffer-modified-p &optional buffer -This function returns @code{t} if the buffer @var{buffer} has been modified -since it was last read in from a file or saved, or @code{nil} -otherwise. If @var{buffer} is not supplied, the current buffer -is tested. +This function returns non-@code{nil} if the buffer @var{buffer} has +been modified since it was last read in from a file or saved, or +@code{nil} otherwise. If @var{buffer} has been autosaved after +@var{buffer} was last modified, the symbol @code{autosaved} is +returned. If @var{buffer} is not supplied, the current buffer is +tested. @end defun @defun set-buffer-modified-p flag diff --git a/lisp/subr.el b/lisp/subr.el index 01549cc6f74..54c9f35264d 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4594,21 +4594,17 @@ like `buffer-modified-p', checking whether the file is locked by someone else, running buffer modification hooks, and other things of that nature." (declare (debug t) (indent 0)) - (let ((modified (make-symbol "modified")) - (tick (make-symbol "tick"))) + (let ((modified (make-symbol "modified"))) `(let* ((,modified (buffer-modified-p)) - (,tick (buffer-modified-tick)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn ,@body) - ;; We restore the buffer tick count, too, because otherwise - ;; we'll trigger a new auto-save. - (internal--set-buffer-modified-tick ,tick) - (unless ,modified - (restore-buffer-modified-p nil)))))) + (when (or (not ,modified) + (eq ,modified 'autosaved)) + (restore-buffer-modified-p ,modified)))))) (defmacro with-output-to-string (&rest body) "Execute BODY, return the text it sent to `standard-output', as a string." diff --git a/src/buffer.c b/src/buffer.c index 6334e197f0e..f54714675e2 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1376,12 +1376,23 @@ No argument or nil as argument means use current buffer as BUFFER. */) DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p, 0, 1, 0, - doc: /* Return t if BUFFER was modified since its file was last read or saved. -No argument or nil as argument means use current buffer as BUFFER. */) + doc: /* Return non-nil if BUFFER was modified since its file was last read or saved. +No argument or nil as argument means use current buffer as BUFFER. + +If BUFFER has been autosaved after BUFFER was last modified, the +symbol `autosaved' is returned. */) (Lisp_Object buffer) { struct buffer *buf = decode_buffer (buffer); - return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil; + if (BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf)) + { + if (BUF_AUTOSAVE_MODIFF (buf) == BUF_MODIFF (buf)) + return Qautosaved; + else + return Qt; + } + else + return Qnil; } DEFUN ("force-mode-line-update", Fforce_mode_line_update, @@ -1436,6 +1447,11 @@ and `buffer-file-truename' are non-nil. */) DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, Srestore_buffer_modified_p, 1, 1, 0, doc: /* Like `set-buffer-modified-p', but doesn't redisplay buffer's mode line. +A nil FLAG means to mark the buffer as unmodified. A non-nil FLAG +means mark the buffer as modified, except the special value +`autosaved', which will instead mark the buffer as having been +autosaved. + This function also locks or unlocks the file visited by the buffer, if both `buffer-file-truename' and `buffer-file-name' are non-nil. @@ -1475,16 +1491,19 @@ state of the current buffer. Use with care. */) recent-auto-save-p from t to nil. Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified we risk changing recent-auto-save-p from nil to t. */ - SAVE_MODIFF = (NILP (flag) - /* FIXME: This unavoidably sets recent-auto-save-p to nil. */ - ? MODIFF - /* Let's try to preserve recent-auto-save-p. */ - : SAVE_MODIFF < MODIFF ? SAVE_MODIFF - /* If SAVE_MODIFF == auto_save_modified == MODIFF, - we can either decrease SAVE_MODIFF and auto_save_modified - or increase MODIFF. */ - : modiff_incr (&MODIFF)); - + if (NILP (flag)) + /* This unavoidably sets recent-auto-save-p to nil. */ + SAVE_MODIFF = MODIFF; + else + { + if (EQ (flag, Qautosaved)) + BUF_AUTOSAVE_MODIFF (b) = MODIFF; + /* If SAVE_MODIFF == auto_save_modified == MODIFF, we can either + decrease SAVE_MODIFF and auto_save_modified or increase + MODIFF. */ + else if (SAVE_MODIFF >= MODIFF) + SAVE_MODIFF = modiff_incr (&MODIFF); + } return flag; } @@ -6465,5 +6484,7 @@ will run for `clone-indirect-buffer' calls as well. */); defsubr (&Soverlay_put); defsubr (&Srestore_buffer_modified_p); + DEFSYM (Qautosaved, "autosaved"); + Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); } diff --git a/src/fileio.c b/src/fileio.c index 0610f7235a5..9da14c8f541 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5972,14 +5972,17 @@ do_auto_save_eh (Lisp_Object ignore) DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "", doc: /* Auto-save all buffers that need it. -This is all buffers that have auto-saving enabled -and are changed since last auto-saved. -Auto-saving writes the buffer into a file -so that your editing is not lost if the system crashes. +This is all buffers that have auto-saving enabled and are changed +since last auto-saved. + +Auto-saving writes the buffer into a file so that your editing is not +lost if the system crashes. + This file is not the file you visited; that changes only when you save. Normally, run the normal hook `auto-save-hook' before saving. A non-nil NO-MESSAGE argument means do not print any message if successful. + A non-nil CURRENT-ONLY argument means save only current buffer. */) (Lisp_Object no_message, Lisp_Object current_only) { diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index c1e5d0ebed3..10dac68f9fe 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -1482,4 +1482,39 @@ with parameters from the *Messages* buffer modification." (when auto-save (ignore-errors (delete-file auto-save)))))))) +(ert-deftest test-buffer-modifications () + (ert-with-temp-file file + (with-current-buffer (find-file file) + (auto-save-mode 1) + (should-not (buffer-modified-p)) + (insert "foo") + (should (buffer-modified-p)) + (should-not (eq (buffer-modified-p) 'autosaved)) + (do-auto-save nil t) + (should (eq (buffer-modified-p) 'autosaved)) + (with-silent-modifications + (put-text-property 1 3 'face 'bold)) + (should (eq (buffer-modified-p) 'autosaved)) + (save-buffer) + (should-not (buffer-modified-p)) + (with-silent-modifications + (put-text-property 1 3 'face 'italic)) + (should-not (buffer-modified-p))))) + +(ert-deftest test-restore-buffer-modified-p () + (ert-with-temp-file file + (with-current-buffer (find-file file) + (auto-save-mode 1) + (should-not (buffer-modified-p)) + (insert "foo") + (should (buffer-modified-p)) + (restore-buffer-modified-p nil) + (should-not (buffer-modified-p)) + (insert "bar") + (do-auto-save nil t) + (should (eq (buffer-modified-p) 'autosaved)) + (insert "zot") + (restore-buffer-modified-p 'autosaved) + (should (eq (buffer-modified-p) 'autosaved))))) + ;;; buffer-tests.el ends here From 54ab2b36740166d379c713e843870310f1ccf7a1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 03:46:34 +0200 Subject: [PATCH 0085/1028] Add NEWS entries for recent autosaved buffer modification status * doc/lispref/buffers.texi (Buffer Modification): Note 'autosaved' value. --- doc/lispref/buffers.texi | 4 +++- etc/NEWS | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 3e3b0bd9f01..8d1d9f5ddb2 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -566,7 +566,9 @@ function @code{force-mode-line-update} works by doing this: @defun restore-buffer-modified-p flag Like @code{set-buffer-modified-p}, but does not force redisplay -of mode lines. +of mode lines. This function also allows a @var{flag} value of +@code{autosaved}, which marks the buffer as having been autosaved +after the last modification. @end defun @deffn Command not-modified &optional arg diff --git a/etc/NEWS b/etc/NEWS index 5cdc9a4b3ee..8306136e5dd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1564,14 +1564,21 @@ Emacs buffers, like indentation and the like. The new ert function * Incompatible Lisp Changes in Emacs 29.1 ++++ +** 'buffer-modified-p' has been extended. +This function was previously documented to return only nil or t. This +has been changed to nil/'autosaved'/non-nil. The new 'autosaved' +value means that the buffer is modified, but that it hasn't been +modified after the last auto-save. + --- -** 'with-silent-modifications' also restores buffer modification ticks. +** 'with-silent-modifications' also restores buffer autosave status. 'with-silent-modifications' is a macro meant to be used by the font locking machinery to allow applying text properties without changing the modification status of the buffer. However, it didn't restore the -buffer modification ticks, so applying font locking to a modified -buffer that had already been auto-saved would trigger another -auto-saving. This is no longer the case. +buffer autosave status, so applying font locking to a modified buffer +that had already been auto-saved would trigger another auto-saving. +This is no longer the case. --- ** 'prin1' doesn't always escape "." and "?" in symbols any more. @@ -1709,6 +1716,11 @@ functions. * Lisp Changes in Emacs 29.1 ++++ +*** 'restore-buffer-modified-p' can now alter buffer auto-save state. +With a FLAG value of 'autosaved', it will mark the buffer as having +been auto-saved after the last modification. + --- *** New minor mode 'isearch-fold-quotes-mode'. This sets up 'search-default-mode' so that quote characters are From 054062060e9f57fd037578378c23ad9ec294edac Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Thu, 5 May 2022 13:03:06 -0700 Subject: [PATCH 0086/1028] Factor out *scratch* initialization * lisp/simple.el (get-scratch-buffer-create): New function, factored out of scratch-buffer, and additionally clearing the modification flag and calling substitute-command-keys (bug#55257). (scratch-buffer): * lisp/server.el (server-execute): * lisp/startup.el (normal-no-mouse-startup-screen, command-line-1): * lisp/window.el (last-buffer, window-normalize-buffer-to-switch-to): * src/buffer.c (Fother_buffer, other_buffer_safely): Use it. (syms_of_buffer): Add Qget_scratch_buffer_create. * lisp/startup.el (startup--get-buffer-create-scratch): Delete now-unused function. * doc/lispref/os.texi (Summary: Sequence of Actions at Startup): * NEWS (Incompatible changes in Emacs 29.1): Document the change. --- doc/lispref/os.texi | 8 ++++---- etc/NEWS | 8 ++++++++ lisp/server.el | 2 +- lisp/simple.el | 20 ++++++++++++++------ lisp/startup.el | 12 +++--------- lisp/window.el | 18 ++++++++---------- src/buffer.c | 22 +++------------------- 7 files changed, 41 insertions(+), 49 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 9df708532d8..f4dd2e70723 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -329,10 +329,10 @@ file will not inhibit the message for someone else. @end defopt @defopt initial-scratch-message -This variable, if non-@code{nil}, should be a string, which is -treated as documentation to be -inserted into the @file{*scratch*} buffer when Emacs starts up. If it -is @code{nil}, the @file{*scratch*} buffer is empty. +This variable, if non-@code{nil}, should be a string, which is treated +as documentation to be inserted into the @file{*scratch*} buffer when +Emacs starts up or when that buffer is recreated. If it is +@code{nil}, the @file{*scratch*} buffer is empty. @end defopt @noindent diff --git a/etc/NEWS b/etc/NEWS index 8306136e5dd..8404a3616e0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -245,6 +245,14 @@ encouraged to test timestamp-related code with this variable set to nil, as it will default to nil in a future Emacs version and will be removed some time after that. ++++ +** Functions which recreate the *scratch* buffer now also initialize it. +When functions like 'other-buffer' and 'server-execute' recreate +*scratch*, they now also insert 'initial-scratch-message' and set +the major mode according to 'initial-major-mode', like at Emacs +startup. Previously, these functions ignored +'initial-scratch-message' and left *scratch* in 'fundamental-mode'. + * Changes in Emacs 29.1 diff --git a/lisp/server.el b/lisp/server.el index 763cf27f7ac..8f47a99a31a 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1367,7 +1367,7 @@ The following commands are accepted by the client: ((functionp initial-buffer-choice) (funcall initial-buffer-choice))))) (switch-to-buffer - (if (buffer-live-p buf) buf (get-buffer-create "*scratch*")) + (if (buffer-live-p buf) buf (get-scratch-buffer-create)) 'norecord))) ;; Delete the client if necessary. diff --git a/lisp/simple.el b/lisp/simple.el index 861d9eefde9..edcc226bfa8 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10213,16 +10213,24 @@ This is an integer indicating the UTC offset in seconds, i.e., the number of seconds east of Greenwich.") ) +(defun get-scratch-buffer-create () + "Return the \*scratch\* buffer, creating a new one if needed." + (or (get-buffer "*scratch*") + (let ((scratch (get-buffer-create "*scratch*"))) + ;; Don't touch the buffer contents or mode unless we know that + ;; we just created it. + (with-current-buffer scratch + (when initial-scratch-message + (insert (substitute-command-keys initial-scratch-message)) + (set-buffer-modified-p nil)) + (funcall initial-major-mode)) + scratch))) + (defun scratch-buffer () "Switch to the \*scratch\* buffer. If the buffer doesn't exist, create it first." (interactive) - (if (get-buffer "*scratch*") - (pop-to-buffer-same-window "*scratch*") - (pop-to-buffer-same-window (get-buffer-create "*scratch*")) - (when initial-scratch-message - (insert initial-scratch-message)) - (funcall initial-major-mode))) + (pop-to-buffer-same-window (get-scratch-buffer-create))) diff --git a/lisp/startup.el b/lisp/startup.el index 0b7d90ecf2b..433a58bf2c4 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -2358,7 +2358,7 @@ If you have no Meta key, you may instead type ESC followed by the character.)")) (insert "\t\t") (insert-button "Open *scratch* buffer" 'action (lambda (_button) (switch-to-buffer - (startup--get-buffer-create-scratch))) + (get-scratch-buffer-create))) 'follow-link t) (insert "\n") (save-restriction @@ -2490,12 +2490,6 @@ A fancy display is used on graphic displays, normal otherwise." (defalias 'about-emacs 'display-about-screen) (defalias 'display-splash-screen 'display-startup-screen) -(defun startup--get-buffer-create-scratch () - (or (get-buffer "*scratch*") - (with-current-buffer (get-buffer-create "*scratch*") - (set-buffer-major-mode (current-buffer)) - (current-buffer)))) - ;; This avoids byte-compiler warning in the unexec build. (declare-function pdumper-stats "pdumper.c" ()) @@ -2787,7 +2781,7 @@ nil default-directory" name) (when (eq initial-buffer-choice t) ;; When `initial-buffer-choice' equals t make sure that *scratch* ;; exists. - (startup--get-buffer-create-scratch)) + (get-scratch-buffer-create)) ;; If *scratch* exists and is empty, insert initial-scratch-message. ;; Do this before switching to *scratch* below to handle bug#9605. @@ -2811,7 +2805,7 @@ nil default-directory" name) ((functionp initial-buffer-choice) (funcall initial-buffer-choice)) ((eq initial-buffer-choice t) - (startup--get-buffer-create-scratch)) + (get-scratch-buffer-create)) (t (error "`initial-buffer-choice' must be a string, a function, or t"))))) (unless (buffer-live-p buf) diff --git a/lisp/window.el b/lisp/window.el index 52003f7b7b4..dd16b83377b 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4886,10 +4886,7 @@ the buffer `*scratch*', creating it if necessary." (setq frame (or frame (selected-frame))) (or (get-next-valid-buffer (nreverse (buffer-list frame)) buffer visible-ok frame) - (get-buffer "*scratch*") - (let ((scratch (get-buffer-create "*scratch*"))) - (set-buffer-major-mode scratch) - scratch))) + (get-scratch-buffer-create))) (defcustom frame-auto-hide-function #'iconify-frame "Function called to automatically hide frames. @@ -8621,12 +8618,13 @@ If BUFFER-OR-NAME is nil, return the buffer returned by `other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME exists, return that buffer. If no such buffer exists, create a buffer with the name BUFFER-OR-NAME and return that buffer." - (if buffer-or-name - (or (get-buffer buffer-or-name) - (let ((buffer (get-buffer-create buffer-or-name))) - (set-buffer-major-mode buffer) - buffer)) - (other-buffer))) + (pcase buffer-or-name + ('nil (other-buffer)) + ("*scratch*" (get-scratch-buffer-create)) + (_ (or (get-buffer buffer-or-name) + (let ((buffer (get-buffer-create buffer-or-name))) + (set-buffer-major-mode buffer) + buffer))))) (defcustom switch-to-buffer-preserve-window-point t "If non-nil, `switch-to-buffer' tries to preserve `window-point'. diff --git a/src/buffer.c b/src/buffer.c index f54714675e2..0f3061b4973 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1665,16 +1665,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) if (!NILP (notsogood)) return notsogood; else - { - AUTO_STRING (scratch, "*scratch*"); - buf = Fget_buffer (scratch); - if (NILP (buf)) - { - buf = Fget_buffer_create (scratch, Qnil); - Fset_buffer_major_mode (buf); - } - return buf; - } + return safe_call (1, Qget_scratch_buffer_create); } /* The following function is a safe variant of Fother_buffer: It doesn't @@ -1690,15 +1681,7 @@ other_buffer_safely (Lisp_Object buffer) if (candidate_buffer (buf, buffer)) return buf; - AUTO_STRING (scratch, "*scratch*"); - buf = Fget_buffer (scratch); - if (NILP (buf)) - { - buf = Fget_buffer_create (scratch, Qnil); - Fset_buffer_major_mode (buf); - } - - return buf; + return safe_call (1, Qget_scratch_buffer_create); } DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo, @@ -5583,6 +5566,7 @@ syms_of_buffer (void) DEFSYM (Qbefore_change_functions, "before-change-functions"); DEFSYM (Qafter_change_functions, "after-change-functions"); DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions"); + DEFSYM (Qget_scratch_buffer_create, "get-scratch-buffer-create"); DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright)); From 20b27d475f1c2de97c7cd94eece986ed16e83cc8 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 10:38:08 +0800 Subject: [PATCH 0087/1028] Simplify XDND code * src/xfns.c (Fx_begin_drag): Use SAFE_ALLOCA_STRING and encode strings in the right coding system. --- src/xfns.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/xfns.c b/src/xfns.c index 7dbf1e16c3a..5522684170f 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6822,14 +6822,12 @@ mouse buttons are released on top of FRAME. */) { struct frame *f = decode_window_system_frame (frame); int ntargets = 0, nnames = 0; - ptrdiff_t len; char *target_names[2048]; Atom *target_atoms; Lisp_Object lval, original, tem, t1, t2; Atom xaction; Atom action_list[2048]; char *name_list[2048]; - char *scratch; USE_SAFE_ALLOCA; @@ -6843,10 +6841,8 @@ mouse buttons are released on top of FRAME. */) if (ntargets < 2048) { - scratch = SSDATA (XCAR (targets)); - len = strlen (scratch); - target_names[ntargets] = SAFE_ALLOCA (len + 1); - strncpy (target_names[ntargets], scratch, len + 1); + SAFE_ALLOCA_STRING (target_names[ntargets], + XCAR (targets)); ntargets++; } else @@ -6896,10 +6892,8 @@ mouse buttons are released on top of FRAME. */) else signal_error ("Invalid drag-and-drop action", tem); - scratch = SSDATA (ENCODE_UTF_8 (t2)); - len = strlen (scratch); - name_list[nnames] = SAFE_ALLOCA (len + 1); - strncpy (name_list[nnames], scratch, len + 1); + SAFE_ALLOCA_STRING (name_list[nnames], + ENCODE_SYSTEM (t2)); nnames++; } From 4c4eda4c314e1226a9e95f4c733416de4df21245 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 04:41:31 +0200 Subject: [PATCH 0088/1028] Make imenu find defalias entries * lisp/emacs-lisp/lisp-mode.el (lisp-imenu-generic-expression): Also find defalias (bug#7855). --- lisp/emacs-lisp/lisp-mode.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index e7c3a4b64f5..5dd2f5162ed 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -119,6 +119,15 @@ t)) "\\s-+\\(" lisp-mode-symbol-regexp "\\)")) 2) + ;; Like the previous, but uses a quoted symbol as the name. + (list nil + (purecopy (concat "^\\s-*(" + (eval-when-compile + (regexp-opt + '("defalias" "define-obsolete-function-alias") + t)) + "\\s-+'\\(" lisp-mode-symbol-regexp "\\)")) + 2) (list (purecopy "Variables") (purecopy (concat "^\\s-*(" (eval-when-compile From 2d0085f756572856a2ed8d1bf043b59195a3e3f3 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 05:09:15 +0200 Subject: [PATCH 0089/1028] Make dabbrev use the buffer's file name as a source for completions * lisp/dabbrev.el (dabbrev--find-expansion): Include the buffer's file name in the completions (bug#8163). --- lisp/dabbrev.el | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index b04128cf677..8f8d553cdab 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -551,8 +551,9 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found) (minibuffer-window-active-p (selected-window)))) (progn - (message "Expansion found in `%s'" - (buffer-name dabbrev--last-buffer)) + (when (buffer-name dabbrev--last-buffer) + (message "Expansion found in `%s'" + (buffer-name dabbrev--last-buffer))) (setq dabbrev--last-buffer-found dabbrev--last-buffer)) (message nil)) (if (and (or (eq (current-buffer) dabbrev--last-buffer) @@ -770,17 +771,38 @@ of the start of the occurrence." (make-progress-reporter "Scanning for dabbrevs..." (- (length dabbrev--friend-buffer-list)) 0 0 1 1.5)))) - ;; Walk through the buffers till we find a match. - (let (expansion) - (while (and (not expansion) dabbrev--friend-buffer-list) - (setq dabbrev--last-buffer (pop dabbrev--friend-buffer-list)) - (set-buffer dabbrev--last-buffer) - (progress-reporter-update dabbrev--progress-reporter - (- (length dabbrev--friend-buffer-list))) - (setq dabbrev--last-expansion-location (point-min)) - (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case))) - (progress-reporter-done dabbrev--progress-reporter) - expansion))))) + (let ((file-name (buffer-file-name)) + file-name-buffer) + (unwind-protect + (progn + ;; Include the file name components into the abbrev + ;; list (because if you have a file name "foobar", it's + ;; somewhat likely that you'll be talking about foobar + ;; stuff in the file itself). + (when file-name + (setq file-name-buffer (generate-new-buffer " *abbrev-file*")) + (with-current-buffer file-name-buffer + (dolist (part (file-name-split file-name)) + (insert part "\n"))) + (setq dabbrev--friend-buffer-list + (append dabbrev--friend-buffer-list + (list file-name-buffer)))) + ;; Walk through the buffers till we find a match. + (let (expansion) + (while (and (not expansion) dabbrev--friend-buffer-list) + (setq dabbrev--last-buffer + (pop dabbrev--friend-buffer-list)) + (set-buffer dabbrev--last-buffer) + (progress-reporter-update + dabbrev--progress-reporter + (- (length dabbrev--friend-buffer-list))) + (setq dabbrev--last-expansion-location (point-min)) + (setq expansion (dabbrev--try-find + abbrev nil 1 ignore-case))) + (progress-reporter-done dabbrev--progress-reporter) + expansion)) + (when (buffer-live-p file-name-buffer) + (kill-buffer file-name-buffer)))))))) ;; Compute the list of buffers to scan. ;; If dabbrev-search-these-buffers-only, then the current buffer From e568c3845cd98b702ce23bdef1b22e088769c9cd Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 05:58:33 +0200 Subject: [PATCH 0090/1028] Add more compilation-auto-jump-to-first-error options * doc/emacs/building.texi (Compilation Mode): Document it. * lisp/progmodes/compile.el (compilation-auto-jump-to-first-error): Extend type. (compilation--file-known-p): New function. (compilation-auto-jump): Use it to support the new values (bug#8228). (compilation-find-file-1): Factored out into own function. (compilation-find-file): Factored out from here. --- doc/emacs/building.texi | 4 ++- etc/NEWS | 6 ++++ lisp/progmodes/compile.el | 65 +++++++++++++++++++++++++++++---------- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 994ad460333..892117e2e82 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -178,7 +178,9 @@ list of customization variables and faces. If you change the variable @code{compilation-auto-jump-to-first-error} to a non-@code{nil} value, Emacs automatically visits the locus of the first error message that -appears in the @file{*compilation*} buffer. +appears in the @file{*compilation*} buffer. (This variable can also +have the values @code{if-location-known} and @code{first-known}, which +modifies whether to automatically visit.) Compilation mode provides the following additional commands. These commands can also be used in @file{*grep*} buffers, where the diff --git a/etc/NEWS b/etc/NEWS index 8404a3616e0..45682998dba 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -810,6 +810,12 @@ which is a change in behaviour from previous Emacs versions. ** Compile ++++ +*** The 'compilation-auto-jump-to-first-error' has been extended. +It can now have the additional values 'if-location-known' (which will +only jump if the location of the first error is known), and +'first-known' (which will jump to the first known error location). + +++ *** New user option 'compilation-max-output-line-length'. Lines longer than this will have the ends hidden, with a button to diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 2c5f4687ac7..5545b4cd4ad 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -951,7 +951,10 @@ Faces `compilation-error-face', `compilation-warning-face', (defcustom compilation-auto-jump-to-first-error nil "If non-nil, automatically jump to the first error during compilation." - :type 'boolean + :type '(choice (const :tag "Never" nil) + (const :tag "Always" t) + (const :tag "If location known" if-location-known) + (const :tag "First known location" first-known)) :version "23.1") (defvar-local compilation-auto-jump-to-next nil @@ -1182,14 +1185,39 @@ POS and RES.") l2 (setcdr l1 (cons (list ,key) l2))))))) +(defun compilation--file-known-p () + "Say whether the file under point can be found." + (when-let* ((msg (get-text-property (point) 'compilation-message)) + (loc (compilation--message->loc msg)) + (elem (compilation-find-file-1 + (point-marker) + (caar (compilation--loc->file-struct loc)) + (cadr (car (compilation--loc->file-struct loc))) + (compilation--file-struct->formats + (compilation--loc->file-struct loc))))) + (car elem))) + (defun compilation-auto-jump (buffer pos) (when (buffer-live-p buffer) (with-current-buffer buffer (goto-char pos) (let ((win (get-buffer-window buffer 0))) (if win (set-window-point win pos))) - (if compilation-auto-jump-to-first-error - (compile-goto-error))))) + (when compilation-auto-jump-to-first-error + (cl-case compilation-auto-jump-to-first-error + ('if-location-known + (when (compilation--file-known-p) + (compile-goto-error))) + ('first-known + (let (match) + (while (and (not (compilation--file-known-p)) + (setq match (text-property-search-forward + 'compilation-message nil nil t))) + (goto-char (prop-match-beginning match)))) + (when (compilation--file-known-p) + (compile-goto-error))) + (otherwise + (compile-goto-error))))))) ;; This function is the central driver, called when font-locking to gather ;; all information needed to later jump to corresponding source code. @@ -2974,19 +3002,7 @@ and overlay is highlighted between MK and END-MK." (remove-hook 'pre-command-hook #'compilation-goto-locus-delete-o)) -(defun compilation-find-file (marker filename directory &rest formats) - "Find a buffer for file FILENAME. -If FILENAME is not found at all, ask the user where to find it. -Pop up the buffer containing MARKER and scroll to MARKER if we ask -the user where to find the file. -Search the directories in `compilation-search-path'. -A nil in `compilation-search-path' means to try the -\"current\" directory, which is passed in DIRECTORY. -If DIRECTORY is relative, it is combined with `default-directory'. -If DIRECTORY is nil, that means use `default-directory'. -FORMATS, if given, is a list of formats to reformat FILENAME when -looking for it: for each element FMT in FORMATS, this function -attempts to find a file whose name is produced by (format FMT FILENAME)." +(defun compilation-find-file-1 (marker filename directory &optional formats) (or formats (setq formats '("%s"))) (let ((dirs compilation-search-path) (spec-dir (if directory @@ -3035,6 +3051,23 @@ attempts to find a file whose name is produced by (format FMT FILENAME)." (find-file-noselect name)) fmts (cdr fmts))) (setq dirs (cdr dirs)))) + (list buffer spec-dir))) + +(defun compilation-find-file (marker filename directory &rest formats) + "Find a buffer for file FILENAME. +If FILENAME is not found at all, ask the user where to find it. +Pop up the buffer containing MARKER and scroll to MARKER if we ask +the user where to find the file. +Search the directories in `compilation-search-path'. +A nil in `compilation-search-path' means to try the +\"current\" directory, which is passed in DIRECTORY. +If DIRECTORY is relative, it is combined with `default-directory'. +If DIRECTORY is nil, that means use `default-directory'. +FORMATS, if given, is a list of formats to reformat FILENAME when +looking for it: for each element FMT in FORMATS, this function +attempts to find a file whose name is produced by (format FMT FILENAME)." + (pcase-let ((`(,buffer ,spec-dir) + (compilation-find-file-1 marker filename directory formats))) (while (null buffer) ;Repeat until the user selects an existing file. ;; The file doesn't exist. Ask the user where to find it. (save-excursion ;This save-excursion is probably not right. From 3c5e1f8ec8d5d52e5bbf185d9618852e7d04e3ca Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 04:11:32 +0000 Subject: [PATCH 0091/1028] Simplify Haiku selection code * src/haiku_select.cc (get_clipboard_object): New function. (BClipboard_find_data, BClipboard_get_targets, BClipboard_set_data) (BClipboard_find_system_data) (BClipboard_find_primary_selection_data) (BClipboard_find_secondary_selection_data) (BClipboard_set_system_data, BClipboard_set_primary_selection_data) (BClipboard_set_secondary_selection_data, BClipboard_free_data) (BClipboard_system_targets, BClipboard_primary_targets) (BClipboard_secondary_targets): Delete functions. (be_find_clipboard_data_1, be_set_clipboard_data_1) (be_get_clipboard_targets_1, be_find_clipboard_data) (be_set_clipboard_data, be_get_clipboard_targets): New functions. (be_lock_clipboard_message, be_unlock_clipboard): Use `get_clipboard_object' to get clipboard from ID. * src/haikuselect.c (haiku_get_clipboard_name): New function. (Fhaiku_selection_data, Fhaiku_selection_put) (Fhaiku_selection_owner_p): Adjust to use new simplified functions. * src/haikuselect.h: Update prototypes. --- src/haiku_select.cc | 174 +++++++++++++++++--------------------------- src/haikuselect.c | 75 +++++++------------ src/haikuselect.h | 21 +----- 3 files changed, 95 insertions(+), 175 deletions(-) diff --git a/src/haiku_select.cc b/src/haiku_select.cc index a26a0049cbf..43b71138b33 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc @@ -35,22 +35,45 @@ static int64 count_clipboard = -1; static int64 count_primary = -1; static int64 count_secondary = -1; -static char * -BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len) +static BClipboard * +get_clipboard_object (enum haiku_clipboard clipboard) { - if (!cb->Lock ()) - return 0; - - BMessage *dat = cb->Data (); - if (!dat) + switch (clipboard) { - cb->Unlock (); - return 0; + case CLIPBOARD_PRIMARY: + return primary; + + case CLIPBOARD_SECONDARY: + return secondary; + + case CLIPBOARD_CLIPBOARD: + return system_clipboard; } + abort (); +} + +static char * +be_find_clipboard_data_1 (BClipboard *cb, const char *type, ssize_t *len) +{ + BMessage *data; const char *ptr; - ssize_t bt; - dat->FindData (type, B_MIME_TYPE, (const void **) &ptr, &bt); + ssize_t nbytes; + void *value; + + if (!cb->Lock ()) + return NULL; + + data = cb->Data (); + + if (!data) + { + cb->Unlock (); + return NULL; + } + + data->FindData (type, B_MIME_TYPE, (const void **) &ptr, + &nbytes); if (!ptr) { @@ -59,9 +82,9 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len) } if (len) - *len = bt; + *len = nbytes; - void *data = malloc (bt); + value = malloc (nbytes); if (!data) { @@ -69,13 +92,14 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len) return NULL; } - memcpy (data, ptr, bt); + memcpy (value, ptr, nbytes); cb->Unlock (); - return (char *) data; + + return (char *) value; } static void -BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size) +be_get_clipboard_targets_1 (BClipboard *cb, char **buf, int buf_size) { BMessage *data; char *name; @@ -122,116 +146,60 @@ BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size) } static void -BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, - ssize_t len, bool clear) +be_set_clipboard_data_1 (BClipboard *cb, const char *type, const char *data, + ssize_t len, bool clear) { + BMessage *message_data; + if (!cb->Lock ()) return; if (clear) cb->Clear (); - BMessage *mdat = cb->Data (); - if (!mdat) + message_data = cb->Data (); + + if (!message_data) { cb->Unlock (); return; } - if (dat) + if (data) { - if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len) + if (message_data->ReplaceData (type, B_MIME_TYPE, data, len) == B_NAME_NOT_FOUND) - mdat->AddData (type, B_MIME_TYPE, dat, len); + message_data->AddData (type, B_MIME_TYPE, data, len); } else - mdat->RemoveName (type); + message_data->RemoveName (type); + cb->Commit (); cb->Unlock (); } char * -BClipboard_find_system_data (const char *type, ssize_t *len) +be_find_clipboard_data (enum haiku_clipboard id, const char *type, + ssize_t *len) { - if (!system_clipboard) - return 0; - - return BClipboard_find_data (system_clipboard, type, len); -} - -char * -BClipboard_find_primary_selection_data (const char *type, ssize_t *len) -{ - if (!primary) - return 0; - - return BClipboard_find_data (primary, type, len); -} - -char * -BClipboard_find_secondary_selection_data (const char *type, ssize_t *len) -{ - if (!secondary) - return 0; - - return BClipboard_find_data (secondary, type, len); + return be_find_clipboard_data_1 (get_clipboard_object (id), + type, len); } void -BClipboard_set_system_data (const char *type, const char *data, - ssize_t len, bool clear) +be_set_clipboard_data (enum haiku_clipboard id, const char *type, + const char *data, ssize_t len, bool clear) { - if (!system_clipboard) - return; - - count_clipboard = system_clipboard->SystemCount (); - BClipboard_set_data (system_clipboard, type, data, len, clear); + be_set_clipboard_data_1 (get_clipboard_object (id), type, + data, len, clear); } void -BClipboard_set_primary_selection_data (const char *type, const char *data, - ssize_t len, bool clear) +be_get_clipboard_targets (enum haiku_clipboard id, char **targets, + int len) { - if (!primary) - return; - - count_primary = primary->SystemCount (); - BClipboard_set_data (primary, type, data, len, clear); -} - -void -BClipboard_set_secondary_selection_data (const char *type, const char *data, - ssize_t len, bool clear) -{ - if (!secondary) - return; - - count_secondary = secondary->SystemCount (); - BClipboard_set_data (secondary, type, data, len, clear); -} - -void -BClipboard_free_data (void *ptr) -{ - std::free (ptr); -} - -void -BClipboard_system_targets (char **buf, int len) -{ - BClipboard_get_targets (system_clipboard, buf, len); -} - -void -BClipboard_primary_targets (char **buf, int len) -{ - BClipboard_get_targets (primary, buf, len); -} - -void -BClipboard_secondary_targets (char **buf, int len) -{ - BClipboard_get_targets (secondary, buf, len); + be_get_clipboard_targets_1 (get_clipboard_object (id), targets, + len); } bool @@ -443,12 +411,7 @@ be_lock_clipboard_message (enum haiku_clipboard clipboard, { BClipboard *board; - if (clipboard == CLIPBOARD_PRIMARY) - board = primary; - else if (clipboard == CLIPBOARD_SECONDARY) - board = secondary; - else - board = system_clipboard; + board = get_clipboard_object (clipboard); if (!board->Lock ()) return 1; @@ -465,12 +428,7 @@ be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard) { BClipboard *board; - if (clipboard == CLIPBOARD_PRIMARY) - board = primary; - else if (clipboard == CLIPBOARD_SECONDARY) - board = secondary; - else - board = system_clipboard; + board = get_clipboard_object (clipboard); if (discard) board->Revert (); diff --git a/src/haikuselect.c b/src/haikuselect.c index 8ce71822983..0c808bdb937 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -35,6 +35,21 @@ struct frame *haiku_dnd_frame; static void haiku_lisp_to_message (Lisp_Object, void *); +static enum haiku_clipboard +haiku_get_clipboard_name (Lisp_Object clipboard) +{ + if (EQ (clipboard, QPRIMARY)) + return CLIPBOARD_PRIMARY; + + if (EQ (clipboard, QSECONDARY)) + return CLIPBOARD_SECONDARY; + + if (EQ (clipboard, QCLIPBOARD)) + return CLIPBOARD_CLIPBOARD; + + signal_error ("Invalid clipboard", clipboard); +} + DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data, 2, 2, 0, doc: /* Retrieve content typed as NAME from the clipboard @@ -53,22 +68,15 @@ message in the format accepted by `haiku-drag-message', which see. */) int rc; CHECK_SYMBOL (clipboard); - - if (!EQ (clipboard, QPRIMARY) && !EQ (clipboard, QSECONDARY) - && !EQ (clipboard, QCLIPBOARD)) - signal_error ("Invalid clipboard", clipboard); + clipboard_name = haiku_get_clipboard_name (clipboard); if (!NILP (name)) { CHECK_STRING (name); block_input (); - if (EQ (clipboard, QPRIMARY)) - dat = BClipboard_find_primary_selection_data (SSDATA (name), &len); - else if (EQ (clipboard, QSECONDARY)) - dat = BClipboard_find_secondary_selection_data (SSDATA (name), &len); - else - dat = BClipboard_find_system_data (SSDATA (name), &len); + dat = be_find_clipboard_data (clipboard_name, + SSDATA (name), &len); unblock_input (); if (!dat) @@ -83,18 +91,11 @@ message in the format accepted by `haiku-drag-message', which see. */) Qforeign_selection, Qt, str); block_input (); - BClipboard_free_data (dat); + free (dat); unblock_input (); } else { - if (EQ (clipboard, QPRIMARY)) - clipboard_name = CLIPBOARD_PRIMARY; - else if (EQ (clipboard, QSECONDARY)) - clipboard_name = CLIPBOARD_SECONDARY; - else - clipboard_name = CLIPBOARD_CLIPBOARD; - block_input (); rc = be_lock_clipboard_message (clipboard_name, &message, false); unblock_input (); @@ -139,17 +140,11 @@ In that case, the arguments after NAME are ignored. */) int rc; void *message; + CHECK_SYMBOL (clipboard); + clipboard_name = haiku_get_clipboard_name (clipboard); + if (CONSP (name) || NILP (name)) { - if (EQ (clipboard, QPRIMARY)) - clipboard_name = CLIPBOARD_PRIMARY; - else if (EQ (clipboard, QSECONDARY)) - clipboard_name = CLIPBOARD_SECONDARY; - else if (EQ (clipboard, QCLIPBOARD)) - clipboard_name = CLIPBOARD_CLIPBOARD; - else - signal_error ("Invalid clipboard", clipboard); - rc = be_lock_clipboard_message (clipboard_name, &message, true); @@ -164,7 +159,6 @@ In that case, the arguments after NAME are ignored. */) return unbind_to (ref, Qnil); } - CHECK_SYMBOL (clipboard); CHECK_STRING (name); if (!NILP (data)) CHECK_STRING (data); @@ -172,20 +166,8 @@ In that case, the arguments after NAME are ignored. */) dat = !NILP (data) ? SSDATA (data) : NULL; len = !NILP (data) ? SBYTES (data) : 0; - if (EQ (clipboard, QPRIMARY)) - BClipboard_set_primary_selection_data (SSDATA (name), dat, len, - !NILP (clear)); - else if (EQ (clipboard, QSECONDARY)) - BClipboard_set_secondary_selection_data (SSDATA (name), dat, len, - !NILP (clear)); - else if (EQ (clipboard, QCLIPBOARD)) - BClipboard_set_system_data (SSDATA (name), dat, len, !NILP (clear)); - else - { - unblock_input (); - signal_error ("Bad clipboard", clipboard); - } - + be_set_clipboard_data (clipboard_name, SSDATA (name), dat, len, + !NILP (clear)); return Qnil; } @@ -193,18 +175,11 @@ DEFUN ("haiku-selection-owner-p", Fhaiku_selection_owner_p, Shaiku_selection_own 0, 1, 0, doc: /* Whether the current Emacs process owns the given SELECTION. The arg should be the name of the selection in question, typically one -of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. For -convenience, the symbol nil is the same as `PRIMARY', and t is the -same as `SECONDARY'. */) +of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. */) (Lisp_Object selection) { bool value; - if (NILP (selection)) - selection = QPRIMARY; - else if (EQ (selection, Qt)) - selection = QSECONDARY; - block_input (); if (EQ (selection, QPRIMARY)) value = BClipboard_owns_primary (); diff --git a/src/haikuselect.h b/src/haikuselect.h index d4f331a9ccb..b63d3c36536 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h @@ -41,28 +41,15 @@ extern void init_haiku_select (void); #endif /* Whether or not the selection was recently changed. */ -/* Find a string with the MIME type TYPE in the system clipboard. */ -extern char *BClipboard_find_system_data (const char *, ssize_t *); -extern char *BClipboard_find_primary_selection_data (const char *, ssize_t *); -extern char *BClipboard_find_secondary_selection_data (const char *, ssize_t *); - -extern void BClipboard_set_system_data (const char *, const char *, ssize_t, bool); -extern void BClipboard_set_primary_selection_data (const char *, const char *, - ssize_t, bool); -extern void BClipboard_set_secondary_selection_data (const char *, const char *, - ssize_t, bool); - -extern void BClipboard_system_targets (char **, int); -extern void BClipboard_primary_targets (char **, int); -extern void BClipboard_secondary_targets (char **, int); +extern char *be_find_clipboard_data (enum haiku_clipboard, const char *, ssize_t *); +extern void be_set_clipboard_data (enum haiku_clipboard, const char *, const char *, + ssize_t, bool); +extern void be_get_clipboard_targets (enum haiku_clipboard, char **, int); extern bool BClipboard_owns_clipboard (void); extern bool BClipboard_owns_primary (void); extern bool BClipboard_owns_secondary (void); -/* Free the returned data. */ -extern void BClipboard_free_data (void *); - extern int be_enum_message (void *, int32 *, int32, int32 *, const char **); extern int be_get_message_data (void *, const char *, int32, int32, const void **, ssize_t *); From d221c02fa1db17e1275687f0bbce4ff1499119a1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 07:05:43 +0200 Subject: [PATCH 0092/1028] Fix bibtex-map-entries regression at bobp * lisp/textmodes/bibtex.el (bibtex-map-entries): Fix regression introduced by c32e8b33f (bug#55342) -- don't fail when the first entry is at bobp. --- lisp/textmodes/bibtex.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index 62a4af13774..544e0da8276 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -2298,11 +2298,11 @@ is non-nil, FUN is not called for @String entries." (set-marker-insertion-type end-marker t) (save-excursion (goto-char (point-min)) - (let ((prev (point))) + (let ((prev nil)) (while (setq found (bibtex-skip-to-valid-entry)) ;; If we have invalid entries, ensure that we have forward ;; progress so that we don't infloop. - (if (= (point) prev) + (if (equal (point) prev) (forward-line 1) (setq prev (point)) (set-marker end-marker (cdr found)) From 58f6cbeb58c2394f6360e97d1a6e49c1c1df3166 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 14:38:22 +0800 Subject: [PATCH 0093/1028] Work around some broken programs when reading opacity prop * src/xterm.c (handle_one_xevent): Accept some other types that property is set to by thoughtless programs. --- src/xterm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index de3129fd87c..5818eb1d02e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14861,11 +14861,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, { rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f), dpyinfo->Xatom_net_wm_window_opacity, - 0, 1, False, XA_CARDINAL, &actual, + 0, 1, False, AnyPropertyType, &actual, &actual_format, &n, &left, &tmp_data); if (rc == Success && actual_format == 32 - && actual == XA_CARDINAL && n) + && (actual == XA_CARDINAL + /* Some broken programs set the opacity property + to those types, but window managers accept + them anyway. */ + || actual == XA_ATOM + || actual == XA_WINDOW) && n) { opacity = *(unsigned long *) tmp_data & OPAQUE; f->alpha[0] = (double) opacity / (double) OPAQUE; From 88545428f0962081e776d903e05dd787677b320a Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 14:40:26 +0800 Subject: [PATCH 0094/1028] Handle deletion of opacity property too * src/xterm.c (handle_one_xevent): Clear `alpha' frame parameter when opacity prop is gone or invalid. --- src/xterm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/xterm.c b/src/xterm.c index 5818eb1d02e..c22a901ff4c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14856,6 +14856,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, { f->alpha[0] = 1.0; f->alpha[1] = 1.0; + + store_frame_param (f, Qalpha, Qnil); } else { @@ -14878,6 +14880,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, store_frame_param (f, Qalpha, make_float (f->alpha[0])); } + else + { + f->alpha[0] = 1.0; + f->alpha[1] = 1.0; + + store_frame_param (f, Qalpha, Qnil); + } } if (tmp_data) From c7b48b61d08f0b6a08584080badc60fe62ba1db1 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 16:01:00 +0800 Subject: [PATCH 0095/1028] Improve display of reliefs on NS * src/nsfont.m (nsfont_draw): Don't compensate for left box twice. * src/nsterm.m (ns_draw_relief): Draw outer edges of box like on X. --- src/nsfont.m | 3 -- src/nsterm.m | 108 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/nsfont.m b/src/nsfont.m index e913a50cb69..ae5e134e15b 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -1177,9 +1177,6 @@ is false when (FROM > 0 || TO < S->nchars). */ face = s->face; r.origin.x = x; - if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p) - r.origin.x += max (s->face->box_vertical_line_width, 0); - r.origin.y = y; r.size.height = FONT_HEIGHT (font); diff --git a/src/nsterm.m b/src/nsterm.m index 82062033335..238a842d789 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3450,36 +3450,32 @@ larger if there are taller display elements (e.g., characters static void ns_draw_relief (NSRect outer, int hthickness, int vthickness, char raised_p, - char top_p, char bottom_p, char left_p, char right_p, - struct glyph_string *s) + char top_p, char bottom_p, char left_p, char right_p, + struct glyph_string *s) /* -------------------------------------------------------------------------- Draw a relief rect inside r, optionally leaving some sides open. Note we can't just use an NSDrawBezel command, because of the possibility of some sides not being drawn, and because the rect will be filled. -------------------------------------------------------------------------- */ { - static NSColor *baseCol = nil, *lightCol = nil, *darkCol = nil; - NSColor *newBaseCol = nil; + static NSColor *baseCol, *lightCol, *darkCol; + NSColor *newBaseCol; NSRect inner; + NSBezierPath *p; + + baseCol = nil; + lightCol = nil; + newBaseCol = nil; + p = nil; NSTRACE ("ns_draw_relief"); /* set up colors */ if (s->face->use_box_color_for_shadows_p) - { - newBaseCol = [NSColor colorWithUnsignedLong:s->face->box_color]; - } -/* else if (s->first_glyph->type == IMAGE_GLYPH - && s->img->pixmap - && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0)) - { - newBaseCol = IMAGE_BACKGROUND (s->img, s->f, 0); - } */ + newBaseCol = [NSColor colorWithUnsignedLong: s->face->box_color]; else - { - newBaseCol = [NSColor colorWithUnsignedLong:s->face->background]; - } + newBaseCol = [NSColor colorWithUnsignedLong: s->face->background]; if (newBaseCol == nil) newBaseCol = [NSColor grayColor]; @@ -3498,26 +3494,27 @@ larger if there are taller display elements (e.g., characters inner = NSMakeRect (NSMinX (outer) + (left_p ? hthickness : 0), NSMinY (outer) + (top_p ? vthickness : 0), NSWidth (outer) - (left_p ? hthickness : 0) - - (right_p ? hthickness : 0), + - (right_p ? hthickness : 0), NSHeight (outer) - (top_p ? vthickness : 0) - - (bottom_p ? vthickness : 0)); + - (bottom_p ? vthickness : 0)); [(raised_p ? lightCol : darkCol) set]; if (top_p || left_p) { - NSBezierPath *p = [NSBezierPath bezierPath]; - [p moveToPoint:NSMakePoint (NSMinX (outer), NSMinY (outer))]; + p = [NSBezierPath bezierPath]; + + [p moveToPoint: NSMakePoint (NSMinX (outer), NSMinY (outer))]; if (top_p) { - [p lineToPoint:NSMakePoint (NSMaxX (outer), NSMinY (outer))]; - [p lineToPoint:NSMakePoint (NSMaxX (inner), NSMinY (inner))]; + [p lineToPoint: NSMakePoint (NSMaxX (outer), NSMinY (outer))]; + [p lineToPoint :NSMakePoint (NSMaxX (inner), NSMinY (inner))]; } - [p lineToPoint:NSMakePoint (NSMinX (inner), NSMinY (inner))]; + [p lineToPoint: NSMakePoint (NSMinX (inner), NSMinY (inner))]; if (left_p) { - [p lineToPoint:NSMakePoint (NSMinX (inner), NSMaxY (inner))]; - [p lineToPoint:NSMakePoint (NSMinX (outer), NSMaxY (outer))]; + [p lineToPoint: NSMakePoint (NSMinX (inner), NSMaxY (inner))]; + [p lineToPoint: NSMakePoint (NSMinX (outer), NSMaxY (outer))]; } [p closePath]; [p fill]; @@ -3525,24 +3522,68 @@ larger if there are taller display elements (e.g., characters [(raised_p ? darkCol : lightCol) set]; - if (bottom_p || right_p) + if (bottom_p || right_p) { - NSBezierPath *p = [NSBezierPath bezierPath]; - [p moveToPoint:NSMakePoint (NSMaxX (outer), NSMaxY (outer))]; + p = [NSBezierPath bezierPath]; + + [p moveToPoint: NSMakePoint (NSMaxX (outer), NSMaxY (outer))]; if (right_p) { - [p lineToPoint:NSMakePoint (NSMaxX (outer), NSMinY (outer))]; - [p lineToPoint:NSMakePoint (NSMaxX (inner), NSMinY (inner))]; + [p lineToPoint: NSMakePoint (NSMaxX (outer), NSMinY (outer))]; + [p lineToPoint: NSMakePoint (NSMaxX (inner), NSMinY (inner))]; } [p lineToPoint:NSMakePoint (NSMaxX (inner), NSMaxY (inner))]; if (bottom_p) { - [p lineToPoint:NSMakePoint (NSMinX (inner), NSMaxY (inner))]; - [p lineToPoint:NSMakePoint (NSMinX (outer), NSMaxY (outer))]; + [p lineToPoint: NSMakePoint (NSMinX (inner), NSMaxY (inner))]; + [p lineToPoint: NSMakePoint (NSMinX (outer), NSMaxY (outer))]; } [p closePath]; [p fill]; } + + /* If one of h/vthickness are more than 1, draw the outermost line + on the respective sides in the black relief color. */ + + if (p) + [p removeAllPoints]; + else + p = [NSBezierPath bezierPath]; + + if (hthickness > 1 && top_p) + { + [p moveToPoint: NSMakePoint (NSMinX (outer), + NSMinY (outer) + 0.5)]; + [p lineToPoint: NSMakePoint (NSMaxX (outer), + NSMinY (outer) + 0.5)]; + } + + if (hthickness > 1 && bottom_p) + { + [p moveToPoint: NSMakePoint (NSMinX (outer), + NSMaxY (outer) - 0.5)]; + [p lineToPoint: NSMakePoint (NSMaxX (outer), + NSMaxY (outer) - 0.5)]; + } + + if (vthickness > 1 && left_p) + { + [p moveToPoint: NSMakePoint (NSMinX (outer) + 0.5, + NSMinY (outer) + 0.5)]; + [p lineToPoint: NSMakePoint (NSMinX (outer) + 0.5, + NSMaxY (outer) - 0.5)]; + } + + if (vthickness > 1 && left_p) + { + [p moveToPoint: NSMakePoint (NSMinX (outer) + 0.5, + NSMinY (outer) + 0.5)]; + [p lineToPoint: NSMakePoint (NSMinX (outer) + 0.5, + NSMaxY (outer) - 0.5)]; + } + + [darkCol set]; + [p stroke]; } @@ -3624,6 +3665,7 @@ Function modeled after x_draw_glyph_string_box (). if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/) { int box_line_width = max (s->face->box_horizontal_line_width, 0); + if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be much @@ -3650,7 +3692,7 @@ Function modeled after x_draw_glyph_string_box (). NSRect r = NSMakeRect (s->x, s->y + box_line_width, s->background_width, - s->height-2*box_line_width); + s->height - 2 * box_line_width); NSRectFill (r); s->background_filled_p = 1; From e8d643eb835e2883e12032a7f25e94a8a3335c87 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 16:50:10 +0800 Subject: [PATCH 0096/1028] Fix X11 relief background clearning when hwidth is larger than vwidth * src/xterm.c (x_fill_triangle, x_make_point, x_inside_rect_p): New functions. (x_draw_relief_rect): Complete rewrite. Use more sensible primitives. --- src/xterm.c | 214 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 73 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index c22a901ff4c..3e5cd45b431 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7390,20 +7390,62 @@ x_setup_relief_colors (struct glyph_string *s) } } +#ifndef USE_CAIRO +static void +x_fill_triangle (struct frame *f, GC gc, XPoint point1, + XPoint point2, XPoint point3) +{ + XPoint abc[3]; + + abc[0] = point1; + abc[1] = point2; + abc[2] = point3; + + XFillPolygon (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), + gc, abc, 3, Convex, CoordModeOrigin); +} + +static XPoint +x_make_point (int x, int y) +{ + XPoint pt; + + pt.x = x; + pt.y = y; + + return pt; +} + +static bool +x_inside_rect_p (XRectangle *rects, int nrects, int x, int y) +{ + int i; + + for (i = 0; i < nrects; ++i) + { + if (x >= rects[i].x && y >= rects[i].y + && x < rects[i].x + rects[i].width + && y < rects[i].y + rects[i].height) + return true; + } + + return false; +} +#endif /* Draw a relief on frame F inside the rectangle given by LEFT_X, - TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief - to draw, it must be >= 0. RAISED_P means draw a raised - relief. LEFT_P means draw a relief on the left side of - the rectangle. RIGHT_P means draw a relief on the right - side of the rectangle. CLIP_RECT is the clipping rectangle to use - when drawing. */ + TOP_Y, RIGHT_X, and BOTTOM_Y. VWIDTH and HWIDTH are respectively + the thickness of the vertical relief (left and right) and + horizontal relief (top and bottom) to draw, it must be >= 0. + RAISED_P means draw a raised relief. LEFT_P means draw a relief on + the left side of the rectangle. RIGHT_P means draw a relief on the + right side of the rectangle. CLIP_RECT is the clipping rectangle + to use when drawing. */ static void -x_draw_relief_rect (struct frame *f, - int left_x, int top_y, int right_x, int bottom_y, - int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p, - bool left_p, bool right_p, +x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x, + int bottom_y, int hwidth, int vwidth, bool raised_p, + bool top_p, bool bot_p, bool left_p, bool right_p, XRectangle *clip_rect) { #ifdef USE_CAIRO @@ -7479,90 +7521,116 @@ x_draw_relief_rect (struct frame *f, x_reset_clip_rectangles (f, top_left_gc); x_reset_clip_rectangles (f, bottom_right_gc); #else - Display *dpy = FRAME_X_DISPLAY (f); - Drawable drawable = FRAME_X_DRAWABLE (f); - int i; - GC gc; - - if (raised_p) - gc = f->output_data.x->white_relief.gc; - else - gc = f->output_data.x->black_relief.gc; - XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); + GC gc, white_gc, black_gc, normal_gc; + Drawable drawable; + Display *dpy; /* This code is more complicated than it has to be, because of two minor hacks to make the boxes look nicer: (i) if width > 1, draw the outermost line using the black relief. (ii) Omit the four corner pixels. */ - /* Top. */ - if (top_p) - { - if (hwidth == 1) - XDrawLine (dpy, drawable, gc, - left_x + left_p, top_y, - right_x + !right_p, top_y); + white_gc = f->output_data.x->white_relief.gc; + black_gc = f->output_data.x->black_relief.gc; + normal_gc = f->output_data.x->normal_gc; - for (i = 1; i < hwidth; ++i) - XDrawLine (dpy, drawable, gc, - left_x + i * left_p, top_y + i, - right_x + 1 - i * right_p, top_y + i); - } + drawable = FRAME_X_DRAWABLE (f); + dpy = FRAME_X_DISPLAY (f); - /* Left. */ - if (left_p) - { - if (vwidth == 1) - XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y); + x_set_clip_rectangles (f, white_gc, clip_rect, 1); + x_set_clip_rectangles (f, black_gc, clip_rect, 1); - for (i = 1; i < vwidth; ++i) - XDrawLine (dpy, drawable, gc, - left_x + i, top_y + (i + 1) * top_p, - left_x + i, bottom_y + 1 - (i + 1) * bot_p); - } - - XSetClipMask (dpy, gc, None); if (raised_p) - gc = f->output_data.x->black_relief.gc; + gc = white_gc; else - gc = f->output_data.x->white_relief.gc; - XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); + gc = black_gc; - /* Outermost top line. */ - if (top_p && hwidth > 1) - XDrawLine (dpy, drawable, gc, - left_x + left_p, top_y, - right_x + !right_p, top_y); + /* Draw lines. */ - /* Outermost left line. */ - if (left_p && vwidth > 1) - XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y); + if (top_p) + x_fill_rectangle (f, gc, left_x, top_y, + right_x - left_x + 1, hwidth, + false); + + if (left_p) + x_fill_rectangle (f, gc, left_x, top_y, vwidth, + bottom_y - top_y + 1, false); + + if (raised_p) + gc = black_gc; + else + gc = white_gc; - /* Bottom. */ if (bot_p) - { - if (hwidth >= 1) - XDrawLine (dpy, drawable, gc, - left_x + left_p, bottom_y, - right_x + !right_p, bottom_y); + x_fill_rectangle (f, gc, left_x, bottom_y - hwidth + 1, + right_x - left_x + 1, hwidth, false); - for (i = 1; i < hwidth; ++i) - XDrawLine (dpy, drawable, gc, - left_x + i * left_p, bottom_y - i, - right_x + 1 - i * right_p, bottom_y - i); - } - - /* Right. */ if (right_p) + x_fill_rectangle (f, gc, right_x - vwidth + 1, top_y, + vwidth, bottom_y - top_y + 1, false); + + /* Draw corners. */ + + if (bot_p && left_p) + x_fill_triangle (f, raised_p ? white_gc : black_gc, + x_make_point (left_x, bottom_y - hwidth), + x_make_point (left_x + vwidth, bottom_y - hwidth), + x_make_point (left_x, bottom_y)); + + if (top_p && right_p) + x_fill_triangle (f, raised_p ? white_gc : black_gc, + x_make_point (right_x - vwidth, top_y), + x_make_point (right_x, top_y), + x_make_point (right_x - vwidth, top_y + hwidth)); + + /* Draw outer line. */ + + if (top_p && left_p && bot_p && right_p + && hwidth > 1 && vwidth > 1) + x_draw_rectangle (f, black_gc, left_x, top_y, + right_x - left_x, top_y - bottom_y); + else { - for (i = 0; i < vwidth; ++i) - XDrawLine (dpy, drawable, gc, - right_x - i, top_y + (i + 1) * top_p, - right_x - i, bottom_y + 1 - (i + 1) * bot_p); + if (top_p && hwidth > 1) + XDrawLine (dpy, drawable, black_gc, left_x, top_y, + right_x + 1, top_y); + + if (bot_p && hwidth > 1) + XDrawLine (dpy, drawable, black_gc, left_x, bottom_y, + right_x + 1, bottom_y); + + if (left_p && vwidth > 1) + XDrawLine (dpy, drawable, black_gc, left_x, top_y, + left_x, bottom_y + 1); + + if (right_p && vwidth > 1) + XDrawLine (dpy, drawable, black_gc, right_x, top_y, + right_x, bottom_y + 1); } - x_reset_clip_rectangles (f, gc); + /* Erase corners. */ + if (hwidth > 1 && vwidth > 1) + { + if (left_p && top_p && x_inside_rect_p (clip_rect, 1, + left_x, top_y)) + x_clear_rectangle (f, normal_gc, left_x, top_y, 1, 1, false); + + if (left_p && bot_p && x_inside_rect_p (clip_rect, 1, + left_x, bottom_y)) + x_clear_rectangle (f, normal_gc, left_x, bottom_y, 1, 1, false); + + if (right_p && top_p && x_inside_rect_p (clip_rect, 1, + right_x, top_y)) + x_clear_rectangle (f, normal_gc, right_x, top_y, 1, 1, false); + + if (right_p && bot_p && x_inside_rect_p (clip_rect, 1, + right_x, bottom_y)) + x_clear_rectangle (f, normal_gc, right_x, bottom_y, 1, 1, false); + } + + x_reset_clip_rectangles (f, white_gc); + x_reset_clip_rectangles (f, black_gc); #endif } From 773c5c00d23ccb78f491b30e67f77ebe5d38be1a Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 09:00:39 +0000 Subject: [PATCH 0097/1028] Improve relief rect handling on Haiku * haikuterm.c (haiku_calculate_relief_colors): Calculate backgrounds for image glyphs like on X. (haiku_draw_relief_rect): Remove extra parameter. (haiku_draw_string_box, haiku_draw_image_relief): Adjust accordingly. --- src/haikuterm.c | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index 802d7d2ac2f..26ea69758b1 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -586,9 +586,9 @@ haiku_defined_color (struct frame *f, /* Adapted from xterm `x_draw_box_rect'. */ static void -haiku_draw_box_rect (struct glyph_string *s, - int left_x, int top_y, int right_x, int bottom_y, int hwidth, - int vwidth, bool left_p, bool right_p, struct haiku_rect *clip_rect) +haiku_draw_box_rect (struct glyph_string *s, int left_x, int top_y, + int right_x, int bottom_y, int hwidth, int vwidth, + bool left_p, bool right_p, struct haiku_rect *clip_rect) { void *view = FRAME_HAIKU_VIEW (s->f); struct face *face = s->face; @@ -612,13 +612,19 @@ static void haiku_calculate_relief_colors (struct glyph_string *s, uint32_t *rgbout_w, uint32_t *rgbout_b) { - struct face *face = s->face; double h, cs, l; uint32_t rgbin; struct haiku_output *di; - rgbin = (face->use_box_color_for_shadows_p - ? face->box_color : face->background); + if (s->face->use_box_color_for_shadows_p) + rgbin = s->face->box_color; + else if (s->first_glyph->type == IMAGE_GLYPH + && s->img->pixmap + && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0)) + rgbin = IMAGE_BACKGROUND (s->img, s->f, 0); + else + rgbin = s->face->background; + di = FRAME_OUTPUT_DATA (s->f); if (s->hl == DRAW_CURSOR) @@ -640,30 +646,35 @@ haiku_calculate_relief_colors (struct glyph_string *s, uint32_t *rgbout_w, } static void -haiku_draw_relief_rect (struct glyph_string *s, - int left_x, int top_y, int right_x, int bottom_y, - int hwidth, int vwidth, bool raised_p, bool top_p, - bool bot_p, bool left_p, bool right_p, - struct haiku_rect *clip_rect, bool fancy_p) +haiku_draw_relief_rect (struct glyph_string *s, int left_x, int top_y, + int right_x, int bottom_y, int hwidth, int vwidth, + bool raised_p, bool top_p, bool bot_p, bool left_p, + bool right_p, struct haiku_rect *clip_rect) { uint32_t color_white, color_black; void *view; + view = FRAME_HAIKU_VIEW (s->f); haiku_calculate_relief_colors (s, &color_white, &color_black); - view = FRAME_HAIKU_VIEW (s->f); BView_SetHighColor (view, raised_p ? color_white : color_black); + if (clip_rect) { BView_StartClip (view); haiku_clip_to_string (s); - BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width, - clip_rect->height); + BView_ClipToRect (view, clip_rect->x, clip_rect->y, + clip_rect->width, clip_rect->height); } + if (top_p) - BView_FillRectangle (view, left_x, top_y, right_x - left_x + 1, hwidth); + BView_FillRectangle (view, left_x, top_y, + right_x - left_x + 1, hwidth); + if (left_p) - BView_FillRectangle (view, left_x, top_y, vwidth, bottom_y - top_y + 1); + BView_FillRectangle (view, left_x, top_y, + vwidth, bottom_y - top_y + 1); + BView_SetHighColor (view, !raised_p ? color_white : color_black); if (bot_p) @@ -707,7 +718,7 @@ haiku_draw_relief_rect (struct glyph_string *s, BView_SetHighColor (view, s->face->background); /* Omit corner pixels. */ - if (hwidth > 1 || vwidth > 1) + if (hwidth > 1 && vwidth > 1) { if (left_p && top_p) BView_FillRectangle (view, left_x, top_y, 1, 1); @@ -989,7 +1000,7 @@ haiku_draw_string_box (struct glyph_string *s) else haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth, vwidth, raised_p, true, true, left_p, right_p, - NULL, 1); + NULL); } static void @@ -1611,7 +1622,7 @@ haiku_draw_image_relief (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); haiku_draw_relief_rect (s, x, y, x1, y1, thick, thick, raised_p, - top_p, bot_p, left_p, right_p, &r, 0); + top_p, bot_p, left_p, right_p, &r); } static void From 145727df29d2e067b062cb44548dd97b076567fa Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 17:38:53 +0800 Subject: [PATCH 0098/1028] Fix display of depressed buttons * src/xterm.c (x_draw_relief_rect): Fix typo. --- src/xterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xterm.c b/src/xterm.c index 3e5cd45b431..40c80eb1f70 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7588,7 +7588,7 @@ x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x, if (top_p && left_p && bot_p && right_p && hwidth > 1 && vwidth > 1) x_draw_rectangle (f, black_gc, left_x, top_y, - right_x - left_x, top_y - bottom_y); + right_x - left_x, bottom_y - top_y); else { if (top_p && hwidth > 1) From 9beb04dd0700a63fdce65351465045587d10e064 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 10 May 2022 15:47:06 +0300 Subject: [PATCH 0099/1028] ; * doc/emacs/building.texi (Compilation Mode): Fix typo. --- doc/emacs/building.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 892117e2e82..8f972de568a 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -180,7 +180,7 @@ list of customization variables and faces. Emacs automatically visits the locus of the first error message that appears in the @file{*compilation*} buffer. (This variable can also have the values @code{if-location-known} and @code{first-known}, which -modifies whether to automatically visit.) +modify the conditions for automatically visiting the error locus.) Compilation mode provides the following additional commands. These commands can also be used in @file{*grep*} buffers, where the From 66e4bf2bcb2c142c023837ce57d5763deffc7d8d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 10 May 2022 15:53:51 +0300 Subject: [PATCH 0100/1028] ; * etc/NEWS: Clarify recently-added entries. --- etc/NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 45682998dba..212253d3dbf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1583,7 +1583,7 @@ Emacs buffers, like indentation and the like. The new ert function This function was previously documented to return only nil or t. This has been changed to nil/'autosaved'/non-nil. The new 'autosaved' value means that the buffer is modified, but that it hasn't been -modified after the last auto-save. +modified since the time of last auto-save. --- ** 'with-silent-modifications' also restores buffer autosave status. @@ -1733,7 +1733,7 @@ functions. +++ *** 'restore-buffer-modified-p' can now alter buffer auto-save state. With a FLAG value of 'autosaved', it will mark the buffer as having -been auto-saved after the last modification. +been auto-saved since the time of last modification. --- *** New minor mode 'isearch-fold-quotes-mode'. From 000f13a2bc60428bf02157956b22ba23570b0725 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 15:01:00 +0200 Subject: [PATCH 0101/1028] Make `apropos-variable' include values in output * lisp/apropos.el (apropos-print): Include variable values in the output (bug#13842). --- etc/NEWS | 3 +++ lisp/apropos.el | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 212253d3dbf..13c8aacb2b7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -476,6 +476,9 @@ This allows you to enter emoji using short strings, eg :face_palm: or ** Help +--- +*** 'M-x apropos-variable' output now includes values of variables. + +++ *** New doc string syntax to indicate that symbols shouldn't be links. When displaying doc strings in *Help* buffers, strings that are diff --git a/lisp/apropos.el b/lisp/apropos.el index 79c4df10d25..28184476e68 100644 --- a/lisp/apropos.el +++ b/lisp/apropos.el @@ -1247,6 +1247,19 @@ as a heading." 'apropos-user-option 'apropos-variable) (not nosubst)) + ;; Insert an excerpt of variable values. + (when (boundp symbol) + (insert " Value: ") + (let* ((print-escape-newlines t) + (value (prin1-to-string (symbol-value symbol))) + (truncated (truncate-string-to-width + value (- (window-width) 20) nil nil t))) + (insert truncated) + (unless (equal value truncated) + (buttonize-region (1- (point)) (point) + (lambda (_) + (message "Value: %s" value)))) + (insert "\n"))) (apropos-print-doc 7 'apropos-group t) (apropos-print-doc 6 'apropos-face t) (apropos-print-doc 5 'apropos-widget t) From 68dd94448f0b46cced59c7fe33f77f74ddf656ad Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 10 May 2022 16:06:10 +0300 Subject: [PATCH 0102/1028] ; Fix recent documentation changes * src/fileio.c (Fdo_auto_save): * src/buffer.c (Fbuffer_modified_p, Frestore_buffer_modified_p): * doc/lispref/buffers.texi (Buffer Modification): Improve documentation of 'do-auto-save', 'buffer-modified-p' and 'restore-buffer-modified-p'. --- doc/lispref/buffers.texi | 10 +++++----- src/buffer.c | 10 +++++----- src/fileio.c | 12 +++++++----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 8d1d9f5ddb2..2e5771f3474 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -541,12 +541,12 @@ file formerly visited. @ref{Text}. @defun buffer-modified-p &optional buffer -This function returns non-@code{nil} if the buffer @var{buffer} has +This function returns non-@code{nil} if @var{buffer} has been modified since it was last read in from a file or saved, or -@code{nil} otherwise. If @var{buffer} has been autosaved after -@var{buffer} was last modified, the symbol @code{autosaved} is -returned. If @var{buffer} is not supplied, the current buffer is -tested. +@code{nil} otherwise. If @var{buffer} has been auto-saved since the +time it was last modified, this function returns the symbol +@code{autosaved}. If @var{buffer} is @code{nil} or omitted, it +defaults to the current buffer. @end defun @defun set-buffer-modified-p flag diff --git a/src/buffer.c b/src/buffer.c index 0f3061b4973..0af14a10609 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1379,8 +1379,8 @@ DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p, doc: /* Return non-nil if BUFFER was modified since its file was last read or saved. No argument or nil as argument means use current buffer as BUFFER. -If BUFFER has been autosaved after BUFFER was last modified, the -symbol `autosaved' is returned. */) +If BUFFER was autosaved since it was last modified, this function +returns the symbol `autosaved'. */) (Lisp_Object buffer) { struct buffer *buf = decode_buffer (buffer); @@ -1448,9 +1448,9 @@ DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, Srestore_buffer_modified_p, 1, 1, 0, doc: /* Like `set-buffer-modified-p', but doesn't redisplay buffer's mode line. A nil FLAG means to mark the buffer as unmodified. A non-nil FLAG -means mark the buffer as modified, except the special value -`autosaved', which will instead mark the buffer as having been -autosaved. +means mark the buffer as modified, but the special value +`autosaved' will instead mark the buffer as having been +autosaved since it was last modified. This function also locks or unlocks the file visited by the buffer, if both `buffer-file-truename' and `buffer-file-name' are non-nil. diff --git a/src/fileio.c b/src/fileio.c index 9da14c8f541..094516bfef5 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5972,13 +5972,15 @@ do_auto_save_eh (Lisp_Object ignore) DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "", doc: /* Auto-save all buffers that need it. -This is all buffers that have auto-saving enabled and are changed -since last auto-saved. +This auto-saves all buffers that have auto-saving enabled and +were changed since last auto-saved. -Auto-saving writes the buffer into a file so that your editing is not -lost if the system crashes. +Auto-saving writes the buffer into a file so that your edits are +not lost if the system crashes. + +The auto-save file is not the file you visited; that changes only +when you save. -This file is not the file you visited; that changes only when you save. Normally, run the normal hook `auto-save-hook' before saving. A non-nil NO-MESSAGE argument means do not print any message if successful. From 77bf4ca000b4d1c901907c774e7bb342b6f24f1e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 21:07:53 +0800 Subject: [PATCH 0103/1028] Respect `alpha-background' drawing relief corners * src/xterm.c (x_draw_relief_rect): Respect background alpha for corner rects. --- src/xterm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 40c80eb1f70..d44554df7b8 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7614,19 +7614,25 @@ x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x, { if (left_p && top_p && x_inside_rect_p (clip_rect, 1, left_x, top_y)) - x_clear_rectangle (f, normal_gc, left_x, top_y, 1, 1, false); + /* This should respect `alpha-backgroun' since it's being + cleared with the background color of the frame. */ + x_clear_rectangle (f, normal_gc, left_x, top_y, 1, 1, + true); if (left_p && bot_p && x_inside_rect_p (clip_rect, 1, left_x, bottom_y)) - x_clear_rectangle (f, normal_gc, left_x, bottom_y, 1, 1, false); + x_clear_rectangle (f, normal_gc, left_x, bottom_y, 1, 1, + true); if (right_p && top_p && x_inside_rect_p (clip_rect, 1, right_x, top_y)) - x_clear_rectangle (f, normal_gc, right_x, top_y, 1, 1, false); + x_clear_rectangle (f, normal_gc, right_x, top_y, 1, 1, + true); if (right_p && bot_p && x_inside_rect_p (clip_rect, 1, right_x, bottom_y)) - x_clear_rectangle (f, normal_gc, right_x, bottom_y, 1, 1, false); + x_clear_rectangle (f, normal_gc, right_x, bottom_y, 1, 1, + true); } x_reset_clip_rectangles (f, white_gc); From 97ca4601632c0ed8434925d7e03e4d644276986a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=B8=E0=A4=AE=E0=A5=80=E0=A4=B0=20=E0=A4=B8=E0=A4=BF?= =?UTF-8?q?=E0=A4=82=E0=A4=B9=20Sameer=20Singh?= Date: Tue, 10 May 2022 00:49:58 +0530 Subject: [PATCH 0104/1028] ; * lisp/language/indian.el: Improve composition rules. (Bug#55341) --- lisp/language/indian.el | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 4b6c4744f1c..1e10c2a61a7 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -462,8 +462,9 @@ language environment.")) ;; Kaithi composition rules (let ((consonant "[\x1108D-\x110AF]") (nukta "\x110BA") + (independent-vowel "[\x11083-\x1108C]") (vowel "[\x1108D-\x110C2]") - (anusvara-candrabindu "[\x11080\x11081]") + (nasal "[\x11080\x11081]") (virama "\x110B9") (number-sign "\x110BD") (number-sign-above "\x110CD") @@ -474,7 +475,11 @@ language environment.")) (list (vector ;; Consonant based syllables (concat consonant nukta "?\\(?:" virama zwj "?" consonant nukta "?\\)*\\(?:" - virama zwj "?\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") + virama zwj "?\\|" vowel "*" nukta "?" nasal "?\\)") + 1 'font-shape-gstring) + (vector + ;; Nasal vowels + (concat independent-vowel nasal "?") 1 'font-shape-gstring))) (set-char-table-range composition-function-table '(#x110BD . #x110BD) @@ -489,29 +494,33 @@ language environment.")) (concat number-sign-above numerals) 0 'font-shape-gstring)))) -(provide 'indian) - ;; Tirhuta composition rules (let ((consonant "[\x1148F-\x114AF]") (nukta "\x114C3") + (independent-vowel "[\x11481-\x1148E]") (vowel "[\x114B0-\x114BE]") - (anusvara-candrabindu "[\x114BF\x114C0]") + (nasal "[\x114BF\x114C0]") (virama "\x114C2")) (set-char-table-range composition-function-table '(#x114B0 . #x114C3) (list (vector ;; Consonant based syllables (concat consonant nukta "?\\(?:" virama consonant nukta "?\\)*\\(?:" - virama "\\|" vowel "*" nukta "?" anusvara-candrabindu "?\\)") + virama "\\|" vowel "*" nukta "?" nasal "?\\)") + 1 'font-shape-gstring) + (vector + ;; Nasal vowels + (concat independent-vowel nasal "?") 1 'font-shape-gstring)))) ;; Sharada composition rules (let ((consonant "[\x11191-\x111B2]") (nukta "\x111CA") + (independent-vowel "[\x11183-\x11190]") (vowel "[\x111B3-\x111BF\x111CE]") (vowel-modifier "\x111CB") (extra-short-vowel-mark "\x111CC") - (anusvara-candrabindu "[\x11181\x11180\x111CF]") + (nasal "[\x11181\x11180\x111CF]") (virama "\x111C0") (fricatives "[\x111C2\x111C3]") (sandhi-mark "\x111C9") @@ -522,15 +531,17 @@ language environment.")) ;; Consonant based syllables (concat consonant nukta "?" vowel-modifier "?\\(?:" virama consonant nukta "?" vowel-modifier "?\\)*\\(?:" virama - "\\|" vowel "*" nukta "?" anusvara-candrabindu "?" - extra-short-vowel-mark "?" vowel-modifier "?" sandhi-mark - "?+" misc "?\\)") - 1 'font-shape-gstring))) - (set-char-table-range composition-function-table - '(#x111C2 . #x111C3) - (list (vector + "\\|" vowel "*" nukta "?" nasal "?" extra-short-vowel-mark + "?" vowel-modifier "?" sandhi-mark "?+" misc "?\\)") + 1 'font-shape-gstring) + (vector + ;; Nasal vowels + (concat independent-vowel nasal "?") + 1 'font-shape-gstring) + (vector ;; Fricatives with Consonants (concat fricatives "?" consonant vowel "?") 0 'font-shape-gstring)))) +(provide 'indian) ;;; indian.el ends here From cfa317fa92c3ebc47bbdee25b5595cb85a21e298 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 10 May 2022 21:34:19 +0800 Subject: [PATCH 0105/1028] Improve display of relief rectangles on NS * src/nsterm.m (ns_draw_relief): Respect cursor color and draw corners like X. --- src/nsterm.m | 59 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 238a842d789..e25f94e5d80 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3477,6 +3477,9 @@ larger if there are taller display elements (e.g., characters else newBaseCol = [NSColor colorWithUnsignedLong: s->face->background]; + if (s->hl == DRAW_CURSOR) + newBaseCol = FRAME_CURSOR_COLOR (s->f); + if (newBaseCol == nil) newBaseCol = [NSColor grayColor]; @@ -3485,18 +3488,31 @@ larger if there are taller display elements (e.g., characters [baseCol release]; baseCol = [newBaseCol retain]; [lightCol release]; - lightCol = [[baseCol highlightWithLevel: 0.2] retain]; + lightCol = [[baseCol highlightWithLevel: 0.4] retain]; [darkCol release]; - darkCol = [[baseCol shadowWithLevel: 0.3] retain]; + darkCol = [[baseCol shadowWithLevel: 0.4] retain]; } /* Calculate the inner rectangle. */ - inner = NSMakeRect (NSMinX (outer) + (left_p ? hthickness : 0), - NSMinY (outer) + (top_p ? vthickness : 0), - NSWidth (outer) - (left_p ? hthickness : 0) - - (right_p ? hthickness : 0), - NSHeight (outer) - (top_p ? vthickness : 0) - - (bottom_p ? vthickness : 0)); + inner = outer; + + if (left_p) + { + inner.origin.x += vthickness; + inner.size.width -= vthickness; + } + + if (right_p) + inner.size.width -= vthickness; + + if (top_p) + { + inner.origin.y += hthickness; + inner.size.height -= hthickness; + } + + if (bottom_p) + inner.size.height -= hthickness; [(raised_p ? lightCol : darkCol) set]; @@ -3508,7 +3524,7 @@ larger if there are taller display elements (e.g., characters if (top_p) { [p lineToPoint: NSMakePoint (NSMaxX (outer), NSMinY (outer))]; - [p lineToPoint :NSMakePoint (NSMaxX (inner), NSMinY (inner))]; + [p lineToPoint: NSMakePoint (NSMaxX (inner), NSMinY (inner))]; } [p lineToPoint: NSMakePoint (NSMinX (inner), NSMinY (inner))]; if (left_p) @@ -3584,6 +3600,31 @@ larger if there are taller display elements (e.g., characters [darkCol set]; [p stroke]; + + if (vthickness > 1 && hthickness > 1) + { + [FRAME_BACKGROUND_COLOR (s->f) set]; + + if (left_p && top_p) + [NSBezierPath fillRect: NSMakeRect (NSMinX (outer), + NSMinY (outer), + 1, 1)]; + + if (right_p && top_p) + [NSBezierPath fillRect: NSMakeRect (NSMaxX (outer) - 1, + NSMinY (outer), + 1, 1)]; + + if (right_p && bottom_p) + [NSBezierPath fillRect: NSMakeRect (NSMaxX (outer) - 1, + NSMaxY (outer) - 1, + 1, 1)]; + + if (left_p && bottom_p) + [NSBezierPath fillRect: NSMakeRect (NSMinX (outer), + NSMaxY (outer) - 1, + 1, 1)]; + } } From ec01391ab3ecf3c1edb1070c97803e2aa2273367 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 15:25:06 +0200 Subject: [PATCH 0106/1028] Allow packages to alter menu entries in the Buffers menu * lisp/menu-bar.el (menu-bar-update-buffers): Use it. (menu-bar-buffers-menu-command-entries): Put the entries into the defvar so that packages can modify it (bug#14244). --- etc/NEWS | 7 ++++++ lisp/menu-bar.el | 55 +++++++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 13c8aacb2b7..2557a092a83 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -256,6 +256,13 @@ startup. Previously, these functions ignored * Changes in Emacs 29.1 +** Menus + +--- +*** The entries following the buffers in the "Buffers" menu can now be altered. +Change the 'menu-bar-buffers-menu-command-entries' variable to alter +the remaining entries. + --- ** 'delete-process' is now a command. When called interactively, it will kill the process running in the diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 9a3181afb8d..488bf05f3ab 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2320,8 +2320,29 @@ Buffers menu is regenerated." (cdr elt))) buf))) -;; Used to cache the menu entries for commands in the Buffers menu -(defvar menu-bar-buffers-menu-command-entries nil) +(defvar menu-bar-buffers-menu-command-entries + (list '(command-separator "--") + (list 'next-buffer + 'menu-item + "Next Buffer" + 'next-buffer + :help "Switch to the \"next\" buffer in a cyclic order") + (list 'previous-buffer + 'menu-item + "Previous Buffer" + 'previous-buffer + :help "Switch to the \"previous\" buffer in a cyclic order") + (list 'select-named-buffer + 'menu-item + "Select Named Buffer..." + 'switch-to-buffer + :help "Prompt for a buffer name, and select that buffer in the current window") + (list 'list-all-buffers + 'menu-item + "List All Buffers" + 'list-buffers + :help "Pop up a window listing all Emacs buffers")) + "Entries to be included at the end of the \"Buffers\" menu.") (defvar menu-bar-select-buffer-function 'switch-to-buffer "Function to select the buffer chosen from the `Buffers' menu-bar menu. @@ -2406,35 +2427,7 @@ It must accept a buffer as its only required argument.") `((frames-separator "--") (frames menu-item "Frames" ,frames-menu)))))) - ;; Add in some normal commands at the end of the menu. We use - ;; the copy cached in `menu-bar-buffers-menu-command-entries' - ;; if it's been set already. Note that we can't use constant - ;; lists for the menu-entries, because the low-level menu-code - ;; modifies them. - (unless menu-bar-buffers-menu-command-entries - (setq menu-bar-buffers-menu-command-entries - (list '(command-separator "--") - (list 'next-buffer - 'menu-item - "Next Buffer" - 'next-buffer - :help "Switch to the \"next\" buffer in a cyclic order") - (list 'previous-buffer - 'menu-item - "Previous Buffer" - 'previous-buffer - :help "Switch to the \"previous\" buffer in a cyclic order") - (list 'select-named-buffer - 'menu-item - "Select Named Buffer..." - 'switch-to-buffer - :help "Prompt for a buffer name, and select that buffer in the current window") - (list 'list-all-buffers - 'menu-item - "List All Buffers" - 'list-buffers - :help "Pop up a window listing all Emacs buffers" - )))) + ;; Add in some normal commands at the end of the menu. (setq buffers-menu (nconc buffers-menu menu-bar-buffers-menu-command-entries)) From f38a5e45c891f80b4537c8cda28783d3bb43cdec Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 15:33:32 +0200 Subject: [PATCH 0107/1028] Fix markup in read-number doc string * lisp/subr.el (read-number): Fix markup for the letter. --- lisp/subr.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/subr.el b/lisp/subr.el index 54c9f35264d..d7f06bdcde8 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3055,7 +3055,8 @@ DEFAULT specifies a default value to return if the user just types RET. The value of DEFAULT is inserted into PROMPT. HIST specifies a history list variable. See `read-from-minibuffer' for details of the HIST argument. -This function is used by the `interactive' code letter `n'." + +This function is used by the `interactive' code letter \"n\"." (let ((n nil) (default1 (if (consp default) (car default) default))) (when default1 From 00451c6fc62d96c866fe87ae153e27d687c50d1a Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 16:23:43 +0200 Subject: [PATCH 0108/1028] Make ispell-region/buffer push the mark of the final word * lisp/textmodes/ispell.el (ispell-region): Push the mark of the final location. (ispell-process-line): Change the return value to include the position of the final word. --- etc/NEWS | 8 ++++++++ lisp/textmodes/ispell.el | 33 ++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 2557a092a83..1c89493a1ff 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -780,6 +780,14 @@ so automatically. * Changes in Specialized Modes and Packages in Emacs 29.1 +** ispell + +--- +*** 'ispell-region' and 'ispell-buffer' now push the mark. +The location of the last word the user was queried about is pushed to +the mark ring, so that the user can skip back to the location with +'C-x C-x'. + ** dabbrev --- diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index b58514972a1..93008ca7fbd 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -3052,6 +3052,8 @@ when needed." ;;;###autoload (defun ispell-region (reg-start reg-end &optional recheckp shift) "Interactively check a region for spelling errors. +Mark is left at the final word that the user was queried about. + Return nil if spell session was terminated, otherwise returns shift offset amount for last line processed." (interactive "r") ; Don't flag errors on read-only bufs. @@ -3063,7 +3065,8 @@ amount for last line processed." (region-type (if (and (= reg-start (point-min)) (= reg-end (point-max))) (buffer-name) "region")) (program-basename (file-name-nondirectory ispell-program-name)) - (dictionary (or ispell-current-dictionary "default"))) + (dictionary (or ispell-current-dictionary "default")) + max-word) (unwind-protect (save-excursion (message "Spell-checking %s using %s with %s dictionary..." @@ -3159,10 +3162,14 @@ ispell-region: Search for first region to skip after (ispell-begin-skip-region-r ;; Reset `in-comment' (and indirectly `add-comment') for new line in-comment nil)) (setq ispell-end (point)) ; "end" tracks region retrieved. - (if string ; there is something to spell check! - ;; (special start end) - (setq shift (ispell-process-line string - (and recheckp shift)))) + ;; There is something to spell check! + (when string + ;; (special start end) + (let ((res (ispell-process-line string + (and recheckp shift)))) + (setq shift (car res)) + (when (cdr res) + (setq max-word (cdr res))))) (goto-char ispell-end))))) (if ispell-quit nil @@ -3173,6 +3180,9 @@ ispell-region: Search for first region to skip after (ispell-begin-skip-region-r (kill-buffer ispell-choices-buffer)) (set-marker skip-region-start nil) (set-marker rstart nil) + ;; Allow the user to pop back to the last position. + (when max-word + (push-mark max-word t)) (if ispell-quit (progn ;; preserve or clear the region for ispell-continue. @@ -3407,9 +3417,12 @@ Returns a string with the line data." This will modify the buffer for spelling errors. Requires variables ISPELL-START and ISPELL-END to be defined in its dynamic scope. -Returns the sum SHIFT due to changes in word replacements." + +Returns a cons cell where the `car' is sum SHIFT due to changes +in word replacements, and the `cdr' is the location of the final +word that was queried about." ;;(declare special ispell-start ispell-end) - (let (poss accept-list) + (let (poss accept-list max-word) (if (not (numberp shift)) (setq shift 0)) ;; send string to spell process and get input. @@ -3463,6 +3476,7 @@ Returns the sum SHIFT due to changes in word replacements." (error (concat "Ispell misalignment: word " "`%s' point %d; probably incompatible versions") ispell-pipe-word actual-point))) + (setq max-word (marker-position word-start)) ;; ispell-cmd-loop can go recursive & change buffer (if ispell-keep-choices-win (setq replace (ispell-command-loop @@ -3559,7 +3573,7 @@ Returns the sum SHIFT due to changes in word replacements." (set-marker line-end nil))) ;; Finished with misspelling! (setq ispell-filter (cdr ispell-filter))) - shift)) + (cons shift max-word))) ;;;###autoload @@ -3600,7 +3614,8 @@ to limit the check." ;;;###autoload (defun ispell-buffer () - "Check the current buffer for spelling errors interactively." + "Check the current buffer for spelling errors interactively. +Mark is left at the final word that the user was queried about." (interactive) (ispell-region (point-min) (point-max))) From 2f3cf7ffe3c9ce986caf6d093b880fed6046b7ec Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 17:05:22 +0200 Subject: [PATCH 0109/1028] Use fields on log-edit headers (which changes `C-a' behaviour) * lisp/vc/log-edit.el (log-edit-insert-message-template): Fieldify headers so that `C-a' takes us to the start of the string, not the line (bug#15645). --- lisp/vc/log-edit.el | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index 79dafe60cc2..e958673fea8 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -710,10 +710,14 @@ different header separator appropriate for `log-edit-mode'." (interactive) (when (or (called-interactively-p 'interactive) (log-edit-empty-buffer-p)) - (insert "Summary: ") - (when log-edit-setup-add-author - (insert "\nAuthor: ")) - (insert "\n\n") + (dolist (header (append '("Summary") (and log-edit-setup-add-author + '("Author")))) + ;; Make `C-a' work like in other buffers with header names. + (insert (propertize (concat header ": ") + 'field 'header + 'rear-nonsticky t) + "\n")) + (insert "\n") (message-position-point))) (defun log-edit-insert-cvs-template () From fd49e3c62bf162bbe27de6ecc107a4e934a21708 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 17:46:55 +0200 Subject: [PATCH 0110/1028] Add new command to toggle hiding all widgets in a Customize buffer * lisp/cus-edit.el (custom-commands): Add menu entry. (custom-toggle-hide-all-variables): New command (bug#15748). --- etc/NEWS | 7 +++++++ lisp/cus-edit.el | 30 +++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 1c89493a1ff..ac357a28863 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -780,6 +780,13 @@ so automatically. * Changes in Specialized Modes and Packages in Emacs 29.1 +** Customize + +--- +*** New command 'custom-toggle-hide-all-variables'. +This is bound to 'H' and toggles whether to hide or show the widget +contents. + ** ispell --- diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index dae97b02303..0870bf6782f 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -441,6 +441,7 @@ Use group `text' for this instead. This group is deprecated." (define-key map "u" 'Custom-goto-parent) (define-key map "n" 'widget-forward) (define-key map "p" 'widget-backward) + (define-key map "H" 'custom-toggle-hide-all-variables) map) "Keymap for `Custom-mode'.") @@ -745,6 +746,9 @@ groups after non-groups, if nil do not order groups at all." (or custom-file user-init-file) "Un-customize settings in this and future sessions." "delete" "Uncustomize" (modified set changed rogue saved)) + (" Toggle hiding all values " custom-toggle-hide-all-variables + t "Toggle hiding all values." + "hide" "Hide" t) (" Help for Customize " Custom-help t "Get help for using Customize." "help" "Help" t) (" Exit " Custom-buffer-done t "Exit Customize." "exit" "Exit" t)) @@ -2834,6 +2838,29 @@ try matching its doc string against `custom-guess-doc-alist'." (custom-add-parent-links widget)) (custom-add-see-also widget))))) +(defvar custom--hidden-state) + +(defun custom-toggle-hide-all-variables () + "Toggle whether to show contents of the widgets in the current buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + ;; Surely there's a better way to find all the "top level" widgets + ;; in a buffer, but I couldn't find it. + (while (not (eobp)) + (when-let* ((widget (widget-at (point))) + (parent (widget-get widget :parent)) + (state (widget-get parent :custom-state))) + (when (eq state custom--hidden-state) + (custom-toggle-hide-variable widget))) + (forward-line 1))) + (setq custom--hidden-state (if (eq custom--hidden-state 'hidden) + 'standard + 'hidden)) + (if (eq custom--hidden-state 'hidden) + (message "All variables hidden") + (message "All variables shown"))) + (defun custom-toggle-hide-variable (visibility-widget &rest _ignore) "Toggle the visibility of a `custom-variable' parent widget. By default, this signals an error if the parent has unsaved @@ -5230,7 +5257,8 @@ if that value is non-nil." :label (nth 5 arg))) custom-commands) (setq custom-tool-bar-map map)))) - (setq-local custom--invocation-options nil) + (setq-local custom--invocation-options nil + custom--hidden-state 'hidden) (setq-local revert-buffer-function #'custom--revert-buffer) (make-local-variable 'custom-options) (make-local-variable 'custom-local-buffer) From 44db73d968040cf76ba3b50694cb43d30667205a Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 10 May 2022 18:33:14 +0200 Subject: [PATCH 0111/1028] Fix some quoting problems in defcustom :type * lisp/progmodes/gdb-mi.el (gdb-restore-window-configuration-after-quit): * lisp/gnus/gnus.el (large-newsgroup-initial): * lisp/eshell/em-hist.el (eshell-hist-ignoredups): Fix invalid quoting in :type. --- lisp/eshell/em-hist.el | 2 +- lisp/gnus/gnus.el | 2 +- lisp/progmodes/gdb-mi.el | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index a18127a547a..1877749c5cf 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -104,7 +104,7 @@ in bash, and any other non-nil value mirrors the \"ignoredups\" value." :type '(choice (const :tag "Don't ignore anything" nil) (const :tag "Ignore consecutive duplicates" t) - (const :tag "Only keep last duplicate" 'erase))) + (const :tag "Only keep last duplicate" erase))) (defcustom eshell-save-history-on-exit t "Determine if history should be automatically saved. diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 1f673771fa1..f60c11f985d 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -1591,7 +1591,7 @@ posting an article." "Alist of group regexps and its initial input of the number of articles." :variable-group gnus-group-parameter :parameter-type '(choice :tag "Initial Input for Large Newsgroup" - (const :tag "All" 'all) + (const :tag "All" all) (integer)) :parameter-document "\ diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 089c273bc6d..3b9e1231abb 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -284,8 +284,8 @@ Possible values are: :type '(choice (const :tag "Always restore" t) (const :tag "Don't restore" nil) - (const :tag "Depends on `gdb-show-main'" 'if-gdb-show-main) - (const :tag "Depends on `gdb-many-windows'" 'if-gdb-many-windows)) + (const :tag "Depends on `gdb-show-main'" if-gdb-show-main) + (const :tag "Depends on `gdb-many-windows'" if-gdb-many-windows)) :group 'gdb :version "28.1") From b1cc3adac2ea31699cdbfe166078b463af7e8894 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 10 May 2022 20:13:43 +0300 Subject: [PATCH 0112/1028] ; Fix recent changes in documentation of ispell.el * etc/NEWS: * lisp/textmodes/ispell.el (ispell-region, ispell-buffer): Avoid passive tense in doc strings and NEWS. --- etc/NEWS | 6 +++--- lisp/textmodes/ispell.el | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index ac357a28863..0eb240e2a04 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -791,9 +791,9 @@ contents. --- *** 'ispell-region' and 'ispell-buffer' now push the mark. -The location of the last word the user was queried about is pushed to -the mark ring, so that the user can skip back to the location with -'C-x C-x'. +These commands push onto the mark ring the location of the last +misspelled word where corrections were offered, so that you can then +skip back to that location with 'C-x C-x'. ** dabbrev diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 93008ca7fbd..1810d7bcaeb 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -3052,7 +3052,7 @@ when needed." ;;;###autoload (defun ispell-region (reg-start reg-end &optional recheckp shift) "Interactively check a region for spelling errors. -Mark is left at the final word that the user was queried about. +Leave the mark at the last misspelled word that the user was queried about. Return nil if spell session was terminated, otherwise returns shift offset amount for last line processed." @@ -3615,7 +3615,7 @@ to limit the check." ;;;###autoload (defun ispell-buffer () "Check the current buffer for spelling errors interactively. -Mark is left at the final word that the user was queried about." +Leave the mark at the last misspelled word that the user was queried about." (interactive) (ispell-region (point-min) (point-max))) From a175c9f3f0b9d40f65ee084e5177f401c791c3ae Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 10 May 2022 20:17:59 +0300 Subject: [PATCH 0113/1028] ; * etc/NEWS: Clarify entry about Buffers menu. --- etc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 0eb240e2a04..06a3b24a1dd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -261,7 +261,7 @@ startup. Previously, these functions ignored --- *** The entries following the buffers in the "Buffers" menu can now be altered. Change the 'menu-bar-buffers-menu-command-entries' variable to alter -the remaining entries. +the entries that follow the buffer list. --- ** 'delete-process' is now a command. From b186d5063d0a32ccab1abd8212c7b2858fd8b044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=B8=E0=A4=AE=E0=A5=80=E0=A4=B0=20=E0=A4=B8=E0=A4=BF?= =?UTF-8?q?=E0=A4=82=E0=A4=B9=20Sameer=20Singh?= Date: Tue, 10 May 2022 03:54:14 +0530 Subject: [PATCH 0114/1028] Add support for the Siddham script * lisp/language/indian.el ("Siddham"): New language environment. Add composition rules for Siddham. Add sample text and input method. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Support Siddham. * lisp/leim/quail/indian.el ("siddham"): New input method. * etc/HELLO: Add a Siddham greeting. * etc/NEWS: Announce the new language environment and its input method. (Bug#55350) --- etc/HELLO | 1 + etc/NEWS | 6 ++ lisp/international/fontset.el | 3 +- lisp/language/indian.el | 30 ++++++++++ lisp/leim/quail/indian.el | 104 ++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 1 deletion(-) diff --git a/etc/HELLO b/etc/HELLO index b64aacfbe5b..b14fa0e8614 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -76,6 +76,7 @@ Oriya (ଓଡ଼ିଆ) ଶୁଣିବେ Polish (język polski) Dzień dobry! / Cześć! Russian (русский) Здра́вствуйте! Sharada (𑆯𑆳𑆫𑆢𑆳) 𑆤𑆩𑆱𑇀𑆑𑆳𑆫 +Siddham (𑖭𑖰𑖟𑖿𑖠𑖽) 𑖡𑖦𑖫𑖿𑖝𑖸 Sinhala (සිංහල) ආයුබෝවන් Slovak (slovenčina) Dobrý deň Slovenian (slovenščina) Pozdravljeni! diff --git a/etc/NEWS b/etc/NEWS index 06a3b24a1dd..5b0922506a0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -772,6 +772,12 @@ This language environment supports the Sharada script. Named after the goddess of learning, this script is used to write the Kashmiri language. A new input method, 'sharada', is provided to type text in this script. +*** New language environment "Siddham". +This language environment supports the Siddham script for the Sanskrit +language. Nowadays it is mostly used by the Buddhist monks in Japan for +religious writings. A new input method, 'siddham', is provided to type +text in this script. + --- *** New Greek translation of the Emacs tutorial. Type 'C-u C-h t' to select it in case your language setup does not do diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 7fa390a34be..144c3761a01 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -240,7 +240,7 @@ (grantha #x11305) (newa #x11400) (tirhuta #x11481 #x1148F #x114D0) - (siddham #x11580) + (siddham #x1158E #x115AF #x115D4) (modi #x11600) (takri #x11680) (dogra #x11800) @@ -777,6 +777,7 @@ kaithi sharada tirhuta + siddham makasar dives-akuru cuneiform diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 1e10c2a61a7..b399756bbea 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -169,6 +169,17 @@ Kashmiri language and its script Sharada is supported in this language environment.")) '("Indian")) +(set-language-info-alist + "Siddham" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "siddham") + (sample-text . "Siddham (𑖭𑖰𑖟𑖿𑖠𑖽) 𑖡𑖦𑖭𑖿𑖝𑖸") + (documentation . "\ +Sanskrit language and one of its script Siddham is supported +in this language environment.")) + '("Indian")) + ;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is ;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING). @@ -543,5 +554,24 @@ language environment.")) (concat fricatives "?" consonant vowel "?") 0 'font-shape-gstring)))) +;; Siddham composition rules +(let ((consonant "[\x1158E-\x115AE]") + (nukta "\x115C0") + (independent-vowel "[\x11580-\x1158D\x115D8-\x115DB]") + (vowel "[\x115AF-\x115BB\x115DC\x115DD]") + (nasal "[\x115BC\x115BD]") + (virama "\x115BF")) + (set-char-table-range composition-function-table + '(#x115AF . #x115C0) + (list (vector + ;; Consonant based syllables + (concat consonant nukta "?\\(?:" virama consonant nukta "?\\)*\\(?:" + virama "\\|" vowel "*" nukta "?" nasal "?\\)") + 1 'font-shape-gstring) + (vector + ;; Nasal vowels + (concat independent-vowel nasal "?") + 1 'font-shape-gstring)))) + (provide 'indian) ;;; indian.el ends here diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index b1e547a26ec..3bc03558c32 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -1163,4 +1163,108 @@ Full key sequences are listed below:") ("`M" ?𑇏) ) +(quail-define-package + "siddham" "Sharada" "𑖭𑖰" t "Siddham phonetic input method. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules +("``" ?₹) +("`1" ?𑗊) +("`!" ?𑗔) +("`2" ?𑗋) +("`@" ?𑗕) +("`3" ?𑗌) +("`#" ?𑗖) +("`4" ?𑗍) +("`$" ?𑗗) +("`5" ?𑗎) +("`%" ?𑗅) +("`6" ?𑗏) +("`^" ?𑗆) +("`7" ?𑗐) +("`&" ?𑗇) +("`8" ?𑗑) +("`*" ?𑗈) +("`9" ?𑗒) +("`\(" ?𑗉) +("`0" ?𑗓) +("`\)" ?𑗄) +("`\\" ?𑗂) +("`|" ?𑗃) +("`" ?𑖘) +("q" ?𑖘) +("Q" ?𑖙) +("`q" ?𑗘) +("`Q" ?𑗙) +("w" ?𑖚) +("W" ?𑖛) +("`w" ?𑗚) +("`W" ?𑗛) +("e" ?𑖸) +("E" ?𑖹) +("`e" ?𑖊) +("`E" ?𑖋) +("r" ?𑖨) +("R" ?𑖴) +("`r" ?𑖆) +("t" ?𑖝) +("T" ?𑖞) +("`t" ?𑗜) +("`T" ?𑗝) +("y" ?𑖧) +("u" ?𑖲) +("U" ?𑖳) +("`u" ?𑖄) +("`U" ?𑖅) +("i" ?𑖰) +("I" ?𑖱) +("`i" ?𑖂) +("`I" ?𑖃) +("o" ?𑖺) +("O" ?𑖻) +("`o" ?𑖌) +("`O" ?𑖍) +("p" ?𑖢) +("P" ?𑖣) +("a" ?𑖯) +("A" ?𑖁) +("`a" ?𑖀) +("s" ?𑖭) +("S" ?𑖫) +("d" ?𑖟) +("D" ?𑖠) +("`d" ?𑗁) +("f" ?𑖿) +("F" ?𑖵) +("`f" ?𑖇) +("g" ?𑖐) +("G" ?𑖑) +("h" ?𑖮) +("H" ?𑖾) +("j" ?𑖕) +("J" ?𑖖) +("k" ?𑖎) +("K" ?𑖏) +("l" ?𑖩) +("L" ?𑖈) +("`l" ?𑖉) +("z" ?𑖗) +("Z" ?𑖒) +("x" ?𑖬) +("X" ?𑗀) +("c" ?𑖓) +("C" ?𑖔) +("`c" #x200C) ; ZWNJ +("v" ?𑖪) +("b" ?𑖤) +("B" ?𑖥) +("n" ?𑖡) +("N" ?𑖜) +("m" ?𑖦) +("M" ?𑖽) +("`m" ?𑖼) +) + ;;; indian.el ends here From 620ac6735520aea97ce49059b0df38ed41930b6b Mon Sep 17 00:00:00 2001 From: Alexander Adolf Date: Mon, 2 May 2022 23:01:11 +0200 Subject: [PATCH 0115/1028] EUDC: Add completion-at-point support * lisp/net/eudc-capf.el: New file. * lisp/gnus/message.el (message-mode): Add `eudc-capf-complete' to `completion-at-point-functions' when a `message-mode' buffer is created. * doc/misc/eudc.texi (Inline Query Expansion): Add a new subsection, describing the new `completion-at-point' mechanism in `message-mode'. * etc/NEWS (EUDC): Describe the new `completion-at-point' method. --- doc/misc/eudc.texi | 24 ++++++++ etc/NEWS | 6 ++ lisp/gnus/message.el | 7 ++- lisp/net/eudc-capf.el | 133 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 lisp/net/eudc-capf.el diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index d2850282fea..7fd5add67ea 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -713,6 +713,7 @@ be passed to the program. @node Inline Query Expansion @section Inline Query Expansion +@subsection Inline Query Expansion Using a Key Binding Inline query expansion is a powerful method to get completion from your directory servers. The most common usage is for expanding names @@ -885,6 +886,29 @@ An error is signaled. The expansion aborts. Default is @code{select} @end defvar +@subsection Inline Query Expansion Using completion-at-point + +In addition to providing a dedicated EUDC function for binding to a +key shortcut (@pxref{Inline Query Expansion}), EUDC also provides a +function to contribute search results to the Emacs in-buffer +completion system available via the function +@code{completion-at-point} (@pxref{Identifier +Inquiries,,,maintaining}) in @code{message-mode} buffers +(@pxref{Top,Message,, message, Message}). When using this mechanism, +queries are made in the multi-server query mode of operation +(@pxref{Multi-server Queries}). + +When a buffer in @code{message-mode} is created, EUDC's inline +expansion function is automatically added to the variable +@code{completion-at-point-functions}. As a result, whenever +@code{completion-at-point} is invoked in a @code{message-mode} buffer, +EUDC will be queried for email addresses matching the words before +point. Since this will be useful only when editing specific message +header fields that require specifying one or more email addresses, an +additional check is performed whether point is actually in one of +those header fields. Thus, any matching email addresses will be +offered for completion in suitable message header fields only, and not +in other places, like for example the body of the message. @node The Server Hotlist diff --git a/etc/NEWS b/etc/NEWS index 5b0922506a0..a0164bbf3f0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1073,6 +1073,12 @@ is called, and the returned values are used to populate the phrase and comment parts (see RFC 5322 for definitions). In both cases, the phrase part will be automatically quoted if necessary. ++++ +*** New function 'eudc-capf-complete' with message-mode integration +EUDC can now contribute email addresses to 'completion-at-point' by +adding the new function 'eudc-capf-complete' to +'completion-at-point-functions' in message-mode. + ** eww/shr +++ diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index e7dc089a3c6..3cef2475227 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -51,6 +51,7 @@ (require 'yank-media) (require 'mailcap) (require 'sendmail) +(require 'eudc-capf) (autoload 'mailclient-send-it "mailclient") @@ -3180,8 +3181,7 @@ Like `text-mode', but with these additional commands: (mail-abbrevs-setup)) ((message-mail-alias-type-p 'ecomplete) (ecomplete-setup))) - ;; FIXME: merge the completion tables from ecomplete/bbdb/...? - ;;(add-hook 'completion-at-point-functions #'message-ecomplete-capf nil t) + (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) (add-hook 'completion-at-point-functions #'message-completion-function nil t) (unless buffer-file-name (message-set-auto-save-file-name)) @@ -8364,7 +8364,8 @@ set to nil." (t (expand-abbrev)))) -(add-to-list 'completion-category-defaults '(email (styles substring))) +(add-to-list 'completion-category-defaults '(email (styles substring + partial-completion))) (defun message--bbdb-query-with-words (words) ;; FIXME: This (or something like this) should live on the BBDB side. diff --git a/lisp/net/eudc-capf.el b/lisp/net/eudc-capf.el new file mode 100644 index 00000000000..68cbfd93ffe --- /dev/null +++ b/lisp/net/eudc-capf.el @@ -0,0 +1,133 @@ +;;; eudc-capf.el --- EUDC - completion-at-point bindings -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. +;; +;; Author: Alexander Adolf +;; +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This library provides functions to deliver email addresses from +;; EUDC search results to `completion-at-point'. +;; +;; Email address completion will likely be desirable only in +;; situations where designating email recipients plays a role, such +;; as when composing or replying to email messages, or when posting +;; to newsgroups, possibly with copies of the post being emailed. +;; Hence, modes relevant in such contexts, such as for example +;; `message-mode' and `mail-mode', often at least to some extent +;; provide infrastructure for different functions to be called when +;; completing in certain message header fields, or in the body of +;; the message. In other modes for editing email messages or +;; newsgroup posts, which do not provide such infrastructure, any +;; completion function providing email addresses will need to check +;; whether the completion attempt occurs in an appropriate context +;; (that is, in a relevant message header field) before providing +;; completion candidates. Two mechanisms are thus provided by this +;; library. +;; +;; The first mechanism is intended for use by the modes listed in +;; `eudc-capf-modes', and relies on these modes adding +;; `eudc-capf-complete' to `completion-at-point-functions', as +;; would be usually done for any general-purpose completion +;; function. In this mode of operation, and in order to offer +;; email addresses only in contexts where the user would expect +;; them, a check is performed whether point is on a line that is a +;; message header field suitable for email addresses, such as for +;; example "To:", "Cc:", etc. +;; +;; The second mechanism is intended for when the user modifies +;; `message-completion-alist' to replace `message-expand-name' with +;; the function `eudc-capf-message-expand-name'. As a result, +;; minibuffer completion (`completing-read') for email addresses +;; would no longer enabled in `message-mode', but +;; `completion-at-point' (in-buffer completion) only. + +;;; Usage: + +;; In a major mode, or context where you want email address +;; completion, you would do something along the lines of: +;; +;; (require 'eudc-capf) +;; (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) +;; +;; The minus one argument puts it at the front of the list so it is +;; called first, and the t value for the LOCAL parameter causes the +;; setting to be buffer local, so as to avoid modifying any global +;; setting. +;; +;; The value of the variable `eudc-capf-modes' indicates which +;; major modes do such a setup as part of their initialisation +;; code. + +;;; Code: + +(require 'eudc) + +(defvar message-email-recipient-header-regexp) +(defvar mail-abbrev-mode-regexp) +(declare-function mail-abbrev-in-expansion-header-p "mailabbrev" ()) + +(defconst eudc-capf-modes '(message-mode) + "List of modes in which email address completion is to be attempted.") + +;; completion functions + +;;;###autoload +(defun eudc-capf-complete () + "Email address completion function for `completion-at-point-functions'. + +This function checks whether the current major mode is one of the +modes listed in `eudc-capf-modes', and whether point is on a line +with a message header listing email recipients, that is, a line +whose beginning matches `message-email-recipient-header-regexp', +and, if the check succeeds, searches for records matching the +words before point. + +The return value is either nil when no match is found, or a +completion table as required for functions listed in +`completion-at-point-functions'." + (if (and (seq-some #'derived-mode-p eudc-capf-modes) + (let ((mail-abbrev-mode-regexp message-email-recipient-header-regexp)) + (mail-abbrev-in-expansion-header-p))) + (eudc-capf-message-expand-name))) + +;;;###autoload +(defun eudc-capf-message-expand-name () + "Email address completion function for `message-completion-alist'. + +When this function is added to `message-completion-alist', +replacing any existing entry for `message-expand-name' there, +with an appropriate regular expression such as for example +`message-email-recipient-header-regexp', then EUDC will be +queried for email addresses, and the results delivered to +`completion-at-point'." + (if (or eudc-server eudc-server-hotlist) + (progn + (let* ((beg (save-excursion + (re-search-backward "\\([:,]\\|^\\)[ \t]*") + (match-end 0))) + (end (point)) + (prefix (save-excursion (buffer-substring-no-properties beg end)))) + (list beg end + (completion-table-with-cache + (lambda (_) + (eudc-query-with-words (split-string prefix "[ \t]+") t)) + t)))))) + +(provide 'eudc-capf) +;;; eudc-capf.el ends here From 203ffc68468abaccfed7e8ee630d9aa143ce5dbf Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 10 May 2022 14:44:35 -0700 Subject: [PATCH 0116/1028] Port libm configure-time test to Solaris 11.4 * configure.ac (LIB_MATH): Check all the math.h functions that Emacs uses, not just sqrt (Bug#55294). --- configure.ac | 67 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 484ce980a52..1ba4448d1e4 100644 --- a/configure.ac +++ b/configure.ac @@ -1617,16 +1617,63 @@ AC_DEFUN([AC_TYPE_SIZE_T]) # Likewise for obsolescent test for uid_t, gid_t; Emacs assumes them. AC_DEFUN([AC_TYPE_UID_T]) -# sqrt and other floating-point functions such as fmod and frexp -# are found in -lm on many systems. -OLD_LIBS=$LIBS -AC_SEARCH_LIBS([sqrt], [m]) -if test "X$LIBS" = "X$OLD_LIBS"; then - LIB_MATH= -else - LIB_MATH=$ac_cv_search_sqrt -fi -LIBS=$OLD_LIBS +# Check for all math.h functions that Emacs uses; on some platforms, +# -lm is needed for some of these functions. +AC_CACHE_CHECK([for math library], + [emacs_cv_lib_math], + [OLD_LIBS=$LIBS + AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + #include + int + main (int argc, char **argv) + { + double d = argc; + float f = argc; + int i = argc; + long l = argc; + d = acos (d); + d = asin (d); + d = atan (d); + d = atan2 (d, d); + d = ceil (d); + d = copysign (d, d); + d = cos (d); + d = exp (d); + d = fabs (d); + d = floor (d); + d = fmod (d, d); + d = frexp (d, &i); + d = ldexp (d, i); + d = log (d); + d = log2 (d); + d = log10 (d); + d = pow (d, d); + d = rint (d); + d = scalbn (d, l); + d = sin (d); + d = sqrt (d); + d = tan (d); + d = trunc (d); + f = fabsf (f); + f = powf (f, f); + i = ilogb (d); + i = signbit (d); + l = lrint (d); + l = lround (d); + return d == f && i == l; + } + ]])], + [emacs_cv_lib_math='none required'], + [LIBS="-lm $LIBS" + AC_LINK_IFELSE([], + [emacs_cv_lib_math=-lm], + [AC_MSG_ERROR([Math library (-lm) not found])])]) + LIBS=$OLD_LIBS]) +case $emacs_cv_lib_math in + -*) LIB_MATH=$emacs_cv_lib_math;; + *) LIB_MATH=;; +esac dnl Current possibilities handled by sed (aix4-2 -> aix, dnl gnu-linux -> gnu/linux, etc.): From 4433df3b2015b3b1acd9d24bf7169c010fb51a05 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 10 May 2022 14:47:09 -0700 Subject: [PATCH 0117/1028] * src/floatfns.c: Update comment. --- src/floatfns.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/floatfns.c b/src/floatfns.c index f2b3b13acd8..293184c70f1 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -29,14 +29,20 @@ along with GNU Emacs. If not, see . */ C99 and C11 require the following math.h functions in addition to the C89 functions. Of these, Emacs currently exports only the - starred ones to Lisp, since we haven't found a use for the others: - acosh, atanh, cbrt, *copysign, erf, erfc, exp2, expm1, fdim, fma, - fmax, fmin, fpclassify, hypot, ilogb, isfinite, isgreater, - isgreaterequal, isinf, isless, islessequal, islessgreater, *isnan, - isnormal, isunordered, lgamma, log1p, *log2 [via (log X 2)], *logb - (approximately), lrint/llrint, lround/llround, nan, nearbyint, - nextafter, nexttoward, remainder, remquo, *rint, round, scalbln, - scalbn, signbit, tgamma, *trunc. + starred ones to Lisp, since we haven't found a use for the others. + Also, it uses the ones marked "+" internally: + acosh, atanh, cbrt, copysign (implemented by signbit), erf, erfc, + exp2, expm1, fdim, fma, fmax, fmin, fpclassify, hypot, +ilogb, + isfinite, isgreater, isgreaterequal, isinf, isless, islessequal, + islessgreater, *isnan, isnormal, isunordered, lgamma, log1p, *log2 + [via (log X 2)], logb (approximately; implemented by frexp), + +lrint/llrint, +lround/llround, nan, nearbyint, nextafter, + nexttoward, remainder, remquo, *rint, round, scalbln, +scalbn, + +signbit, tgamma, *trunc. + + The C standard also requires functions for float and long double + that are not listed above. Of these functions, Emacs uses only the + following internally: fabsf, powf, sprintf. */ #include From 430b5ba838f31865139e3a724f9191e2b1de57d1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 10 May 2022 15:20:49 -0700 Subject: [PATCH 0118/1028] * src/eval.c (Ffunctionp): Clarify "function" in doc string. --- src/eval.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index 77ec47e2b79..950338bf799 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2803,7 +2803,11 @@ apply1 (Lisp_Object fn, Lisp_Object arg) } DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0, - doc: /* Return t if OBJECT is a function. */) + doc: /* Return t if OBJECT is a function. + +An object is a function if it is callable via `funcall'; +this includes primitive functions, byte-code functions, closures, and +symbols with function bindings. */) (Lisp_Object object) { if (FUNCTIONP (object)) From 8baa13ed999f5c7895013f86009a983047b12cec Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 09:09:05 +0800 Subject: [PATCH 0119/1028] Clean up some MAYBE_UNUSED functions * src/xterm.c (x_clear_area1): Wrap in the conditions where it will actually be used. --- src/xterm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xterm.c b/src/xterm.c index d44554df7b8..4c1720ca94f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8848,13 +8848,15 @@ x_delete_glyphs (struct frame *f, int n) /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable. If they are <= 0, this is probably an error. */ -MAYBE_UNUSED static void +#if defined USE_GTK || !defined USE_CAIRO +static void x_clear_area1 (Display *dpy, Window window, int x, int y, int width, int height, int exposures) { eassert (width > 0 && height > 0); XClearArea (dpy, window, x, y, width, height, exposures); } +#endif void x_clear_area (struct frame *f, int x, int y, int width, int height) From a09fc827489d595f8776aa0091ec853e4c825d66 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 09:13:36 +0800 Subject: [PATCH 0120/1028] ; * src/window.c (Fset_window_vscroll): Fix doc string. --- src/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.c b/src/window.c index 47c008a643a..a87b4834aaf 100644 --- a/src/window.c +++ b/src/window.c @@ -7959,7 +7959,7 @@ corresponds to an integral number of pixels. The return value is the result of this rounding. If PIXELS-P is non-nil, the return value is VSCROLL. -PRESERVE_VSCROLL_P makes setting the start of WINDOW preserve the +PRESERVE-VSCROLL-P makes setting the start of WINDOW preserve the vscroll if its start is "frozen" due to a resized mini-window. */) (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p, Lisp_Object preserve_vscroll_p) From a78a5b1346683b882613dca1a63d47359fcc8983 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 01:21:18 +0000 Subject: [PATCH 0121/1028] Make reliefs on Haiku more like X * src/haikuterm.c (haiku_draw_relief_rect): Use frame background (normal GC) for corners. --- src/haikuterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index 26ea69758b1..28ab66c9bce 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -715,7 +715,7 @@ haiku_draw_relief_rect (struct glyph_string *s, int left_x, int top_y, if (vwidth > 1 && right_p) BView_StrokeLine (view, right_x, top_y, right_x, bottom_y); - BView_SetHighColor (view, s->face->background); + BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (s->f)); /* Omit corner pixels. */ if (hwidth > 1 && vwidth > 1) From 736081320803c6d1f987f753f63581a0fd42b1fe Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 02:02:21 +0000 Subject: [PATCH 0122/1028] Try to preserve font styles in the Haiku font dialog * haiku_support.cc (class EmacsFontSelectionDialog) (UpdateStylesForIndex): If a style was previously selected and exists in the new family as well, select it after adding the new items. --- src/haiku_support.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 6b4951e139a..cb9dfabc4e7 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -2619,13 +2619,22 @@ class EmacsFontSelectionDialog : public BWindow void UpdateStylesForIndex (int idx) { - int n, i; + int n, i, previous_selection; uint32 flags; font_family family; font_style style; BStringItem *item; + char *current_style; n = all_styles.CountItems (); + current_style = NULL; + previous_selection = font_style_pane.CurrentSelection (); + + if (previous_selection >= 0) + { + item = all_styles.ItemAt (previous_selection); + current_style = strdup (item->Text ()); + } font_style_pane.MakeEmpty (); all_styles.MakeEmpty (); @@ -2641,6 +2650,10 @@ class EmacsFontSelectionDialog : public BWindow else item = new BStringItem (""); + if (current_style && pending_selection_idx < 0 + && !strcmp (current_style, style)) + pending_selection_idx = i; + font_style_pane.AddItem (item); all_styles.AddItem (item); } @@ -2654,6 +2667,9 @@ class EmacsFontSelectionDialog : public BWindow pending_selection_idx = -1; UpdateForSelectedStyle (); + + if (current_style) + free (current_style); } bool From 80951f764b7053f93d69ac5c73c0e504ab308450 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 03:48:36 +0000 Subject: [PATCH 0123/1028] Fix frame invalidation on Haiku * src/haiku_support.cc (FlipBuffers): Only set view bitmap if it actually changed. * src/haikuterm.c (haiku_clip_to_string_exactly) (haiku_draw_window_cursor, haiku_draw_fringe_bitmap): Fix region invalidation. --- src/haiku_support.cc | 9 +++++---- src/haikuterm.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index cb9dfabc4e7..6caf8049d1f 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1619,16 +1619,17 @@ class EmacsView : public BView copy_bitmap = NULL; } if (!copy_bitmap) - copy_bitmap = new BBitmap (offscreen_draw_bitmap_1); + { + copy_bitmap = new BBitmap (offscreen_draw_bitmap_1); + SetViewBitmap (copy_bitmap, Frame (), + Frame (), B_FOLLOW_NONE, 0); + } else copy_bitmap->ImportBits (offscreen_draw_bitmap_1); if (copy_bitmap->InitCheck () != B_OK) gui_abort ("Failed to init copy bitmap during buffer flip"); - SetViewBitmap (copy_bitmap, - Frame (), Frame (), B_FOLLOW_NONE, 0); - Invalidate (&invalid_region); invalid_region.MakeEmpty (); UnlockLooper (); diff --git a/src/haikuterm.c b/src/haikuterm.c index 28ab66c9bce..a7403314823 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -204,6 +204,8 @@ haiku_clip_to_string_exactly (struct glyph_string *s, struct glyph_string *dst) { BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), s->x, s->y, s->width, s->height); + BView_invalidate_region (FRAME_HAIKU_VIEW (s->f), s->x, + s->y, s->width, s->height); } static void @@ -2087,10 +2089,12 @@ haiku_draw_window_cursor (struct window *w, case DEFAULT_CURSOR: case NO_CURSOR: break; + case HBAR_CURSOR: BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h); BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h); break; + case BAR_CURSOR: if (cursor_glyph->resolved_level & 1) { @@ -2104,6 +2108,7 @@ haiku_draw_window_cursor (struct window *w, BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h); break; + case HOLLOW_BOX_CURSOR: if (phys_cursor_glyph->type != IMAGE_GLYPH) { @@ -2115,6 +2120,7 @@ haiku_draw_window_cursor (struct window *w, BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h); break; + case FILLED_BOX_CURSOR: draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); } @@ -2575,13 +2581,18 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row, face = p->face; block_input (); - BView_draw_lock (view, true, p->x, p->y, p->wd, p->h); + BView_draw_lock (view, true, 0, 0, 0, 0); BView_StartClip (view); + if (p->wd && p->h) + BView_invalidate_region (view, p->x, p->y, p->wd, p->h); + haiku_clip_to_row (w, row, ANY_AREA); if (p->bx >= 0 && !p->overlay_p) { + BView_invalidate_region (view, p->bx, p->by, p->nx, p->ny); + if (!face->stipple) { BView_SetHighColor (view, face->background); From 70c4b5bdc6d5e534e1a23c05da1b60c47243a192 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 06:56:43 +0000 Subject: [PATCH 0124/1028] Fix event memory leak on Haiku * src/haikuterm.c (haiku_read_socket): Allocate event buffer on the stack. --- src/haikuterm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index a7403314823..ec6a8f0cea1 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3007,11 +3007,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) message_count = 0; button_or_motion_p = 0; do_help = 0; - buf = NULL; + + buf = alloca (200); block_input (); - if (!buf) - buf = xmalloc (200); haiku_read_size (&b_size, false); while (b_size >= 0) { From 96be8458b09f95eb33a149b724e40c1b38c78478 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 06:59:39 +0000 Subject: [PATCH 0125/1028] Make Haiku event buffer non-static * src/haikuterm.c (haiku_read_socket): Don't make `buf' static in case thread yielding happens inside. --- src/haikuterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haikuterm.c b/src/haikuterm.c index ec6a8f0cea1..58855d07fb8 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -2998,7 +2998,7 @@ static int haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) { int message_count; - static void *buf; + void *buf; ssize_t b_size; int button_or_motion_p, do_help; enum haiku_event_type type; From c8141f76758c43ef861cf6ba70895c01252f85c5 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Wed, 11 May 2022 10:50:12 +0300 Subject: [PATCH 0126/1028] * lisp/textmodes/string-edit.el: Improvements for pop-to-buffer (bug#33007) * lisp/textmodes/string-edit.el (string-edit): Use pop-to-buffer with fit-window-to-buffer after the buffer is filled with text. (string-edit-done, string-edit-abort): Use (quit-window 'kill). --- lisp/textmodes/string-edit.el | 63 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index ab0b3b3bd7c..53850674ac0 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -47,32 +47,39 @@ called with no parameters. PROMPT will be inserted at the start of the buffer, but won't be included in the resulting string. If PROMPT is nil, no help text will be inserted." - (pop-to-buffer-same-window (generate-new-buffer "*edit string*")) - (when prompt - (let ((inhibit-read-only t)) - (insert prompt) - (ensure-empty-lines 0) - (add-text-properties (point-min) (point) - (list 'intangible t - 'face 'string-edit-prompt - 'read-only t)) - (insert (propertize (make-separator-line) 'rear-nonsticky t)) - (add-text-properties (point-min) (point) - (list 'string-edit--prompt t)))) - (let ((start (point))) - (insert string) - (goto-char start)) - (set-buffer-modified-p nil) - (setq buffer-undo-list nil) - (string-edit-mode) - (setq-local string-edit--success-callback success-callback) - (when abort-callback - (setq-local string-edit--abort-callback abort-callback)) - (setq-local header-line-format - (substitute-command-keys - "Type \\\\[string-edit-done] when you've finished editing or \\[string-edit-abort] to abort")) - (message "%s" (substitute-command-keys - "Type \\\\[string-edit-done] when you've finished editing"))) + (with-current-buffer (generate-new-buffer "*edit string*") + (when prompt + (let ((inhibit-read-only t)) + (insert prompt) + (ensure-empty-lines 0) + (add-text-properties (point-min) (point) + (list 'intangible t + 'face 'string-edit-prompt + 'read-only t)) + (insert (propertize (make-separator-line) 'rear-nonsticky t)) + (add-text-properties (point-min) (point) + (list 'string-edit--prompt t)))) + (let ((start (point))) + (insert string) + (goto-char start)) + + ;; Use `fit-window-to-buffer' after the buffer is filled with text. + (pop-to-buffer (current-buffer) + '(display-buffer-below-selected + (window-height . (lambda (window) + (fit-window-to-buffer window nil 10))))) + + (set-buffer-modified-p nil) + (setq buffer-undo-list nil) + (string-edit-mode) + (setq-local string-edit--success-callback success-callback) + (when abort-callback + (setq-local string-edit--abort-callback abort-callback)) + (setq-local header-line-format + (substitute-command-keys + "Type \\\\[string-edit-done] when you've finished editing or \\[string-edit-abort] to abort")) + (message "%s" (substitute-command-keys + "Type \\\\[string-edit-done] when you've finished editing")))) ;;;###autoload (defun read-string-from-buffer (prompt string) @@ -113,14 +120,14 @@ This will kill the current buffer." (goto-char (prop-match-beginning match))) (let ((string (buffer-substring (point) (point-max))) (callback string-edit--success-callback)) - (kill-buffer (current-buffer)) + (quit-window 'kill) (funcall callback string))) (defun string-edit-abort () "Abort editing the current string." (interactive) (let ((callback string-edit--abort-callback)) - (kill-buffer (current-buffer)) + (quit-window 'kill) (when callback (funcall callback)))) From 95717db1e8045f14ca427243a86a0cd433e07273 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 16:01:32 +0800 Subject: [PATCH 0127/1028] Fix mouse pointer avoidance in some configurations * lisp/avoid.el (mouse-avoidance-random-shape): Ignore invisible pointer. (mouse-avoidance-ignore-p): Adjust for interprogram DND. * lisp/term/x-win.el (x-pointer-invisible): Make value larger than the maximum possible glyph. * src/xfns.c (x_set_mouse_color): Use function that handles `x-pointer-invisible' too. * src/xterm.c (x_create_font_cursor): New function. Handle invisible cursors. * src/xterm.h: Update prototypes. --- lisp/avoid.el | 17 ++++++++++------- lisp/term/x-win.el | 4 +++- src/xfns.c | 44 ++++++++++++++++++++++++-------------------- src/xterm.c | 12 ++++++++++++ src/xterm.h | 3 ++- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/lisp/avoid.el b/lisp/avoid.el index b53d84d2e8d..c97e51a6f7d 100644 --- a/lisp/avoid.el +++ b/lisp/avoid.el @@ -300,12 +300,14 @@ has an integer value is a valid cursor shape. You might want to redefine this function to suit your own tastes." (if (null mouse-avoidance-pointer-shapes) (progn - (setq mouse-avoidance-pointer-shapes - (mapcar (lambda (x) (symbol-value (intern x))) - (all-completions "x-pointer-" obarray - (lambda (x) - (and (boundp x) - (integerp (symbol-value x))))))))) + (dolist (i (all-completions "x-pointer-" obarray + (lambda (x) + (and (boundp x) + (integerp (symbol-value x)))))) + (ignore-errors + (let ((value (symbol-value (intern i)))) + (when (< value x-pointer-invisible) + (push value mouse-avoidance-pointer-shapes))))))) (seq-random-elt mouse-avoidance-pointer-shapes)) (defun mouse-avoidance-ignore-p () @@ -317,7 +319,8 @@ redefine this function to suit your own tastes." (not (eq (car mp) (selected-frame))) ;; Don't interfere with ongoing `mouse-drag-and-drop-region' ;; (Bug#36269). - (eq track-mouse 'dropping) + (or (eq track-mouse 'dropping) + (eq track-mouse 'drag-source)) ;; Don't do anything if last event was a mouse event. ;; FIXME: this code fails in the case where the mouse was moved ;; since the last key-press but without generating any event. diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index ca38a0a8c92..08a8bf88e5d 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -241,7 +241,9 @@ exists." (defconst x-pointer-ur-angle 148) (defconst x-pointer-watch 150) (defconst x-pointer-xterm 152) -(defconst x-pointer-invisible 255) +(defconst x-pointer-invisible 65536) ;; This value is larger than a + ;; CARD16, so it cannot be a + ;; valid cursor. ;;;; Keysyms diff --git a/src/xfns.c b/src/xfns.c index 5522684170f..6eddf3a4949 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1261,25 +1261,27 @@ struct mouse_cursor_types { }; /* This array must stay in sync with enum mouse_cursor above! */ -static const struct mouse_cursor_types mouse_cursor_types[] = { - { "text", &Vx_pointer_shape, XC_xterm }, - { "nontext", &Vx_nontext_pointer_shape, XC_left_ptr }, - { "hourglass", &Vx_hourglass_pointer_shape, XC_watch }, - { "modeline", &Vx_mode_pointer_shape, XC_xterm }, - { NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 }, - { NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow }, - { NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow }, - { NULL, &Vx_window_left_edge_shape, XC_left_side }, - { NULL, &Vx_window_top_left_corner_shape, XC_top_left_corner }, - { NULL, &Vx_window_top_edge_shape, XC_top_side }, - { NULL, &Vx_window_top_right_corner_shape, XC_top_right_corner }, - { NULL, &Vx_window_right_edge_shape, XC_right_side }, - { NULL, &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner }, - { NULL, &Vx_window_bottom_edge_shape, XC_bottom_side }, - { NULL, &Vx_window_bottom_left_corner_shape, XC_bottom_left_corner }, -}; +static const struct mouse_cursor_types mouse_cursor_types[] = + { + { "text", &Vx_pointer_shape, XC_xterm }, + { "nontext", &Vx_nontext_pointer_shape, XC_left_ptr }, + { "hourglass", &Vx_hourglass_pointer_shape, XC_watch }, + { "modeline", &Vx_mode_pointer_shape, XC_xterm }, + { NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 }, + { NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow }, + { NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow }, + { NULL, &Vx_window_left_edge_shape, XC_left_side }, + { NULL, &Vx_window_top_left_corner_shape, XC_top_left_corner }, + { NULL, &Vx_window_top_edge_shape, XC_top_side }, + { NULL, &Vx_window_top_right_corner_shape, XC_top_right_corner }, + { NULL, &Vx_window_right_edge_shape, XC_right_side }, + { NULL, &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner }, + { NULL, &Vx_window_bottom_edge_shape, XC_bottom_side }, + { NULL, &Vx_window_bottom_left_corner_shape, XC_bottom_left_corner }, + }; -struct mouse_cursor_data { +struct mouse_cursor_data +{ /* Last index for which XCreateFontCursor has been called, and thus the last index for which x_request_serial[] is valid. */ int last_cursor_create_request; @@ -1360,8 +1362,10 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { cursor_data.x_request_serial[i] = XNextRequest (dpy); cursor_data.last_cursor_create_request = i; - cursor_data.cursor[i] = XCreateFontCursor (dpy, - cursor_data.cursor_num[i]); + + cursor_data.cursor[i] + = x_create_font_cursor (FRAME_DISPLAY_INFO (f), + cursor_data.cursor_num[i]); } /* Now sync up and process all received errors from cursor diff --git a/src/xterm.c b/src/xterm.c index 4c1720ca94f..a250fce9b09 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -22639,6 +22639,18 @@ x_make_frame_visible_invisible (struct frame *f, bool visible) x_make_frame_invisible (f); } +Cursor +x_create_font_cursor (struct x_display_info *dpyinfo, int glyph) +{ + if (glyph <= 65535) + return XCreateFontCursor (dpyinfo->display, glyph); + + /* x-pointer-invisible cannot fit in CARD16, and thus cannot be any + existing cursor. */ + return make_invisible_cursor (dpyinfo); +} + + /* Change window state from mapped to iconified. */ void diff --git a/src/xterm.h b/src/xterm.h index 98c4c5f01c6..3437037e674 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1383,7 +1383,8 @@ extern void x_iconify_frame (struct frame *f); extern void x_free_frame_resources (struct frame *); extern void x_wm_set_size_hint (struct frame *, long, bool); -extern void x_delete_terminal (struct terminal *terminal); +extern void x_delete_terminal (struct terminal *); +extern Cursor x_create_font_cursor (struct x_display_info *, int); extern unsigned long x_copy_color (struct frame *, unsigned long); #ifdef USE_X_TOOLKIT extern XtAppContext Xt_app_con; From 14fe0eec0cc6e4ad636d28832ca6ae22955abd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sun, 8 May 2022 23:33:49 +0200 Subject: [PATCH 0128/1028] * src/lisp.h (FOR_EACH_TAIL_INTERNAL): Faster node comparison. --- src/lisp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lisp.h b/src/lisp.h index 1ad89fc4689..b00f3f7e2e6 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -5515,7 +5515,7 @@ struct for_each_tail_internal || ((check_quit) ? maybe_quit () : (void) 0, 0 < --li.n) \ || (li.q = li.n = li.max <<= 1, li.n >>= USHRT_WIDTH, \ li.tortoise = (tail), false)) \ - && EQ (tail, li.tortoise)) \ + && BASE_EQ (tail, li.tortoise)) \ ? (cycle) : (void) 0)) /* Do a `for' loop over alist values. */ From 474241f356c638bfd8d4eecb7138e3af76a8c036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sun, 8 May 2022 23:37:10 +0200 Subject: [PATCH 0129/1028] Remedy ineffective backslashes and fix regexps * lisp/info.el (Info-read-node-name-2): Double backslash for intended escaping effect. * lisp/term.el (term-send-function-key): Remove redundant `+`. * lisp/leim/quail/indian.el: * lisp/simple.el (scratch-buffer, get-scratch-buffer-create): Remove ineffective backslashes. --- lisp/info.el | 2 +- lisp/leim/quail/indian.el | 18 +++++++++--------- lisp/simple.el | 4 ++-- lisp/term.el | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lisp/info.el b/lisp/info.el index 514cf7b3f47..e51f0b9537a 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1834,7 +1834,7 @@ list of valid filename suffixes for Info files. See ;; include it (without the suffix). (when (and (string-match suffix file) ;; But exclude subfiles of split Info files. - (not (string-match "\.info-[0-9]+" file)) + (not (string-match "\\.info-[0-9]+" file)) ;; And exclude backup files. (not (string-match "~\\'" file))) (push (substring file 0 (match-beginning 0)) diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 3bc03558c32..6c58fdd40be 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -730,10 +730,10 @@ Full key sequences are listed below:") ("`*" ?𑁙) ("9" ?𑁯) ("`9" ?9) - ("`\(" ?𑁚) + ("`(" ?𑁚) ("0" ?𑁦) ("`0" ?0) - ("`\)" ?𑁛) + ("`)" ?𑁛) ("`-" ?𑁜) ("`_" ?𑁝) ("`=" ?𑁞) @@ -780,8 +780,8 @@ Full key sequences are listed below:") ("P" ?𑀨) ("`p" ?𑁳) ("`P" ?𑁱) - ("`\[" ?𑁴) - ("`\{" ?𑁲) + ("`[" ?𑁴) + ("`{" ?𑁲) ("a" ?𑀸) ("A" ?𑀆) ("`a" ?𑀅) @@ -863,7 +863,7 @@ Full key sequences are listed below:") ("`9" ?9) ("0" ?०) ("`0" ?0) -("`\)" ?𑂻) +("`)" ?𑂻) ("`\\" ?𑃀) ("`|" ?𑃁) ("`" ?𑂗) @@ -965,7 +965,7 @@ Full key sequences are listed below:") ("`9" ?9) ("0" ?𑓐) ("`0" ?0) -("`\)" ?𑓆) +("`)" ?𑓆) ("`\\" ?।) ("`|" ?॥) ("`" ?𑒙) @@ -1071,7 +1071,7 @@ Full key sequences are listed below:") ("`9" ?9) ("0" ?𑇐) ("`0" ?0) -("`\)" ?𑇇) +("`)" ?𑇇) ("`\\" ?𑇅) ("`|" ?𑇆) ("`" ?𑆛) @@ -1188,9 +1188,9 @@ Full key sequences are listed below:") ("`8" ?𑗑) ("`*" ?𑗈) ("`9" ?𑗒) -("`\(" ?𑗉) +("`(" ?𑗉) ("`0" ?𑗓) -("`\)" ?𑗄) +("`)" ?𑗄) ("`\\" ?𑗂) ("`|" ?𑗃) ("`" ?𑖘) diff --git a/lisp/simple.el b/lisp/simple.el index edcc226bfa8..89fb0ea97ec 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10214,7 +10214,7 @@ the number of seconds east of Greenwich.") ) (defun get-scratch-buffer-create () - "Return the \*scratch\* buffer, creating a new one if needed." + "Return the *scratch* buffer, creating a new one if needed." (or (get-buffer "*scratch*") (let ((scratch (get-buffer-create "*scratch*"))) ;; Don't touch the buffer contents or mode unless we know that @@ -10227,7 +10227,7 @@ the number of seconds east of Greenwich.") scratch))) (defun scratch-buffer () - "Switch to the \*scratch\* buffer. + "Switch to the *scratch* buffer. If the buffer doesn't exist, create it first." (interactive) (pop-to-buffer-same-window (get-scratch-buffer-create))) diff --git a/lisp/term.el b/lisp/term.el index 640478b59a2..54e19a3ea92 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -1430,7 +1430,7 @@ Entry to this mode runs the hooks on `term-mode-hook'." (when (and (= (length key) 1) (symbolp (elt key 0))) (let ((name (symbol-name (elt key 0)))) - (when (string-match "\\`f\\([0-9]++\\)\\'" name) + (when (string-match "\\`f\\([0-9]+\\)\\'" name) (let* ((num (string-to-number (match-string 1 name))) (ansi (cond From cd7f7c2c33b9bfec1090e88b173adf7788b76bb3 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 02:25:14 +0200 Subject: [PATCH 0130/1028] Fix more defcustom :type errors * lisp/vc/vc-src.el (vc-src-master-templates): * lisp/vc/vc-rcs.el (vc-rcs-master-templates): Remove quote characters inserted by mistake. --- lisp/vc/vc-rcs.el | 2 +- lisp/vc/vc-src.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el index 0a2b8fa53c3..a4345c7d7e2 100644 --- a/lisp/vc/vc-rcs.el +++ b/lisp/vc/vc-rcs.el @@ -100,7 +100,7 @@ to use --brief and sets this variable to remember whether it worked." "Where to look for RCS master files. For a description of possible values, see `vc-check-master-templates'." :type '(choice (const :tag "Use standard RCS file names" - '("%sRCS/%s,v" "%s%s,v" "%sRCS/%s")) + ("%sRCS/%s,v" "%s%s,v" "%sRCS/%s")) (repeat :tag "User-specified" (choice string function))) diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el index 5a252c55cb2..432448bde58 100644 --- a/lisp/vc/vc-src.el +++ b/lisp/vc/vc-src.el @@ -120,7 +120,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." "Where to look for SRC master files. For a description of possible values, see `vc-check-master-templates'." :type '(choice (const :tag "Use standard SRC file names" - '("%s.src/%s,v")) + ("%s.src/%s,v")) (repeat :tag "User-specified" (choice string function)))) From 9fae7b8e033afd3f990b0746bc43713b0c4eeba8 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 02:31:29 +0200 Subject: [PATCH 0131/1028] Regenerated ldefs-boot.el --- lisp/ldefs-boot.el | 47 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index b79c6b2a08b..8f8795196c4 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -2709,6 +2709,12 @@ The optional argument NEW-WINDOW is not used. \(fn URL &optional NEW-WINDOW)" t nil) +(autoload 'browse-url-default-haiku-browser "browse-url" "\ +Browse URL with the system default browser. +Default to the URL around or before point. + +\(fn URL &optional NEW-WINDOW)" t nil) + (autoload 'browse-url-emacs "browse-url" "\ Ask Emacs to load URL into a buffer and show it in another window. Optional argument SAME-WINDOW non-nil means show the URL in the @@ -10207,7 +10213,7 @@ It creates an autoload function for CNAME's constructor. ;;;### (autoloads nil "eldoc" "emacs-lisp/eldoc.el" (0 0 0 0)) ;;; Generated autoloads from emacs-lisp/eldoc.el -(push (purecopy '(eldoc 1 11 1)) package--builtin-versions) +(push (purecopy '(eldoc 1 12 0)) package--builtin-versions) ;;;*** @@ -11961,6 +11967,37 @@ Display a button for the JPEG DATA. (register-definition-prefixes "eudc-bob" '("eudc-bob-")) +;;;*** + +;;;### (autoloads nil "eudc-capf" "net/eudc-capf.el" (0 0 0 0)) +;;; Generated autoloads from net/eudc-capf.el + +(autoload 'eudc-capf-complete "eudc-capf" "\ +Email address completion function for `completion-at-point-functions'. + +This function checks whether the current major mode is one of the +modes listed in `eudc-capf-modes', and whether point is on a line +with a message header listing email recipients, that is, a line +whose beginning matches `message-email-recipient-header-regexp', +and, if the check succeeds, searches for records matching the +words before point. + +The return value is either nil when no match is found, or a +completion table as required for functions listed in +`completion-at-point-functions'." nil nil) + +(autoload 'eudc-capf-message-expand-name "eudc-capf" "\ +Email address completion function for `message-completion-alist'. + +When this function is added to `message-completion-alist', +replacing any existing entry for `message-expand-name' there, +with an appropriate regular expression such as for example +`message-email-recipient-header-regexp', then EUDC will be +queried for email addresses, and the results delivered to +`completion-at-point'." nil nil) + +(register-definition-prefixes "eudc-capf" '("eudc-capf-modes")) + ;;;*** ;;;### (autoloads nil "eudc-export" "net/eudc-export.el" (0 0 0 0)) @@ -19728,6 +19765,8 @@ By just answering RET you can find out what the current dictionary is. (autoload 'ispell-region "ispell" "\ Interactively check a region for spelling errors. +Leave the mark at the last misspelled word that the user was queried about. + Return nil if spell session was terminated, otherwise returns shift offset amount for last line processed. @@ -19746,7 +19785,8 @@ to limit the check. Check the comment or string containing point for spelling errors." t nil) (autoload 'ispell-buffer "ispell" "\ -Check the current buffer for spelling errors interactively." t nil) +Check the current buffer for spelling errors interactively. +Leave the mark at the last misspelled word that the user was queried about." t nil) (autoload 'ispell-buffer-with-debug "ispell" "\ `ispell-buffer' with some output sent to `ispell-debug-buffer'. @@ -31248,8 +31288,9 @@ Make the shell buffer the current buffer, and return it. (autoload 'shortdoc-display-group "shortdoc" "\ Pop to a buffer with short documentation summary for functions in GROUP. If FUNCTION is non-nil, place point on the entry for FUNCTION (if any). +If SAME-WINDOW, don't pop to a new window. -\(fn GROUP &optional FUNCTION)" t nil) +\(fn GROUP &optional FUNCTION SAME-WINDOW)" t nil) (defalias 'shortdoc #'shortdoc-display-group) From 5a121485037a21d03449bc955476c253c89e3671 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 12:37:07 +0200 Subject: [PATCH 0132/1028] Use `nicknames' instead if `'nicknames' in erc-button-alist * lisp/erc/erc-button.el (erc-button-alist): Use "nicknames" instead of "'nicknames" to enable automatic syntax checking (bug#16271). (erc-button-add-buttons): Adjust usage. --- lisp/erc/erc-button.el | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 0e7d0d584fe..dcf6a324351 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -125,7 +125,7 @@ longer than `erc-fill-column'." ;; a button, it makes no sense to optimize performance by ;; bytecompiling lambdas in this alist. On the other hand, it makes ;; things hard to maintain. - '(('nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0) + '((nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0) (erc-button-url-regexp 0 t browse-url-button-open-url 0) (" ]+\\) *>" 0 t browse-url-button-open-url 1) ;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3) @@ -158,12 +158,12 @@ REGEXP is the string matching text around the button or a symbol strings, or an alist with the strings in the car. Note that entries in lists or alists are considered to be nicks or other complete words. Therefore they are enclosed in \\< and \\> - while searching. REGEXP can also be the quoted symbol - \\='nicknames, which matches the nickname of any user on the + while searching. REGEXP can also be the symbol + `nicknames', which matches the nickname of any user on the current server. BUTTON is the number of the regexp grouping actually matching the - button. This is ignored if REGEXP is \\='nicknames. + button. This is ignored if REGEXP is `nicknames'. FORM is a Lisp expression which must eval to true for the button to be added. @@ -174,17 +174,15 @@ CALLBACK is the function to call when the user push this button. PAR is a number of a regexp grouping whose text will be passed to CALLBACK. There can be several PAR arguments. If REGEXP is - \\='nicknames, these are ignored, and CALLBACK will be called with + `nicknames', these are ignored, and CALLBACK will be called with the nickname matched as the argument." - :version "24.1" ; remove finger (bug#4443) + :version "29.1" :type '(repeat (list :tag "Button" (choice :tag "Matches" regexp (variable :tag "Variable containing regexp") - ;; FIXME It really does mean 'nicknames - ;; rather than just nicknames. - (const :tag "Nicknames" 'nicknames)) + (const :tag "Nicknames" nicknames)) (integer :tag "Number of the regexp section that matches") (choice :tag "When to buttonize" (const :tag "Always" t) @@ -256,7 +254,7 @@ specified by `erc-button-alist'." regexp) (erc-button-remove-old-buttons) (dolist (entry alist) - (if (equal (car entry) (quote (quote nicknames))) + (if (eq (car entry) 'nicknames) (erc-button-add-nickname-buttons entry) (progn (setq regexp (or (and (stringp (car entry)) (car entry)) From 231cf5ee2bed8a2b574ad424b624b36c0ee0733f Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 12:51:11 +0200 Subject: [PATCH 0133/1028] Warn about quoted symbols in defcustom choice/other forms * lisp/emacs-lisp/bytecomp.el (byte-compile--suspicious-defcustom-choice): New function (bug#16271). (byte-compile-nogroup-warn): Use it to warn about forms like (choice (const :tag "foo" 'bar)). --- etc/NEWS | 13 +++++++++++ lisp/emacs-lisp/bytecomp.el | 32 ++++++++++++++++++++++---- test/lisp/emacs-lisp/bytecomp-tests.el | 6 +++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index a0164bbf3f0..595e477e2f3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1767,6 +1767,19 @@ functions. * Lisp Changes in Emacs 29.1 +** Byte compilation + +--- +*** Byte compilation will now warn about some malformed 'defcustom' types. +It's very common to write 'defcustom' types on the form: + + :type '(choice (const :tag "foo" 'bar)) + +I.e., double-quoting the 'bar', which is almost never the correct +value. The byte compiler will now issue a warning if it encounters +these forms. + + +++ *** 'restore-buffer-modified-p' can now alter buffer auto-save state. With a FLAG value of 'autosaved', it will mark the buffer as having diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index c0dffe544cf..cbf2659109a 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1562,15 +1562,39 @@ extra args." (dolist (elt '(format message error)) (put elt 'byte-compile-format-like t)) +(defun byte-compile--suspicious-defcustom-choice (type) + "Say whether defcustom TYPE looks odd." + ;; Check whether there's anything like (choice (const :tag "foo" ;; 'bar)). + ;; We don't actually follow the syntax for defcustom types, but this + ;; should be good enough. + (catch 'found + (if (and (consp type) + (proper-list-p type)) + (if (memq (car type) '(const other)) + (when (assq 'quote type) + (throw 'found t)) + (when (memq t (mapcar #'byte-compile--suspicious-defcustom-choice + type)) + (throw 'found t))) + nil))) + ;; Warn if a custom definition fails to specify :group, or :type. (defun byte-compile-nogroup-warn (form) (let ((keyword-args (cdr (cdr (cdr (cdr form))))) (name (cadr form))) (when (eq (car-safe name) 'quote) - (or (not (eq (car form) 'custom-declare-variable)) - (plist-get keyword-args :type) - (byte-compile-warn-x (cadr name) - "defcustom for `%s' fails to specify type" (cadr name))) + (when (eq (car form) 'custom-declare-variable) + (let ((type (plist-get keyword-args :type))) + (cond + ((not type) + (byte-compile-warn-x (cadr name) + "defcustom for `%s' fails to specify type" + (cadr name))) + ((byte-compile--suspicious-defcustom-choice type) + (byte-compile-warn-x + (cadr name) + "defcustom for `%s' has syntactically odd type `%s'" + (cadr name) type))))) (if (and (memq (car form) '(custom-declare-face custom-declare-variable)) byte-compile-current-group) ;; The group will be provided implicitly. diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index abd33ab8e5a..051e8b9e5c9 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -1538,6 +1538,12 @@ EXPECTED-POINT BINDINGS (MODES \\='\\='(ruby-mode js-mode python-mode)) \ (TEST-IN-COMMENTS t) (TEST-IN-STRINGS t) (TEST-IN-CODE t) \ (FIXTURE-FN \\='#\\='electric-pair-mode))" fill-column))) +(defun test-bytecomp-defgroup-choice () + (should-not (byte-compile--suspicious-defcustom-choice 'integer)) + (should-not (byte-compile--suspicious-defcustom-choice + '(choice (const :tag "foo" bar)))) + (should (byte-compile--suspicious-defcustom-choice + '(choice (const :tag "foo" 'bar))))) ;; Local Variables: ;; no-byte-compile: t From 6e275c1bf8d8fd5c276b9cfdbba9201c4e28d9b9 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 13:42:02 +0200 Subject: [PATCH 0134/1028] Don't try to toggle untogglable widgets in custom-toggle-hide-all-variables * lisp/cus-edit.el (custom-toggle-hide-all-variables): Only toggle the widgets that can be toggled. --- lisp/cus-edit.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index 0870bf6782f..f2202563456 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -2851,7 +2851,10 @@ try matching its doc string against `custom-guess-doc-alist'." (when-let* ((widget (widget-at (point))) (parent (widget-get widget :parent)) (state (widget-get parent :custom-state))) - (when (eq state custom--hidden-state) + (when (eq state 'changed) + (setq state 'standard)) + (when (and (eq (widget-type widget) 'custom-visibility) + (eq state custom--hidden-state)) (custom-toggle-hide-variable widget))) (forward-line 1))) (setq custom--hidden-state (if (eq custom--hidden-state 'hidden) From f8bafead0b54655d269f3fa57021ddc922b0a2a7 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 13:56:10 +0200 Subject: [PATCH 0135/1028] Revert "Add meta navigation keys to outline-minor-mode-cycle-map" This reverts commit 2e949031160d769bbac941c064b825a5c578afc5. These key bindings are too intrusive. --- lisp/outline.el | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lisp/outline.el b/lisp/outline.el index 81e312ee019..7fd43195cc0 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -215,10 +215,6 @@ This option is only in effect when `outline-minor-mode-cycle' is non-nil." (let ((map (make-sparse-keymap))) (outline-minor-mode-cycle--bind map (kbd "TAB") #'outline-cycle) (outline-minor-mode-cycle--bind map (kbd "") #'outline-cycle-buffer) - (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-promote) - (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-demote) - (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-move-subtree-up) - (outline-minor-mode-cycle--bind map (kbd "M-") #'outline-move-subtree-down) map) "Keymap used by `outline-minor-mode-cycle'.") From 72b100798743685e87f336a8dffa97ee149eeefe Mon Sep 17 00:00:00 2001 From: Yoav Marco Date: Wed, 11 May 2022 14:05:37 +0200 Subject: [PATCH 0136/1028] (sqlite-mode--column-names): Suppport nested parens * lisp/sqlite-mode.el (sqlite-mode--column-names): Make parsing more resilient (bug#55363). Copyright-paperwork-exempt: yes --- lisp/sqlite-mode.el | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lisp/sqlite-mode.el b/lisp/sqlite-mode.el index ba1b81ef7e2..66e2e487d9c 100644 --- a/lisp/sqlite-mode.el +++ b/lisp/sqlite-mode.el @@ -129,15 +129,23 @@ (insert (format " %s\n" column)))))))) (defun sqlite-mode--column-names (table) + "Return a list of the column names for TABLE." (let ((sql (caar (sqlite-select sqlite--db "select sql from sqlite_master where tbl_name = ? AND type = 'table'" (list table))))) - (mapcar - #'string-trim - (split-string (replace-regexp-in-string "^.*(\\|)$" "" sql) ",")))) + (with-temp-buffer + (insert sql) + (mapcar #'string-trim + (split-string + ;; Extract the args to CREATE TABLE. Point is + ;; currently at its end. + (buffer-substring + (1- (point)) ; right before ) + (1+ (progn (backward-sexp) (point)))) ; right after ( + ","))))) (defun sqlite-mode-list-data () "List the data from the table under point." From ed1a24b4b2e39498e4c4448365e1d5f0149e5fc6 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 14:18:27 +0200 Subject: [PATCH 0137/1028] Don't signal errors in check-declare-directory * lisp/emacs-lisp/check-declare.el (check-declare-directory): Don't bug out if we don't find any files with declare-function:(bug#55354) because this is a predicate function, and that's inconvenient. --- lisp/emacs-lisp/check-declare.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index eeefb3de10c..b3c965166b6 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -319,10 +319,11 @@ Returns non-nil if any false statements are found." (setq root (directory-file-name (file-relative-name root))) (or (file-directory-p root) (error "Directory `%s' not found" root)) - (let ((files (process-lines find-program root - "-name" "*.el" - "-exec" grep-program - "-l" "^[ \t]*(declare-function" "{}" "+"))) + (let ((files (process-lines-ignore-status + find-program root + "-name" "*.el" + "-exec" grep-program + "-l" "^[ \t]*(declare-function" "{}" "+"))) (when files (apply #'check-declare-files files)))) From 61046ffbec0d819856a04d7aa72e32e5cc402838 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 14:26:53 +0200 Subject: [PATCH 0138/1028] Bind gud-go and allow the prefix to enter arguments * lisp/progmodes/gdb-mi.el (gdb): Bind gud-go to `C-c C-v' and allow a prefix to enter arguments (bug#10106). --- etc/NEWS | 5 +++++ lisp/progmodes/gdb-mi.el | 14 +++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 595e477e2f3..9e985de0b39 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -786,6 +786,11 @@ so automatically. * Changes in Specialized Modes and Packages in Emacs 29.1 +--- +*** 'gud-go' is now bound to 'C-c C-v'. +If given a prefix, it will query the user for an argument to use for +the run/continue command. + ** Customize --- diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 3b9e1231abb..06746af761c 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -955,12 +955,16 @@ detailed description of this mode. (forward-char 2) (gud-call "-exec-until *%a" arg))) "\C-u" "Continue to current line or address.") - ;; TODO Why arg here? (gud-def - gud-go (gud-call (if gdb-active-process - (gdb-gud-context-command "-exec-continue") - "-exec-run") arg) - nil "Start or continue execution.") + gud-go (progn + (when arg + (gud-call (concat "-exec-arguments " + (read-string "Arguments to exec-run: ")))) + (gud-call + (if gdb-active-process + (gdb-gud-context-command "-exec-continue") + "-exec-run"))) + "C-v" "Start or continue execution. Use a prefix to specify arguments.") ;; For debugging Emacs only. (gud-def gud-pp From 125cda74981fddf63f827f96844cf6d9a413aa1a Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 14:28:32 +0200 Subject: [PATCH 0139/1028] Fix compilation warning in gdb-mi.el * lisp/progmodes/gdb-mi.el (gud-go): Fix compilation warning introduced by previous change. --- lisp/progmodes/gdb-mi.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 06746af761c..c9b6ccd324f 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -105,6 +105,7 @@ ;; at toplevel, so the compiler doesn't know under which circumstances ;; they're defined. (declare-function gud-until "gud" (arg)) +(declare-function gud-go "gud" (arg)) (declare-function gud-print "gud" (arg)) (declare-function gud-down "gud" (arg)) (declare-function gud-up "gud" (arg)) From 5079f42446aab520e20aad30f825ccbc448ba4e3 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 12:40:32 +0000 Subject: [PATCH 0140/1028] Add support for changing pointer types on Haiku * doc/lispref/frames.texi (Pointer Shape): Document that the pointer shape can now be changed on some window systems other than X. * lisp/term/haiku-win.el (x-pointer-X-cursor, x-pointer-arrow) (x-pointer-bottom-left-corner, x-pointer-bottom-right-corner) (x-pointer-bottom-side, x-pointer-clock, x-pointer-cross) (x-pointer-cross-reverse, x-pointer-crosshair) (x-pointer-diamond-cross, x-pointer-hand1, x-pointer-hand2) (x-pointer-left-side, x-pointer-right-side) (x-pointer-sb-down-arrow, x-pointer-sb-left-arrow) (x-pointer-sb-right-arrow, x-pointer-sb-up-arrow, x-pointer-target) (x-pointer-top-left-corner, x-pointer-top-right-corner) (x-pointer-top-side, x-pointer-watch, x-pointer-invisible): New pointer constants. * src/haiku_support.cc (BCursor_from_id): Accept int instead of enum. * src/haiku_support.h: Update prototypes. * src/haikufns.c (haiku_create_frame): Stop manually assigning cursors and set default value of the mouse color property. (haiku_free_frame_resources): Free custom cursors too. (struct user_cursor_info, INIT_USER_CURSOR): New struct. (haiku_free_custom_cursors): New function. (haiku_set_mouse_color): New param handler. (haiku_frame_parm_handlers): Add param handler. (syms_of_haikufns): New cursor shape variables from X. * src/haikuterm.h: Update prototypes. --- doc/lispref/frames.texi | 5 +- lisp/term/haiku-win.el | 31 +++++++ src/haiku_support.cc | 2 +- src/haiku_support.h | 2 +- src/haikufns.c | 173 ++++++++++++++++++++++++++++++++++------ src/haikuterm.h | 1 + 6 files changed, 184 insertions(+), 30 deletions(-) diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 05c6e4b719b..3bbeef005bd 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -3877,8 +3877,9 @@ in the buffer. The default is to use the @code{arrow} (non-text) pointer style. @end defopt - When using X, you can specify what the @code{text} pointer style -really looks like by setting the variable @code{x-pointer-shape}. + When using some window systems, you can specify what the @code{text} +pointer style really looks like by setting the variable +@code{x-pointer-shape}. @defvar x-pointer-shape This variable specifies the pointer shape to use ordinarily in the diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 6396779d60d..7f3bba52e59 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -392,6 +392,37 @@ take effect on menu items until the menu bar is updated again." ;; the Deskbar will not, so kill ourself here. (unless cancel-shutdown (kill-emacs)))) + +;;;; Cursors. + +;; We use the same interface as X, but the cursor numbers are +;; different, and there are also less cursors. + +(defconst x-pointer-X-cursor 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-arrow 1) ; B_CURSOR_ID_SYSTEM_DEFAULT +(defconst x-pointer-bottom-left-corner 22) ; B_CURSOR_ID_RESIZE_SOUTH_WEST +(defconst x-pointer-bottom-right-corner 21) ; B_CURSOR_ID_RESIZE_SOUTH_EAST +(defconst x-pointer-bottom-side 17) ; B_CURSOR_ID_RESIZE_SOUTH +(defconst x-pointer-clock 14) ; B_CURSOR_ID_PROGRESS +(defconst x-pointer-cross 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-cross-reverse 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-crosshair 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-diamond-cross 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-hand1 7) ; B_CURSOR_ID_GRAB +(defconst x-pointer-hand2 8) ; B_CURSOR_ID_GRABBING +(defconst x-pointer-left-side 18) ; B_CURSOR_ID_RESIZE_WEST +(defconst x-pointer-right-side 16) ; B_CURSOR_ID_RESIZE_EAST +(defconst x-pointer-sb-down-arrow 17) ; B_CURSOR_ID_RESIZE_SOUTH +(defconst x-pointer-sb-left-arrow 18) ; B_CURSOR_ID_RESIZE_WEST +(defconst x-pointer-sb-right-arrow 16) ; B_CURSOR_ID_RESIZE_EAST +(defconst x-pointer-sb-up-arrow 16) ; B_CURSOR_ID_RESIZE_NORTH +(defconst x-pointer-target 5) ; B_CURSOR_ID_CROSS_HAIR +(defconst x-pointer-top-left-corner 20) ; B_CURSOR_ID_RESIZE_NORTH_WEST +(defconst x-pointer-top-right-corner 19) ; B_CURSOR_ID_RESIZE_NORTH_EAST +(defconst x-pointer-top-side 16) ; B_CURSOR_ID_RESIZE_NORTH +(defconst x-pointer-watch 14) ; B_CURSOR_ID_PROGRESS +(defconst x-pointer-invisible 12) ; B_CURSOR_ID_NO_CURSOR + (provide 'haiku-win) (provide 'term/haiku-win) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 6caf8049d1f..39e8daa8269 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -3392,7 +3392,7 @@ BCursor_create_modeline (void) } void * -BCursor_from_id (enum haiku_cursor cursor) +BCursor_from_id (int cursor) { return new BCursor ((enum BCursorID) cursor); } diff --git a/src/haiku_support.h b/src/haiku_support.h index 416c717546f..3ea6e838d7f 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -557,7 +557,7 @@ extern void be_get_screen_dimensions (int *, int *); /* Functions for creating and freeing cursors. */ extern void *BCursor_create_default (void); -extern void *BCursor_from_id (enum haiku_cursor); +extern void *BCursor_from_id (int); extern void *BCursor_create_modeline (void); extern void *BCursor_create_i_beam (void); extern void *BCursor_create_progress_cursor (void); diff --git a/src/haikufns.c b/src/haikufns.c index 8596317de25..0abb4188955 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -763,6 +763,8 @@ haiku_create_frame (Lisp_Object parms) "foreground", "Foreground", RES_TYPE_STRING); gui_default_parameter (f, parms, Qbackground_color, build_string ("white"), "background", "Background", RES_TYPE_STRING); + gui_default_parameter (f, parms, Qmouse_color, build_string ("black"), + "pointerColor", "Foreground", RES_TYPE_STRING); gui_default_parameter (f, parms, Qline_spacing, Qnil, "lineSpacing", "LineSpacing", RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qleft_fringe, Qnil, @@ -820,33 +822,11 @@ haiku_create_frame (Lisp_Object parms) RES_TYPE_BOOLEAN); f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem)); - block_input (); -#define ASSIGN_CURSOR(cursor) \ - (FRAME_OUTPUT_DATA (f)->cursor = dpyinfo->cursor) - - ASSIGN_CURSOR (text_cursor); - ASSIGN_CURSOR (nontext_cursor); - ASSIGN_CURSOR (modeline_cursor); - ASSIGN_CURSOR (hand_cursor); - ASSIGN_CURSOR (hourglass_cursor); - ASSIGN_CURSOR (horizontal_drag_cursor); - ASSIGN_CURSOR (vertical_drag_cursor); - ASSIGN_CURSOR (left_edge_cursor); - ASSIGN_CURSOR (top_left_corner_cursor); - ASSIGN_CURSOR (top_edge_cursor); - ASSIGN_CURSOR (top_right_corner_cursor); - ASSIGN_CURSOR (right_edge_cursor); - ASSIGN_CURSOR (bottom_right_corner_cursor); - ASSIGN_CURSOR (bottom_edge_cursor); - ASSIGN_CURSOR (bottom_left_corner_cursor); - ASSIGN_CURSOR (no_cursor); - - FRAME_OUTPUT_DATA (f)->current_cursor = dpyinfo->text_cursor; -#undef ASSIGN_CURSOR - f->terminal->reference_count++; - FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view); + block_input (); + FRAME_OUTPUT_DATA (f)->window + = BWindow_new (&FRAME_OUTPUT_DATA (f)->view); unblock_input (); if (!FRAME_OUTPUT_DATA (f)->window) @@ -1567,6 +1547,7 @@ haiku_free_frame_resources (struct frame *f) dpyinfo = FRAME_DISPLAY_INFO (f); free_frame_faces (f); + haiku_free_custom_cursors (f); /* Free scroll bars */ for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next) @@ -1792,6 +1773,133 @@ haiku_set_sticky (struct frame *f, Lisp_Object new_value, unblock_input (); } +struct user_cursor_info +{ + /* A pointer to the Lisp_Object describing the cursor. */ + Lisp_Object *lisp_cursor; + + /* The offset of the cursor in the `struct haiku_output' of each + frame. */ + ptrdiff_t output_offset; + + /* The offset of the default value of the cursor in the display + info structure. */ + ptrdiff_t default_offset; +}; + +#define INIT_USER_CURSOR(lisp, cursor) \ + { (lisp), offsetof (struct haiku_output, cursor), \ + offsetof (struct haiku_display_info, cursor) } + +struct user_cursor_info custom_cursors[] = + { + INIT_USER_CURSOR (&Vx_pointer_shape, text_cursor), + INIT_USER_CURSOR (NULL, nontext_cursor), + INIT_USER_CURSOR (NULL, modeline_cursor), + INIT_USER_CURSOR (&Vx_sensitive_text_pointer_shape, hand_cursor), + INIT_USER_CURSOR (&Vx_hourglass_pointer_shape, hourglass_cursor), + INIT_USER_CURSOR (NULL, horizontal_drag_cursor), + INIT_USER_CURSOR (NULL, vertical_drag_cursor), + INIT_USER_CURSOR (NULL, left_edge_cursor), + INIT_USER_CURSOR (NULL, top_left_corner_cursor), + INIT_USER_CURSOR (NULL, top_edge_cursor), + INIT_USER_CURSOR (NULL, top_right_corner_cursor), + INIT_USER_CURSOR (NULL, right_edge_cursor), + INIT_USER_CURSOR (NULL, bottom_right_corner_cursor), + INIT_USER_CURSOR (NULL, bottom_edge_cursor), + INIT_USER_CURSOR (NULL, bottom_left_corner_cursor), + INIT_USER_CURSOR (NULL, no_cursor), + }; + +/* Free all cursors not default in F. */ +void +haiku_free_custom_cursors (struct frame *f) +{ + struct user_cursor_info *cursor; + struct haiku_output *output; + struct haiku_display_info *dpyinfo; + Emacs_Cursor *frame_cursor; + Emacs_Cursor *display_cursor; + int i; + + output = FRAME_OUTPUT_DATA (f); + dpyinfo = FRAME_DISPLAY_INFO (f); + + for (i = 0; i < ARRAYELTS (custom_cursors); ++i) + { + cursor = &custom_cursors[i]; + frame_cursor = (Emacs_Cursor *) ((char *) output + + cursor->output_offset); + display_cursor = (Emacs_Cursor *) ((char *) dpyinfo + + cursor->default_offset); + + if (*frame_cursor != *display_cursor + && *frame_cursor) + { + BCursor_delete (*frame_cursor); + + if (output->current_cursor == *frame_cursor) + output->current_cursor = *display_cursor; + } + + *frame_cursor = *display_cursor; + } +} + +static void +haiku_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + struct haiku_output *output; + Emacs_Cursor *frame_cursor, old; + int i, n; + + output = FRAME_OUTPUT_DATA (f); + + /* This will also reset all the cursors back to their default + values. */ + haiku_free_custom_cursors (f); + + for (i = 0; i < ARRAYELTS (custom_cursors); ++i) + { + frame_cursor = (Emacs_Cursor *) ((char *) output + + custom_cursors[i].output_offset); + old = *frame_cursor; + + if (custom_cursors[i].lisp_cursor + && FIXNUMP (*custom_cursors[i].lisp_cursor)) + { + if (!RANGED_FIXNUMP (0, *custom_cursors[i].lisp_cursor, + 28)) /* 28 is the largest Haiku cursor ID. */ + signal_error ("Invalid cursor", + *custom_cursors[i].lisp_cursor); + + n = XFIXNUM (*custom_cursors[i].lisp_cursor); + + /* Create and set the custom cursor. */ + block_input (); + *frame_cursor = BCursor_from_id (n); + unblock_input (); + + /* This function can be called before the frame's window is + created. */ + if (FRAME_HAIKU_WINDOW (f)) + { + if (output->current_cursor == old) + { + output->current_cursor = *frame_cursor; + + block_input (); + BView_set_view_cursor (FRAME_HAIKU_VIEW (f), + *frame_cursor); + unblock_input (); + } + } + } + } + + update_face_from_frame_parameter (f, Qmouse_color, arg); +} + DEFUN ("haiku-set-mouse-absolute-pixel-position", @@ -2701,7 +2809,7 @@ frame_parm_handler haiku_frame_parm_handlers[] = gui_set_right_divider_width, gui_set_bottom_divider_width, haiku_set_menu_bar_lines, - NULL, /* set mouse color */ + haiku_set_mouse_color, haiku_explicitly_set_name, gui_set_scroll_bar_width, gui_set_scroll_bar_height, @@ -2805,6 +2913,19 @@ syms_of_haikufns (void) doc: /* SKIP: real doc in xfns.c. */); Vx_cursor_fore_pixel = Qnil; + DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape, + doc: /* SKIP: real doc in xfns.c. */); + Vx_pointer_shape = Qnil; + + DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape, + doc: /* SKIP: real doc in xfns.c. */); + Vx_hourglass_pointer_shape = Qnil; + + DEFVAR_LISP ("x-sensitive-text-pointer-shape", + Vx_sensitive_text_pointer_shape, + doc: /* SKIP: real doc in xfns.c. */); + Vx_sensitive_text_pointer_shape = Qnil; + DEFVAR_LISP ("haiku-allowed-ui-colors", Vhaiku_allowed_ui_colors, doc: /* Vector of UI colors that Emacs can look up from the system. If this is set up incorrectly, Emacs can crash when encoutering an diff --git a/src/haikuterm.h b/src/haikuterm.h index cc032d03892..4b124a6ba30 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -304,6 +304,7 @@ extern void haiku_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object); extern void haiku_set_internal_border_width (struct frame *, Lisp_Object, Lisp_Object); extern void haiku_change_tab_bar_height (struct frame *, int); extern void haiku_change_tool_bar_height (struct frame *, int); +extern void haiku_free_custom_cursors (struct frame *); extern void haiku_query_color (uint32_t, Emacs_Color *); From d373daf568cd45153d842de49288eb424e5b32e9 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 14:59:17 +0200 Subject: [PATCH 0141/1028] Add new command 'vc-dir-mark-by-regexp' * doc/emacs/maintaining.texi (VC Directory Commands): Document it. * lisp/vc/vc-dir.el (vc-dir-mode-map): Bind it to `%'. (vc-dir-mark-by-regexp): New command (bug#16460). --- doc/emacs/maintaining.texi | 6 ++++++ etc/NEWS | 5 +++++ lisp/vc/vc-dir.el | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index cca8441daa5..3ddea0ae588 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1316,6 +1316,12 @@ point is on a directory entry, mark all files in that directory tree (@code{vc-dir-mark-all-files}). With a prefix argument, mark all listed files and directories. +@findex vc-dir-mark-by-regexp +@item % +You can use this command to mark files by regexp +(@code{vc-dir-mark-by-regexp}). If given a prefix, unmark files +instead. + @item G Add the file under point to the list of files that the VC should ignore (@code{vc-dir-ignore}). For instance, if the VC is Git, it diff --git a/etc/NEWS b/etc/NEWS index 9e985de0b39..68c7490e56c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1009,6 +1009,11 @@ info node. This command only works for the Emacs and Emacs Lisp manuals. ** vc ++++ +*** New command '%' ('vc-dir-mark-by-regexp'). +This command marks files based on a regexp. If given a prefix +argument, unmark instead. + --- *** 'C-x v v' on an unregistered file will now use the most specific backend. Previously, if you had an SVN-covered "~/" directory, and a Git-covered diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 1545763a3a1..9335da10065 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -325,6 +325,7 @@ See `run-hooks'." (define-key map "U" #'vc-dir-unmark-all-files) (define-key map "\C-?" #'vc-dir-unmark-file-up) (define-key map "\M-\C-?" #'vc-dir-unmark-all-files) + (define-key map "%" #'vc-dir-mark-by-regexp) ;; Movement. (define-key map "n" #'vc-dir-next-line) (define-key map " " #'vc-dir-next-line) @@ -750,6 +751,23 @@ share the same state." (vc-dir-mark-file crt))) (setq crt (ewoc-next vc-ewoc crt)))))))) +(defun vc-dir-mark-by-regexp (regexp &optional unmark) + "Mark all files that match REGEXP. +If UNMARK (interactively, the prefix), unmark instead." + (interactive "sMark files matching: \nP") + (ewoc-map + (lambda (filearg) + (when (and (not (vc-dir-fileinfo->directory filearg)) + (eq (not unmark) + (not (vc-dir-fileinfo->marked filearg))) + ;; We don't want to match on the part of the file + ;; that's above the current directory. + (string-match-p regexp (file-relative-name + (vc-dir-fileinfo->name filearg)))) + (setf (vc-dir-fileinfo->marked filearg) (not unmark)) + t)) + vc-ewoc)) + (defun vc-dir-mark-files (mark-files) "Mark files specified by file names in the argument MARK-FILES. MARK-FILES should be a list of absolute filenames." From c113f2626e58a1d3b98bdf364902f53caa2dc3a8 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 15:02:08 +0200 Subject: [PATCH 0142/1028] Make recent nicknames erc change more backwards-compatible * lisp/erc/erc-button.el (erc-button-add-buttons): Make the nicknames change more backwards-compatible (bug#16271). --- lisp/erc/erc-button.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index dcf6a324351..aeada705c4a 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -254,7 +254,9 @@ specified by `erc-button-alist'." regexp) (erc-button-remove-old-buttons) (dolist (entry alist) - (if (eq (car entry) 'nicknames) + (if (or (eq (car entry) 'nicknames) + ;; Old form retained for backward compatibility. + (equal (car entry) (quote 'nicknames))) (erc-button-add-nickname-buttons entry) (progn (setq regexp (or (and (stringp (car entry)) (car entry)) From 4e4c62a156f6440a9144f43875a9ad3ebfbc05d0 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 11 May 2022 15:13:37 +0200 Subject: [PATCH 0143/1028] Add grep-files-aliases entry for .am files * lisp/progmodes/grep.el (grep-files-aliases): Add an alias for .am files (bug#16921). --- lisp/progmodes/grep.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 7620536b4b6..a8d743b87a8 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -215,6 +215,7 @@ by `grep-compute-defaults'; to change the default value, use ("hh" . "*.hxx *.hpp *.[Hh] *.HH *.h++") ("h" . "*.h") ("l" . "[Cc]hange[Ll]og*") + ("am" . "Makefile.am GNUmakefile *.mk") ("m" . "[Mm]akefile*") ("tex" . "*.tex") ("texi" . "*.texi") From fb42001086a67a1cf47ad31c2495de4f5c6661e7 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 11 May 2022 16:49:15 +0300 Subject: [PATCH 0144/1028] ; * lisp/cus-edit.el (custom-toggle-hide-all-variables): Doc fix. --- lisp/cus-edit.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index f2202563456..a7d06d5e421 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -2841,7 +2841,14 @@ try matching its doc string against `custom-guess-doc-alist'." (defvar custom--hidden-state) (defun custom-toggle-hide-all-variables () - "Toggle whether to show contents of the widgets in the current buffer." + "Hide or show details of all customizable settings in a Custom buffer. +This command is for use in a Custom buffer that shows many +customizable settings, like \"*Customize Group*\" or \"*Customize Faces*\". +It toggles the display of each of the customizable settings in the buffer +between the expanded view, where the values of the settings and the value +menus to change them are visible; and the concise view, where only the +minimal details are shown, usually the name, the doc string and little +else." (interactive) (save-excursion (goto-char (point-min)) From 4993050c2aacee2d05b090861566a7f3a56cb64c Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 10 May 2022 22:55:08 +0200 Subject: [PATCH 0145/1028] * lisp/calendar/diary-lib.el (diary-mode-map): Prefer defvar-keymap. --- lisp/calendar/diary-lib.el | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index 45df0c6259c..48dbf33adff 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -1,7 +1,6 @@ ;;; diary-lib.el --- diary functions -*- lexical-binding:t -*- -;; Copyright (C) 1989-1990, 1992-1995, 2001-2022 Free Software -;; Foundation, Inc. +;; Copyright (C) 1989-2022 Free Software Foundation, Inc. ;; Author: Edward M. Reingold ;; Maintainer: emacs-devel@gnu.org @@ -2246,12 +2245,10 @@ Prefix argument ARG makes the entry nonmarking." ;; Return value suitable for `write-contents-functions'. nil) -(defvar diary-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-s" 'diary-show-all-entries) - (define-key map "\C-c\C-q" 'quit-window) - map) - "Keymap for `diary-mode'.") +(defvar-keymap diary-mode-map + :doc "Keymap for `diary-mode'." + "C-c C-s" #'diary-show-all-entries + "C-c C-q" #'quit-window) (defun diary-font-lock-sexps (limit) "Recognize sexp diary entry up to LIMIT for font-locking." From 9971a309aab7a8b4055fb0f2ee749da2fae6e3ed Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 10 May 2022 22:59:57 +0200 Subject: [PATCH 0146/1028] * lisp/iimage.el (iimage-mode-map): Prefer defvar-keymap. --- lisp/iimage.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lisp/iimage.el b/lisp/iimage.el index 2fe50d3e3f1..8a765d5e5d5 100644 --- a/lisp/iimage.el +++ b/lisp/iimage.el @@ -76,11 +76,9 @@ Examples of image filename patterns to match: foo.JPG" :type '(alist :key-type regexp :value-type integer)) -(defvar iimage-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-l" #'iimage-recenter) - map) - "Keymap used in `iimage-mode'.") +(defvar-keymap iimage-mode-map + :doc "Keymap used in `iimage-mode'." + "C-l" #'iimage-recenter) (defun iimage-recenter (&optional arg) "Re-draw images and recenter." From 4299bf6da78f786a6db7880009d61addba55c71f Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 10 May 2022 23:13:19 +0200 Subject: [PATCH 0147/1028] * lisp/scroll-lock.el (scroll-lock-mode-map): Prefer defvar-keymap. --- lisp/scroll-lock.el | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lisp/scroll-lock.el b/lisp/scroll-lock.el index 3f5f777f53f..fa1f3a633b5 100644 --- a/lisp/scroll-lock.el +++ b/lisp/scroll-lock.el @@ -30,15 +30,13 @@ ;;; Code: -(defvar scroll-lock-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [remap next-line] 'scroll-lock-next-line) - (define-key map [remap previous-line] 'scroll-lock-previous-line) - (define-key map [remap forward-paragraph] 'scroll-lock-forward-paragraph) - (define-key map [remap backward-paragraph] 'scroll-lock-backward-paragraph) - (define-key map [S-down] 'scroll-lock-next-line-always-scroll) - map) - "Keymap for Scroll Lock mode.") +(defvar-keymap scroll-lock-mode-map + :doc "Keymap for Scroll Lock mode." + " " #'scroll-lock-next-line + " " #'scroll-lock-previous-line + " " #'scroll-lock-forward-paragraph + " " #'scroll-lock-backward-paragraph + "S-" #'scroll-lock-next-line-always-scroll) (defvar-local scroll-lock-preserve-screen-pos-save scroll-preserve-screen-position "Used for saving the state of `scroll-preserve-screen-position'.") From 7529ddef22adc3c0aed1cc0bbe191ad992e37019 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 10 May 2022 23:20:52 +0200 Subject: [PATCH 0148/1028] * lisp/net/browse-url.el (browse-url-button-map): Prefer defvar-keymap. --- lisp/net/browse-url.el | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index c563a27ac85..362dcf25b55 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1633,13 +1633,11 @@ from `browse-url-elinks-wrapper'." ;;; Adding buttons to a buffer to call `browse-url' when you hit them. -(defvar browse-url-button-map - (let ((map (make-sparse-keymap))) - (define-key map "\r" #'browse-url-button-open) - (define-key map [mouse-2] #'browse-url-button-open) - (define-key map "w" #'browse-url-button-copy) - map) - "The keymap used for `browse-url' buttons.") +(defvar-keymap browse-url-button-map + :doc "The keymap used for `browse-url' buttons." + "RET" #'browse-url-button-open + "" #'browse-url-button-open + "w" #'browse-url-button-copy) (defface browse-url-button '((t :inherit link)) From c874916d8d27226dcfd97ee2b78c911b0fb60e25 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 11 May 2022 06:22:57 +0200 Subject: [PATCH 0149/1028] * etc/NEWS: Improve some entries. --- etc/NEWS | 71 ++++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 68c7490e56c..926f5d64645 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -121,7 +121,7 @@ This will output a string identifying the current Emacs build. +++ ** New hook 'after-pdump-load-hook'. -This is run at the end of the Emacs startup process, and it meant to +This is run at the end of the Emacs startup process, and is meant to be used to reinitialize structures that would normally be done at load time. @@ -158,10 +158,10 @@ newline. --- ** 'TAB' and '' are now bound in 'button-map'. -This means that if your cursor is on a button, 'TAB' will take you to -the next button, even if the mode has bound it to something else. -This also means that 'TAB' on a button in an 'outline-minor-mode' -heading will move point instead of collapsing the outline. +This means that if point is on a button, 'TAB' will take you to the +next button, even if the mode has bound it to something else. This +also means that 'TAB' on a button in an 'outline-minor-mode' heading +will move point instead of collapsing the outline. --- ** 'Info-default-directory-list' is no longer populated at Emacs startup. @@ -171,7 +171,7 @@ If you have code in your init file that removes directories from --- ** 'C-k' no longer deletes files in 'ido-mode'. To get the previous action back, put something like the following in -your init file: +your Init file: (require 'ido) (keymap-set ido-file-completion-map "C-k" #'ido-delete-file-at-head) @@ -235,8 +235,8 @@ use the new 'tamil-itrans-digits' and 'tamil-inscript-digits' input methods instead. +++ -** New variable current-time-list governing default timestamp form. -Functions like current-time now yield (TICKS . HZ) timestamps if this +** New variable 'current-time-list' governing default timestamp form. +Functions like 'current-time' now yield (TICKS . HZ) timestamps if this new variable is nil. The variable defaults to t, which means these functions default to timestamps of the forms (HI LO US PS), (HI LO US) or (HI LO), which are less regular and less efficient. This is part @@ -403,8 +403,8 @@ make it more convenient to inspect and modify them. Running 'with-connection-local-variables' defaults to application 'tramp'. This can be changed by let-binding 'connection-local-default-application' to another symbol. This is -useful when running code in a buffer, where Tramp has already set some -connection local variables. +useful when running code in a buffer where Tramp has already set some +connection-local variables. --- ** New minor mode 'pixel-scroll-precision-mode'. @@ -573,7 +573,7 @@ or is itself too long. +++ *** New user option 'outline-minor-mode-use-buttons'. If non-nil, Outline Minor Mode will use buttons to hide/show outlines -in addition to the ellipsis. Default nil. +in addition to the ellipsis. The default is nil. --- *** New user option 'outline-minor-mode-buttons'. @@ -582,8 +582,8 @@ This is a list of pairs of open/close strings used to display buttons. +++ ** Support for the WebP image format. This support is built by default when the libwebp library is -available. (This also includes support for animated WebP images.) To -disable WebP support, use the '--without-webp' configure flag. Image +available, and includes support for animated WebP images. To disable +WebP support, use the '--without-webp' configure flag. Image specifiers can now use ':type webp'. ** Windows @@ -681,7 +681,7 @@ This change also affects 'cl-macrolet', 'cl-flet*' and +++ ** New user option 'translate-upper-case-key-bindings'. -This can be set to nil to inhibit translating upper case keys to lower +Set this option to nil to inhibit translating upper case keys to lower case keys. +++ @@ -691,8 +691,8 @@ point. --- ** Improved mouse behavior with auto-scrolling modes. -When clicking inside the 'scroll-margin' or 'hscroll-margin' region -the point is now moved only when releasing the mouse button. This no +When clicking inside the 'scroll-margin' or 'hscroll-margin' region, +point is now moved only when releasing the mouse button. This no longer results in a bogus selection, unless the mouse has been effectively dragged. @@ -713,9 +713,9 @@ Customize this option to limit the number of entries in the menu *** New user option 'show-paren-context-when-offscreen'. When non-nil, if the point is in a closing delimiter and the opening delimiter is offscreen, shows some context around the opening -delimiter in the echo area. Default nil. +delimiter in the echo area. The default is nil. -May also be set to the symbols 'overlay' or 'child-frame' in which +May also be set to the symbols 'overlay' or 'child-frame', in which case the context is shown in an overlay or child-frame at the top-left of the current window. The latter option requires a graphical frame. On non-graphical frames, the context is shown in the echo area. @@ -724,7 +724,7 @@ On non-graphical frames, the context is shown in the echo area. +++ *** 'comint-term-environment' is now aware of connection-local variables. -The user option 'comint-terminfo-terminal' and variable +The user option 'comint-terminfo-terminal' and the variable 'system-uses-terminfo' can now be set as connection-local variables to change the terminal used on a remote host. @@ -1108,7 +1108,7 @@ allowed images. *** New user option 'shr-use-xwidgets-for-media'. If non-nil (and Emacs has been built with support for xwidgets), display