commit 8a64107f7de6db557a2c43147369c6a93adf6668 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Sat Mar 2 23:02:01 2019 -0800 Fix typo in previous change * src/alloc.c (memory_full_cons_threshold): Move to after definition of struct cons_block. Problem reported by Basil L. Contovounesios in: https://lists.gnu.org/r/emacs-devel/2019-03/msg00067.html diff --git a/src/alloc.c b/src/alloc.c index 9b3dc4be99..6b36648555 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -231,11 +231,6 @@ byte_ct consing_since_gc; byte_ct gc_relative_threshold; -/* Minimum number of bytes of consing since GC before next GC, - when memory is full. */ - -byte_ct const memory_full_cons_threshold = sizeof (struct cons_block); - #ifdef HAVE_PDUMPER /* Number of finalizers run: used to loop over GC until we stop generating garbage. */ @@ -2754,6 +2749,11 @@ struct cons_block #define XUNMARK_CONS(fptr) \ UNSETMARKBIT (CONS_BLOCK (fptr), CONS_INDEX ((fptr))) +/* Minimum number of bytes of consing since GC before next GC, + when memory is full. */ + +byte_ct const memory_full_cons_threshold = sizeof (struct cons_block); + /* Current cons_block. */ static struct cons_block *cons_block; commit 5e841bc9e5ff878b3dce36a712386ed6f53b6e60 Author: Glenn Morris Date: Sat Mar 2 19:02:50 2019 -0800 * test/lisp/progmodes/python-tests.el (python-syntax-after-python-backspace): Expect success. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 94c846ecb1..26aaff463c 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -184,7 +184,8 @@ aliqua." (ert-deftest python-syntax-after-python-backspace () ;; `python-indent-dedent-line-backspace' garbles syntax - :expected-result :failed + ;; But it seems that since da7580, the test passes. +;;; :expected-result :failed (python-tests-with-temp-buffer "\"\"\"" (goto-char (point-max)) commit 284f635da833d2dbf0102af3442197b46adf78c5 Author: Paul Eggert Date: Sat Mar 2 13:13:05 2019 -0800 memory_full_cons_threshold is a constant * src/alloc.c (memory_full_cons_threshold): Now const. (memory_full): Omit no-longer-needed initialization. diff --git a/src/alloc.c b/src/alloc.c index 452d31f939..9b3dc4be99 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -234,7 +234,7 @@ byte_ct gc_relative_threshold; /* Minimum number of bytes of consing since GC before next GC, when memory is full. */ -byte_ct memory_full_cons_threshold; +byte_ct const memory_full_cons_threshold = sizeof (struct cons_block); #ifdef HAVE_PDUMPER /* Number of finalizers run: used to loop over GC until we stop @@ -4082,7 +4082,7 @@ void memory_full (size_t nbytes) { /* Do not go into hysterics merely because a large request failed. */ - bool enough_free_memory = 0; + bool enough_free_memory = false; if (SPARE_MEMORY < nbytes) { void *p; @@ -4092,21 +4092,17 @@ memory_full (size_t nbytes) if (p) { free (p); - enough_free_memory = 1; + enough_free_memory = true; } MALLOC_UNBLOCK_INPUT; } if (! enough_free_memory) { - int i; - Vmemory_full = Qt; - memory_full_cons_threshold = sizeof (struct cons_block); - /* The first time we get here, free the spare memory. */ - for (i = 0; i < ARRAYELTS (spare_memory); i++) + for (int i = 0; i < ARRAYELTS (spare_memory); i++) if (spare_memory[i]) { if (i == 0) diff --git a/src/lisp.h b/src/lisp.h index 32576930b2..2a3eaf3812 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3769,7 +3769,7 @@ extern Lisp_Object zero_vector; typedef uintptr_t byte_ct; /* System byte counts reported by GC. */ extern byte_ct consing_since_gc; extern byte_ct gc_relative_threshold; -extern byte_ct memory_full_cons_threshold; +extern byte_ct const memory_full_cons_threshold; #ifdef HAVE_PDUMPER extern int number_finalizers_run; #endif commit 5f99d515c921ee5546483ddab15e08f9b23280d9 Author: Paul Eggert Date: Sat Mar 2 11:05:40 2019 -0800 Avoid staticvec duplicates * src/alloc.c (staticpro) [ENABLE_CHECKING]: Check for duplicates. * src/keyboard.c (syms_of_keyboard): Define while-no-input-ignore-events and inhibit--record-char here ... (syms_of_keyboard_for_pdumper): ... instead of here. This avoids duplicates in staticvec. diff --git a/src/alloc.c b/src/alloc.c index 7d63e3c79b..452d31f939 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5725,6 +5725,8 @@ purecopy (Lisp_Object obj) void staticpro (Lisp_Object *varaddress) { + for (int i = 0; i < staticidx; i++) + eassert (staticvec[i] != varaddress); if (staticidx >= NSTATICS) fatal ("NSTATICS too small; try increasing and recompiling Emacs."); staticvec[staticidx++] = varaddress; diff --git a/src/keyboard.c b/src/keyboard.c index 6e805ec7e6..3807445837 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -11844,6 +11844,17 @@ preserve data in modified buffers that would otherwise be lost. If nil, Emacs crashes immediately in response to fatal signals. */); attempt_orderly_shutdown_on_fatal_signal = true; + DEFVAR_LISP ("while-no-input-ignore-events", + Vwhile_no_input_ignore_events, + doc: /* Ignored events from while-no-input. */); + + DEFVAR_BOOL ("inhibit--record-char", + inhibit_record_char, + doc: /* If non-nil, don't record input events. +This inhibits recording input events for the purposes of keyboard +macros, dribble file, and `recent-keys'. +Internal use only. */); + pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); } @@ -11878,17 +11889,8 @@ syms_of_keyboard_for_pdumper (void) eassert (initial_kboard == NULL); initial_kboard = allocate_kboard (Qt); - DEFVAR_LISP ("while-no-input-ignore-events", - Vwhile_no_input_ignore_events, - doc: /* Ignored events from while-no-input. */); Vwhile_no_input_ignore_events = Qnil; - DEFVAR_BOOL ("inhibit--record-char", - inhibit_record_char, - doc: /* If non-nil, don't record input events. -This inhibits recording input events for the purposes of keyboard -macros, dribble file, and `recent-keys'. -Internal use only. */); inhibit_record_char = false; } commit 954c9c5bc344cdd6b201c2260b306ec0999aff24 Author: Alan Mackenzie Date: Sat Mar 2 18:23:34 2019 +0000 Check by eassert that a bytepos argument isn't in the middle of a character * src/marker.c (buf_bytepos_to_charpos): Add an eassert to check that the parameter bytepos is at the beginning of a character or EOB. diff --git a/src/marker.c b/src/marker.c index b58051a8c2..0b2e1bf5c6 100644 --- a/src/marker.c +++ b/src/marker.c @@ -332,6 +332,10 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) if (best_above == best_above_byte) return bytepos; + /* Check bytepos is not in the middle of a character. */ + eassert (bytepos >= BUF_Z_BYTE (b) + || CHAR_HEAD_P (BUF_FETCH_BYTE (b, bytepos))); + best_below = BEG; best_below_byte = BEG_BYTE; commit d2b5f445c1a5f9e105eb65e10b28a40645516656 Author: Eli Zaretskii Date: Sat Mar 2 20:07:36 2019 +0200 Fix DND on MS-Windows with files from UNC directories * lisp/dnd.el (dnd-get-local-file-uri): Always return nil on MS-Windows, as this method cannot possibly work there: URIs that begin with the local system's name are UNCs, where the //SERVER part cannot be removed. (Bug#34675) diff --git a/lisp/dnd.el b/lisp/dnd.el index 73703863e6..459a7238dc 100644 --- a/lisp/dnd.el +++ b/lisp/dnd.el @@ -130,6 +130,7 @@ Return nil if URI is not a local file." (match-string 0 sysname) sysname)))) (when (and hostname + (not (eq system-type 'windows-nt)) (or (string-equal "localhost" hostname) (string-equal (downcase sysname) hostname) (string-equal sysname-no-dot hostname))) commit 7523a9e8b26f763eecd50981a3f2d6e705284324 Author: Phillip Lord Date: Sat Mar 2 16:52:53 2019 +0000 Revert "Add hook for all events" This reverts commit 7b31de4d107302ed91ce7519cd778b340a9880ee. diff --git a/etc/NEWS b/etc/NEWS index 5b4d9488ed..b265185567 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1293,13 +1293,11 @@ removed. * Lisp Changes in Emacs 27.1 - ++++ ** 'self-insert-command' takes the char to insert as (optional) argument. ** 'lookup-key' can take a list of keymaps as argument. -** New hook `input-event-functions` run whenever a user-input is read. - +++ ** 'condition-case' now accepts 't' to match any error symbol. diff --git a/lisp/subr.el b/lisp/subr.el index 5c8b84b8e9..5b0330745f 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1289,12 +1289,6 @@ See `event-start' for a description of the value returned." The return value is a positive integer." (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1)) -(defvar input-event-functions nil - ;; BEWARE: If it looks like this is not run anywhere, it's normal: - ;; this is run in keyboard.c. - "Special hook run each time a user-input event is read. -Each function is called with one argument: the event.") - (defsubst event-line-count (event) "Return the line count of EVENT, a mousewheel event. The return value is a positive integer." diff --git a/src/keyboard.c b/src/keyboard.c index c2d8b860e4..6e805ec7e6 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2928,8 +2928,6 @@ read_char (int commandflag, Lisp_Object map, if (! NILP (also_record)) record_char (also_record); - CALLN (Frun_hook_with_args, Qinput_event_functions, c); - /* Wipe the echo area. But first, if we are about to use an input method, save the echo area contents for it to refer to. */ @@ -11034,8 +11032,6 @@ syms_of_keyboard (void) DEFSYM (Qundefined, "undefined"); - DEFSYM (Qinput_event_functions, "input-event-functions"); - /* Hooks to run before and after each command. */ DEFSYM (Qpre_command_hook, "pre-command-hook"); DEFSYM (Qpost_command_hook, "post-command-hook"); commit 5e4b8538207c1d181372077d2adb6597f3b05e07 Author: Phillip Lord Date: Sat Mar 2 16:51:31 2019 +0000 Revert "; Fix typos in NEWS" This reverts commit d52bc534d799c255f24ff2a56e8bed830d8f68ca. diff --git a/etc/NEWS b/etc/NEWS index 0dba8fec0d..5b4d9488ed 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1293,12 +1293,12 @@ removed. * Lisp Changes in Emacs 27.1 -+++ + ** 'self-insert-command' takes the char to insert as (optional) argument. ** 'lookup-key' can take a list of keymaps as argument. -** New hook 'input-event-functions' run whenever a user-input is read. +** New hook `input-event-functions` run whenever a user-input is read. +++ ** 'condition-case' now accepts 't' to match any error symbol. commit 325b5dbd87ecfc4457ad0aecf1407be8c5cd167a Author: Phillip Lord Date: Sat Mar 2 16:48:50 2019 +0000 Revert "; Document input-event-functions" This reverts commit 27fffb2701c38090916e077d28a4a6b9e2bc09d2. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index bf66734157..1eb580e1e0 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2920,18 +2920,6 @@ this expression) remains the value of @code{last-command-event}. @end example @end defvar -@defvar input-event-functions -This variable holds a list of functions to call after Emacs reads an -event, but before any commands are run. Each function receives a -single argument: the event that has been read. - -There are normally easier hooks to use than this; in particular -@var{pre-command-hook} is run immediately before any command resulting -from an event. However, not all events result in a command, including -many mouse events and some keyboard events when an input-method is -active (@pxref{Reading Input}). -@end defvar - @defmac while-no-input body@dots{} This construct runs the @var{body} forms and returns the value of the last one---but only if no input arrives. If any input arrives during diff --git a/etc/NEWS b/etc/NEWS index 65eb9ba1af..0dba8fec0d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1298,7 +1298,6 @@ removed. ** 'lookup-key' can take a list of keymaps as argument. -+++ ** New hook 'input-event-functions' run whenever a user-input is read. +++ commit 7bda34af52687440632127b4b79986e951b978b1 Author: Mattias EngdegÄrd Date: Mon Feb 25 15:22:02 2019 +0100 Correct regexp-opt return value for empty string list When regexp-opt is called with an empty list of strings, return a regexp that doesn't match anything instead of the empty string (Bug#20307). * doc/lispref/searching.texi (Regular Expression Functions): * etc/NEWS: Document the new behaviour. * lisp/emacs-lisp/regexp-opt.el (regexp-opt): Return a never-match regexp for empty inputs. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index fb7f48474d..38e6204055 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -960,6 +960,9 @@ possible. A hand-tuned regular expression can sometimes be slightly more efficient, but is almost never worth the effort.}. @c E.g., see https://debbugs.gnu.org/2816 +If @var{strings} is the empty list, the return value is a regexp that +never matches anything. + The optional argument @var{paren} can be any of the following: @table @asis diff --git a/etc/NEWS b/etc/NEWS index 7c95988ff5..65eb9ba1af 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1649,6 +1649,12 @@ in any order. If the new third argument is non-nil, the match is guaranteed to be performed in the order given, as if the strings were made into a regexp by joining them with '\|'. ++++ +** The function 'regexp-opt', when given an empty list of strings, now +returns a regexp that never matches anything, which is an identity for +this operation. Previously, the empty string was returned in this +case. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el index d0c5f2d3fc..4404b905a6 100644 --- a/lisp/emacs-lisp/regexp-opt.el +++ b/lisp/emacs-lisp/regexp-opt.el @@ -90,6 +90,9 @@ Each string should be unique in STRINGS and should not contain any regexps, quoted or not. Optional PAREN specifies how the returned regexp is surrounded by grouping constructs. +If STRINGS is the empty list, the return value is a regexp that +never matches anything. + The optional argument PAREN can be any of the following: a string @@ -140,14 +143,18 @@ usually more efficient than that of a simplified version: (sorted-strings (delete-dups (sort (copy-sequence strings) 'string-lessp))) (re - ;; If NOREORDER is non-nil and the list contains a prefix - ;; of another string, we give up all attempts at optimisation. - ;; There is plenty of room for improvement (Bug#34641). - (if (and noreorder (regexp-opt--contains-prefix sorted-strings)) - (concat (or open "\\(?:") - (mapconcat #'regexp-quote strings "\\|") - "\\)") - (regexp-opt-group sorted-strings (or open t) (not open))))) + (cond + ;; No strings: return a\` which cannot match anything. + ((null strings) + (concat (or open "\\(?:") "a\\`\\)")) + ;; If we cannot reorder, give up all attempts at + ;; optimisation. There is room for improvement (Bug#34641). + ((and noreorder (regexp-opt--contains-prefix sorted-strings)) + (concat (or open "\\(?:") + (mapconcat #'regexp-quote strings "\\|") + "\\)")) + (t + (regexp-opt-group sorted-strings (or open t) (not open)))))) (cond ((eq paren 'words) (concat "\\<" re "\\>")) ((eq paren 'symbols) commit da758046da74e33273265cd2e72a8aa1a0c9c7e3 Author: Mattias EngdegÄrd Date: Sun Feb 24 22:12:52 2019 +0100 rx: fix `or' ordering by adding argument to regexp-opt The rx `or' form may reorder its arguments in an unpredictable way, contrary to user expectation, since it sometimes uses `regexp-opt'. Add a NOREORDER option to `regexp-opt' for preventing it from producing a reordered regexp (Bug#34641). * doc/lispref/searching.texi (Regular Expression Functions): * etc/NEWS (Lisp Changes in Emacs 27.1): Describe the new regexp-opt NOREORDER argument. * lisp/emacs-lisp/regexp-opt.el (regexp-opt): Add NOREORDER. Make no attempt at regexp improvement if the set of strings contains a prefix of another string. (regexp-opt--contains-prefix): New. * lisp/emacs-lisp/rx.el (rx-or): Call regexp-opt with NOREORDER. * test/lisp/emacs-lisp/rx-tests.el: Test rx `or' form match order. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index cfbd2449b1..fb7f48474d 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -950,7 +950,7 @@ whitespace: @end defun @cindex optimize regexp -@defun regexp-opt strings &optional paren +@defun regexp-opt strings &optional paren noreorder This function returns an efficient regular expression that will match any of the strings in the list @var{strings}. This is useful when you need to make matching or searching as fast as possible---for example, @@ -985,8 +985,15 @@ if it is necessary to ensure that a postfix operator appended to it will apply to the whole expression. @end table -The resulting regexp of @code{regexp-opt} is equivalent to but usually -more efficient than that of a simplified version: +The optional argument @var{noreorder}, if @code{nil} or omitted, +allows the returned regexp to match the strings in any order. If +non-@code{nil}, the match is guaranteed to be performed in the order +given, as if the strings were made into a regexp by joining them with +the @samp{\|} operator. + +Up to reordering, the resulting regexp of @code{regexp-opt} is +equivalent to but usually more efficient than that of a simplified +version: @example (defun simplified-regexp-opt (strings &optional paren) diff --git a/etc/NEWS b/etc/NEWS index 29ed7ab481..7c95988ff5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1642,6 +1642,13 @@ MS-Windows. ** New module environment function 'process_input' to process user input while module code is running. ++++ +** The function 'regexp-opt' accepts an additional optional argument. +By default, the regexp returned by 'regexp-opt' may match the strings +in any order. If the new third argument is non-nil, the match is +guaranteed to be performed in the order given, as if the strings were +made into a regexp by joining them with '\|'. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el index 63786c1508..d0c5f2d3fc 100644 --- a/lisp/emacs-lisp/regexp-opt.el +++ b/lisp/emacs-lisp/regexp-opt.el @@ -84,7 +84,7 @@ ;;; Code: ;;;###autoload -(defun regexp-opt (strings &optional paren) +(defun regexp-opt (strings &optional paren noreorder) "Return a regexp to match a string in the list STRINGS. Each string should be unique in STRINGS and should not contain any regexps, quoted or not. Optional PAREN specifies how the @@ -111,8 +111,14 @@ nil necessary to ensure that a postfix operator appended to it will apply to the whole expression. -The resulting regexp is equivalent to but usually more efficient -than that of a simplified version: +The optional argument NOREORDER, if nil or omitted, allows the +returned regexp to match the strings in any order. If non-nil, +the match is guaranteed to be performed in the order given, as if +the strings were made into a regexp by joining them with the +`\\|' operator. + +Up to reordering, the resulting regexp is equivalent to but +usually more efficient than that of a simplified version: (defun simplified-regexp-opt (strings &optional paren) (let ((parens @@ -133,7 +139,15 @@ than that of a simplified version: (open (cond ((stringp paren) paren) (paren "\\("))) (sorted-strings (delete-dups (sort (copy-sequence strings) 'string-lessp))) - (re (regexp-opt-group sorted-strings (or open t) (not open)))) + (re + ;; If NOREORDER is non-nil and the list contains a prefix + ;; of another string, we give up all attempts at optimisation. + ;; There is plenty of room for improvement (Bug#34641). + (if (and noreorder (regexp-opt--contains-prefix sorted-strings)) + (concat (or open "\\(?:") + (mapconcat #'regexp-quote strings "\\|") + "\\)") + (regexp-opt-group sorted-strings (or open t) (not open))))) (cond ((eq paren 'words) (concat "\\<" re "\\>")) ((eq paren 'symbols) @@ -313,6 +327,22 @@ CHARS should be a list of characters." (concat "[" dash caret "]")) (concat "[" bracket charset caret dash "]")))) + +(defun regexp-opt--contains-prefix (strings) + "Whether STRINGS contains a proper prefix of one of its other elements. +STRINGS must be a list of sorted strings without duplicates." + (let ((s strings)) + ;; In a lexicographically sorted list, a string always immediately + ;; succeeds one of its prefixes. + (while (and (cdr s) + (not (string-equal + (car s) + (substring (cadr s) 0 (min (length (car s)) + (length (cadr s))))))) + (setq s (cdr s))) + (cdr s))) + + (provide 'regexp-opt) ;;; regexp-opt.el ends here diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 715cd608c4..ca756efb49 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -393,7 +393,7 @@ FORM is of the form `(and FORM1 ...)'." (rx-group-if (if (memq nil (mapcar 'stringp (cdr form))) (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|") - (regexp-opt (cdr form))) + (regexp-opt (cdr form) nil t)) (and (memq rx-parent '(: * t)) rx-parent))) diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index e14feda347..fa3d9b0d5e 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -92,5 +92,18 @@ (*? "e") (+? "f") (\?? "g") (?? "h")))) "a*b+c?d?e*?f+?g??h??"))) +(ert-deftest rx-or () + ;; Test or-pattern reordering (Bug#34641). + (let ((s "abc")) + (should (equal (and (string-match (rx (or "abc" "ab" "a")) s) + (match-string 0 s)) + "abc")) + (should (equal (and (string-match (rx (or "ab" "abc" "a")) s) + (match-string 0 s)) + "ab")) + (should (equal (and (string-match (rx (or "a" "ab" "abc")) s) + (match-string 0 s)) + "a")))) + (provide 'rx-tests) ;; rx-tests.el ends here. commit dbffbe08815644fd30404891ef81496277ed27da Author: Eli Zaretskii Date: Sat Mar 2 12:17:47 2019 +0200 Fix 'end-of-visual-line' with overlay strings with newlines * src/indent.c (Fvertical_motion): Get out of overlay strings with embedded newlines even if moving within the same screen line. See https://github.com/emacs-lsp/lsp-mode/issues/677 for more details. Fix test for IT_CHARPOS being at the beginning of the accessible portion of the buffer. diff --git a/src/indent.c b/src/indent.c index bc1aa8ca2c..1d5d346e63 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2286,7 +2286,7 @@ whether or not it is currently displayed in some window. */) it.current_y = 0; /* Do this even if LINES is 0, so that we move back to the beginning of the current line as we ought. */ - if ((nlines < 0 && IT_CHARPOS (it) > 0) + if ((nlines < 0 && IT_CHARPOS (it) > BEGV) || (nlines == 0 && !(start_x_given && start_x <= to_x))) move_it_by_lines (&it, max (PTRDIFF_MIN, nlines)); } @@ -2338,7 +2338,7 @@ whether or not it is currently displayed in some window. */) and then reposition point at the requested X coordinate; if we don't, the cursor will be placed just after the string, which might not be the requested column. */ - if (nlines > 0 && it.area == TEXT_AREA) + if (nlines >= 0 && it.area == TEXT_AREA) { while (it.method == GET_FROM_STRING && !it.string_from_display_prop_p