commit 841614c72272146fff1b9afa05d52150da6d6e66 (HEAD, refs/remotes/origin/master) Merge: 828c49ae29f 9e105d483fa Author: Stefan Kangas Date: Fri Mar 3 06:30:12 2023 +0100 Merge from origin/emacs-29 9e105d483fa Fix c-ts-mode indentation for statement after preproc (bu... a72a55e3e49 Fix c/c++-ts-mode's mode lighter 67befc1f5a5 Eglot: use shell-file-name in eglot--cmd (bug#61748) 1c7b2673bdd Avoid signaling errors in url-basic-auth when password is... 756225e3778 Fix wdired-tests on MS-Windows a137f71c67e Improvements to xwidget on macOS (bug#60703) 3f43a16bc63 ; Avoid byte-compilation warning in c-ts-mode.el commit 9e105d483fa54c5f07a42b4c0fab40507f1fd9ec (refs/remotes/origin/emacs-29) Author: Yuan Fu Date: Thu Mar 2 19:59:11 2023 -0800 Fix c-ts-mode indentation for statement after preproc (bug#61893) Originally our c-ts-mode--anchor-prev-sibling only specially handled labeled_statements, now we add special case for preproc in the similar fasion: instead of using the preproc directive as anchor, use the last statement in that preproc as the anchor. Thus effectively ignore the preproc. There should be an accompanying test, but there are some problem in the elif preproc directive indent so it would pass, we'll add the test when that is fixed. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--anchor-prev-sibling): Add special case for preproc directives. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 3afd7a4a913..eb07eb74676 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -282,12 +282,19 @@ c-ts-mode--anchor-prev-sibling (or (treesit-node-prev-sibling node t) (treesit-node-prev-sibling (treesit-node-first-child-for-pos parent bol) t) - (treesit-node-child parent -1 t)))) - (while (and prev-sibling - (equal "labeled_statement" - (treesit-node-type prev-sibling))) - ;; The 0th child is the label, the 1th the colon. - (setq prev-sibling (treesit-node-child prev-sibling 2))) + (treesit-node-child parent -1 t))) + (continue t)) + (while (and prev-sibling continue) + (pcase (treesit-node-type prev-sibling) + ;; Get the statement in the label. + ("labeled_statement" + (setq prev-sibling (treesit-node-child prev-sibling 2))) + ;; Get the last statement in the preproc. Tested by + ;; "Prev-Sibling When Prev-Sibling is Preproc" test. + ((or "preproc_if" "preproc_ifdef" "preproc_elif" "preproc_else") + (setq prev-sibling (treesit-node-child prev-sibling -2))) + ;; Don't do anything special. + (_ (setq continue nil)))) ;; This could be nil if a) there is no prev-sibling or b) ;; prev-sibling doesn't have a child. (treesit-node-start prev-sibling))) commit a72a55e3e497f7451000fdcf76000eb76946d827 Author: Eli Zaretskii Date: Thu Mar 2 21:34:22 2023 +0200 Fix c/c++-ts-mode's mode lighter * lisp/progmodes/c-ts-mode.el (c-ts-mode-set-modeline): Remove trailing blank from comment-start when indicating the comment style on the mode line. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index a29bf4f3480..3afd7a4a913 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -109,7 +109,8 @@ c-ts-mode-toggle-comment-style (defun c-ts-mode-set-modeline () (setq mode-name - (concat (if (eq major-mode 'c-ts-mode) "C" "C++") comment-start)) + (concat (if (eq major-mode 'c-ts-mode) "C" "C++") + (string-trim-right comment-start))) (force-mode-line-update)) (defun c-ts-mode--indent-style-setter (sym val) commit 828c49ae29fd318547d7bbe4e7fdc65da316e309 Author: Mattias Engdegård Date: Thu Mar 2 09:56:59 2023 +0100 Fix `cond` miscompilation bug This fixes a bug that miscompiled (cond ... C S1...Sn) where S1...Sn are switch clauses (that can be compiled into a switch op) and C a non-switch clause, by tucking on an extra copy of C at the end. This was a serious wrong-code bug when the condition of C had side-effects; otherwise it was only a waste of time and space. * lisp/emacs-lisp/bytecomp.el (byte-compile-cond): Fix. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test case. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 095468ad978..6f3d7a70903 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -4590,6 +4590,7 @@ byte-compile-cond (if switch-prefix (progn (byte-compile-cond-jump-table (cdr switch-prefix) donetag) + (setq clause nil) (setq clauses (car switch-prefix))) (setq clause (car clauses)) (cond ((or (eq (car clause) t) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index b6dcfeedb0c..10b009a261c 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -757,6 +757,15 @@ bytecomp-tests--test-cases (bytecomp-test-identity 3) (error 'bad) (:success)) ; empty handler + + ;; `cond' miscompilation bug + (let ((fn (lambda (x) + (let ((y nil)) + (cond ((progn (setq x (1+ x)) (> x 10)) (setq y 'a)) + ((eq x 1) (setq y 'b)) + ((eq x 2) (setq y 'c))) + (list x y))))) + (mapcar fn (bytecomp-test-identity '(0 1 2 3 10 11)))) ) "List of expressions for cross-testing interpreted and compiled code.") commit a1d90e48bb0076e68592d6a6880c28b52e61d219 Author: Mattias Engdegård Date: Wed Mar 1 19:37:52 2023 +0100 Small unwind-protect optimisation improvement * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Use the current for-effect mode when optimising the body form, instead of always optimising it for value. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 0ae4c452c73..3c7aeb89525 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -439,13 +439,12 @@ byte-optimize-form-code-walker (byte-optimize-body (cdr clause) for-effect)))) clauses))) - ;; `unwind-protect' is a special form which here takes the shape - ;; (unwind-protect EXPR :fun-body UNWIND-FUN). - ;; We can treat it as if it were a plain function at this point, - ;; although there are specific optimizations possible. - ;; In particular, the return value of UNWIND-FUN is never used - ;; so its body should really be compiled for-effect, but we - ;; don't do that right now. + (`(unwind-protect ,protected-expr :fun-body ,unwind-fun) + ;; FIXME: The return value of UNWIND-FUN is never used so we + ;; could potentially optimise it for-effect, but we don't do + ;; that right no. + `(,fn ,(byte-optimize-form protected-expr for-effect) + :fun-body ,(byte-optimize-form unwind-fun))) (`(catch ,tag . ,exps) `(,fn ,(byte-optimize-form tag nil) commit 67befc1f5a5492fee5fb3891083df77831ec830e Author: João Távora Date: Thu Mar 2 13:27:14 2023 +0000 Eglot: use shell-file-name in eglot--cmd (bug#61748) * lisp/progmodes/eglot.el (eglot--cmd): Use shell-file-name. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 36aafac8938..b17370ebf8b 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1206,7 +1206,7 @@ eglot--cmd ;; ;; Not only does this seem like there should be a better way, ;; but it almost certainly doesn’t work on non-unix systems. - (list "sh" "-c" + (list shell-file-name "-c" (string-join (cons "stty raw > /dev/null;" (mapcar #'shell-quote-argument contact)) " ")) commit 8106cb50f58ca9662b1add24afe03cb424b45225 Author: Michael Albinus Date: Thu Mar 2 13:54:14 2023 +0100 Tramp cleanup * lisp/net/tramp.el (tramp-handle-unlock-file): Raise a warning only when `create-lockfiles'. * test/lisp/net/tramp-tests.el (tramp-test26-file-name-completion): Extend test. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 1b434a726a1..47173b95bea 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4791,7 +4791,9 @@ tramp-handle-unlock-file ;; Trigger the unlock error. (signal 'file-error `("Cannot remove lock file for" ,file))) ;; `userlock--handle-unlock-error' exists since Emacs 28.1. - (error (tramp-compat-funcall 'userlock--handle-unlock-error err)))) + (error + (when create-lockfiles + (tramp-compat-funcall 'userlock--handle-unlock-error err))))) (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) "Like `load' for Tramp files." diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 948bf0ab9e2..b6ad2e2f219 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4590,6 +4590,11 @@ tramp-test26-file-name-completion (should (equal (file-name-completion "foo" tmp-name) t)) (should (equal (file-name-completion "b" tmp-name) "bo")) (should-not (file-name-completion "a" tmp-name)) + ;; `file-name-completion' should not err out if + ;; directory does not exist. (Bug#61890) + (should-not + (file-name-completion + "a" (tramp-compat-file-name-concat tmp-name "fuzz"))) ;; Ange-FTP does not support predicates. (unless (tramp--test-ange-ftp-p) (should commit 3b39873ce214bf58f23d0130c2df7308e69c656b Author: Po Lu Date: Thu Mar 2 20:44:47 2023 +0800 Fix bootstrap failure * lisp/man.el (Man-prefer-synchronous-call): Fix version specification. diff --git a/lisp/man.el b/lisp/man.el index 3ab9aa5b4dd..479bf9f9a3c 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -103,7 +103,7 @@ Man-prefer-synchronous-call (rather than asynchronously, which is the default behavior)." :type 'boolean :group 'man - :version 30.1) + :version "30.1") (defcustom Man-filter-list nil "Manpage cleaning filter command phrases. commit 1c7b2673bddc711abd032df5fbff38fc48aba16d Author: Eli Zaretskii Date: Thu Mar 2 14:35:15 2023 +0200 Avoid signaling errors in url-basic-auth when password is nil * lisp/url/url-auth.el (url-basic-auth): Handle nil PASS. Suggested by Ellis Kenyo . (Bug#61411) diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el index e9ee72029f3..6848c0c73a7 100644 --- a/lisp/url/url-auth.el +++ b/lisp/url/url-auth.el @@ -100,7 +100,10 @@ url-basic-auth (setq retval (base64-encode-string (format "%s:%s" user - (encode-coding-string pass 'utf-8)) + (if pass + (encode-coding-string pass + 'utf-8) + "")) t)))) (symbol-value url-basic-auth-storage)))) (byserv commit 756225e37783a7b8fe73be1280c82f521e72d60f Author: Eli Zaretskii Date: Thu Mar 2 14:21:33 2023 +0200 Fix wdired-tests on MS-Windows * test/lisp/wdired-tests.el (wdired-test-bug32173-01) (wdired-test-bug32173-02, wdired-test-unfinished-edit-01) (wdired-test-bug39280): Run test-dir through file-truename, to avoid failures due to MS-Windows "numeric tails" (mis)feature and similar issues, which make file names fail to compare 'equal'. (wdired-test-bug34915, wdired-test-bug61510): Skip if symlinks fail. diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el index 897c6cd69a8..20caaff17c7 100644 --- a/test/lisp/wdired-tests.el +++ b/test/lisp/wdired-tests.el @@ -31,6 +31,10 @@ wdired-test-bug32173-01 "Test using non-nil wdired-use-interactive-rename. Partially modifying a file name should succeed." (ert-with-temp-directory test-dir + ;; The call to file-truename is for MS-Windows, where numeric + ;; tails or some other feature (like SUBST) could cause file names + ;; to fail to compare 'equal'. + (setq test-dir (file-truename test-dir)) (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c")) (replace "bar") (new-file (string-replace "foo" replace test-file)) @@ -56,6 +60,7 @@ wdired-test-bug32173-02 "Test using non-nil wdired-use-interactive-rename. Aborting an edit should leaving original file name unchanged." (ert-with-temp-directory test-dir + (setq test-dir (file-truename test-dir)) (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c")) (wdired-use-interactive-rename t)) (write-region "" nil test-file nil 'silent) @@ -106,6 +111,7 @@ wdired-test-unfinished-edit-01 Finding the new name should be possible while still in wdired-mode." (ert-with-temp-directory test-dir + (setq test-dir (file-truename test-dir)) (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c")) (replace "bar") (new-file (string-replace "foo" replace test-file))) @@ -143,7 +149,11 @@ wdired-test-bug34915 (with-current-buffer buf (dired-create-empty-file "foo") (set-file-modes "foo" (file-modes-symbolic-to-number "+x")) - (make-symbolic-link "foo" "bar") + (skip-unless + ;; This check is for wdired, not symbolic links, so skip + ;; it when make-symbolic-link fails for any reason (like + ;; insufficient privileges). + (ignore-errors (make-symbolic-link "foo" "bar") t)) (make-directory "foodir") (dired-smart-shell-command "mkfifo foopipe") (when (featurep 'make-network-process '(:family local)) @@ -176,6 +186,7 @@ wdired-test-bug34915 (ert-deftest wdired-test-bug39280 () "Test for https://debbugs.gnu.org/39280." (ert-with-temp-directory test-dir + (setq test-dir (file-truename test-dir)) (let* ((fname "foo") (full-fname (expand-file-name fname test-dir))) (make-empty-file full-fname) @@ -202,7 +213,11 @@ wdired-test-bug61510 (dired-hide-details-hide-symlink-targets t)) (unwind-protect (with-current-buffer buf - (make-symbolic-link "bar" "foo") + (skip-unless + ;; This check is for wdired, not symbolic links, so skip + ;; it when make-symbolic-link fails for any reason (like + ;; insufficient privileges). + (ignore-errors (make-symbolic-link "bar" "foo") t)) (dired-hide-details-mode) (should (memq 'dired-hide-details-link buffer-invisibility-spec)) (dired-toggle-read-only) commit 11c4177430230ef41cb700c48afecf475cf39893 Author: Augusto Stoffel Date: Sat Feb 25 12:15:43 2023 +0100 Add option to keep some columns in dired-hide-details-mode * lisp/dired.el (dired-hide-details-preserved-columns): New user option. (dired-insert-set-properties): Use it. (Bug#61785) diff --git a/lisp/dired.el b/lisp/dired.el index 55a5bbd9800..8e3244356fe 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -490,6 +490,11 @@ dired-guess-shell-znew-switches (string :tag "Switches")) :version "29.1") +(defcustom dired-hide-details-preserved-columns nil + "List of columns which are not hidden in `dired-hide-details-mode'." + :type '(repeat integer) + :version "30.1") + ;;; Internal variables @@ -1880,8 +1885,15 @@ dired-insert-set-properties (put-text-property (line-beginning-position) (1+ (line-end-position)) 'invisible 'dired-hide-details-information)) - (put-text-property (+ (line-beginning-position) 1) (1- (point)) - 'invisible 'dired-hide-details-detail) + (save-excursion + (let ((end (1- (point))) + (opoint (goto-char (1+ (pos-bol)))) + (i 0)) + (put-text-property opoint end 'invisible 'dired-hide-details-detail) + (while (re-search-forward "[^ ]+" end t) + (when (member (cl-incf i) dired-hide-details-preserved-columns) + (put-text-property opoint (point) 'invisible nil)) + (setq opoint (point))))) (when (and dired-mouse-drag-files (fboundp 'x-begin-drag)) (put-text-property (point) (save-excursion commit 8d5d7509b0a2c248084fa349b0b188d4de4af804 Author: Eli Zaretskii Date: Thu Mar 2 13:28:28 2023 +0200 ; Fix last change * doc/emacs/programs.texi (Man Page): Improve wording. * lisp/man.el (Man-prefer-synchronous-call): Fix quoting and spelling. (Bug#61552) diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index c6c67047c43..62df88a731e 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -1389,9 +1389,9 @@ Man Page @vindex Man-prefer-synchronous-call By default, @kbd{M-x man} calls the @code{man} program -asynchronously. If you would prefer it if @kbd{M-x man} called the -@code{man} program synchronously, you may set variable -@code{Man-prefer-synchronous-calls} to a non-@code{nil} value. +asynchronously. You can force the invocation to be synchronous by +customizing @code{Man-prefer-synchronous-calls} to a non-@code{nil} +value. @findex woman @cindex manual pages, on MS-DOS/MS-Windows diff --git a/etc/NEWS b/etc/NEWS index 744eab41558..116b60d8b11 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -206,7 +206,7 @@ bound to 'C-c C-d' in 'go-ts-mode'. +++ *** New user option 'Man-prefer-synchronous-call'. When this is non-nil, call the 'man' program synchronously rather than -asynchronously, which is the default behaviour. +asynchronously (which is the default behavior). * New Modes and Packages in Emacs 30.1 diff --git a/lisp/man.el b/lisp/man.el index 5e5c10aac36..3ab9aa5b4dd 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -98,9 +98,9 @@ man :group 'help) (defcustom Man-prefer-synchronous-call nil - "Whether to call the Un*x 'man' program synchronously. -When this is non-nil, call the 'man' program synchronously -(rather than asynchronously, which is the default behaviour)." + "Whether to call the Un*x \"man\" program synchronously. +When this is non-nil, call the \"man\" program synchronously +(rather than asynchronously, which is the default behavior)." :type 'boolean :group 'man :version 30.1) commit cf3c89423fabc2c5a7891a5b5465fa995e461218 Author: Sebastian Tennant Date: Thu Mar 10 08:36:04 2022 +0000 Add new user option Man-prefer-synchronous-call * lisp/man.el (Man-getpage-in-background): Add new defcustom Man-prefer-synchronous-call and modify #'Man-getpage-in-background. Only call #'start-process when 'make-process satisfies #'fboundp AND Man-prefer-synchronous-call is bound to nil. (Bug#61552) Copyright-paperwork-exempt: yes diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index d97bd56be21..c6c67047c43 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -1387,6 +1387,12 @@ Man Page @kbd{M-p} to switch between man pages in different sections. The mode line shows how many manual pages are available. +@vindex Man-prefer-synchronous-call + By default, @kbd{M-x man} calls the @code{man} program +asynchronously. If you would prefer it if @kbd{M-x man} called the +@code{man} program synchronously, you may set variable +@code{Man-prefer-synchronous-calls} to a non-@code{nil} value. + @findex woman @cindex manual pages, on MS-DOS/MS-Windows An alternative way of reading manual pages is the @kbd{M-x woman} diff --git a/etc/NEWS b/etc/NEWS index 31fb22fc1e2..744eab41558 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -201,6 +201,13 @@ This command adds a docstring comment to the current defun. If a comment already exists, point is only moved to the comment. It is bound to 'C-c C-d' in 'go-ts-mode'. +** Man-mode + ++++ +*** New user option 'Man-prefer-synchronous-call'. +When this is non-nil, call the 'man' program synchronously rather than +asynchronously, which is the default behaviour. + * New Modes and Packages in Emacs 30.1 diff --git a/lisp/man.el b/lisp/man.el index 9f75c07c791..5e5c10aac36 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -97,6 +97,14 @@ man :group 'external :group 'help) +(defcustom Man-prefer-synchronous-call nil + "Whether to call the Un*x 'man' program synchronously. +When this is non-nil, call the 'man' program synchronously +(rather than asynchronously, which is the default behaviour)." + :type 'boolean + :group 'man + :version 30.1) + (defcustom Man-filter-list nil "Manpage cleaning filter command phrases. This variable contains a list of the following form: @@ -1118,7 +1126,8 @@ Man-getpage-in-background "[cleaning...]") 'face 'mode-line-emphasis))) (Man-start-calling - (if (fboundp 'make-process) + (if (and (fboundp 'make-process) + (not Man-prefer-synchronous-call)) (let ((proc (start-process manual-program buffer (if (memq system-type '(cygwin windows-nt)) commit a137f71c67e88204a32ebd747beb8fdd7db2fbe9 Author: Andrew De Angelis Date: Thu Feb 23 22:47:41 2023 -0500 Improvements to xwidget on macOS (bug#60703) * src/nsxwidget.m () ([XwWebView initWithFrame:configuration:xwidget:]) (nsxwidget_init): Fixed memory leaks: when sending an alloc message to an object, send an autorelease message to any objects we won't explictly release. ([XwWebView webView:didFinishNavigation:]): Second string to store in 'store_xwidget_event_string' is "load finished" rather than empty string. ([XwWebView webView:didStartProvisionalNavigation:]) ([XwWebView webView:didReceiveServerRedirectForProvisionalNavigation:]) ([XwWebView webView:didCommitNavigation:]): New functions. (nsxwidget_webkit_estimated_load_progress): New function. (nsxwidget_webkit_stop_loading): New function. * src/xwidget.c (Fxwidget_webkit_estimated_load_progress): Call 'nsxwidget_webkit_estimated_load_progress' if we're on MacOS. (Fxwidget_webkit_stop_loading): Call 'nsxwidget_webkit_stop_loading' if we're on MacOS. (syms_of_xwidget): Define symbol for function. 'xwidget_webkit_estimated_load_progress' if we're on MacOS. * src/nsxwidget.h: Signature for functions 'nsxwidget_webkit_estimated_load_progress' and 'nsxwidget_webkit_stop_loading'. * lisp/xwidget.el (xwidget-webkit-current-url): Message URL rather than return value of 'kill-new' (which is always nil). diff --git a/lisp/xwidget.el b/lisp/xwidget.el index abbda29081e..7daca81f9f7 100644 --- a/lisp/xwidget.el +++ b/lisp/xwidget.el @@ -925,7 +925,8 @@ xwidget-webkit-current-url "Display the current xwidget webkit URL and place it on the `kill-ring'." (interactive nil xwidget-webkit-mode) (let ((url (xwidget-webkit-uri (xwidget-webkit-current-session)))) - (message "URL: %s" (kill-new (or url ""))))) + (when url (kill-new url)) + (message "URL: %s" url))) (defun xwidget-webkit-browse-history () "Display a buffer containing the history of page loads." diff --git a/src/nsxwidget.h b/src/nsxwidget.h index 8d55fac5326..2b5596f905e 100644 --- a/src/nsxwidget.h +++ b/src/nsxwidget.h @@ -36,6 +36,8 @@ #define NSXWIDGET_H_INCLUDED Lisp_Object nsxwidget_webkit_title (struct xwidget *xw); void nsxwidget_webkit_goto_uri (struct xwidget *xw, const char *uri); void nsxwidget_webkit_goto_history (struct xwidget *xw, int rel_pos); +double nsxwidget_webkit_estimated_load_progress(struct xwidget *xw); +void nsxwidget_webkit_stop_loading (struct xwidget *xw); void nsxwidget_webkit_zoom (struct xwidget *xw, double zoom_change); void nsxwidget_webkit_execute_script (struct xwidget *xw, const char *script, Lisp_Object fun); diff --git a/src/nsxwidget.m b/src/nsxwidget.m index e1fbd749b62..0e00589bb7f 100644 --- a/src/nsxwidget.m +++ b/src/nsxwidget.m @@ -57,12 +57,13 @@ @interface XwWebView : WKWebView @end @implementation XwWebView : WKWebView -- (id)initWithFrame:(CGRect)frame +- (id) initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration xwidget:(struct xwidget *)xw { /* Script controller to add script message handler and user script. */ - WKUserContentController *scriptor = [[WKUserContentController alloc] init]; + WKUserContentController *scriptor = [[[WKUserContentController alloc] init] + autorelease]; configuration.userContentController = scriptor; /* Enable inspect element context menu item for debugging. */ @@ -81,7 +82,8 @@ - (id)initWithFrame:(CGRect)frame if (self) { self.xw = xw; - self.urlScriptBlocked = [[NSMutableDictionary alloc] init]; + self.urlScriptBlocked = [[[NSMutableDictionary alloc] init] + autorelease]; self.navigationDelegate = self; self.UIDelegate = self; self.customUserAgent = @@ -89,23 +91,48 @@ - (id)initWithFrame:(CGRect)frame @" AppleWebKit/603.3.8 (KHTML, like Gecko)" @" Version/11.0.1 Safari/603.3.8"; [scriptor addScriptMessageHandler:self name:@"keyDown"]; - [scriptor addUserScript:[[WKUserScript alloc] - initWithSource:xwScript - injectionTime: - WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:NO]]; + WKUserScript *userScript = [[[WKUserScript alloc] + initWithSource:xwScript + injectionTime: + WKUserScriptInjectionTimeAtDocumentStart + forMainFrameOnly:NO] autorelease]; + [scriptor addUserScript:userScript]; } return self; } -- (void)webView:(WKWebView *)webView +/* These 4 functions emulate the behavior of webkit_view_load_changed_cb + in the GTK implementation*/ +- (void) webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { if (EQ (Fbuffer_live_p (self.xw->buffer), Qt)) - store_xwidget_event_string (self.xw, "load-changed", ""); + store_xwidget_event_string (self.xw, "load-changed", "load-finished"); } -- (void)webView:(WKWebView *)webView +- (void) webView:(WKWebView *)webView +didStartProvisionalNavigation:(WKNavigation *)navigation +{ + if (EQ (Fbuffer_live_p (self.xw->buffer), Qt)) + store_xwidget_event_string (self.xw, "load-changed", "load-started"); +} + +- (void) webView:(WKWebView *)webView +didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation +{ + if (EQ (Fbuffer_live_p (self.xw->buffer), Qt)) + store_xwidget_event_string (self.xw, "load-changed", "load-redirected"); +} + +/* Start loading WKWebView */ +- (void) webView:(WKWebView *)webView +didCommitNavigation:(WKNavigation *)navigation +{ + if (EQ (Fbuffer_live_p (self.xw->buffer), Qt)) + store_xwidget_event_string (self.xw, "load-changed", "load-committed"); +} + +- (void) webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { @@ -114,13 +141,13 @@ - (void)webView:(WKWebView *)webView decisionHandler (WKNavigationActionPolicyAllow); break; default: - // decisionHandler (WKNavigationActionPolicyCancel); + /* decisionHandler (WKNavigationActionPolicyCancel); */ decisionHandler (WKNavigationActionPolicyAllow); break; } } -- (void)webView:(WKWebView *)webView +- (void) webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { @@ -166,7 +193,7 @@ - (void)webView:(WKWebView *)webView /* No additional new webview or emacs window will be created for . */ -- (WKWebView *)webView:(WKWebView *)webView +- (WKWebView *) webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures @@ -177,7 +204,7 @@ - (WKWebView *)webView:(WKWebView *)webView } /* Open panel for file upload. */ -- (void)webView:(WKWebView *)webView +- (void) webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler @@ -197,13 +224,13 @@ - (void)webView:(WKWebView *)webView - Correct mouse hand/arrow/I-beam is displayed (TODO: not perfect yet). */ -- (void)mouseDown:(NSEvent *)event +- (void) mouseDown:(NSEvent *)event { [self.xw->xv->emacswindow mouseDown:event]; [super mouseDown:event]; } -- (void)mouseUp:(NSEvent *)event +- (void) mouseUp:(NSEvent *)event { [self.xw->xv->emacswindow mouseUp:event]; [super mouseUp:event]; @@ -214,7 +241,7 @@ - (void)mouseUp:(NSEvent *)event emacs as first responder to avoid focus held in an input element with matching text. */ -- (void)keyDown:(NSEvent *)event +- (void) keyDown:(NSEvent *)event { Lisp_Object var = Fintern (build_string ("isearch-mode"), Qnil); Lisp_Object val = buffer_local_value (var, Fcurrent_buffer ()); @@ -250,7 +277,7 @@ - (void)keyDown:(NSEvent *)event }]; } -- (void)interpretKeyEvents:(NSArray *)eventArray +- (void) interpretKeyEvents:(NSArray *)eventArray { /* We should do nothing and do not forward (default implementation if we not override here) to let emacs collect key events and ask @@ -258,7 +285,7 @@ - (void)interpretKeyEvents:(NSArray *)eventArray } static NSString *xwScript; -+ (void)initialize ++ (void) initialize { /* Find out if an input element has focus. Message to script message handler when 'C-g' key down. */ @@ -284,7 +311,7 @@ + (void)initialize /* Confirming to WKScriptMessageHandler, listens concerning keyDown in webkit. Currently 'C-g'. */ -- (void)userContentController:(WKUserContentController *)userContentController +- (void) userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.body isEqualToString:@"C-g"]) @@ -343,6 +370,20 @@ - (void)userContentController:(WKUserContentController *)userContentController } } +double +nsxwidget_webkit_estimated_load_progress (struct xwidget *xw) +{ + XwWebView *xwWebView = (XwWebView *) xw->xwWidget; + return xwWebView.estimatedProgress; +} + +void +nsxwidget_webkit_stop_loading (struct xwidget *xw) +{ + XwWebView *xwWebView = (XwWebView *) xw->xwWidget; + [xwWebView stopLoading]; +} + void nsxwidget_webkit_zoom (struct xwidget *xw, double zoom_change) { @@ -430,7 +471,7 @@ - (void)userContentController:(WKUserContentController *)userContentController } else if (result && FUNCTIONP (fun)) { - // NSLog (@"result=%@, type=%@", result, [result class]); + /* NSLog (@"result=%@, type=%@", result, [result class]); */ Lisp_Object lisp_value = js_to_lisp (result); store_xwidget_js_callback_event (xw, fun, lisp_value); } @@ -440,19 +481,20 @@ - (void)userContentController:(WKUserContentController *)userContentController /* Window containing an xwidget. */ @implementation XwWindow -- (BOOL)isFlipped { return YES; } +- (BOOL) isFlipped { return YES; } @end /* Xwidget model, macOS Cocoa part. */ void -nsxwidget_init(struct xwidget *xw) +nsxwidget_init (struct xwidget *xw) { block_input (); NSRect rect = NSMakeRect (0, 0, xw->width, xw->height); xw->xwWidget = [[XwWebView alloc] initWithFrame:rect - configuration:[[WKWebViewConfiguration alloc] init] + configuration:[[[WKWebViewConfiguration alloc] init] + autorelease] xwidget:xw]; xw->xwWindow = [[XwWindow alloc] initWithFrame:rect]; @@ -470,16 +512,18 @@ - (BOOL)isFlipped { return YES; } ((XwWebView *) xw->xwWidget).configuration.userContentController; [scriptor removeAllUserScripts]; [scriptor removeScriptMessageHandlerForName:@"keyDown"]; - [scriptor release]; + if (xw->xv) xw->xv->model = Qnil; /* Make sure related view stale. */ /* This stops playing audio when a xwidget-webkit buffer is - killed. I could not find other solution. */ + killed. I could not find other solution. + TODO: improve this */ nsxwidget_webkit_goto_uri (xw, "about:blank"); [((XwWebView *) xw->xwWidget).urlScriptBlocked release]; [xw->xwWidget removeFromSuperviewWithoutNeedingDisplay]; + [xw->xwWidget release]; [xw->xwWindow removeFromSuperviewWithoutNeedingDisplay]; [xw->xwWindow release]; @@ -507,7 +551,7 @@ - (BOOL)isFlipped { return YES; } /* Xwidget view, macOS Cocoa part. */ @implementation XvWindow : NSView -- (BOOL)isFlipped { return YES; } +- (BOOL) isFlipped { return YES; } @end void diff --git a/src/xwidget.c b/src/xwidget.c index efe27055629..7f30e48c954 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -3063,6 +3063,36 @@ DEFUN ("xwidget-webkit-title", #endif } +DEFUN ("xwidget-webkit-estimated-load-progress", + Fxwidget_webkit_estimated_load_progress, Sxwidget_webkit_estimated_load_progress, + 1, 1, 0, doc: /* Get the estimated load progress of XWIDGET, a WebKit widget. +Return a value ranging from 0.0 to 1.0, based on how close XWIDGET +is to completely loading its page. */) + (Lisp_Object xwidget) +{ + struct xwidget *xw; +#ifdef USE_GTK + WebKitWebView *webview; +#endif + double value; + + CHECK_LIVE_XWIDGET (xwidget); + xw = XXWIDGET (xwidget); + CHECK_WEBKIT_WIDGET (xw); + + block_input (); +#ifdef USE_GTK + webview = WEBKIT_WEB_VIEW (xw->widget_osr); + value = webkit_web_view_get_estimated_load_progress (webview); +#elif defined NS_IMPL_COCOA + value = nsxwidget_webkit_estimated_load_progress (xw); +#endif + + unblock_input (); + + return make_float (value); +} + DEFUN ("xwidget-webkit-goto-uri", Fxwidget_webkit_goto_uri, Sxwidget_webkit_goto_uri, 2, 2, 0, @@ -3810,28 +3840,6 @@ DEFUN ("xwidget-webkit-back-forward-list", Fxwidget_webkit_back_forward_list, return list3 (back, here, forward); } -DEFUN ("xwidget-webkit-estimated-load-progress", - Fxwidget_webkit_estimated_load_progress, Sxwidget_webkit_estimated_load_progress, - 1, 1, 0, doc: /* Get the estimated load progress of XWIDGET, a WebKit widget. -Return a value ranging from 0.0 to 1.0, based on how close XWIDGET -is to completely loading its page. */) - (Lisp_Object xwidget) -{ - struct xwidget *xw; - WebKitWebView *webview; - double value; - - CHECK_LIVE_XWIDGET (xwidget); - xw = XXWIDGET (xwidget); - CHECK_WEBKIT_WIDGET (xw); - - block_input (); - webview = WEBKIT_WEB_VIEW (xw->widget_osr); - value = webkit_web_view_get_estimated_load_progress (webview); - unblock_input (); - - return make_float (value); -} #endif DEFUN ("xwidget-webkit-set-cookie-storage-file", @@ -3874,19 +3882,23 @@ DEFUN ("xwidget-webkit-stop-loading", Fxwidget_webkit_stop_loading, XWIDGET as part of loading a page. */) (Lisp_Object xwidget) { -#ifdef USE_GTK struct xwidget *xw; +#ifdef USE_GTK WebKitWebView *webview; +#endif CHECK_LIVE_XWIDGET (xwidget); xw = XXWIDGET (xwidget); CHECK_WEBKIT_WIDGET (xw); block_input (); +#ifdef USE_GTK webview = WEBKIT_WEB_VIEW (xw->widget_osr); webkit_web_view_stop_loading (webview); - unblock_input (); +#elif defined NS_IMPL_COCOA + nsxwidget_webkit_stop_loading (xw); #endif + unblock_input (); return Qnil; } @@ -3936,8 +3948,9 @@ syms_of_xwidget (void) #ifdef USE_GTK defsubr (&Sxwidget_webkit_load_html); defsubr (&Sxwidget_webkit_back_forward_list); - defsubr (&Sxwidget_webkit_estimated_load_progress); #endif + + defsubr (&Sxwidget_webkit_estimated_load_progress); defsubr (&Skill_xwidget); DEFSYM (QCxwidget, ":xwidget"); commit 68f49083af7ac5ffd9cde4bc7167d4e2ccbba4b6 Author: Philippe Altherr Date: Sun Jan 15 13:37:00 2023 +0100 Add support for Zsh's case branches ;|. * lisp/progmodes/sh-script.el (sh-font-lock-paren) (sh-smie-sh-grammar, sh-smie-sh-rules, sh-smie-rc-grammar): Support case branches ending with ";|", per Zsh. (Bug#60833) * test/manual/indent/shell.sh (bar): Add ";|". diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 741803a5175..398a2c8946b 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1042,7 +1042,9 @@ sh-font-lock-paren ;; Maybe we've bumped into an escaped newline. (sh-is-quoted-p (point))) (backward-char 1)) - (when (eq (char-before) ?|) + (when (and + (eq (char-before) ?|) + (not (eq (char-before (1- (point))) ?\;))) (backward-char 1) t))) (and (> (point) (1+ (point-min))) (progn (backward-char 2) @@ -1053,7 +1055,7 @@ sh-font-lock-paren ;; a normal command rather than the real `in' keyword. ;; I.e. we should look back to try and find the ;; corresponding `case'. - (and (looking-at ";[;&]\\|\\_ Date: Sat Jan 14 05:22:26 2023 +0100 Use 'sh-indent-for-continuation' for continued lines in 'sh-script-mode' * lisp/progmodes/sh-script.el (sh-smie--indent-continuation): Use 'sh-indent-for-continuation' instead of 'sh-basic-offset'. (Bug#60832) * test/lisp/progmodes/sh-script-tests.el (test-indent-after-continuation): New test. diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 17c22ff4751..741803a5175 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -2010,7 +2010,7 @@ sh-smie--indent-continuation (forward-line -1) (if (sh-smie--looking-back-at-continuation-p) (current-indentation) - (+ (current-indentation) sh-basic-offset)))) + (+ (current-indentation) (sh-var-value 'sh-indent-for-continuation))))) (t ;; Just make sure a line-continuation is indented deeper. (save-excursion @@ -2031,7 +2031,10 @@ sh-smie--indent-continuation ;; check the line before that one. (> ci indent)) (t ;Previous line is the beginning of the continued line. - (setq indent (min (+ ci sh-basic-offset) max)) + (setq + indent + (min + (+ ci (sh-var-value 'sh-indent-for-continuation)) max)) nil))))) indent)))))) diff --git a/test/lisp/progmodes/sh-script-tests.el b/test/lisp/progmodes/sh-script-tests.el index c850a5d8af7..52c1303c414 100644 --- a/test/lisp/progmodes/sh-script-tests.el +++ b/test/lisp/progmodes/sh-script-tests.el @@ -52,6 +52,24 @@ test-basic-sh-indentation (ert-deftest test-indentation () (ert-test-erts-file (ert-resource-file "sh-indents.erts"))) +(ert-deftest test-indent-after-continuation () + (with-temp-buffer + (insert "for f \\\nin a; do \\\ntoto; \\\ndone\n") + (shell-script-mode) + (let ((sh-indent-for-continuation '++)) + (let ((sh-indent-after-continuation t)) + (indent-region (point-min) (point-max)) + (should (equal (buffer-string) + "for f \\\n\tin a; do \\\n toto; \\\n done\n"))) + (let ((sh-indent-after-continuation 'always)) + (indent-region (point-min) (point-max)) + (should (equal (buffer-string) + "for f \\\n\tin a; do \\\n\ttoto; \\\n\tdone\n"))) + (let ((sh-indent-after-continuation nil)) + (indent-region (point-min) (point-max)) + (should (equal (buffer-string) + "for f \\\nin a; do \\\n toto; \\\ndone\n")))))) + (defun test-sh-back (string &optional pos) (with-temp-buffer (shell-script-mode) commit 3f43a16bc63eac12db5707b26da2507077b4f13c Author: Eli Zaretskii Date: Thu Mar 2 09:33:04 2023 +0200 ; Avoid byte-compilation warning in c-ts-mode.el * lisp/progmodes/c-ts-mode.el (treesit-node-first-child-for-pos): Declare. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 259b96d342e..a29bf4f3480 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -78,6 +78,7 @@ (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-type "treesit.c") (declare-function treesit-node-prev-sibling "treesit.c") +(declare-function treesit-node-first-child-for-pos "treesit.c") ;;; Custom variables