Skip to content

Comment cache #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions doc/emacs/programs.texi
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ a function, is called a @dfn{defun}. The name comes from Lisp, but in
Emacs we use it for all languages.

@menu
* Left Margin Paren:: An open-paren or similar opening delimiter
starts a defun if it is at the left margin.
* Left Margin Paren:: An open-paren or similar opening delimiter at
the left Margin started a defun in older Emacsen.
* Moving by Defuns:: Commands to move over or mark a major definition.
* Imenu:: Making buffer indexes as menus.
* Which Function:: Which Function mode shows which function you are in.
Expand All @@ -153,55 +153,55 @@ Emacs we use it for all languages.
@cindex ( in leftmost column
Many programming-language modes assume by default that any opening
delimiter found at the left margin is the start of a top-level
definition, or defun. Therefore, @strong{don't put an opening
delimiter at the left margin unless it should have that significance}.
For instance, never put an open-parenthesis at the left margin in a
Lisp file unless it is the start of a top-level list.

The convention speeds up many Emacs operations, which would
otherwise have to scan back to the beginning of the buffer to analyze
the syntax of the code.

If you don't follow this convention, not only will you have trouble
when you explicitly use the commands for motion by defuns; other
features that use them will also give you trouble. This includes the
indentation commands (@pxref{Program Indent}) and Font Lock mode
(@pxref{Font Lock}).

The most likely problem case is when you want an opening delimiter
at the start of a line inside a string. To avoid trouble, put an
escape character (@samp{\}, in C and Emacs Lisp, @samp{/} in some
other Lisp dialects) before the opening delimiter. This will not
affect the contents of the string, but will prevent that opening
delimiter from starting a defun. Here's an example:
definition, or defun. Therefore, in these modes, don't put an opening
delimiter at the left margin, except in a comment or string, unless it
should have that significance. For instance, don't put an
open-parenthesis at the left margin in a Lisp file unless it is the
start of a top-level list.

@c In earlier versions of Emacs (up until version 25.n), Emacs exploited
@c this convention to speed up many low-level operations, which would
@c otherwise have to scan back to the beginning of the buffer.

@c Unfortunately, this exploitation often caused confusion when an
@c opening delimiter occurred at column 0 inside a comment. This would
@c cause mis-analysis of the buffer, leading to wrong indentation or
@c wrong fontification, or could cause simple operations to take
@c inordinately long to complete. This problem even caught out the Emacs
@c development team occasionally. The convention could be overridden by
@c setting the variable @code{open-paren-in-column-0-is-defun-start} to
@c @code{nil}, but this could slow Emacs down, particularly when editing
@c large buffers.

In earlier versions of Emacs (through version 25.n), Emacs exploited
this convention to speed up many low-level operations, which would
otherwise have to scan back to the beginning of the buffer.
Unfortunately, this caused confusion when an opening delimiter
occurred at column 0 inside a comment. The resulting faulty analysis
often caused wrong indentation or fontification, or even simple edits
to take inordinately long to complete. The convention could be
overridden by setting the variable
@code{open-paren-in-column-0-is-defun-start} to @code{nil}, but this
tended to slow Emacs down, particularly when editing large buffers.

To eliminate these problems, the low level functionality which used
to test for opening delimiters at column 0 no longer does so, having
been completely redesigned. Open delimiters may now be freely written
at the left margin inside comments without triggering these problems.

@example
(insert "Foo:
\(bar)
")
@end example
@vindex open-paren-in-column-0-is-defun-start
If you want to override the convention, which is still used by some
higher level commands, you can do so by setting the variable
@code{open-paren-in-column-0-is-defun-start} to @code{nil}. If this
user option is set to @code{t} (the default), these commands will stop
at opening parentheses or braces at column zero when seeking the start
of defuns. When it is @code{nil}, defuns are found by searching for
parens or braces at the outermost level.

To help you catch violations of this convention, Font Lock mode
highlights confusing opening delimiters (those that ought to be
quoted) in bold red.

@vindex open-paren-in-column-0-is-defun-start
If you need to override this convention, you can do so by setting
the variable @code{open-paren-in-column-0-is-defun-start}.
If this user option is set to @code{t} (the default), opening
parentheses or braces at column zero always start defuns. When it is
@code{nil}, defuns are found by searching for parens or braces at the
outermost level.

Usually, you should leave this option at its default value of
@code{t}. If your buffer contains parentheses or braces in column
zero which don't start defuns, and it is somehow impractical to remove
these parentheses or braces, it might be helpful to set the option to
@code{nil}. Be aware that this might make scrolling and display in
large buffers quite sluggish. Furthermore, the parentheses and braces
must be correctly matched throughout the buffer for it to work
properly.

@node Moving by Defuns
@subsection Moving by Defuns
@cindex defuns
Expand Down
26 changes: 14 additions & 12 deletions lisp/progmodes/cc-defs.el
Original file line number Diff line number Diff line change
Expand Up @@ -375,18 +375,19 @@ to it is returned. This function does not modify the point or the mark."
;; Constant to decide at compilation time whether to use category
;; properties. Currently (2010-03) they're available only on GNU Emacs.
(defconst c-use-category
(with-temp-buffer
(let ((parse-sexp-lookup-properties t)
(lookup-syntax-properties t))
(set-syntax-table (make-syntax-table))
(insert "<()>")
(put-text-property (point-min) (1+ (point-min))
'category 'c-<-as-paren-syntax)
(put-text-property (+ 3 (point-min)) (+ 4 (point-min))
'category 'c->-as-paren-syntax)
(goto-char (point-min))
(forward-sexp)
(= (point) (+ 4 (point-min)))))))
(and (not (boundp 'literal-cache-hwm))
(with-temp-buffer
(let ((parse-sexp-lookup-properties t)
(lookup-syntax-properties t))
(set-syntax-table (make-syntax-table))
(insert "<()>")
(put-text-property (point-min) (1+ (point-min))
'category 'c-<-as-paren-syntax)
(put-text-property (+ 3 (point-min)) (+ 4 (point-min))
'category 'c->-as-paren-syntax)
(goto-char (point-min))
(forward-sexp)
(= (point) (+ 4 (point-min))))))))

(defvar c-use-extents)

Expand Down Expand Up @@ -498,6 +499,7 @@ The return value is the value of the last form in BODY."
`(with-silent-modifications (let* ,varlist ,@body))
`(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
(inhibit-read-only t) (inhibit-point-motion-hooks t)
(inhibit-modification-hooks t)
before-change-functions after-change-functions
deactivate-mark
buffer-file-name buffer-file-truename ; Prevent primitives checking
Expand Down
2 changes: 1 addition & 1 deletion lisp/progmodes/cc-engine.el
Original file line number Diff line number Diff line change
Expand Up @@ -11655,7 +11655,7 @@ comment at the start of cc-engine.el for more info."
(cond
((c-backward-over-enum-header)
(setq placeholder (c-point 'boi)))
((consp (setq placeholder
((consp (setq placeholder
(c-looking-at-or-maybe-in-bracelist
containing-sexp lim)))
(setq tmpsymbol (and (cdr placeholder) 'topmost-intro-cont))
Expand Down
11 changes: 11 additions & 0 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ bset_zv_marker (struct buffer *b, Lisp_Object val)
{
b->zv_marker_ = val;
}
static void
bset_literal_cache_hwm (struct buffer *b, Lisp_Object val)
{
b->literal_cache_hwm_ = val;
}

void
nsberror (Lisp_Object spec)
Expand Down Expand Up @@ -5116,6 +5121,7 @@ init_buffer_once (void)
XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, literal_cache_hwm), idx); ++idx;

/* Need more room? */
if (idx >= MAX_PER_BUFFER_VARS)
Expand Down Expand Up @@ -5202,6 +5208,7 @@ init_buffer_once (void)
bset_scroll_up_aggressively (&buffer_defaults, Qnil);
bset_scroll_down_aggressively (&buffer_defaults, Qnil);
bset_display_time (&buffer_defaults, Qnil);
bset_literal_cache_hwm (&buffer_defaults, make_number (1));

/* Assign the local-flags to the slots that have default values.
The local flag is a bit that is used in the buffer
Expand Down Expand Up @@ -6133,6 +6140,10 @@ If t, displays a cursor related to the usual cursor type
You can also specify the cursor type as in the `cursor-type' variable.
Use Custom to set this variable and update the display. */);

DEFVAR_PER_BUFFER ("literal-cache-hwm",
&BVAR (current_buffer, literal_cache_hwm), Qintegerp,
doc: /* Buffer position below which the `literal-cache' property is valid. */);

DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
doc: /* List of functions called with no args to query before killing a buffer.
The buffer being killed will be current while the functions are running.
Expand Down
5 changes: 4 additions & 1 deletion src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,9 @@ struct buffer
See `cursor-type' for other values. */
Lisp_Object cursor_in_non_selected_windows_;

/* Buffer position below which the `literal-cache' property is valid. */
Lisp_Object literal_cache_hwm_;

/* No more Lisp_Object beyond this point. Except undo_list,
which is handled specially in Fgarbage_collect. */

Expand Down Expand Up @@ -1272,7 +1275,7 @@ extern int last_per_buffer_idx;

#define FOR_EACH_PER_BUFFER_OBJECT_AT(offset) \
for (offset = PER_BUFFER_VAR_OFFSET (name); \
offset <= PER_BUFFER_VAR_OFFSET (cursor_in_non_selected_windows); \
offset <= PER_BUFFER_VAR_OFFSET (literal_cache_hwm); \
offset += word_size)

/* Return the index of buffer-local variable VAR. Each per-buffer
Expand Down
63 changes: 60 additions & 3 deletions src/chartab.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ set_char_table_parent (Lisp_Object table, Lisp_Object val)

DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0,
doc: /* Return a newly created char-table, with purpose PURPOSE.
Each element is initialized to INIT, which defaults to nil.
Each element is initialized to INIT, which defaults to nil. Any extra
slots created will be initialized to nil.

PURPOSE should be a symbol. If it has a `char-table-extra-slots'
property, the property's value should be an integer between 0 and 10
Expand All @@ -109,7 +110,7 @@ the char-table has no extra slot. */)
{
Lisp_Object vector;
Lisp_Object n;
int n_extras;
int n_extras, i;
int size;

CHECK_SYMBOL (purpose);
Expand All @@ -130,6 +131,8 @@ the char-table has no extra slot. */)
set_char_table_parent (vector, Qnil);
set_char_table_purpose (vector, purpose);
XSETCHAR_TABLE (vector, XCHAR_TABLE (vector));
for (i = 0; i < n_extras ; i++)
XCHAR_TABLE (vector)->extras[i] = Qnil;
return vector;
}

Expand Down Expand Up @@ -250,7 +253,7 @@ char_table_ref (Lisp_Object table, int c)
return val;
}

static Lisp_Object
Lisp_Object
sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to,
Lisp_Object defalt, bool is_uniprop)
{
Expand Down Expand Up @@ -386,6 +389,60 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
return val;
}

/* Return the value for C in char-table TABLE. Shrink the range
*FROM and *TO to cover characters (containing C) that have the same
value as C. Should the value for C in TABLE be nil, consult the
parent table of TABLE, recursively if necessary. It is not
guaranteed that the values of (*FROM - 1) and (*TO + 1) are
different from that of C. */
Lisp_Object
char_table_ref_and_range_with_parents (Lisp_Object table, int c,
int *from, int *to)
{
Lisp_Object val;
Lisp_Object parent, defalt;
struct Lisp_Char_Table *tbl;

if (*to < 0)
*to = MAX_CHAR;
if (ASCII_CHAR_P (c)
&& *from <= c
&& *to >= c)
{
tbl = XCHAR_TABLE (table);
defalt = tbl->defalt;
val = NILP (tbl->ascii)
? defalt /*Qnil*/
: sub_char_table_ref_and_range (tbl->ascii, c, from, to, defalt, false);
while (NILP (val) && !NILP (parent))
{
tbl = XCHAR_TABLE (parent);
parent = tbl->parent;
defalt = tbl->defalt;
val = NILP (tbl->ascii)
? defalt /*Qnil*/
: sub_char_table_ref_and_range (tbl->ascii, c, from, to, defalt, false);
}
return val;
}
else if (!ASCII_CHAR_P (c))
{
val = char_table_ref_and_range (table, c, from, to);
tbl = XCHAR_TABLE (table);
while (NILP (val))
{
parent = tbl->parent;
if (NILP (parent))
break;
val = char_table_ref_and_range (parent, c, from, to);
tbl = XCHAR_TABLE (parent);
}
return val;
}
else
return Qnil;
}


static void
sub_char_table_set (Lisp_Object table, int c, Lisp_Object val, bool is_uniprop)
Expand Down
2 changes: 2 additions & 0 deletions src/insdel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2182,6 +2182,8 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)

specbind (Qinhibit_modification_hooks, Qt);

Ftrim_literal_cache (make_number (charpos));

if (!NILP (Vafter_change_functions))
{
rvoe_arg.location = &Vafter_change_functions;
Expand Down
5 changes: 5 additions & 0 deletions src/lisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3706,8 +3706,13 @@ extern void r_alloc_inhibit_buffer_relocation (int);

/* Defined in chartab.c. */
extern Lisp_Object copy_char_table (Lisp_Object);
extern Lisp_Object sub_char_table_ref_and_range (Lisp_Object, int,
int *, int *,
Lisp_Object, bool);
extern Lisp_Object char_table_ref_and_range (Lisp_Object, int,
int *, int *);
extern Lisp_Object char_table_ref_and_range_with_parents (Lisp_Object, int,
int *, int *);
extern void char_table_set_range (Lisp_Object, int, int, Lisp_Object);
extern void map_char_table (void (*) (Lisp_Object, Lisp_Object,
Lisp_Object),
Expand Down
Loading