Mercurial > hg > xemacs-beta
comparison src/process.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 |
---|---|
866 | 866 |
867 /************************************************************************/ | 867 /************************************************************************/ |
868 /* Process I/O */ | 868 /* Process I/O */ |
869 /************************************************************************/ | 869 /************************************************************************/ |
870 | 870 |
871 /* Set up PROCESS's buffer for insertion of process data at PROCESS's | |
872 mark. | |
873 | |
874 Sets the current buffer to PROCESS's buffer, inhibits read only, | |
875 remembers current point, sets point to PROCESS'S mark, widens if | |
876 necessary. | |
877 */ | |
878 static int | |
879 process_setup_for_insertion (Lisp_Object process) | |
880 { | |
881 Lisp_Process *p = XPROCESS (process); | |
882 int spec = specpdl_depth (); | |
883 struct buffer *buf = XBUFFER (p->buffer); | |
884 Charbpos output_pt; | |
885 | |
886 if (buf != current_buffer) | |
887 { | |
888 record_unwind_protect (save_current_buffer_restore, | |
889 Fcurrent_buffer ()); | |
890 set_buffer_internal (buf); | |
891 } | |
892 | |
893 record_unwind_protect (save_excursion_restore, save_excursion_save ()); | |
894 specbind (Qinhibit_read_only, Qt); | |
895 | |
896 /* Insert new output into buffer | |
897 at the current end-of-output marker, | |
898 thus preserving logical ordering of input and output. */ | |
899 if (XMARKER (p->mark)->buffer) | |
900 output_pt = marker_position (p->mark); | |
901 else | |
902 output_pt = BUF_ZV (buf); | |
903 | |
904 /* If the output marker is outside of the visible region, save | |
905 the restriction and widen. */ | |
906 if (! (BUF_BEGV (buf) <= output_pt && output_pt <= BUF_ZV (buf))) | |
907 { | |
908 record_unwind_protect (save_restriction_restore, | |
909 save_restriction_save (buf)); | |
910 Fwiden (wrap_buffer (buf)); | |
911 } | |
912 | |
913 BUF_SET_PT (buf, output_pt); | |
914 return spec; | |
915 } | |
916 | |
871 /* Read pending output from the process channel, | 917 /* Read pending output from the process channel, |
872 starting with our buffered-ahead character if we have one. | 918 starting with our buffered-ahead character if we have one. |
873 Yield number of characters read. | 919 Yield number of characters read. |
874 | 920 |
875 This function reads at most 1024 bytes. | 921 This function reads at most 1024 bytes. |
938 } | 984 } |
939 | 985 |
940 /* If no filter, write into buffer if it isn't dead. */ | 986 /* If no filter, write into buffer if it isn't dead. */ |
941 if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) | 987 if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) |
942 { | 988 { |
943 Lisp_Object old_read_only = Qnil; | 989 struct gcpro gcpro1; |
944 Charbpos old_point; | |
945 Charbpos old_begv; | |
946 Charbpos old_zv; | |
947 struct gcpro gcpro1, gcpro2; | |
948 struct buffer *buf = XBUFFER (p->buffer); | 990 struct buffer *buf = XBUFFER (p->buffer); |
949 | 991 int spec = process_setup_for_insertion (process); |
950 GCPRO2 (process, old_read_only); | 992 |
951 | 993 GCPRO1 (process); |
952 old_point = BUF_PT (buf); | |
953 old_begv = BUF_BEGV (buf); | |
954 old_zv = BUF_ZV (buf); | |
955 old_read_only = buf->read_only; | |
956 buf->read_only = Qnil; | |
957 | |
958 /* Insert new output into buffer | |
959 at the current end-of-output marker, | |
960 thus preserving logical ordering of input and output. */ | |
961 if (XMARKER (p->mark)->buffer) | |
962 BUF_SET_PT (buf, | |
963 charbpos_clip_to_bounds (old_begv, marker_position (p->mark), | |
964 old_zv)); | |
965 else | |
966 BUF_SET_PT (buf, old_zv); | |
967 | |
968 /* If the output marker is outside of the visible region, save | |
969 the restriction and widen. */ | |
970 if (! (BUF_BEGV (buf) <= BUF_PT (buf) && | |
971 BUF_PT (buf) <= BUF_ZV (buf))) | |
972 Fwiden (p->buffer); | |
973 | |
974 /* Make sure opoint floats ahead of any new text, just as point | |
975 would. */ | |
976 if (BUF_PT (buf) <= old_point) | |
977 old_point += nchars; | |
978 | |
979 /* Insert after old_begv, but before old_zv. */ | |
980 if (BUF_PT (buf) < old_begv) | |
981 old_begv += nchars; | |
982 if (BUF_PT (buf) <= old_zv) | |
983 old_zv += nchars; | |
984 | 994 |
985 #if 0 | 995 #if 0 |
986 /* This screws up initial display of the window. jla */ | 996 /* This screws up initial display of the window. jla */ |
987 | 997 |
988 /* Insert before markers in case we are inserting where | 998 /* Insert before markers in case we are inserting where |
992 #else | 1002 #else |
993 buffer_insert_raw_string (buf, chars, nbytes); | 1003 buffer_insert_raw_string (buf, chars, nbytes); |
994 #endif | 1004 #endif |
995 | 1005 |
996 Fset_marker (p->mark, make_int (BUF_PT (buf)), p->buffer); | 1006 Fset_marker (p->mark, make_int (BUF_PT (buf)), p->buffer); |
997 | |
998 MARK_MODELINE_CHANGED; | 1007 MARK_MODELINE_CHANGED; |
999 | 1008 unbind_to (spec); |
1000 /* If the restriction isn't what it should be, set it. */ | |
1001 if (old_begv != BUF_BEGV (buf) || old_zv != BUF_ZV (buf)) | |
1002 { | |
1003 Fwiden(p->buffer); | |
1004 old_begv = charbpos_clip_to_bounds (BUF_BEG (buf), | |
1005 old_begv, | |
1006 BUF_Z (buf)); | |
1007 old_zv = charbpos_clip_to_bounds (BUF_BEG (buf), | |
1008 old_zv, | |
1009 BUF_Z (buf)); | |
1010 Fnarrow_to_region (make_int (old_begv), make_int (old_zv), | |
1011 p->buffer); | |
1012 } | |
1013 | |
1014 buf->read_only = old_read_only; | |
1015 old_point = charbpos_clip_to_bounds (BUF_BEGV (buf), | |
1016 old_point, | |
1017 BUF_ZV (buf)); | |
1018 BUF_SET_PT (buf, old_point); | |
1019 | |
1020 UNGCPRO; | 1009 UNGCPRO; |
1021 } | 1010 } |
1022 return nchars; | 1011 return nchars; |
1023 } | 1012 } |
1024 | 1013 |
1497 /* Now output the message suitably. */ | 1486 /* Now output the message suitably. */ |
1498 if (!NILP (p->sentinel)) | 1487 if (!NILP (p->sentinel)) |
1499 exec_sentinel (process, msg); | 1488 exec_sentinel (process, msg); |
1500 /* Don't bother with a message in the buffer | 1489 /* Don't bother with a message in the buffer |
1501 when a process becomes runnable. */ | 1490 when a process becomes runnable. */ |
1502 else if (!EQ (symbol, Qrun) && !NILP (p->buffer)) | 1491 else if (!EQ (symbol, Qrun) && !NILP (p->buffer) && |
1492 /* Avoid error if buffer is deleted | |
1493 (probably that's why the process is dead, too) */ | |
1494 BUFFER_LIVE_P (XBUFFER (p->buffer))) | |
1503 { | 1495 { |
1504 Lisp_Object old_read_only = Qnil; | 1496 struct gcpro ngcpro1; |
1505 Lisp_Object old = Fcurrent_buffer (); | 1497 struct buffer *buf = XBUFFER (p->buffer); |
1506 Charbpos opoint; | 1498 int spec = process_setup_for_insertion (process); |
1507 struct gcpro ngcpro1, ngcpro2; | 1499 |
1508 | 1500 NGCPRO1 (process); |
1509 /* Avoid error if buffer is deleted | |
1510 (probably that's why the process is dead, too) */ | |
1511 if (!BUFFER_LIVE_P (XBUFFER (p->buffer))) | |
1512 continue; | |
1513 | |
1514 NGCPRO2 (old, old_read_only); | |
1515 Fset_buffer (p->buffer); | |
1516 opoint = BUF_PT (current_buffer); | |
1517 /* Insert new output into buffer | |
1518 at the current end-of-output marker, | |
1519 thus preserving logical ordering of input and output. */ | |
1520 if (XMARKER (p->mark)->buffer) | |
1521 BUF_SET_PT (current_buffer, marker_position (p->mark)); | |
1522 else | |
1523 BUF_SET_PT (current_buffer, BUF_ZV (current_buffer)); | |
1524 if (BUF_PT (current_buffer) <= opoint) | |
1525 opoint += (string_char_length (msg) | |
1526 + string_char_length (p->name) | |
1527 + 10); | |
1528 | |
1529 old_read_only = current_buffer->read_only; | |
1530 current_buffer->read_only = Qnil; | |
1531 buffer_insert_c_string (current_buffer, "\nProcess "); | 1501 buffer_insert_c_string (current_buffer, "\nProcess "); |
1532 Finsert (1, &p->name); | 1502 Finsert (1, &p->name); |
1533 buffer_insert_c_string (current_buffer, " "); | 1503 buffer_insert_c_string (current_buffer, " "); |
1534 Finsert (1, &msg); | 1504 Finsert (1, &msg); |
1535 current_buffer->read_only = old_read_only; | |
1536 Fset_marker (p->mark, make_int (BUF_PT (current_buffer)), | 1505 Fset_marker (p->mark, make_int (BUF_PT (current_buffer)), |
1537 p->buffer); | 1506 p->buffer); |
1538 | 1507 |
1539 opoint = charbpos_clip_to_bounds(BUF_BEGV (XBUFFER (p->buffer)), | 1508 unbind_to (spec); |
1540 opoint, | |
1541 BUF_ZV (XBUFFER (p->buffer))); | |
1542 BUF_SET_PT (current_buffer, opoint); | |
1543 Fset_buffer (old); | |
1544 NUNGCPRO; | 1509 NUNGCPRO; |
1545 } | 1510 } |
1546 } | 1511 } |
1547 } /* end for */ | 1512 } /* end for */ |
1548 | 1513 |