commit 66b7543eab5f500f2e7cf0cce9b260991107fc97 (HEAD, refs/remotes/origin/master) Author: Noam Postavsky Date: Sun Feb 26 22:17:28 2017 -0500 Set default when asking for send-mail-function (Bug#25874). * lisp/mail/sendmail.el (sendmail-query-user-about-smtp): Pass first option as default for `completing-read'. diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index 70c8ea1f93..42b688fbab 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -555,8 +555,9 @@ This also saves the value of `send-mail-function' via Customize." (goto-char (point-min)) (display-buffer (current-buffer)) (let ((completion-ignore-case t)) - (completing-read "Send mail via: " - options nil 'require-match))))) + (completing-read + (format "Send mail via (default %s): " (caar options)) + options nil 'require-match nil nil (car options)))))) (customize-save-variable 'send-mail-function (cdr (assoc-string choice options t))))) commit 37940b347052418f0589bd52b06e56fffb594ea2 Author: Paul Eggert Date: Mon Mar 6 15:14:32 2017 -0800 min and max now return one of their arguments * doc/lispref/numbers.texi (Comparison of Numbers): * etc/NEWS: Document this. * src/data.c (Amax, Amin): Remove constants. All uses removed. (minmax_driver): New function. (Fmax, Fmin): Use it instead of arith_driver. * test/src/data-tests.el (data-tests-max, data-tests-min): New tests. diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index deae5fd85d..3fdc94169b 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -427,8 +427,6 @@ the following argument. It returns @code{t} if so, @code{nil} otherwise. @defun max number-or-marker &rest numbers-or-markers This function returns the largest of its arguments. -If any of the arguments is floating point, the value is returned -as floating point, even if it was given as an integer. @example (max 20) @@ -436,14 +434,12 @@ as floating point, even if it was given as an integer. (max 1 2.5) @result{} 2.5 (max 1 3 2.5) - @result{} 3.0 + @result{} 3 @end example @end defun @defun min number-or-marker &rest numbers-or-markers This function returns the smallest of its arguments. -If any of the arguments is floating point, the value is returned -as floating point, even if it was given as an integer. @example (min -4 1) diff --git a/etc/NEWS b/etc/NEWS index 8f7356f3e0..ce20dfb15d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -803,6 +803,13 @@ Unicode horizontal whitespace as defined in the Unicode Technical Standard #18. If you only want to match space and tab, use [ \t] instead. ++++ +** 'min' and 'max' now always return one of their arguments. +Formerly, they returned a floating-point value if any argument was +floating-point, which was sometimes numerically incorrect. For +example, (min most-positive-fixnum (+ 1.0 most-positive-fixnum)) now +always returns its first argument instead of its second. + * Lisp Changes in Emacs 26.1 diff --git a/src/data.c b/src/data.c index 66f4c9c738..ae88e3f8aa 100644 --- a/src/data.c +++ b/src/data.c @@ -2719,9 +2719,7 @@ enum arithop Adiv, Alogand, Alogior, - Alogxor, - Amax, - Amin + Alogxor }; static Lisp_Object float_arith_driver (double, ptrdiff_t, enum arithop, @@ -2807,14 +2805,6 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) case Alogxor: accum ^= next; break; - case Amax: - if (!argnum || next > accum) - accum = next; - break; - case Amin: - if (!argnum || next < accum) - accum = next; - break; } } @@ -2871,14 +2861,6 @@ float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code, case Alogior: case Alogxor: wrong_type_argument (Qinteger_or_marker_p, val); - case Amax: - if (!argnum || isnan (next) || next > accum) - accum = next; - break; - case Amin: - if (!argnum || isnan (next) || next < accum) - accum = next; - break; } } @@ -2975,22 +2957,37 @@ Both X and Y must be numbers or markers. */) return val; } +static Lisp_Object +minmax_driver (ptrdiff_t nargs, Lisp_Object *args, + enum Arith_Comparison comparison) +{ + eassume (0 < nargs); + Lisp_Object accum; + for (ptrdiff_t argnum = 0; argnum < nargs; argnum++) + { + Lisp_Object val = args[argnum]; + if (argnum == 0 || !NILP (arithcompare (val, accum, comparison))) + accum = val; + else if (FLOATP (accum) && isnan (XFLOAT_DATA (accum))) + break; + } + return accum; +} + DEFUN ("max", Fmax, Smax, 1, MANY, 0, doc: /* Return largest of all the arguments (which must be numbers or markers). -The value is always a number; markers are converted to numbers. usage: (max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) (ptrdiff_t nargs, Lisp_Object *args) { - return arith_driver (Amax, nargs, args); + return minmax_driver (nargs, args, ARITH_GRTR); } DEFUN ("min", Fmin, Smin, 1, MANY, 0, doc: /* Return smallest of all the arguments (which must be numbers or markers). -The value is always a number; markers are converted to numbers. usage: (min NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) (ptrdiff_t nargs, Lisp_Object *args) { - return arith_driver (Amin, nargs, args); + return minmax_driver (nargs, args, ARITH_LESS); } DEFUN ("logand", Flogand, Slogand, 0, MANY, 0, diff --git a/test/src/data-tests.el b/test/src/data-tests.el index d38760cdde..70ffdabe4d 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -80,6 +80,26 @@ ;; Short circuits before getting to bad arg (should-not (>= 8 9 'foo))) +(ert-deftest data-tests-max () + (should-error (max)) + (should (= 1 (max 1))) + (should (= 3 (max 3 2))) + (should (= 666 (max 666 1 0 0 -2 -3 -3 -3 -4 -8 -8 -9 -999))) + (should (= (1+ most-negative-fixnum) + (max (float most-negative-fixnum) (1+ most-negative-fixnum)))) + (should (= 8 (apply #'max '(3 8 3)))) + (should-error (max 9 8 'foo))) + +(ert-deftest data-tests-min () + (should-error (min)) + (should (= 1 (min 1))) + (should (= 2 (min 3 2))) + (should (= -999 (min 666 1 0 0 -2 -3 -3 -3 -4 -8 -8 -9 -999))) + (should (= most-positive-fixnum + (min (+ 1.0 most-positive-fixnum) most-positive-fixnum))) + (should (= 3 (apply #'min '(3 8 3)))) + (should-error (min 9 8 'foo))) + ;; Bool vector tests. Compactly represent bool vectors as hex ;; strings. commit 3bd2e9e975ed29daaf03ca7559e4664aade0674f Author: Alan Third Date: Mon Mar 6 19:50:47 2017 +0000 Remove NSEvent loop from ns_select (bug#25265) * src/nsterm.m (ns_select): Remove event processing loop and replace with simple test for a new event. diff --git a/src/nsterm.m b/src/nsterm.m index 08ee0cdf6f..ebe29e4261 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4108,6 +4108,9 @@ in certain situations (rapid incoming events). struct input_event event; char c; + NSDate *timeout_date = nil; + NSEvent *ns_event; + NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_select"); #ifdef HAVE_NATIVE_FS @@ -4170,65 +4173,58 @@ in certain situations (rapid incoming events). { /* No file descriptor, just a timeout, no need to wake fd_handler */ double time = timespectod (*timeout); - timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time - target: NSApp - selector: - @selector (timeout_handler:) - userInfo: 0 - repeats: NO] - retain]; - } - else /* No timeout and no file descriptors, can this happen? */ - { - /* Send appdefined so we exit from the loop */ - ns_send_appdefined (-1); + timeout_date = [NSDate dateWithTimeIntervalSinceNow: time]; } - block_input (); - ns_init_events (&event); - - [NSApp run]; + /* Listen for a new NSEvent. */ + ns_event = [NSApp nextEventMatchingMask: NSEventMaskAny + untilDate: timeout_date + inMode: NSDefaultRunLoopMode + dequeue: NO]; - ns_finish_events (); if (nr > 0 && readfds) { c = 's'; emacs_write_sig (selfds[1], &c, 1); } - unblock_input (); - - t = last_appdefined_event_data; - if (t != NO_APPDEFINED_DATA) + if (ns_event != nil) { - last_appdefined_event_data = NO_APPDEFINED_DATA; - - if (t == -2) + if ([ns_event type] == NSEventTypeApplicationDefined) { - /* The NX_APPDEFINED event we received was a timeout. */ - result = 0; + if ([ns_event data1] < 0) + { + /* The NX_APPDEFINED event we received was a timeout. */ + result = 0; + } + else + { + /* Received back from select () in fd_handler; copy the results */ + pthread_mutex_lock (&select_mutex); + if (readfds) *readfds = select_readfds; + if (writefds) *writefds = select_writefds; + pthread_mutex_unlock (&select_mutex); + result = [ns_event data1]; + } + + /* Remove the NX_APPDEFINED event from the queue as it's no + longer needed. */ + [NSApp nextEventMatchingMask: NSEventMaskAny + untilDate: nil + inMode: NSDefaultRunLoopMode + dequeue: YES]; } - else if (t == -1) + else { - /* The NX_APPDEFINED event we received was the result of - at least one real input event arriving. */ + /* A real NSEvent came in. */ errno = EINTR; result = -1; } - else - { - /* Received back from select () in fd_handler; copy the results */ - pthread_mutex_lock (&select_mutex); - if (readfds) *readfds = select_readfds; - if (writefds) *writefds = select_writefds; - pthread_mutex_unlock (&select_mutex); - result = t; - } } else { - errno = EINTR; - result = -1; + /* Reading from the NSEvent queue timed out. */ + result = 0; } return result; commit eae5dcd57d1a73688ccb576decbf90fa711105e7 Author: Eli Zaretskii Date: Mon Mar 6 18:22:53 2017 +0200 A better fix for bug#25845 * src/xdisp.c (font_for_underline_metrics): New function. * src/dispextern.h: Add its prototype. * src/xterm.c (x_draw_glyph_string): * src/w32term.c (x_draw_glyph_string): * src/nsterm.m (ns_draw_text_decoration): Call it. This avoids having identical code 3 times in 3 different files. diff --git a/src/dispextern.h b/src/dispextern.h index e030618a9b..679820d506 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3293,6 +3293,7 @@ extern void dump_glyph_string (struct glyph_string *) EXTERNALLY_VISIBLE; extern void x_get_glyph_overhangs (struct glyph *, struct frame *, int *, int *); +extern struct font *font_for_underline_metrics (struct glyph_string *); extern void x_produce_glyphs (struct it *); extern void x_write_glyphs (struct window *, struct glyph_row *, diff --git a/src/nsterm.m b/src/nsterm.m index bc89925b0e..08ee0cdf6f 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3043,28 +3043,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. } else { - /* If we are drawing in the middle of a glyph row, find - the first glyph in the run of underlined glyphs - preceding the beginning of glyph string S. This is - because that glyph determines the underline position - and thickness for the entire run of the underlined - glyphs. */ - struct glyph *g0 = s->row->glyphs[s->area], *g; - - for (g = s->first_glyph - 1; g >= g0; g--) - { - struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); - if (!(prev_face && prev_face->underline_p)) - break; - } - - /* Now use the font of the last glyph we saw that - still has the underlined_p flag set. */ - struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id); - struct font *font = glyph_face->font; - if (font) - font_prepare_for_face (s->f, glyph_face); - + struct font *font = font_for_underline_metrics (s); unsigned long descent = s->y + s->height - s->ybase; /* Use underline thickness of font, defaulting to 1. */ diff --git a/src/w32term.c b/src/w32term.c index 6a98fc721c..81666f5bc4 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2433,27 +2433,7 @@ x_draw_glyph_string (struct glyph_string *s) } else { - /* If we are drawing in the middle of a glyph row, - find the first glyph in the run of underlined - glyphs preceding the beginning of glyph string S. - This is because that glyph determines the - underline position and thickness for the entire - run of the underlined glyphs. */ - struct glyph *g0 = s->row->glyphs[s->area], *g; - - for (g = s->first_glyph - 1; g >= g0; g--) - { - struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); - if (!(prev_face && prev_face->underline_p)) - break; - } - - /* Now use the font of the last glyph we saw that - still has the underlined_p flag set. */ - struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id); - struct font *font = glyph_face->font; - if (font) - font_prepare_for_face (s->f, glyph_face); + struct font *font = font_for_underline_metrics (s); /* Get the underline thickness. Default is 1 pixel. */ if (font && font->underline_thickness > 0) diff --git a/src/xdisp.c b/src/xdisp.c index 82c4c775c1..1e7cb4ec66 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25948,6 +25948,36 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, return x_reached; } +/* Find the first glyph in the run of underlined glyphs preceding the + beginning of glyph string S, and return its font (which could be + NULL). This is needed because that font determines the underline + position and thickness for the entire run of the underlined glyphs. + This function is called from the draw_glyph_string method of GUI + frame's redisplay interface (RIF) when it needs to draw in an + underlined face. */ +struct font * +font_for_underline_metrics (struct glyph_string *s) +{ + struct glyph *g0 = s->row->glyphs[s->area], *g; + + for (g = s->first_glyph - 1; g >= g0; g--) + { + struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); + if (!(prev_face && prev_face->underline_p)) + break; + } + + /* If preceding glyphs are not underlined, use the font of S. */ + if (g == s->first_glyph - 1) + return s->font; + else + { + /* Otherwise use the font of the last glyph we saw in the above + loop whose face had the underline_p flag set. */ + return FACE_FROM_ID (s->f, g[1].face_id)->font; + } +} + /* Expand row matrix if too narrow. Don't expand if area is not present. */ diff --git a/src/xterm.c b/src/xterm.c index 57e64c4888..28faea14a3 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3636,27 +3636,7 @@ x_draw_glyph_string (struct glyph_string *s) } else { - /* If we are drawing in the middle of a glyph row, - find the first glyph in the run of underlined - glyphs preceding the beginning of glyph string S. - This is because that glyph determines the - underline position and thickness for the entire - run of the underlined glyphs. */ - struct glyph *g0 = s->row->glyphs[s->area], *g; - - for (g = s->first_glyph - 1; g >= g0; g--) - { - struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); - if (!(prev_face && prev_face->underline_p)) - break; - } - - /* Now use the font of the last glyph we saw that - still has the underlined_p flag set. */ - struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id); - struct font *font = glyph_face->font; - if (font) - font_prepare_for_face (s->f, glyph_face); + struct font *font = font_for_underline_metrics (s); /* Get the underline thickness. Default is 1 pixel. */ if (font && font->underline_thickness > 0)