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