diff options
author | Miles Bader <miles@gnu.org> | 2005-06-30 00:31:46 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 2005-06-30 00:31:46 +0000 |
commit | eeb88b27e1dbd3f412aa684d44e4a784f6e536a2 (patch) | |
tree | 23ea1eda87f588e060b6c00e9c7ffac6a89a7e42 /src | |
parent | 16e1457021e3f6e3b83fc9b5262fde38b7140c96 (diff) | |
parent | 84861437f914ac45c1eea7b6477ffc4783bb3bdd (diff) | |
download | emacs-eeb88b27e1dbd3f412aa684d44e4a784f6e536a2.tar.gz |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-67
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 447-458)
- Update from CVS
- Update from CVS: lisp/subr.el (add-to-ordered-list): Doc fix.
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 83-85)
- Merge from emacs--cvs-trunk--0
- Update from CVS
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 76 | ||||
-rw-r--r-- | src/dispextern.h | 2 | ||||
-rw-r--r-- | src/eval.c | 143 | ||||
-rw-r--r-- | src/fileio.c | 57 | ||||
-rw-r--r-- | src/lread.c | 17 | ||||
-rw-r--r-- | src/macfns.c | 2 | ||||
-rw-r--r-- | src/macterm.c | 2 | ||||
-rw-r--r-- | src/s/ms-w32.h | 1 | ||||
-rw-r--r-- | src/w32.c | 8 | ||||
-rw-r--r-- | src/w32fns.c | 2 | ||||
-rw-r--r-- | src/xdisp.c | 75 | ||||
-rw-r--r-- | src/xfns.c | 2 |
12 files changed, 291 insertions, 96 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 94cfec41a62..2d312756daf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,11 +1,80 @@ +2005-06-29 Juanma Barranquero <lekktu@gmail.com> + + * eval.c (user_variable_p_eh): New function. + (Fuser_variable_p): Use it. Clarify docstring. + Return t for aliases of user options, nil for alias loops. + +2005-06-27 Richard M. Stallman <rms@gnu.org> + + * eval.c (Fdefvar): Improve error message. + +2005-06-27 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * macterm.c [USE_CARBON_EVENTS] (mac_convert_event_ref): Fix last + change. + +2005-06-27 Juanma Barranquero <lekktu@gmail.com> + + * eval.c (Fdefvar): Don't try to set constant symbols. + +2005-06-25 Richard M. Stallman <rms@gnu.org> + + * macfns.c (Fx_show_tip): Pass new arg to try_window. + + * w32fns.c (Fx_show_tip): Pass new arg to try_window. + + * xfns.c (Fx_show_tip): Pass new arg to try_window. + + * xdisp.c (try_window): New arg CHECK_MARGINS. Calls changed. + (redisplay_window): Handle try_window reporting point in scroll margin. + + * dispextern.h (try_window): Declare new arg. + + * fileio.c (Fcopy_file): New arg PRESERVE_UID_GID. + Use fchmod to copy the file modes. + (Frename_file): Don't copy UID and GID here; + instead, specify t for PRESERVE_UID_GID when calling Fcopy_file. + + * eval.c (call_debugger): Take full care of extending stack limits + to make space for the debugger, and restore the change afterward. + Bind debug-on-error to nil. + (restore_stack_limits): New subroutine. + (Fsignal): Extend specpdl bound along with eval depth bound, + for calling edebug. Don't do either one, for calling debugger. + (find_handler_clause): Don't bind debug-on-error here. + Don't unbind anything either. + Temporarily advance max_specpdl_size for calling + internal_with_output_to_temp_buffer. + (grow_specpdl): Don't alter max_specpdl_size before signaling + an error. + (syms_of_eval) <max-specpdl-size>: Doc fix. + + * lread.c (read1): 0.0e+NaN should make a "positive" NaN. + +2005-06-24 Eli Zaretskii <eliz@gnu.org> + + * fileio.c (Frename_file): Undo last change: no need to ifdef away + chown on DOS_NT platforms. + + * w32.c (sys_chown): New function. + + * s/ms-w32.h (chown): New; define to sys_chown. + +2005-06-24 Juanma Barranquero <lekktu@gmail.com> + + * xdisp.c (syms_of_xdisp) <nobreak-char-display>: Doc fix. + (syms_of_xdisp) <void-text-area-pointer>: Doc fix. + + * fileio.c (Frename_file)[!DOS_NT]: Don't call chown on MSDOS/Windows. + 2005-06-23 Richard M. Stallman <rms@gnu.org> * xdisp.c (get_next_display_element): Finish reversing the tests of Vnobreak_char_display. - * xdisp.c (Vnobreak_char_display): Renamed from Vshow_nonbreak_escape. + * xdisp.c (Vnobreak_char_display): Rename from Vshow_nonbreak_escape. All uses changed. - (Qnobreak_space): Renamed from Qno_break_space. All uses changed. + (Qnobreak_space): Rename from Qno_break_space. All uses changed. (syms_of_xdisp): Define nobreak-char-display and nobreak-space. * fileio.c (Frename_file): Preserve owner and group, if possible, @@ -301,8 +370,7 @@ 2005-06-06 Eli Zaretskii <eliz@gnu.org> - * w32heap.h (OFFSET_TO_RVA, RVA_TO_OFFSET, RVA_TO_PTR): - Remove macros. + * w32heap.h (OFFSET_TO_RVA, RVA_TO_OFFSET, RVA_TO_PTR): Remove macros. * unexw32.c (RVA_TO_PTR): Move here from w32heap.h. diff --git a/src/dispextern.h b/src/dispextern.h index cd8488830f0..c049b17ce56 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2589,7 +2589,7 @@ int line_bottom_y P_ ((struct it *)); int display_prop_intangible_p P_ ((Lisp_Object)); void resize_echo_area_exactly P_ ((void)); int resize_mini_window P_ ((struct window *, int)); -int try_window P_ ((Lisp_Object, struct text_pos)); +int try_window P_ ((Lisp_Object, struct text_pos, int)); void window_box P_ ((struct window *, int, int *, int *, int *, int *)); int window_box_height P_ ((struct window *)); int window_text_bottom_y P_ ((struct window *)); diff --git a/src/eval.c b/src/eval.c index 8ad289fd51f..17e9f7f4360 100644 --- a/src/eval.c +++ b/src/eval.c @@ -227,6 +227,18 @@ init_eval () when_entered_debugger = -1; } +/* unwind-protect function used by call_debugger. */ + +static Lisp_Object +restore_stack_limits (data) + Lisp_Object data; +{ + max_specpdl_size = XINT (XCAR (data)); + max_lisp_eval_depth = XINT (XCDR (data)); +} + +/* Call the Lisp debugger, giving it argument ARG. */ + Lisp_Object call_debugger (arg) Lisp_Object arg; @@ -234,12 +246,22 @@ call_debugger (arg) int debug_while_redisplaying; int count = SPECPDL_INDEX (); Lisp_Object val; + int old_max = max_specpdl_size; + + /* Temporarily bump up the stack limits, + so the debugger won't run out of stack. */ + + max_specpdl_size += 1; + record_unwind_protect (restore_stack_limits, + Fcons (make_number (old_max), + make_number (max_lisp_eval_depth))); + max_specpdl_size = old_max; - if (lisp_eval_depth + 20 > max_lisp_eval_depth) - max_lisp_eval_depth = lisp_eval_depth + 20; + if (lisp_eval_depth + 40 > max_lisp_eval_depth) + max_lisp_eval_depth = lisp_eval_depth + 40; - if (specpdl_size + 40 > max_specpdl_size) - max_specpdl_size = specpdl_size + 40; + if (SPECPDL_INDEX () + 100 > max_specpdl_size) + max_specpdl_size = SPECPDL_INDEX () + 100; #ifdef HAVE_X_WINDOWS if (display_hourglass_p) @@ -256,6 +278,7 @@ call_debugger (arg) specbind (intern ("debugger-may-continue"), debug_while_redisplaying ? Qnil : Qt); specbind (Qinhibit_redisplay, Qnil); + specbind (Qdebug_on_error, Qnil); #if 0 /* Binding this prevents execution of Lisp code during redisplay, which necessarily leads to display problems. */ @@ -783,6 +806,10 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) register Lisp_Object sym, tem, tail; sym = Fcar (args); + if (SYMBOL_CONSTANT_P (sym)) + error ("Constant symbol `%s' specified in defvar", + SDATA (SYMBOL_NAME (sym))); + tail = Fcdr (args); if (!NILP (Fcdr (Fcdr (tail)))) error ("Too many arguments"); @@ -862,12 +889,24 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) return sym; } +/* Error handler used in Fuser_variable_p. */ +static Lisp_Object +user_variable_p_eh (ignore) + Lisp_Object ignore; +{ + return Qnil; +} + DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0, - doc: /* Returns t if VARIABLE is intended to be set and modified by users. + doc: /* Return t if VARIABLE is intended to be set and modified by users. \(The alternative is a variable used internally in a Lisp program.) -Determined by whether the first character of the documentation -for the variable is `*' or if the variable is customizable (has a non-nil -value of `standard-value' or of `custom-autoload' on its property list). */) +A variable is a user variable if +\(1) the first character of its documentation is `*', or +\(2) it is customizable (its property list contains a non-nil value + of `standard-value' or `custom-autoload'), or +\(3) it is an alias for another user variable. +Return nil if VARIABLE is an alias and there is a loop in the +chain of symbols. */) (variable) Lisp_Object variable; { @@ -876,23 +915,37 @@ value of `standard-value' or of `custom-autoload' on its property list). */) if (!SYMBOLP (variable)) return Qnil; - documentation = Fget (variable, Qvariable_documentation); - if (INTEGERP (documentation) && XINT (documentation) < 0) - return Qt; - if (STRINGP (documentation) - && ((unsigned char) SREF (documentation, 0) == '*')) - return Qt; - /* If it is (STRING . INTEGER), a negative integer means a user variable. */ - if (CONSP (documentation) - && STRINGP (XCAR (documentation)) - && INTEGERP (XCDR (documentation)) - && XINT (XCDR (documentation)) < 0) - return Qt; - /* Customizable? See `custom-variable-p'. */ - if ((!NILP (Fget (variable, intern ("standard-value")))) - || (!NILP (Fget (variable, intern ("custom-autoload"))))) - return Qt; - return Qnil; + /* If indirect and there's an alias loop, don't check anything else. */ + if (XSYMBOL (variable)->indirect_variable + && NILP (internal_condition_case_1 (indirect_variable, variable, + Qt, user_variable_p_eh))) + return Qnil; + + while (1) + { + documentation = Fget (variable, Qvariable_documentation); + if (INTEGERP (documentation) && XINT (documentation) < 0) + return Qt; + if (STRINGP (documentation) + && ((unsigned char) SREF (documentation, 0) == '*')) + return Qt; + /* If it is (STRING . INTEGER), a negative integer means a user variable. */ + if (CONSP (documentation) + && STRINGP (XCAR (documentation)) + && INTEGERP (XCDR (documentation)) + && XINT (XCDR (documentation)) < 0) + return Qt; + /* Customizable? See `custom-variable-p'. */ + if ((!NILP (Fget (variable, intern ("standard-value")))) + || (!NILP (Fget (variable, intern ("custom-autoload"))))) + return Qt; + + if (!XSYMBOL (variable)->indirect_variable) + return Qnil; + + /* An indirect variable? Let's follow the chain. */ + variable = XSYMBOL (variable)->value; + } } DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0, @@ -1533,7 +1586,16 @@ See also the function `condition-case'. */) /* This hook is used by edebug. */ if (! NILP (Vsignal_hook_function) && ! NILP (error_symbol)) - call2 (Vsignal_hook_function, error_symbol, data); + { + /* Edebug takes care of restoring these variables when it exits. */ + if (lisp_eval_depth + 20 > max_lisp_eval_depth) + max_lisp_eval_depth = lisp_eval_depth + 20; + + if (SPECPDL_INDEX () + 40 > max_specpdl_size) + max_specpdl_size = SPECPDL_INDEX () + 40; + + call2 (Vsignal_hook_function, error_symbol, data); + } conditions = Fget (real_error_symbol, Qerror_conditions); @@ -1555,12 +1617,6 @@ See also the function `condition-case'. */) { register Lisp_Object clause; - if (lisp_eval_depth + 20 > max_lisp_eval_depth) - max_lisp_eval_depth = lisp_eval_depth + 20; - - if (specpdl_size + 40 > max_specpdl_size) - max_specpdl_size = specpdl_size + 40; - clause = find_handler_clause (handlerlist->handler, conditions, error_symbol, data, &debugger_value); @@ -1673,7 +1729,11 @@ skip_debugger (conditions, data) = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). This is for memory-full errors only. - Store value returned from debugger into *DEBUGGER_VALUE_PTR. */ + Store value returned from debugger into *DEBUGGER_VALUE_PTR. + + We need to increase max_specpdl_size temporarily around + anything we do that can push on the specpdl, so as not to get + a second error here in case we're handling specpdl overflow. */ static Lisp_Object find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) @@ -1691,7 +1751,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) || !NILP (Vdebug_on_signal)) /* This says call debugger even if there is a handler. */ { - int count = SPECPDL_INDEX (); int debugger_called = 0; Lisp_Object sig_symbol, combined_data; /* This is set to 1 if we are handling a memory-full error, @@ -1713,6 +1772,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) if (wants_debugger (Vstack_trace_on_error, conditions)) { + max_specpdl_size++; #ifdef PROTOTYPES internal_with_output_to_temp_buffer ("*Backtrace*", (Lisp_Object (*) (Lisp_Object)) Fbacktrace, @@ -1721,6 +1781,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil); #endif + max_specpdl_size--; } if (! no_debugger && (EQ (sig_symbol, Qquit) @@ -1729,7 +1790,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) && ! skip_debugger (conditions, combined_data) && when_entered_debugger < num_nonmacro_input_events) { - specbind (Qdebug_on_error, Qnil); *debugger_value_ptr = call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); @@ -1739,7 +1799,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) if (EQ (handlers, Qerror)) { if (debugger_called) - return unbind_to (count, Qlambda); + return Qlambda; return Qt; } } @@ -3019,13 +3079,8 @@ grow_specpdl () if (max_specpdl_size < 400) max_specpdl_size = 400; if (specpdl_size >= max_specpdl_size) - { - if (!NILP (Vdebug_on_error)) - /* Leave room for some specpdl in the debugger. */ - max_specpdl_size = specpdl_size + 100; - Fsignal (Qerror, - Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); - } + Fsignal (Qerror, + Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); } specpdl_size *= 2; if (specpdl_size > max_specpdl_size) @@ -3333,7 +3388,7 @@ syms_of_eval () { DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, doc: /* *Limit on number of Lisp variable bindings & unwind-protects. -If Lisp code tries to make more than this many at once, +If Lisp code tries to increase the total number past this amount, an error is signaled. You can safely use a value considerably larger than the default value, if that proves inconveniently small. However, if you increase it too far, diff --git a/src/fileio.c b/src/fileio.c index 3dab52c47f0..112c879c1c5 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2411,7 +2411,7 @@ barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick) return; } -DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5, +DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6, "fCopy file: \nGCopy %s to file: \np\nP", doc: /* Copy FILE to NEWNAME. Both args must be strings. If NEWNAME names a directory, copy FILE there. @@ -2431,9 +2431,13 @@ for an existing file with the same name. If MUSTBENEW is `excl', that means to get an error if the file already exists; never overwrite. If MUSTBENEW is neither nil nor `excl', that means ask for confirmation before overwriting, but do go ahead and overwrite the file -if the user confirms. */) - (file, newname, ok_if_already_exists, keep_time, mustbenew) +if the user confirms. + +If PRESERVE-UID-GID is non-nil, we try to transfer the +uid and gid of FILE to NEWNAME. */) + (file, newname, ok_if_already_exists, keep_time, mustbenew, preserve_uid_gid) Lisp_Object file, newname, ok_if_already_exists, keep_time, mustbenew; + Lisp_Object preserve_uid_gid; { int ifd, ofd, n; char buf[16 * 1024]; @@ -2575,6 +2579,26 @@ if the user confirms. */) report_file_error ("I/O error", Fcons (newname, Qnil)); immediate_quit = 0; + /* Preserve the owner and group, if requested. */ + if (input_file_statable_p && ! NILP (preserve_uid_gid)) + fchown (ofd, st.st_uid, st.st_gid); + + if (input_file_statable_p) + { +#ifndef MSDOS + fchmod (ofd, st.st_mode & 07777); +#else /* MSDOS */ +#if defined (__DJGPP__) && __DJGPP__ > 1 + /* In DJGPP v2.0 and later, fstat usually returns true file mode bits, + and if it can't, it tells so. Otherwise, under MSDOS we usually + get only the READ bit, which will make the copied file read-only, + so it's better not to chmod at all. */ + if ((_djstat_flags & _STFAIL_WRITEBIT) == 0) + chmod (SDATA (encoded_newname), st.st_mode & 07777); +#endif /* DJGPP version 2 or newer */ +#endif /* MSDOS */ + } + /* Closing the output clobbers the file times on some systems. */ if (emacs_close (ofd) < 0) report_file_error ("I/O error", Fcons (newname, Qnil)); @@ -2592,18 +2616,6 @@ if the user confirms. */) Fcons (build_string ("Cannot set file date"), Fcons (newname, Qnil))); } -#ifndef MSDOS - chmod (SDATA (encoded_newname), st.st_mode & 07777); -#else /* MSDOS */ -#if defined (__DJGPP__) && __DJGPP__ > 1 - /* In DJGPP v2.0 and later, fstat usually returns true file mode bits, - and if it can't, it tells so. Otherwise, under MSDOS we usually - get only the READ bit, which will make the copied file read-only, - so it's better not to chmod at all. */ - if ((_djstat_flags & _STFAIL_WRITEBIT) == 0) - chmod (SDATA (encoded_newname), st.st_mode & 07777); -#endif /* DJGPP version 2 or newer */ -#endif /* MSDOS */ } emacs_close (ifd); @@ -2780,7 +2792,6 @@ This is what happens in interactive use with M-x. */) { if (errno == EXDEV) { - struct stat data; #ifdef S_IFLNK symlink_target = Ffile_symlink_p (file); if (! NILP (symlink_target)) @@ -2788,15 +2799,11 @@ This is what happens in interactive use with M-x. */) NILP (ok_if_already_exists) ? Qnil : Qt); else #endif - Fcopy_file (file, newname, - /* We have already prompted if it was an integer, - so don't have copy-file prompt again. */ - NILP (ok_if_already_exists) ? Qnil : Qt, - Qt, Qnil); - - /* Preserve owner and group, if possible (if we are root). */ - if (stat (SDATA (encoded_file), &data) >= 0) - chown (SDATA (encoded_file), data.st_uid, data.st_gid); + Fcopy_file (file, newname, + /* We have already prompted if it was an integer, + so don't have copy-file prompt again. */ + NILP (ok_if_already_exists) ? Qnil : Qt, + Qt, Qnil, Qt); Fdelete_file (file); } diff --git a/src/lread.c b/src/lread.c index d180836ada3..389bc04ddaa 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2715,6 +2715,23 @@ read1 (readcharfun, pch, first_in_list) break; case 'N': value = zero / zero; + + /* If that made a "negative" NaN, negate it. */ + + { + int i; + union { double d; char c[sizeof (double)]; } u_data, u_minus_zero; + + u_data.d = value; + u_minus_zero.d = - 0.0; + for (i = 0; i < sizeof (double); i++) + if (u_data.c[i] & u_minus_zero.c[i]) + { + value = - value; + break; + } + } + /* Now VALUE is a positive NaN. */ break; default: value = atof (read_buffer + negative); diff --git a/src/macfns.c b/src/macfns.c index 346ee1e2bde..f6ce7c42a67 100644 --- a/src/macfns.c +++ b/src/macfns.c @@ -4088,7 +4088,7 @@ Text larger than the specified size is clipped. */) clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); SET_TEXT_POS (pos, BEGV, BEGV_BYTE); - try_window (FRAME_ROOT_WINDOW (f), pos); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ width = height = 0; diff --git a/src/macterm.c b/src/macterm.c index cef213024fa..16d8452c87c 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -7666,6 +7666,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) default: break; } + break; case kEventClassKeyboard: switch (GetEventKind (eventRef)) @@ -7688,6 +7689,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) default: break; } + break; default: break; diff --git a/src/s/ms-w32.h b/src/s/ms-w32.h index 998c1f7cf05..10e3bfe3a5a 100644 --- a/src/s/ms-w32.h +++ b/src/s/ms-w32.h @@ -311,6 +311,7 @@ Boston, MA 02111-1307, USA. */ #define chdir sys_chdir #undef chmod #define chmod sys_chmod +#define chown sys_chown #undef close #define close sys_close #undef creat diff --git a/src/w32.c b/src/w32.c index 1bb4a91ff03..1585b3eaf1e 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1898,6 +1898,14 @@ sys_chmod (const char * path, int mode) } int +sys_chown (const char *path, uid_t owner, gid_t group) +{ + if (sys_chmod (path, _S_IREAD) == -1) /* check if file exists */ + return -1; + return 0; +} + +int sys_creat (const char * path, int mode) { return _creat (map_w32_filename (path, NULL), mode); diff --git a/src/w32fns.c b/src/w32fns.c index 3913349d8bd..5d92cb03d00 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7648,7 +7648,7 @@ Text larger than the specified size is clipped. */) clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); SET_TEXT_POS (pos, BEGV, BEGV_BYTE); - try_window (FRAME_ROOT_WINDOW (f), pos); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ width = height = 0; diff --git a/src/xdisp.c b/src/xdisp.c index b5f69a93810..0a2a02b4628 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -7697,7 +7697,7 @@ display_echo_area_1 (a1, a2, a3, a4) clear_glyph_matrix (w->desired_matrix); XSETWINDOW (window, w); SET_TEXT_POS (start, BEG, BEG_BYTE); - try_window (window, start); + try_window (window, start, 0); return window_height_changed_p; } @@ -11665,7 +11665,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively, /* Display the window. Give up if new fonts are loaded, or if point doesn't appear. */ - if (!try_window (window, startp)) + if (!try_window (window, startp, 0)) rc = SCROLLING_NEED_LARGER_MATRICES; else if (w->cursor.vpos < 0) { @@ -12268,6 +12268,7 @@ redisplay_window (window, just_this_one_p) { /* We set this later on if we have to adjust point. */ int new_vpos = -1; + int val; w->force_start = Qnil; w->vscroll = 0; @@ -12301,12 +12302,16 @@ redisplay_window (window, just_this_one_p) /* Redisplay, then check if cursor has been set during the redisplay. Give up if new fonts were loaded. */ - if (!try_window (window, startp)) + val = try_window (window, startp, 1); + if (!val) { w->force_start = Qt; clear_glyph_matrix (w->desired_matrix); goto need_larger_matrices; } + /* Point was outside the scroll margins. */ + if (val < 0) + new_vpos = window_box_height (w) / 2; if (w->cursor.vpos < 0 && !w->frozen_window_start_p) { @@ -12349,7 +12354,7 @@ redisplay_window (window, just_this_one_p) && !NILP (current_buffer->mark_active)) { clear_glyph_matrix (w->desired_matrix); - if (!try_window (window, startp)) + if (!try_window (window, startp, 0)) goto need_larger_matrices; } } @@ -12439,7 +12444,11 @@ redisplay_window (window, just_this_one_p) = try_window_reusing_current_matrix (w))) { IF_DEBUG (debug_method_add (w, "1")); - try_window (window, startp); + if (try_window (window, startp, 1) < 0) + /* -1 means we need to scroll. + 0 means we need new matrices, but fonts_changed_p + is set in that case, so we will detect it below. */ + goto try_to_scroll; } if (fonts_changed_p) @@ -12569,7 +12578,7 @@ redisplay_window (window, just_this_one_p) || MINI_WINDOW_P (w) || !(used_current_matrix_p = try_window_reusing_current_matrix (w))) - try_window (window, startp); + try_window (window, startp, 0); /* If new fonts have been loaded (due to fontsets), give up. We have to start a new redisplay since we need to re-adjust glyph @@ -12589,13 +12598,13 @@ redisplay_window (window, just_this_one_p) { clear_glyph_matrix (w->desired_matrix); move_it_by_lines (&it, 1, 0); - try_window (window, it.current.pos); + try_window (window, it.current.pos, 0); } else if (PT < IT_CHARPOS (it)) { clear_glyph_matrix (w->desired_matrix); move_it_by_lines (&it, -1, 0); - try_window (window, it.current.pos); + try_window (window, it.current.pos, 0); } else { @@ -12778,14 +12787,18 @@ redisplay_window (window, just_this_one_p) /* Build the complete desired matrix of WINDOW with a window start - buffer position POS. Value is non-zero if successful. It is zero - if fonts were loaded during redisplay which makes re-adjusting - glyph matrices necessary. */ + buffer position POS. + + Value is 1 if successful. It is zero if fonts were loaded during + redisplay which makes re-adjusting glyph matrices necessary, and -1 + if point would appear in the scroll margins. + (We check that only if CHECK_MARGINS is nonzero. */ int -try_window (window, pos) +try_window (window, pos, check_margins) Lisp_Object window; struct text_pos pos; + int check_margins; { struct window *w = XWINDOW (window); struct it it; @@ -12810,6 +12823,30 @@ try_window (window, pos) return 0; } + /* Don't let the cursor end in the scroll margins. */ + if (check_margins) + { + int this_scroll_margin, cursor_height; + + this_scroll_margin = max (0, scroll_margin); + this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); + this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); + cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height; + + if ((w->cursor.y < this_scroll_margin + && CHARPOS (pos) > BEGV) + /* Old redisplay didn't take scroll margin into account at the bottom, + but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */ + || (w->cursor.y + (make_cursor_line_fully_visible_p + ? cursor_height + this_scroll_margin + : 1)) > it.last_visible_y) + { + w->cursor.vpos = -1; + clear_glyph_matrix (w->desired_matrix); + return -1; + } + } + /* If bottom moved off end of frame, change mode line percentage. */ if (XFASTINT (w->window_end_pos) <= 0 && Z != IT_CHARPOS (it)) @@ -21801,7 +21838,7 @@ note_mouse_highlight (f, x, y) /* If we were displaying active text in another window, clear that. Also clear if we move out of text area in same window. */ if (! EQ (window, dpyinfo->mouse_face_window) - || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE + || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE && !NILP (dpyinfo->mouse_face_window))) clear_mouse_face (dpyinfo); @@ -23026,17 +23063,17 @@ The face used for trailing whitespace is `trailing-whitespace'. */); DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display, doc: /* *Control highlighting of nobreak space and soft hyphen. -t means highlight the character itself (for nobreak space, -use face `nobreak-space'. -nil means no highlighting. -other values mean display the escape glyph followed by an ordinary +A value of t means highlight the character itself (for nobreak space, +use face `nobreak-space'). +A value of nil means no highlighting. +Other values mean display the escape glyph followed by an ordinary space or ordinary hyphen. */); Vnobreak_char_display = Qt; DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer, doc: /* *The pointer shape to show in void text areas. -Nil means to show the text pointer. Other options are `arrow', `text', -`hand', `vdrag', `hdrag', `modeline', and `hourglass'. */); +A value of nil means to show the text pointer. Other options are `arrow', +`text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */); Vvoid_text_area_pointer = Qarrow; DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay, diff --git a/src/xfns.c b/src/xfns.c index e5efec27b7d..1de6fc71d1a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5070,7 +5070,7 @@ Text larger than the specified size is clipped. */) clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); SET_TEXT_POS (pos, BEGV, BEGV_BYTE); - try_window (FRAME_ROOT_WINDOW (f), pos); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ width = height = 0; |