From 7068e4c811f7530e14d2684fea68499418642b33 Mon Sep 17 00:00:00 2001 From: Vitalie Spinu Date: Mon, 21 Mar 2016 05:41:55 +0100 Subject: [PATCH] Hard narrowing Idem --- src/buffer.c | 16 +++++++++--- src/buffer.h | 36 ++++++++++++++++++++++++++ src/bytecode.c | 7 ++--- src/editfns.c | 69 ++++++++++++++++++++++++++++++++++++-------------- src/fileio.c | 2 +- src/lread.c | 2 +- src/process.c | 4 +-- 7 files changed, 106 insertions(+), 30 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index f06d7e08e49..2d75dba6e95 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -571,6 +571,9 @@ even if it is dead. The return value is never nil. */) bset_begv_marker (b, Qnil); bset_zv_marker (b, Qnil); + bset_begh_marker (b, Qnil); + bset_zh_marker (b, Qnil); + name = Fcopy_sequence (buffer_or_name); set_string_intervals (name, NULL); bset_name (b, name); @@ -835,6 +838,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) bset_pt_marker (b, build_marker (b, b->pt, b->pt_byte)); bset_begv_marker (b, build_marker (b, b->begv, b->begv_byte)); bset_zv_marker (b, build_marker (b, b->zv, b->zv_byte)); + XMARKER (BVAR (b, zv_marker))->insertion_type = 1; } else @@ -2165,9 +2169,9 @@ Any narrowing restriction in effect (see `narrow-to-region') is removed, so the buffer is truly empty after this. */) (void) { - Fwiden (); + Fwiden (Qnil); - del_range (BEG, Z); + del_range (BEGV, ZV); current_buffer->last_window_start = 1; /* Prevent warnings, or suspension of auto saving, that would happen @@ -2310,6 +2314,8 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, swapfield_ (pt_marker, Lisp_Object); swapfield_ (begv_marker, Lisp_Object); swapfield_ (zv_marker, Lisp_Object); + swapfield_ (begh_marker, Lisp_Object); + swapfield_ (zh_marker, Lisp_Object); bset_point_before_scroll (current_buffer, Qnil); bset_point_before_scroll (other_buffer, Qnil); @@ -2490,7 +2496,7 @@ current buffer is cleared. */) } } if (narrowed) - Fnarrow_to_region (make_number (begv), make_number (zv)); + Fnarrow_to_region (make_number (begv), make_number (zv), Qnil); } else { @@ -2571,7 +2577,7 @@ current buffer is cleared. */) TEMP_SET_PT (pt); if (narrowed) - Fnarrow_to_region (make_number (begv), make_number (zv)); + Fnarrow_to_region (make_number (begv), make_number (zv), Qnil); /* Do this first, so that chars_in_text asks the right question. set_intervals_multibyte needs it too. */ @@ -5053,6 +5059,8 @@ init_buffer_once (void) bset_pt_marker (&buffer_local_flags, make_number (0)); bset_begv_marker (&buffer_local_flags, make_number (0)); bset_zv_marker (&buffer_local_flags, make_number (0)); + bset_begh_marker (&buffer_local_flags, make_number (0)); + bset_zh_marker (&buffer_local_flags, make_number (0)); bset_last_selected_window (&buffer_local_flags, make_number (0)); idx = 1; diff --git a/src/buffer.h b/src/buffer.h index 87b7cee4413..5eeb3ce26e7 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -416,6 +416,26 @@ extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); #define BUF_FETCH_BYTE(buf, n) \ *(BUF_BYTE_ADDRESS ((buf), (n))) + + +/* Macros for setting and accessing hard-narrow markers */ + +/* Position of beginning of hard-narrowed range of buffer. */ +#define BEGH (BUF_BEGH (current_buffer)) +#define BUF_BEGH(buf) \ + ((NILP (BVAR (buf, begh_marker))) ? BUF_BEG (buf) \ + : marker_position (BVAR (buf, begh_marker))) +#define SET_BUF_BEGH(buf, charpos) \ + (bset_begh_marker (buf, build_marker(buf, charpos, buf_charpos_to_bytepos(buf, charpos)))) + +/* Position of end of hard-narrowed range of buffer. */ +#define ZH (BUF_ZH(current_buffer)) +#define BUF_ZH(buf) \ + ((NILP (BVAR (buf, zh_marker))) ? BUF_Z (buf) \ + : marker_position (BVAR (buf, zh_marker))) +#define SET_BUF_ZH(buf, charpos) \ + (bset_zh_marker (buf, build_marker(buf, charpos, buf_charpos_to_bytepos(buf, charpos)))) + /* Define the actual buffer data structures. */ @@ -666,6 +686,12 @@ struct buffer ZV for this buffer when the buffer is not current. */ Lisp_Object zv_marker_; + /* Lower hard limit of the buffer.*/ + Lisp_Object begh_marker_; + + /* Upper hard limit of the buffer.*/ + Lisp_Object zh_marker_; + /* This holds the point value before the last scroll operation. Explicitly setting point sets this to nil. */ Lisp_Object point_before_scroll_; @@ -984,6 +1010,16 @@ bset_width_table (struct buffer *b, Lisp_Object val) { b->width_table_ = val; } +INLINE void +bset_begh_marker (struct buffer *b, Lisp_Object val) +{ + b->begh_marker_ = val; +} +INLINE void +bset_zh_marker (struct buffer *b, Lisp_Object val) +{ + b->zh_marker_ = val; +} /* Number of Lisp_Objects at the beginning of struct buffer. If you add, remove, or reorder Lisp_Objects within buffer diff --git a/src/bytecode.c b/src/bytecode.c index 9ae2e820d51..8cefa10475c 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1682,17 +1682,18 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bnarrow_to_region): { - Lisp_Object v1; + Lisp_Object v1, v2; BEFORE_POTENTIAL_GC (); v1 = POP; - TOP = Fnarrow_to_region (TOP, v1); + v2 = POP; + TOP = Fnarrow_to_region (TOP, v2, v1); AFTER_POTENTIAL_GC (); NEXT; } CASE (Bwiden): BEFORE_POTENTIAL_GC (); - PUSH (Fwiden ()); + TOP = Fwiden (TOP); AFTER_POTENTIAL_GC (); NEXT; diff --git a/src/editfns.c b/src/editfns.c index 2ac0537eddb..80f111774ef 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3480,33 +3480,54 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, return empty_unibyte_string; return del_range_1 (XINT (start), XINT (end), 1, 1); } + -DEFUN ("widen", Fwiden, Swiden, 0, 0, "", +DEFUN ("widen", Fwiden, Swiden, 0, 1, "", doc: /* Remove restrictions (narrowing) from current buffer. -This allows the buffer's full text to be seen and edited. */) - (void) +If HARD is non-nil, remove the hard restriction imposed by a previous +call to \\[narrow-to-region]. If HARD is nil, remove visual +restriction up to the previously imposed hard limit (if any). */) + (Lisp_Object hard) { - if (BEG != BEGV || Z != ZV) - current_buffer->clip_changed = 1; - BEGV = BEG; - BEGV_BYTE = BEG_BYTE; - SET_BUF_ZV_BOTH (current_buffer, Z, Z_BYTE); - /* Changing the buffer bounds invalidates any recorded current column. */ - invalidate_current_column (); + + if(!NILP (hard)) + { + bset_begh_marker(current_buffer, Qnil); + bset_zh_marker(current_buffer, Qnil); + } + else + { + if (BEG != BEGV || Z != ZV) + current_buffer->clip_changed = 1; + BEGV = BEG; + BEGV_BYTE = BEG_BYTE; + SET_BUF_ZV_BOTH (current_buffer, Z, Z_BYTE); + /* Changing the buffer bounds invalidates any recorded current column. */ + invalidate_current_column (); + } + return Qnil; } -DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 2, "r", - doc: /* Restrict editing in this buffer to the current region. -The rest of the text becomes temporarily invisible and untouchable -but is not deleted; if you save the buffer in a file, the invisible -text is included in the file. \\[widen] makes all visible again. -See also `save-restriction'. +DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 3, "r", + doc: /* Restrict editing in this buffer to the current +region. START and END are positions (integers or markers) bounding the +text that should restricted. There can be two types of restrictions, +visual and hard. If HARD is nil, impose visual restriction, otherwise +a hard one. -When calling from a program, pass two arguments; positions (integers -or markers) bounding the text that should remain visible. */) - (register Lisp_Object start, Lisp_Object end) +When visual restriction is in place, the rest of the text is invisible +and untouchable but is not deleted; if you save the buffer in a file, +the invisible text is included in the file. \\[widen] with nil +optional argument makes it all visible again. + +When hard restriction is in place, invocations of (visual) \\[widen] +with nil argument removes visual narrowing up to the hard +restriction. In order to lift hard restriction, call \\[widen] with +non-nil HARD argument. */) + (register Lisp_Object start, Lisp_Object end, Lisp_Object hard) { + CHECK_NUMBER_COERCE_MARKER (start); CHECK_NUMBER_COERCE_MARKER (end); @@ -3519,6 +3540,15 @@ or markers) bounding the text that should remain visible. */) if (!(BEG <= XINT (start) && XINT (start) <= XINT (end) && XINT (end) <= Z)) args_out_of_range (start, end); + if (!NILP (hard)) + { + SET_BUF_BEGH (current_buffer, XFASTINT (start)); + SET_BUF_ZH (current_buffer, XFASTINT (end)); + if (BEGV >= XFASTINT (start) && ZV <= XFASTINT (end)) + /* Visual narrowing within hard limits. */ + return Qnil; + } + if (BEGV != XFASTINT (start) || ZV != XFASTINT (end)) current_buffer->clip_changed = 1; @@ -3533,6 +3563,7 @@ or markers) bounding the text that should remain visible. */) return Qnil; } + Lisp_Object save_restriction_save (void) { diff --git a/src/fileio.c b/src/fileio.c index dfab3de9e94..5b63e394216 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4764,7 +4764,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, This is useful in tar-mode. --Stef XSETFASTINT (start, BEG); XSETFASTINT (end, Z); */ - Fwiden (); + Fwiden (Qnil); } record_unwind_protect (build_annotations_unwind, diff --git a/src/lread.c b/src/lread.c index 91469230b7e..515eca1ceca 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1850,7 +1850,7 @@ readevalloop (Lisp_Object readcharfun, /* Set point and ZV around stuff to be read. */ Fgoto_char (start); if (!NILP (end)) - Fnarrow_to_region (make_number (BEGV), end); + Fnarrow_to_region (make_number (BEGV), end, Qnil); /* Just for cleanliness, convert END to a marker if it is an integer. */ diff --git a/src/process.c b/src/process.c index dd508836f79..75e3934237d 100644 --- a/src/process.c +++ b/src/process.c @@ -5514,7 +5514,7 @@ Otherwise it discards the output. */) /* If the output marker is outside of the visible region, save the restriction and widen. */ if (! (BEGV <= PT && PT <= ZV)) - Fwiden (); + Fwiden (Qnil); /* Adjust the multibyteness of TEXT to that of the buffer. */ if (NILP (BVAR (current_buffer, enable_multibyte_characters)) @@ -5558,7 +5558,7 @@ Otherwise it discards the output. */) /* If the restriction isn't what it should be, set it. */ if (old_begv != BEGV || old_zv != ZV) - Fnarrow_to_region (make_number (old_begv), make_number (old_zv)); + Fnarrow_to_region (make_number (old_begv), make_number (old_zv), Qnil); bset_read_only (current_buffer, old_read_only); SET_PT_BOTH (opoint, opoint_byte); -- 2.39.2