summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalie Spinu <spinuvit@gmail.com>2016-03-21 05:41:55 +0100
committerVitalie Spinu <spinuvit@gmail.com>2016-03-29 23:29:54 +0200
commit7068e4c811f7530e14d2684fea68499418642b33 (patch)
tree3c44890147e77c32a5a9f4aeb60ca88d9eb6a050
parentf99b51295b86770e4b16d4717c0e73049191c4c5 (diff)
downloademacs-scratch/hard-narrow.tar.gz
Hard narrowingscratch/hard-narrow
Idem
-rw-r--r--src/buffer.c16
-rw-r--r--src/buffer.h36
-rw-r--r--src/bytecode.c7
-rw-r--r--src/editfns.c69
-rw-r--r--src/fileio.c2
-rw-r--r--src/lread.c2
-rw-r--r--src/process.c4
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);