Mercurial > hg > xemacs-beta
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 |