comparison src/window.c @ 844:047d37eb70d7

[xemacs-hg @ 2002-05-16 13:30:23 by ben] ui fixes for things that were bothering me bytecode.c, editfns.c, lisp.h, lread.c: Fix save-restriction to use markers rather than pseudo-markers (integers representing the amount of text on either side of the region). That way, all inserts are handled correctly, not just those inside old restriction. Add buffer argument to save_restriction_save(). process.c: Clean up very dirty and kludgy code that outputs into a buffer -- use proper unwind protects, etc. font-lock.c: Do save-restriction/widen around the function -- otherwise, incorrect results will ensue when a buffer has been narrowed before a call to e.g. `buffer-syntactic-context' -- something that happens quite often. fileio.c: Look for a handler for make-temp-name. window.c, winslots.h: Try to solve this annoying problem: have two frames displaying the buffer, in different places; in one, temporarily switch away to another buffer and then back -- and you've lost your position; it's reset to the other one in the other frame. My current solution involves window-level caches of buffers and points (also a cache for window-start); when set-window-buffer is called, it looks to see if the buffer was previously visited in the window, and if so, uses the most recent point at that time. (It's a marker, so it handles changes.) #### Note: It could be argued that doing it on the frame level would be better -- e.g. if you visit a buffer temporarily through a grep, and then go back to that buffer, you presumably want the grep's position rather than some previous position provided everything was in the same frame, even though the grep was in another window in the frame. However, doing it on the frame level fails when you have two windows on the same frame. Perhaps we keep both a window and a frame cache, and use the frame cache if there are no other windows on the frame showing the buffer, else the window's cache? This is probably something to be configurable using a specifier. Suggestions please please please? window.c: Clean up a bit code that deals with the annoyance of window-point vs. point. dialog.el: Function to ask a multiple-choice question, automatically choosing a dialog box or minibuffer representation as necessary. Generalized version of yes-or-no-p, y-or-n-p. files.el: Use get-user-response to ask "yes/no/diff" question when recovering. "diff" means that a diff is displayed between the current file and the autosave. (Converts/deconverts escape-quoted as necessary. No more complaints from you, Mr. Turnbull!) One known problem: when a dialog is used, it's modal, so you can't scroll the diff. Will fix soon. lisp-mode.el: If we're filling a string, don't treat semicolon as a comment, which would give very unfriendly results. Uses `buffer-syntactic-context'. simple.el: all changes back to the beginning. (Useful if you've saved the file in the middle of the changes.) simple.el: Add option kill-word-into-kill-ring, which controls whether words deleted with kill-word, backward-kill-word, etc. are "cut" into the kill ring, or "cleared" into nothingness. (My preference is the latter, by far. I'd almost go so far as suggesting we make it the default, as you can always select a word and then cut it if you want it cut.) menubar-items.el: Add option corresponding to kill-word-into-kill-ring.
author ben
date Thu, 16 May 2002 13:30:58 +0000
parents 6728e641994e
children 2b6fa2618f76
comparison
equal deleted inserted replaced
843:f46864126a0d 844:047d37eb70d7
210 Dynarr_free (w->glyph_cachels); 210 Dynarr_free (w->glyph_cachels);
211 w->glyph_cachels = 0; 211 w->glyph_cachels = 0;
212 } 212 }
213 } 213 }
214 214
215 /* These caches map buffers to markers. They are key-weak so that entries
216 remain around as long as the buffers do. */
217
218 static Lisp_Object
219 make_saved_buffer_point_cache (void)
220 {
221 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ);
222 }
223
215 DEFINE_LRECORD_IMPLEMENTATION ("window", window, 224 DEFINE_LRECORD_IMPLEMENTATION ("window", window,
216 mark_window, print_window, finalize_window, 225 mark_window, print_window, finalize_window,
217 0, 0, 0, struct window); 226 0, 0, 0, struct window);
218 227
219 228
246 #include "winslots.h" 255 #include "winslots.h"
247 256
248 INIT_DISP_VARIABLE (start, Fmake_marker ()); 257 INIT_DISP_VARIABLE (start, Fmake_marker ());
249 INIT_DISP_VARIABLE (pointm, Fmake_marker ()); 258 INIT_DISP_VARIABLE (pointm, Fmake_marker ());
250 p->sb_point = Fmake_marker (); 259 p->sb_point = Fmake_marker ();
260 p->saved_point_cache = make_saved_buffer_point_cache ();
261 p->saved_last_window_start_cache = make_saved_buffer_point_cache ();
251 p->use_time = Qzero; 262 p->use_time = Qzero;
252 INIT_DISP_VARIABLE (last_modified, Qzero); 263 INIT_DISP_VARIABLE (last_modified, Qzero);
253 INIT_DISP_VARIABLE (last_point, Fmake_marker ()); 264 INIT_DISP_VARIABLE (last_point, Fmake_marker ());
254 INIT_DISP_VARIABLE (last_start, Fmake_marker ()); 265 INIT_DISP_VARIABLE (last_start, Fmake_marker ());
255 INIT_DISP_VARIABLE (last_facechange, Qzero); 266 INIT_DISP_VARIABLE (last_facechange, Qzero);
1755 return make_int (dl->ascent + dl->descent - dl->clip); 1766 return make_int (dl->ascent + dl->descent - dl->clip);
1756 } 1767 }
1757 1768
1758 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /* 1769 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /*
1759 Make point value in WINDOW be at position POS in WINDOW's buffer. 1770 Make point value in WINDOW be at position POS in WINDOW's buffer.
1771 If WINDOW is the selected window, this actually changes the buffer's point
1772 instead of the window's point. (The equivalence of the selected window's
1773 point with its buffer's point is maintained throughout XEmacs.)
1760 */ 1774 */
1761 (window, pos)) 1775 (window, pos))
1762 { 1776 {
1763 struct window *w = decode_window (window); 1777 struct window *w = decode_window (window);
1764 1778
1765 CHECK_INT_COERCE_MARKER (pos); 1779 CHECK_INT_COERCE_MARKER (pos);
1766 if (w == XWINDOW (Fselected_window (Qnil))) 1780 /* Don't dereference selected-window because there may not
1767 Fgoto_char (pos, Qnil); 1781 be one -- e.g. at startup */
1782 if (EQ (wrap_window (w), Fselected_window (Qnil)))
1783 /* Even though window selected, buffer may not be current */
1784 Fgoto_char (pos, w->buffer);
1768 else 1785 else
1769 set_marker_restricted (w->pointm[CURRENT_DISP], pos, w->buffer); 1786 set_marker_restricted (w->pointm[CURRENT_DISP], pos, w->buffer);
1770 1787
1771 MARK_POINT_CHANGED; 1788 MARK_POINT_CHANGED;
1772 return pos; 1789 return pos;
1832 when it is about to cease to display that buffer. */ 1849 when it is about to cease to display that buffer. */
1833 static void 1850 static void
1834 unshow_buffer (struct window *w) 1851 unshow_buffer (struct window *w)
1835 { 1852 {
1836 Lisp_Object buf = w->buffer; 1853 Lisp_Object buf = w->buffer;
1837 1854 struct buffer *b = XBUFFER (buf);
1838 if (XBUFFER (buf) != XMARKER (w->pointm[CURRENT_DISP])->buffer) 1855
1856 if (b != XMARKER (w->pointm[CURRENT_DISP])->buffer)
1839 abort (); 1857 abort ();
1840 1858
1841 /* FSF disables this check, so I'll do it too. I hope it won't 1859 /* FSF disables this check, so I'll do it too. I hope it won't
1842 break things. --ben */ 1860 break things. --ben */
1843 #if 0 1861 #if 0
1858 1876
1859 /* Point in the selected window's buffer 1877 /* Point in the selected window's buffer
1860 is actually stored in that buffer, and the window's pointm isn't used. 1878 is actually stored in that buffer, and the window's pointm isn't used.
1861 So don't clobber point in that buffer. */ 1879 So don't clobber point in that buffer. */
1862 if (! EQ (buf, XWINDOW (Fselected_window (Qnil))->buffer)) 1880 if (! EQ (buf, XWINDOW (Fselected_window (Qnil))->buffer))
1863 { 1881 BUF_SET_PT (b,
1864 struct buffer *b= XBUFFER (buf); 1882 charbpos_clip_to_bounds
1865 BUF_SET_PT (b, charbpos_clip_to_bounds (BUF_BEGV (b), 1883 (BUF_BEGV (b),
1866 marker_position (w->pointm[CURRENT_DISP]), 1884 marker_position (w->pointm[CURRENT_DISP]),
1867 BUF_ZV (b))); 1885 BUF_ZV (b)));
1868 } 1886
1887 {
1888 Lisp_Object marker = Fgethash (buf, w->saved_point_cache, Qnil);
1889 int selected = EQ (wrap_window (w), Fselected_window (Qnil));
1890
1891 if (NILP (marker))
1892 {
1893 marker = Fmake_marker ();
1894 Fputhash (buf, marker, w->saved_point_cache);
1895 }
1896 Fset_marker (marker,
1897 selected ? make_int (BUF_PT (b)) : w->pointm[CURRENT_DISP],
1898 buf);
1899
1900 marker = Fgethash (buf, w->saved_last_window_start_cache, Qnil);
1901
1902 if (NILP (marker))
1903 {
1904 marker = Fmake_marker ();
1905 Fputhash (buf, marker, w->saved_last_window_start_cache);
1906 }
1907 Fset_marker (marker, w->start[CURRENT_DISP], buf);
1908 }
1869 } 1909 }
1870 1910
1871 /* Put REPLACEMENT into the window structure in place of OLD. */ 1911 /* Put REPLACEMENT into the window structure in place of OLD. */
1872 static void 1912 static void
1873 replace_window (Lisp_Object old, Lisp_Object replacement) 1913 replace_window (Lisp_Object old, Lisp_Object replacement)
3488 3528
3489 w->buffer = buffer; 3529 w->buffer = buffer;
3490 w->window_end_pos[CURRENT_DISP] = 0; 3530 w->window_end_pos[CURRENT_DISP] = 0;
3491 w->hscroll = 0; 3531 w->hscroll = 0;
3492 w->modeline_hscroll = 0; 3532 w->modeline_hscroll = 0;
3533 #if 0 /* pre point caches */
3493 Fset_marker (w->pointm[CURRENT_DISP], 3534 Fset_marker (w->pointm[CURRENT_DISP],
3494 make_int (BUF_PT (XBUFFER (buffer))), 3535 make_int (BUF_PT (XBUFFER (buffer))),
3495 buffer); 3536 buffer);
3496 set_marker_restricted (w->start[CURRENT_DISP], 3537 set_marker_restricted (w->start[CURRENT_DISP],
3497 make_int (XBUFFER (buffer)->last_window_start), 3538 make_int (XBUFFER (buffer)->last_window_start),
3498 buffer); 3539 buffer);
3540 #else
3541 {
3542 Lisp_Object marker = Fgethash (buffer, w->saved_point_cache, Qnil);
3543 Lisp_Object newpoint =
3544 !NILP (marker) ? make_int (marker_position (marker)) :
3545 make_int (BUF_PT (XBUFFER (buffer)));
3546 /* Previously, we had in here set-window-point, which did one of the
3547 following two, but not both. However, that could result in pointm
3548 being in a different buffer from the window's buffer! Probably
3549 not a travesty since it always occurred when the window was
3550 selected, meaning its value of point was ignored in favor of the
3551 buffer's; but it tripped an assert() in unshow_buffer(). */
3552 set_marker_restricted (w->pointm[CURRENT_DISP], newpoint, buffer);
3553 if (EQ (wrap_window (w), Fselected_window (Qnil)))
3554 Fgoto_char (newpoint, buffer); /* this will automatically clip to
3555 accessible */
3556 marker = Fgethash (buffer, w->saved_last_window_start_cache, Qnil);
3557 set_marker_restricted (w->start[CURRENT_DISP],
3558 !NILP (marker) ?
3559 make_int (marker_position (marker)) :
3560 make_int (XBUFFER (buffer)->last_window_start),
3561 buffer);
3562 }
3563 #endif
3564
3499 Fset_marker (w->sb_point, w->start[CURRENT_DISP], buffer); 3565 Fset_marker (w->sb_point, w->start[CURRENT_DISP], buffer);
3500 /* set start_at_line_beg correctly. GE */ 3566 /* set start_at_line_beg correctly. GE */
3501 w->start_at_line_beg = beginning_of_line_p (XBUFFER (buffer), 3567 w->start_at_line_beg =
3502 marker_position (w->start[CURRENT_DISP])); 3568 beginning_of_line_p (XBUFFER (buffer),
3503 w->force_start = 0; /* Lucid fix */ 3569 marker_position (w->start[CURRENT_DISP]));
3570 w->force_start = 0; /* XEmacs fix */
3504 SET_LAST_MODIFIED (w, 1); 3571 SET_LAST_MODIFIED (w, 1);
3505 SET_LAST_FACECHANGE (w); 3572 SET_LAST_FACECHANGE (w);
3506 MARK_WINDOWS_CHANGED (w); 3573 MARK_WINDOWS_CHANGED (w);
3507 { 3574 {
3508 int new_buffer_local_face_property = 3575 int new_buffer_local_face_property =
3685 p->start[CMOTION_DISP] = Qnil; 3752 p->start[CMOTION_DISP] = Qnil;
3686 p->pointm[CURRENT_DISP] = Qnil; 3753 p->pointm[CURRENT_DISP] = Qnil;
3687 p->pointm[DESIRED_DISP] = Qnil; 3754 p->pointm[DESIRED_DISP] = Qnil;
3688 p->pointm[CMOTION_DISP] = Qnil; 3755 p->pointm[CMOTION_DISP] = Qnil;
3689 p->sb_point = Qnil; 3756 p->sb_point = Qnil;
3757 p->saved_point_cache = make_saved_buffer_point_cache ();
3758 p->saved_last_window_start_cache = make_saved_buffer_point_cache ();
3690 p->buffer = Qnil; 3759 p->buffer = Qnil;
3691 } 3760 }
3692 3761
3693 DEFUN ("split-window", Fsplit_window, 0, 3, "", /* 3762 DEFUN ("split-window", Fsplit_window, 0, 3, "", /*
3694 Split WINDOW, putting SIZE lines in the first of the pair. 3763 Split WINDOW, putting SIZE lines in the first of the pair.
4427 w->force_start = 1; 4496 w->force_start = 1;
4428 w->start_at_line_beg = beginning_of_line_p (b, startp); 4497 w->start_at_line_beg = beginning_of_line_p (b, startp);
4429 MARK_WINDOWS_CHANGED (w); 4498 MARK_WINDOWS_CHANGED (w);
4430 4499
4431 if (!point_would_be_visible (w, startp, XINT (point))) 4500 if (!point_would_be_visible (w, startp, XINT (point)))
4432 { 4501 Fset_window_point (wrap_window (w), make_int (startp));
4433 if (selected)
4434 BUF_SET_PT (b, startp);
4435 else
4436 set_marker_restricted (w->pointm[CURRENT_DISP],
4437 make_int (startp),
4438 w->buffer);
4439 }
4440 } 4502 }
4441 } 4503 }
4442 } 4504 }
4443 else if (value < 0) 4505 else if (value < 0)
4444 { 4506 {
4510 if (MINI_WINDOW_P (w)) 4572 if (MINI_WINDOW_P (w))
4511 new_point = startp; 4573 new_point = startp;
4512 else 4574 else
4513 new_point = start_of_last_line (w, startp); 4575 new_point = start_of_last_line (w, startp);
4514 4576
4515 if (selected) 4577 Fset_window_point (wrap_window (w), make_int (new_point));
4516 BUF_SET_PT (b, new_point);
4517 else
4518 set_marker_restricted (w->pointm[CURRENT_DISP],
4519 make_int (new_point),
4520 w->buffer);
4521 } 4578 }
4522 } 4579 }
4523 } 4580 }
4524 } 4581 }
4525 else /* value == 0 && direction == -1 */ 4582 else /* value == 0 && direction == -1 */
4555 4612
4556 if (!point_would_be_visible (w, startp, XINT (point))) 4613 if (!point_would_be_visible (w, startp, XINT (point)))
4557 { 4614 {
4558 Charbpos new_point = start_of_last_line (w, startp); 4615 Charbpos new_point = start_of_last_line (w, startp);
4559 4616
4560 if (selected) 4617 Fset_window_point (wrap_window (w), make_int (new_point));
4561 BUF_SET_PT (b, new_point);
4562 else
4563 set_marker_restricted (w->pointm[CURRENT_DISP],
4564 make_int (new_point),
4565 w->buffer);
4566 } 4618 }
4567 } 4619 }
4568 } 4620 }
4569 } 4621 }
4570 4622
4773 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b) 4825 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
4774 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)) 4826 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b))
4775 { 4827 {
4776 new_point = point_at_center (w, CURRENT_DISP, 0, 0); 4828 new_point = point_at_center (w, CURRENT_DISP, 0, 0);
4777 4829
4830 /* #### Here we are checking the selected window of the frame
4831 instead of the selected window period. Elsewhere we check
4832 the selected window of the device. What a mess! */
4778 if (selected) 4833 if (selected)
4779 BUF_SET_PT (b, new_point); 4834 BUF_SET_PT (b, new_point);
4780 else 4835 else
4781 Fset_window_point (window, make_int (new_point)); 4836 Fset_window_point (window, make_int (new_point));
4782 4837