commit ecbd5f9ac6eb2d31241657bbb3e3f9b860391054 (HEAD, refs/remotes/origin/master) Author: Peder O. Klingenberg Date: Sat Feb 25 10:30:46 2017 +0200 New option -u / --suppress-output to emacsclient * lib-src/emacsclient.c (print_help_and_exit, longopts) (decode_options, main): Implement new option --suppress-output / -u to suppress printing of eval-results. * doc/emacs/misc.texi (emacsclient Options): Document the new "--suppress-output/-u" options. * etc/NEWS: Mention the new options. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 091ead1bae..bcc20a6db1 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -1847,6 +1847,12 @@ option is mainly useful for developers. Do not let @command{emacsclient} display messages about waiting for Emacs or connecting to remote server sockets. +@item -u +@itemx --suppress-output +Do not let @command{emacsclient} display results returned from the +server. Mostly useful in combination with @samp{-e} when the +evaluation performed is for side-effect rather than result. + @item -s @var{server-name} @itemx --socket-name=@var{server-name} Connect to the Emacs server named @var{server-name}. The server name diff --git a/etc/NEWS b/etc/NEWS index 9355dff7a0..5d14e122a2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -321,6 +321,10 @@ substituted by a home directory by writing it as "/foo:/:/~/file". settings of 'scroll-margin' up to half the window size, instead of always restricting the margin to a quarter of the window. ++++ +** Emacsclient has a new option -u/--suppress-output. The option +suppresses display of return values from the server process. + * Editing Changes in Emacs 26.1 diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 70709ecec0..7b735dfb05 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -118,6 +118,9 @@ int nowait = 0; /* Nonzero means don't print messages for successful operations. --quiet. */ int quiet = 0; +/* Nonzero means don't print values returned from emacs. --suppress-output. */ +int suppress_output = 0; + /* Nonzero means args are expressions to be evaluated. --eval. */ int eval = 0; @@ -160,6 +163,7 @@ struct option longopts[] = { { "no-wait", no_argument, NULL, 'n' }, { "quiet", no_argument, NULL, 'q' }, + { "suppress-output", no_argument, NULL, 'u' }, { "eval", no_argument, NULL, 'e' }, { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, @@ -469,9 +473,9 @@ decode_options (int argc, char **argv) { int opt = getopt_long_only (argc, argv, #ifndef NO_SOCKETS_IN_FILE_SYSTEM - "VHneqa:s:f:d:F:tc", + "VHnequa:s:f:d:F:tc", #else - "VHneqa:f:d:F:tc", + "VHnequa:f:d:F:tc", #endif longopts, 0); @@ -519,6 +523,10 @@ decode_options (int argc, char **argv) quiet = 1; break; + case 'u': + suppress_output = 1; + break; + case 'V': message (false, "emacsclient %s\n", VERSION); exit (EXIT_SUCCESS); @@ -631,6 +639,7 @@ The following OPTIONS are accepted:\n\ -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ -n, --no-wait Don't wait for the server to return\n\ -q, --quiet Don't display messages on success\n\ +-u, --suppress-output Don't display return values from the server\n\ -d DISPLAY, --display=DISPLAY\n\ Visit the file in the given display\n\ ", "\ @@ -1860,19 +1869,25 @@ main (int argc, char **argv) else if (strprefix ("-print ", p)) { /* -print STRING: Print STRING on the terminal. */ - str = unquote_argument (p + strlen ("-print ")); - if (needlf) - printf ("\n"); - printf ("%s", str); - needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; - } + if (!suppress_output) + { + str = unquote_argument (p + strlen ("-print ")); + if (needlf) + printf ("\n"); + printf ("%s", str); + needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + } + } else if (strprefix ("-print-nonl ", p)) { /* -print-nonl STRING: Print STRING on the terminal. Used to continue a preceding -print command. */ - str = unquote_argument (p + strlen ("-print-nonl ")); - printf ("%s", str); - needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + if (!suppress_output) + { + str = unquote_argument (p + strlen ("-print-nonl ")); + printf ("%s", str); + needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + } } else if (strprefix ("-error ", p)) { commit f0e7f39e0b4026a3d613416ad8ffc84e6b74242b Author: Noam Postavsky Date: Mon Feb 20 13:34:39 2017 -0500 Fix scrolling with partial line corner case (Bug#25792) Also fix up the scrolling tests so that they don't make so many assumptions about the current window configuration. * src/xdisp.c (try_window): Take partial line height into account when comparing cursor position against scroll margin. * test/manual/scroll-tests.el (scroll-tests-with-buffer-window): Add HEIGHT argument, to allow setting up window with exact height and partial line. (scroll-tests-display-buffer-with-height): New display-buffer action function. (scroll-tests-scroll-margin-over-max): (scroll-tests--scroll-margin-whole-window): Pass HEIGHT to `scroll-tests--scroll-margin-whole-window'. (scroll-tests-conservative-show-trailing-whitespace): New test. (scroll-tests-scroll-margin-negative): Fix line counting. (scroll-tests--point-in-middle-of-window-p): Set window height properly. diff --git a/src/xdisp.c b/src/xdisp.c index b0ff627c70..b0644882bd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -17380,21 +17380,27 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) return 0; } + /* Save the character position of 'it' before we call + 'start_display' again. */ + ptrdiff_t it_charpos = IT_CHARPOS (it); + /* Don't let the cursor end in the scroll margins. */ if ((flags & TRY_WINDOW_CHECK_MARGINS) && !MINI_WINDOW_P (w)) { int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS); + start_display (&it, w, pos); if ((w->cursor.y >= 0 /* not vscrolled */ && w->cursor.y < this_scroll_margin && CHARPOS (pos) > BEGV - && IT_CHARPOS (it) < ZV) + && it_charpos < ZV) /* rms: considering make_cursor_line_fully_visible_p here seems to give wrong results. We don't want to recenter when the last line is partly visible, we want to allow that case to be handled in the usual way. */ - || w->cursor.y > it.last_visible_y - this_scroll_margin - 1) + || w->cursor.y > (it.last_visible_y - partial_line_height (&it) + - this_scroll_margin - 1)) { w->cursor.vpos = -1; clear_glyph_matrix (w->desired_matrix); @@ -17403,7 +17409,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) } /* If bottom moved off end of frame, change mode line percentage. */ - if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it)) + if (w->window_end_pos <= 0 && Z != it_charpos) w->update_mode_line = true; /* Set window_end_pos to the offset of the last character displayed diff --git a/test/manual/scroll-tests.el b/test/manual/scroll-tests.el index 1167efd6a6..95647ce0c4 100644 --- a/test/manual/scroll-tests.el +++ b/test/manual/scroll-tests.el @@ -53,41 +53,79 @@ (sit-for 0) (should (= 1 (window-start))))) -(defmacro scroll-tests-with-buffer-window (&rest body) - (declare (debug t)) +(defun scroll-tests-display-buffer-with-height (buffer alist) + (let ((height (alist-get 'window-height alist))) + (when height + (let* ((window (or (get-buffer-window buffer) (selected-window))) + (lines (floor height)) + (partial (round (* (- height lines) (default-line-height))))) + (setq window (cond ((window-in-direction 'above window nil +1)) + ((or (window-in-direction 'below window nil -1) + (split-window-below lines)) + window))) + (set-window-buffer window buffer) + (set-window-text-height window lines) + (adjust-window-trailing-edge window partial nil t) + window)))) + +(defmacro scroll-tests-with-buffer-window (&optional height &rest body) + (declare (debug t) (indent defun)) `(with-temp-buffer - (with-selected-window (display-buffer (current-buffer)) + (with-selected-window (display-buffer (current-buffer) + '(scroll-tests-display-buffer-with-height + . ,(if (numberp height) + `((window-height . ,height)) + (push height body) + nil))) ,@body))) (ert-deftest scroll-tests-scroll-margin-0 () (skip-unless (not noninteractive)) (scroll-tests-with-buffer-window - (scroll-tests-up-and-down 0))) + (scroll-tests-up-and-down 0))) (ert-deftest scroll-tests-scroll-margin-negative () "A negative `scroll-margin' should be the same as 0." (skip-unless (not noninteractive)) (scroll-tests-with-buffer-window - (scroll-tests-up-and-down -10 0))) + (scroll-tests-up-and-down -10 0))) (ert-deftest scroll-tests-scroll-margin-max () (skip-unless (not noninteractive)) (scroll-tests-with-buffer-window - (let ((max-margin (/ (window-text-height) 4))) - (scroll-tests-up-and-down max-margin)))) + (let ((max-margin (/ (window-text-height) 4))) + (scroll-tests-up-and-down max-margin)))) (ert-deftest scroll-tests-scroll-margin-over-max () "A `scroll-margin' more than max should be the same as max." (skip-unless (not noninteractive)) - (scroll-tests-with-buffer-window - (set-window-text-height nil 7) - (let ((max-margin (/ (window-text-height) 4))) - (scroll-tests-up-and-down (+ max-margin 1) max-margin) - (scroll-tests-up-and-down (+ max-margin 2) max-margin)))) + (scroll-tests-with-buffer-window 7 + (let ((max-margin (/ (window-text-height) 4))) + (scroll-tests-up-and-down (+ max-margin 1) max-margin) + (scroll-tests-up-and-down (+ max-margin 2) max-margin)))) + +(ert-deftest scroll-tests-conservative-show-trailing-whitespace () + "Test for Bug#25792." + ;; Note: requires partial line to trigger problem. + (scroll-tests-with-buffer-window 20.5 + (let ((show-trailing-whitespace t) + (scroll-conservatively 101) + (scroll-margin 5)) + (insert (mapconcat #'number-to-string + (number-sequence 1 200) "\n")) + (goto-char 1) + (forward-line 15) + (sit-for 0) + (let ((window-line (count-lines (window-start) (window-point)))) + (dotimes (_ 10) + (call-interactively 'next-line) + (sit-for 0) + (should (= window-line (count-lines (window-start) + (window-point))))))))) (defun scroll-tests--point-in-middle-of-window-p () (= (count-lines (window-start) (window-point)) - (/ (1- (window-text-height)) 2))) + (/ (1- (floor (window-screen-lines))) 2))) (cl-defun scroll-tests--scroll-margin-whole-window (&key with-line-spacing) "Test `maximum-scroll-margin' at 0.5. @@ -95,27 +133,26 @@ With a high `scroll-margin', this should keep cursor in the middle of the window." (let ((maximum-scroll-margin 0.5) (scroll-margin 100)) - (scroll-tests-with-buffer-window - (setq-local line-spacing with-line-spacing) - ;; Choose an odd number, so there is one line in the middle. - (set-window-text-height nil 7) - ;; `set-window-text-height' doesn't count `line-spacing'. - (when with-line-spacing - (window-resize nil (* line-spacing 7) nil nil 'pixels)) - (erase-buffer) - (insert (mapconcat #'number-to-string - (number-sequence 1 200) "\n")) - (goto-char 1) - (sit-for 0) - (call-interactively 'scroll-up-command) - (sit-for 0) - (should (scroll-tests--point-in-middle-of-window-p)) - (call-interactively 'scroll-up-command) - (sit-for 0) - (should (scroll-tests--point-in-middle-of-window-p)) - (call-interactively 'scroll-down-command) - (sit-for 0) - (should (scroll-tests--point-in-middle-of-window-p))))) + ;; Choose an odd number of lines, so there is a middle line. + (scroll-tests-with-buffer-window 7 + (setq-local line-spacing with-line-spacing) + ;; `set-window-text-height' doesn't count `line-spacing'. + (when with-line-spacing + (window-resize nil (* line-spacing 8) nil nil 'pixels)) + (erase-buffer) + (insert (mapconcat #'number-to-string + (number-sequence 1 200) "\n")) + (goto-char 1) + (sit-for 0) + (call-interactively 'scroll-up-command) + (sit-for 0) + (should (scroll-tests--point-in-middle-of-window-p)) + (call-interactively 'scroll-up-command) + (sit-for 0) + (should (scroll-tests--point-in-middle-of-window-p)) + (call-interactively 'scroll-down-command) + (sit-for 0) + (should (scroll-tests--point-in-middle-of-window-p))))) (ert-deftest scroll-tests-scroll-margin-whole-window () (skip-unless (not noninteractive)) commit e52287ca3e974ed9f658315288060f638081abb0 Author: Tom Tromey Date: Fri Feb 24 00:24:17 2017 -0700 Fix indentation error in js.el * lisp/progmodes/js.el (js--indent-in-array-comp): Wrap forward-sexp call in condition-case. * test/lisp/progmodes/js-tests.el (js-mode-indentation-error): New test. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 6e313dc51b..65325a8ffa 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -1986,11 +1986,16 @@ In particular, return the buffer position of the first `for' kwd." (js--forward-syntactic-ws) (if (looking-at "[[{]") (let (forward-sexp-function) ; Use Lisp version. - (forward-sexp) ; Skip destructuring form. - (js--forward-syntactic-ws) - (if (and (/= (char-after) ?,) ; Regular array. - (looking-at "for")) - (match-beginning 0))) + (condition-case nil + (progn + (forward-sexp) ; Skip destructuring form. + (js--forward-syntactic-ws) + (if (and (/= (char-after) ?,) ; Regular array. + (looking-at "for")) + (match-beginning 0))) + (scan-error + ;; Nothing to do here. + nil))) ;; To skip arbitrary expressions we need the parser, ;; so we'll just guess at it. (if (and (> end (point)) ; Not empty literal. diff --git a/test/lisp/progmodes/js-tests.el b/test/lisp/progmodes/js-tests.el index 99f5898525..07e659af60 100644 --- a/test/lisp/progmodes/js-tests.el +++ b/test/lisp/progmodes/js-tests.el @@ -118,6 +118,16 @@ if (!/[ (:,='\"]/.test(value)) { ;; implementation not recognizing the comment example. (should-not (syntax-ppss-context (syntax-ppss)))))) +(ert-deftest js-mode-indentation-error () + (with-temp-buffer + (js-mode) + ;; The bug previously was that requesting re-indentation on the + ;; "{" line here threw an exception. + (insert "const TESTS = [\n{") + (js-indent-line) + ;; Any success is ok here. + (should t))) + (provide 'js-tests) ;;; js-tests.el ends here commit 7b49bd44b70d0583e7e5989513b38e6f77e1c559 Author: Tom Tromey Date: Thu Feb 23 23:57:59 2017 -0700 add "async" and "await" keywords * lisp/progmodes/js.el (js--keyword-re): Add async, await. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index b42b2bca82..6e313dc51b 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -277,7 +277,7 @@ Match group 1 is the name of the macro.") (defconst js--keyword-re (js--regexp-opt-symbol - '("abstract" "break" "case" "catch" "class" "const" + '("abstract" "async" "await" "break" "case" "catch" "class" "const" "continue" "debugger" "default" "delete" "do" "else" "enum" "export" "extends" "final" "finally" "for" "function" "goto" "if" "implements" "import" "in"