]> code.delx.au - gnu-emacs/commitdiff
Implement an `inhibit-read-only' text property
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Sun, 16 Nov 2014 22:36:58 +0000 (23:36 +0100)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Sun, 16 Nov 2014 22:41:55 +0000 (23:41 +0100)
* doc/lispref/text.texi (Special Properties): Mention `inhibit-read-only'.

* src/buffer.c (Fbarf_if_buffer_read_only): Don't raise an error if
the text at POSITION (new optional argument) has the
`inhibit-read-only' text property set.

* src/callint.c (Fcall_interactively): Pass in nil as argument to
Fbarf_if_buffer_read_only.

* src/fileio.c (Finsert_file_contents): Ditto.

* src/insdel.c (prepare_to_modify_buffer_1): Pass start region in.

* src/intervals.h (INTERVAL_WRITABLE_P): Check the `inhibit-read-only'
text property.

* src/textprop.c (verify_interval_modification): Check buffer
readedness after the last interval.

doc/lispref/ChangeLog
doc/lispref/text.texi
etc/NEWS
src/ChangeLog
src/buffer.c
src/callint.c
src/fileio.c
src/insdel.c
src/intervals.h
src/textprop.c

index 9772391e483b77c2c88a7816a00f83c0110a2797..b7423af07ba47b9c5e628df45a34f66ad2f819fe 100644 (file)
@@ -1,3 +1,7 @@
+2014-11-16  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * text.texi (Special Properties): Mention `inhibit-read-only'.
+
 2014-11-14  Paul Eggert  <eggert@cs.ucla.edu>
 
        * os.texi (Time of Day):
index f21d2b76656cacdc739da5a82330dec7bd916514..d1a1e6fa6b90ac5507cb45fc2d35f207b0059328 100644 (file)
@@ -3241,6 +3241,11 @@ possible to remove a @code{read-only} property unless you know the
 special trick: bind @code{inhibit-read-only} to a non-@code{nil} value
 and then remove the property.  @xref{Read Only Buffers}.
 
+@item inhibit-read-only
+@kindex inhibit-read-only @r{(text property)}
+If a character has the property @code{inhibit-read-only}, and the
+buffer is read-only, editing the character in question is allowed.
+
 @item invisible
 @kindex invisible @r{(text property)}
 A non-@code{nil} @code{invisible} property can make a character invisible
index 2172d078c44dd18946891a477c8ded6229b4977f..b0e08d46819409fefd4d62112ce0484f15ee5d75 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -107,6 +107,9 @@ non-native NS fullscreen.  The default is nil.  Set to t to enable
 animation when entering and leaving fullscreen.  For native OSX fullscreen
 this has no effect.
 
+*** A new text property `inhibit-read-only' can be used in read-only
+buffers to allow certain parts of the text to be writable.
+
 \f
 * Editing Changes in Emacs 25.1
 
index 7bb1666840657a27bfb4c34c1cf0a5b15a483e6a..d1888987dbcf37df20c52791cda812c91821fd44 100644 (file)
@@ -1,3 +1,22 @@
+2014-11-16  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * intervals.h (INTERVAL_WRITABLE_P): Check the `inhibit-read-only'
+       text property.
+
+       * callint.c (Fcall_interactively): Pass in nil as argument to
+       Fbarf_if_buffer_read_only.
+
+       * fileio.c (Finsert_file_contents): Ditto.
+
+       * insdel.c (prepare_to_modify_buffer_1): Pass start region in.
+
+       * textprop.c (verify_interval_modification): Check buffer
+       readedness after the last interval.
+
+       * buffer.c (Fbarf_if_buffer_read_only): Don't raise an error if
+       the text at POSITION (new optional argument) has the
+       `inhibit-read-only' text property set.
+
 2014-11-16  Eli Zaretskii  <eliz@gnu.org>
 
        * window.c (window_scroll_pixel_based): Avoid truncation/rounding
index 80791a1fdb1b1c87a18a769707304b06c607b040..9bdbfb830fd989a33ad46e903b1eecb95b796431 100644 (file)
@@ -2184,12 +2184,20 @@ set_buffer_if_live (Lisp_Object buffer)
 }
 \f
 DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
-                                  Sbarf_if_buffer_read_only, 0, 0, 0,
-       doc: /* Signal a `buffer-read-only' error if the current buffer is read-only.  */)
-  (void)
+                                  Sbarf_if_buffer_read_only, 0, 1, 0,
+       doc: /* Signal a `buffer-read-only' error if the current buffer is read-only.
+If the text under POSITION (which defaults to point) has the
+`inhibit-read-only' text property set, the error will not be raised.  */)
+  (Lisp_Object pos)
 {
+  if (NILP (pos))
+    XSETFASTINT (pos, PT);
+  else
+    CHECK_NUMBER (pos);
+
   if (!NILP (BVAR (current_buffer, read_only))
-      && NILP (Vinhibit_read_only))
+      && NILP (Vinhibit_read_only)
+      && NILP (Fget_text_property (pos, Qinhibit_read_only, Qnil)))
     xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
   return Qnil;
 }
index 9a4573c77be7e701e07c4fe3ff259cd1a5b33b86..94676952b2525941b02bac2af3cdf52afb2822c7 100644 (file)
@@ -448,13 +448,13 @@ invoke it.  If KEYS is omitted or nil, the return value of
                    {
                      if (! (*p == 'r' || *p == 'p' || *p == 'P'
                             || *p == '\n'))
-                       Fbarf_if_buffer_read_only ();
+                       Fbarf_if_buffer_read_only (Qnil);
                      p++;
                    }
                  record_then_fail = 1;
                }
              else
-               Fbarf_if_buffer_read_only ();
+               Fbarf_if_buffer_read_only (Qnil);
            }
        }
       /* Ignore this for semi-compatibility with Lucid.  */
@@ -865,7 +865,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
       XSETINT (args[i], marker_position (args[i]));
 
   if (record_then_fail)
-    Fbarf_if_buffer_read_only ();
+    Fbarf_if_buffer_read_only (Qnil);
 
   Vthis_command = save_this_command;
   Vthis_original_command = save_this_original_command;
index 7d7b0b3148fc16f2c07be2100331a04aa580b660..b8dec3a2041ac1b193d01106cf5de2b74263a47a 100644 (file)
@@ -3471,7 +3471,7 @@ by calling `format-decode', which see.  */)
     error ("Cannot do file visiting in an indirect buffer");
 
   if (!NILP (BVAR (current_buffer, read_only)))
-    Fbarf_if_buffer_read_only ();
+    Fbarf_if_buffer_read_only (Qnil);
 
   val = Qnil;
   p = Qnil;
index 463392dcada70f31b269240ed22010218b8c2439..3133ca4bd2c242c5158da0a229008c9598676535 100644 (file)
@@ -1797,9 +1797,11 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
                            ptrdiff_t *preserve_ptr)
 {
   struct buffer *base_buffer;
+  Lisp_Object temp;
 
+  XSETFASTINT (temp, start);
   if (!NILP (BVAR (current_buffer, read_only)))
-    Fbarf_if_buffer_read_only ();
+    Fbarf_if_buffer_read_only (temp);
 
   bset_redisplay (current_buffer);
 
index 4e7a177140eb14b7f1e7d3352c68ae1fed34efc0..bd1f49dc383ea7d5f1ccde49a143003298930dac 100644 (file)
@@ -197,6 +197,7 @@ set_interval_plist (INTERVAL i, Lisp_Object plist)
 /* Is this interval writable?  Replace later with cache access.  */
 #define INTERVAL_WRITABLE_P(i)                                 \
   (i && (NILP (textget ((i)->plist, Qread_only))               \
+         || !NILP (textget ((i)->plist, Qinhibit_read_only))   \
         || ((CONSP (Vinhibit_read_only)                        \
              ? !NILP (Fmemq (textget ((i)->plist, Qread_only), \
                              Vinhibit_read_only))              \
index 91ade8ae2984f283209de5e2784d376f675b7a8f..7ecac62be98d986469cb4bb97f0561dea4f4b6ba 100644 (file)
@@ -2298,6 +2298,11 @@ verify_interval_modification (struct buffer *buf,
                }
            }
 
+         if (i->position + LENGTH (i) < end
+             && (!NILP (BVAR (current_buffer, read_only))
+                 && NILP (Vinhibit_read_only)))
+           xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
+
          i = next_interval (i);
        }
       /* Keep going thru the interval containing the char before END.  */