unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Can we expand the valid location of "Local Variables" ?
@ 2020-03-10 20:56 Dima Kogan
  2020-03-10 21:39 ` Stefan Monnier
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Dima Kogan @ 2020-03-10 20:56 UTC (permalink / raw)
  To: emacs-devel

Hi.

Currently we can specify buffer-local variables in a "Local Variables"
stanza at the end of a buffer:

  https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables

For efficiency reasons, emacs doesn't look for this stanza in the entire
buffer, but only scans the last 3000 bytes. This is documented. It looks
like this setting (3000 bytes) was there in the first revision of
files.el back in 1991:

  http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/files.el?id=b4da00

At the time, extending this limit would presumably result in an
observable performance penalty, but it's not 1991 anymore. Can we bump
this up? The patch would be trivial, so I'm not attaching one yet. The
locations in the source that currently hard-code this are:

  doc/emacs/custom.texi:1129:The start of the local variables list should be no more than 3000
  doc/misc/calc.texi:31065:The Local Variables section must be within 3000 characters of the
  lisp/allout.el:6329:      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
  lisp/calendar/diary-lib.el:2087:                             (max (- (point-max) 3000) (point-min))
  lisp/cus-edit.el:4574:	  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
  lisp/files-x.el:172:      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
  lisp/files.el:3723:	  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
  lisp/international/latexenc.el:150:	      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
  lisp/org/org-macs.el:189:				      (max (- (point) 3000) 1)
  lisp/progmodes/cc-mode.el:862:  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
  lisp/progmodes/dcl-mode.el:1752:    (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)

Probably we'd want to make this into a variable? And the default maybe
should be higher than 3000?

The use case where I hit this was in an .org file that was defining a
presentation where I needed to control the export with an eval: (progn
...) block. Org wasn't doing quite what I needed it to, so the block had
some advice definitions in it, and that pushed the thing over the 3000
byte limit.

I'm not subscribed to emacs-devel at the moment, so please Cc me in
replies.

Thanks!



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 20:56 Can we expand the valid location of "Local Variables" ? Dima Kogan
@ 2020-03-10 21:39 ` Stefan Monnier
  2020-03-10 23:44   ` Dima Kogan
  2020-03-22 23:08   ` Dima Kogan
  2020-03-12  2:26 ` Richard Stallman
  2020-03-23 15:56 ` Yuri Khan
  2 siblings, 2 replies; 20+ messages in thread
From: Stefan Monnier @ 2020-03-10 21:39 UTC (permalink / raw)
  To: Dima Kogan; +Cc: emacs-devel

> Probably we'd want to make this into a variable? And the default maybe
> should be higher than 3000?

I don't like having this 3000 hard-coded everywhere, so making
a variable makes sense.

But encouraging large "Local Variables" blocks is a bad idea, IMO, so
I'd keep it at 3000 and I wouldn't care to document the var either.
I'd even be happy with a "--" in its name.

> The use case where I hit this was in an .org file that was defining a
> presentation where I needed to control the export with an eval: (progn
> ...) block. Org wasn't doing quite what I needed it to, so the block had
> some advice definitions in it, and that pushed the thing over the 3000
> byte limit.

Of course, you can use a short

    eval: (progn (re-search-backward "^(progn ;;local-config") (eval (read (current-buffer))))

and then put an arbitrarily long Elisp chunk anywhere else in the buffer
with a leading `(progn ;;local-config`.


        Stefan




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 21:39 ` Stefan Monnier
@ 2020-03-10 23:44   ` Dima Kogan
  2020-03-11  2:01     ` Stefan Monnier
  2020-03-22 23:08   ` Dima Kogan
  1 sibling, 1 reply; 20+ messages in thread
From: Dima Kogan @ 2020-03-10 23:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Probably we'd want to make this into a variable? And the default maybe
>> should be higher than 3000?
>
> I don't like having this 3000 hard-coded everywhere, so making
> a variable makes sense.
>
> But encouraging large "Local Variables" blocks is a bad idea, IMO, so
> I'd keep it at 3000 and I wouldn't care to document the var either.
> I'd even be happy with a "--" in its name.

OK. I can write such a patch. Is there an upside to not documenting it?
If we REALLY don't want people touching this variable, then why not
leave the hardcoded 3000?


>> The use case where I hit this was in an .org file that was defining a
>> presentation where I needed to control the export with an eval: (progn
>> ...) block. Org wasn't doing quite what I needed it to, so the block had
>> some advice definitions in it, and that pushed the thing over the 3000
>> byte limit.
>
> Of course, you can use a short
>
>     eval: (progn (re-search-backward "^(progn ;;local-config") (eval (read (current-buffer))))
>
> and then put an arbitrarily long Elisp chunk anywhere else in the buffer
> with a leading `(progn ;;local-config`.

Oof. I COULD do that, but that feels like it makes an already-ugly thing
even uglier. I sent a separate email to the org mailing list about maybe
upstreaming some of the advices, but the general idea doesn't seem
unreasonable to me: we already allow a block to define some custom
variables, so customizing the behavior of some functions doesn't seem
crazy.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 23:44   ` Dima Kogan
@ 2020-03-11  2:01     ` Stefan Monnier
  0 siblings, 0 replies; 20+ messages in thread
From: Stefan Monnier @ 2020-03-11  2:01 UTC (permalink / raw)
  To: Dima Kogan; +Cc: emacs-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/x-markdown; coding=UTF-8, Size: 1222 bytes --]

> OK. I can write such a patch. Is there an upside to not documenting it?
> If we REALLY don't want people touching this variable, then why not
> leave the hardcoded 3000?

I said "variable" just because we don't have constants, but really the
way I see it, it should be a constant: if you put your variables further
than that, it won't work with an Emacs that hasn't been
customized accordingly.

> Oof. I COULD do that, but that feels like it makes an already-ugly thing
> even uglier. I sent a separate email to the org mailing list about maybe
> upstreaming some of the advices, but the general idea doesn't seem
> unreasonable to me: we already allow a block to define some custom
> variables, so customizing the behavior of some functions doesn't seem
> crazy.

Putting a large amount of code this way is a major problem security-wise.
If you're the only one looking at this file and it's code you wrote,
then there's no problem security-wise, but then again you could just
put that code in your ~/.emacs instead.
If it's not your own code or if you share this file with others, then
it's a security hassle and you'd be better off moving that code to some
package on which your file will depend.


        Stefan




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 20:56 Can we expand the valid location of "Local Variables" ? Dima Kogan
  2020-03-10 21:39 ` Stefan Monnier
@ 2020-03-12  2:26 ` Richard Stallman
  2020-03-14  5:54   ` Steve Youngs
  2020-03-23 15:56 ` Yuri Khan
  2 siblings, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2020-03-12  2:26 UTC (permalink / raw)
  To: Dima Kogan; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > For efficiency reasons, emacs doesn't look for this stanza in the entire
  > buffer, but only scans the last 3000 bytes. This is documented.

The reasons for this limit were (1) to avoid needing to search the
whole of a large file, and (2) to make it quick and easy for Emacs or
a user to determine that a file does NOT have local variables.

Searching a little further than 3000 would not have cost significant
time even in 1991.  But if we don't stop at 3000 bytes, how far should
we go?  3500?  4000?  40,000,000?  Even today that could be slow, for
large files.

A solution that occurs to me is to define something to put in a
local variable list that says, "Search further back!"
It could look like this:

    Local Variables:
    Chars further back: 20000
    End:

This way, you would see quickly that the file does have a local
variable list, and where to look to find it.

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-12  2:26 ` Richard Stallman
@ 2020-03-14  5:54   ` Steve Youngs
  2020-03-14  7:07     ` Stefan Monnier
  2020-03-15  3:08     ` Richard Stallman
  0 siblings, 2 replies; 20+ messages in thread
From: Steve Youngs @ 2020-03-14  5:54 UTC (permalink / raw)
  To: Richard Stallman; +Cc: Dima Kogan, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1071 bytes --]

Richard Stallman <rms@gnu.org> writes:

  > A solution that occurs to me is to define something to put in a
  > local variable list that says, "Search further back!"
  > It could look like this:

  >     Local Variables:
  >     Chars further back: 20000
  >     End:

  > This way, you would see quickly that the file does have a local
  > variable list, and where to look to find it.


How about some form of "include" mechanism:

        Local Variables:
        @include: FILENAME
        End:

I would suggest implementing that with the same care, considerations,
and restrictions as has `eval' for Locals

Mind you, if your Local Vars sections are getting so out of hand that
they warrant having a whole extra file to store them, you should probably
re-think what you're doing. :-)


-- 
|---<Steve Youngs>-------<GnuPG KeyID: 9FDFE046F5745911>---|
|       SXEmacs - The only _______ you'll ever need.       |
|         Fill in the blank, yes, it's THAT good!          |
|------------------------------------<steve@sxemacs.org>---|

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 824 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-14  5:54   ` Steve Youngs
@ 2020-03-14  7:07     ` Stefan Monnier
  2020-03-15  3:08     ` Richard Stallman
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Monnier @ 2020-03-14  7:07 UTC (permalink / raw)
  To: Steve Youngs; +Cc: emacs-devel, Richard Stallman, Dima Kogan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/x-markdown; coding=UTF-8, Size: 686 bytes --]

> How about some form of "include" mechanism:
>
>         Local Variables:
>         @include: FILENAME
>         End:

Sounds OK, yes.

> I would suggest implementing that with the same care, considerations,
> and restrictions as has `eval' for Locals

Indeed.  There be dragons.

> Mind you, if your Local Vars sections are getting so out of hand that
> they warrant having a whole extra file to store them, you should probably
> re-think what you're doing. :-)

I think such an @include directive can be useful not just for large
sections but also to avoid duplicating settings (i.e. a kind of
alternative to .dir-locals.el, not tied to the directory hierarchy).


        Stefan




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-14  5:54   ` Steve Youngs
  2020-03-14  7:07     ` Stefan Monnier
@ 2020-03-15  3:08     ` Richard Stallman
  2020-03-15  6:41       ` Steve Youngs
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2020-03-15  3:08 UTC (permalink / raw)
  To: Steve Youngs; +Cc: dima, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > How about some form of "include" mechanism:

  >         Local Variables:
  >         @include: FILENAME
  >         End:

  > I would suggest implementing that with the same care, considerations,
  > and restrictions as has `eval' for Locals

Specifying another file has a serious problem: you can't be sure which file
will get included.

Better to refer to something above in the file.


-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-15  3:08     ` Richard Stallman
@ 2020-03-15  6:41       ` Steve Youngs
  2020-03-16  3:36         ` Richard Stallman
  0 siblings, 1 reply; 20+ messages in thread
From: Steve Youngs @ 2020-03-15  6:41 UTC (permalink / raw)
  To: Richard Stallman; +Cc: dima, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1501 bytes --]

Richard Stallman <rms@gnu.org> writes:

  >> How about some form of "include" mechanism:

  >> Local Variables:
  >> @include: FILENAME
  >> End:

  > Specifying another file has a serious problem: you can't be sure
  > which file will get included.

It'd be no more problematic than any other facility that supports including
sub-files, for example texinfo.  And, if you think about it, the same
could be said for #'require or #'load in elisp where doing something
malicious would only need the right #'provide form and getting to the
head of the load-path.

In my pseudo-example above, if it were real world, obviously FILENAME is
replaced with a path to a, hopefully, existent file.

Wait, here's another idea from the crazy-dept.  Use a hash, like a md5
or sha1 or some such of the file to be included.  Before the inclusion,
check the hash, error out if there's a mismatch.

        Local variables:
        @include-hash: f31785c629584f30116ff45aa681fa5318613fd9
        @include: FILENAME
        End:

  > Better to refer to something above in the file.

I'm not a huge fan of file-local variables or special "cookies" or
whatnot at the best of times, so I'm not going to say what would be
"better". :-)

-- 
|---<Steve Youngs>-------<GnuPG KeyID: 9FDFE046F5745911>---|
|       SXEmacs - The only _______ you'll ever need.       |
|         Fill in the blank, yes, it's THAT good!          |
|------------------------------------<steve@sxemacs.org>---|

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 824 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-15  6:41       ` Steve Youngs
@ 2020-03-16  3:36         ` Richard Stallman
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Stallman @ 2020-03-16  3:36 UTC (permalink / raw)
  To: Steve Youngs; +Cc: dima, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  >   > Specifying another file has a serious problem: you can't be sure
  >   > which file will get included.

  > It'd be no more problematic than any other facility that supports including
  > sub-files, for example texinfo.

It is problematic because this inclusion would take place in the mere
act of visiting a file.  That is more sensitive than things that get
included when you _compile_ the file.

  > Wait, here's another idea from the crazy-dept.  Use a hash, like a md5
  > or sha1 or some such of the file to be included.  Before the inclusion,
  > check the hash, error out if there's a mismatch.

  >         Local variables:
  >         @include-hash: f31785c629584f30116ff45aa681fa5318613fd9
  >         @include: FILENAME
  >         End:

That would make it safer, but you'd have to edit the file whenever
you change what you include.

I think it is better to achieve the desired safety by putting those
settings in the file itself, with something to say "search further back".

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 21:39 ` Stefan Monnier
  2020-03-10 23:44   ` Dima Kogan
@ 2020-03-22 23:08   ` Dima Kogan
  2020-03-23  8:25     ` Robert Pluim
  1 sibling, 1 reply; 20+ messages in thread
From: Dima Kogan @ 2020-03-22 23:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1916 bytes --]

I sent this out a week ago, but I guess the email didn't make it for
some reason (I don't see it in the list archives, and nobody replied).
Apologies if you get this twice.



Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Probably we'd want to make this into a variable? And the default maybe
>> should be higher than 3000?
>
> I don't like having this 3000 hard-coded everywhere, so making
> a variable makes sense.
>
> But encouraging large "Local Variables" blocks is a bad idea, IMO, so
> I'd keep it at 3000 and I wouldn't care to document the var either.
> I'd even be happy with a "--" in its name.
>
>> The use case where I hit this was in an .org file that was defining a
>> presentation where I needed to control the export with an eval: (progn
>> ...) block. Org wasn't doing quite what I needed it to, so the block had
>> some advice definitions in it, and that pushed the thing over the 3000
>> byte limit.
>
> Of course, you can use a short
>
>     eval: (progn (re-search-backward "^(progn ;;local-config") (eval (read (current-buffer))))
>
> and then put an arbitrarily long Elisp chunk anywhere else in the buffer
> with a leading `(progn ;;local-config`.

Thanks for the suggestions, everyone. For my personal usage I think both
including files to eval and specifying custom look-back-distance
variables is a bit overkill. I think that

1. We should put the 3000 into a variable so that this isn't hard-coded.
   I'm attaching a patch. The name of the variable could probably be
   better, and it's not in the right file. I don't know where else to
   put it. Suggestions? And we need a NEWS entry, but I didn't want to
   write one before we talked about it.

2. As workarounds go, I think Stefan's suggestion above is the nicest.
   No custom variables or included files; just a directive to search
   backwards, and execute what it finds. I'll use that. Thanks for the
   pointer

dima


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: files--local-variables-search-distance.patch --]
[-- Type: text/x-diff, Size: 9280 bytes --]

commit 65b63cab97d968dade6ec73c8696f3ee1cce5473
Author: Dima Kogan <dima@secretsauce.net>
Date:   Sun Mar 15 21:46:35 2020 -0700

    added files--local-variables-search-distance

diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index e7e879065ed..d3b5e14cfe0 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1126,9 +1126,10 @@ Specifying File Variables
 
   Apart from using a @samp{-*-} line, you can define file local
 variables using a @dfn{local variables list} near the end of the file.
-The start of the local variables list should be no more than 3000
-characters from the end of the file, and must be on the last page if
-the file is divided into pages.
+The start of the local variables list should be no more than
+@code{files--local-variables-search-distance} characters from the end
+of the file (3000 by default), and must be on the last page if the
+file is divided into pages.
 
   If a file has both a local variables list and a @samp{-*-} line,
 Emacs processes @emph{everything} in the @samp{-*-} line first, and
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 1dab29b8a5a..b707cfec2fa 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -31060,13 +31060,13 @@ Assignments in Embedded Mode
 
 When Emacs loads a file into memory, it checks for a Local Variables
 section like this one at the end of the file.  If it finds this
-section, it does the specified things (in this case, running
-@kbd{C-x * a} automatically) before editing of the file begins.
-The Local Variables section must be within 3000 characters of the
-end of the file for Emacs to find it, and it must be in the last
-page of the file if the file has any page separators.
-@xref{File Variables, , Local Variables in Files, emacs, the
-Emacs manual}.
+section, it does the specified things (in this case, running @kbd{C-x
+* a} automatically) before editing of the file begins.  The Local
+Variables section must be within
+@code{files--local-variables-search-distance} characters of the end of
+the file (3000 by default) for Emacs to find it, and it must be in the
+last page of the file if the file has any page separators.  @xref{File
+Variables, , Local Variables in Files, emacs, the Emacs manual}.
 
 Note that @kbd{C-x * a} does not update the formulas it finds.
 To do this, type, say, @kbd{M-1 C-x * u} after @w{@kbd{C-x * a}}.
diff --git a/lisp/allout.el b/lisp/allout.el
index dedad45f827..f52e27784bb 100644
--- a/lisp/allout.el
+++ b/lisp/allout.el
@@ -6326,7 +6326,10 @@ allout-file-vars-section-data
   (let (beg prefix suffix)
     (save-excursion
       (goto-char (point-max))
-      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
+      (search-backward "\n\^L" (max (- (point-max)
+                                       files--local-variables-search-distance)
+                                    (point-min))
+                       'move)
       (if (let ((case-fold-search t))
 	    (not (search-forward "Local Variables:" nil t)))
           nil
diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el
index da98e44926e..d5b0db1dfbb 100644
--- a/lisp/calendar/diary-lib.el
+++ b/lisp/calendar/diary-lib.el
@@ -2084,7 +2084,9 @@ diary-make-entry
     (goto-char (point-max))
     (when (let ((case-fold-search t))
             (search-backward "Local Variables:"
-                             (max (- (point-max) 3000) (point-min))
+                             (max (- (point-max)
+                                     files--local-variables-search-distance)
+                                  (point-min))
                              t))
       (beginning-of-line)
       (insert "\n")
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index d3d17fda7ad..e1b3cf319a9 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -4571,7 +4571,9 @@ custom-save-delete
 	    (case-fold-search t))
 	(save-excursion
 	  (goto-char (point-max))
-	  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
+	  (search-backward "\n\^L" (max (- (point-max)
+                                           files--local-variables-search-distance)
+                                        (point-min))
 			   'move)
 	  (when (search-forward "Local Variables:" nil t)
 	    (setq pos (line-beginning-position))))
diff --git a/lisp/files-x.el b/lisp/files-x.el
index 5d863626fa5..9aa64fd00be 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -169,7 +169,10 @@ modify-file-local-variable
       ;; Look for "Local variables:" line in last page.
       (widen)
       (goto-char (point-max))
-      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
+      (search-backward "\n\^L" (max (- (point-max)
+                                           files--local-variables-search-distance)
+                                    (point-min))
+                       'move)
 
       ;; Add "Local variables:" list if not found.
       (unless (let ((case-fold-search t))
diff --git a/lisp/files.el b/lisp/files.el
index 8ce0187f5b7..4e173a2a674 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3720,7 +3720,9 @@ hack-local-variables
 	;; Look for "Local variables:" line in last page.
 	(save-excursion
 	  (goto-char (point-max))
-	  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
+	  (search-backward "\n\^L" (max (- (point-max)
+                                           files--local-variables-search-distance)
+                                        (point-min))
 			   'move)
 	  (when (let ((case-fold-search t))
 		  (search-forward "Local Variables:" nil t))
diff --git a/lisp/international/latexenc.el b/lisp/international/latexenc.el
index cce5e06002a..5e3134feb9a 100644
--- a/lisp/international/latexenc.el
+++ b/lisp/international/latexenc.el
@@ -147,7 +147,9 @@ latexenc-find-file-coding-system
             ;; section?
             (unless latexenc-dont-use-TeX-master-flag
               (goto-char (point-max))
-	      (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
+	      (search-backward "\n\^L" (max (- (point-max)
+                                               files--local-variables-search-distance)
+                                            (point-min))
                                'move)
 	      (search-forward "Local Variables:" nil t)
               (when (re-search-forward
diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el
index 2a7ab66a339..dbebf1d5f66 100644
--- a/lisp/org/org-macs.el
+++ b/lisp/org/org-macs.el
@@ -186,7 +186,9 @@ org-preserve-local-variables
 	   (goto-char (point-max))
 	   (let ((case-fold-search t))
 	     (and (re-search-backward "^[ \t]*# +Local Variables:"
-				      (max (- (point) 3000) 1)
+                                      (max (- (point-max)
+                                              files--local-variables-search-distance)
+                                           1)
 				      t)
 		  (delete-and-extract-region (point) (point-max)))))))
      (unwind-protect (progn ,@body)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index f92d3efdeb7..c28a2fd7e07 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -859,7 +859,10 @@ c-remove-any-local-eval-or-mode-variables
   ;; Most of the code here is derived from Emacs 21.3's `hack-local-variables'
   ;; in files.el.
   (goto-char (point-max))
-  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
+  (search-backward "\n\^L" (max (- (point-max)
+                                     files--local-variables-search-distance)
+                                (point-min))
+		   'move)
   (let (lv-point (prefix "") (suffix ""))
     (when (let ((case-fold-search t))
 	    (search-forward "Local Variables:" nil t))
diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el
index ab3321f6868..3d82d878bf3 100644
--- a/lisp/progmodes/dcl-mode.el
+++ b/lisp/progmodes/dcl-mode.el
@@ -1749,7 +1749,9 @@ dcl-save-local-variable
   ;; Look for "Local variables:" line in last page.
   (save-excursion
     (goto-char (point-max))
-    (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
+    (search-backward "\n\^L" (max (- (point-max)
+                                     files--local-variables-search-distance)
+                                  (point-min)) 'move)
     (if (let ((case-fold-search t))
 	  (search-forward "Local Variables:" nil t))
 	(let ((continue t)
diff --git a/src/eval.c b/src/eval.c
index 4559a0e1f66..687576fb681 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4026,6 +4026,14 @@ get_backtrace (Lisp_Object array)
 void
 syms_of_eval (void)
 {
+  DEFVAR_INT ("files--local-variables-search-distance", files__local_variables_search_distance,
+	      doc: /* How far to search for "Local Variables:" string at the end of a file
+
+When loading a file, emacs searches for a string "Local Variables:" at
+the end of the buffer.  This variable controls how far from the end of
+the buffer we search. The default is 3000 characters.  */);
+  files__local_variables_search_distance = 3000;
+
   DEFVAR_INT ("max-specpdl-size", max_specpdl_size,
 	      doc: /* Limit on number of Lisp variable bindings and `unwind-protect's.
 If Lisp code tries to increase the total number past this amount,

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-22 23:08   ` Dima Kogan
@ 2020-03-23  8:25     ` Robert Pluim
  2020-03-23 14:17       ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Robert Pluim @ 2020-03-23  8:25 UTC (permalink / raw)
  To: Dima Kogan; +Cc: Stefan Monnier, emacs-devel

>>>>> On Sun, 22 Mar 2020 16:08:56 -0700, Dima Kogan <dima@secretsauce.net> said:

    Dima> 1. We should put the 3000 into a variable so that this isn't hard-coded.
    Dima>    I'm attaching a patch. The name of the variable could probably be
    Dima>    better, and it's not in the right file. I don't know where else to
    Dima>    put it. Suggestions? And we need a NEWS entry, but I didn't want to
    Dima>    write one before we talked about it.

Itʼs a user option, I donʼt think it should have a double '__' in it.

    Dima> 2. As workarounds go, I think Stefan's suggestion above is the nicest.
    Dima>    No custom variables or included files; just a directive to search
    Dima>    backwards, and execute what it finds. I'll use that. Thanks for the
    Dima>    pointer

Would providing a defcustom be such a hardship?

Robert



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23  8:25     ` Robert Pluim
@ 2020-03-23 14:17       ` Eli Zaretskii
  2020-03-23 15:28         ` Robert Pluim
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2020-03-23 14:17 UTC (permalink / raw)
  To: Robert Pluim; +Cc: emacs-devel, dima, monnier

> From: Robert Pluim <rpluim@gmail.com>
> Date: Mon, 23 Mar 2020 09:25:28 +0100
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
> 
> Would providing a defcustom be such a hardship?

Given that "enlarging the limit is a bad idea", I'm not even sure we
should provide a variable.  We definitely shouldn't document it.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 14:17       ` Eli Zaretskii
@ 2020-03-23 15:28         ` Robert Pluim
  2020-03-23 15:54           ` Eli Zaretskii
  2020-03-24  2:20           ` Richard Stallman
  0 siblings, 2 replies; 20+ messages in thread
From: Robert Pluim @ 2020-03-23 15:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, dima, monnier

>>>>> On Mon, 23 Mar 2020 16:17:46 +0200, Eli Zaretskii <eliz@gnu.org> said:

    >> From: Robert Pluim <rpluim@gmail.com>
    >> Date: Mon, 23 Mar 2020 09:25:28 +0100
    >> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
    >> 
    >> Would providing a defcustom be such a hardship?

    Eli> Given that "enlarging the limit is a bad idea", I'm not even sure we
    Eli> should provide a variable.  We definitely shouldn't document
    Eli> it.

In that case we shouldnʼt even provide the variable, no? People who
know what theyʼre doing can hack their local copy of emacs.

Robert



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 15:28         ` Robert Pluim
@ 2020-03-23 15:54           ` Eli Zaretskii
  2020-03-23 17:03             ` Dima Kogan
  2020-03-23 17:24             ` Stefan Monnier
  2020-03-24  2:20           ` Richard Stallman
  1 sibling, 2 replies; 20+ messages in thread
From: Eli Zaretskii @ 2020-03-23 15:54 UTC (permalink / raw)
  To: Robert Pluim; +Cc: emacs-devel, dima, monnier

> From: Robert Pluim <rpluim@gmail.com>
> Cc: dima@secretsauce.net,  monnier@iro.umontreal.ca,  emacs-devel@gnu.org
> Date: Mon, 23 Mar 2020 16:28:49 +0100
> 
> >>>>> On Mon, 23 Mar 2020 16:17:46 +0200, Eli Zaretskii <eliz@gnu.org> said:
> 
>     >> From: Robert Pluim <rpluim@gmail.com>
>     >> Date: Mon, 23 Mar 2020 09:25:28 +0100
>     >> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
>     >> 
>     >> Would providing a defcustom be such a hardship?
> 
>     Eli> Given that "enlarging the limit is a bad idea", I'm not even sure we
>     Eli> should provide a variable.  We definitely shouldn't document
>     Eli> it.
> 
> In that case we shouldnʼt even provide the variable, no?

Possibly.  Stefan didn't say why he thought adding a variable was an
improvement, but my guess would be ease of change in the future.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-10 20:56 Can we expand the valid location of "Local Variables" ? Dima Kogan
  2020-03-10 21:39 ` Stefan Monnier
  2020-03-12  2:26 ` Richard Stallman
@ 2020-03-23 15:56 ` Yuri Khan
  2020-03-23 16:55   ` Dima Kogan
  2 siblings, 1 reply; 20+ messages in thread
From: Yuri Khan @ 2020-03-23 15:56 UTC (permalink / raw)
  To: Dima Kogan; +Cc: Emacs developers

Going back to the original question:

On Wed, 11 Mar 2020 at 03:56, Dima Kogan <dima@secretsauce.net> wrote:

> Currently we can specify buffer-local variables in a "Local Variables"
> stanza at the end of a buffer:
>
>   https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables
>
> For efficiency reasons, emacs doesn't look for this stanza in the entire
> buffer, but only scans the last 3000 bytes.
>
> The use case where I hit this was in an .org file that was defining a
> presentation where I needed to control the export with an eval: (progn
> ...) block. Org wasn't doing quite what I needed it to, so the block had
> some advice definitions in it, and that pushed the thing over the 3000
> byte limit.

Maybe your use case could be solved by using directory-local variables?

Alternatively, maybe the body of that eval block could become a defun
somewhere in your private configuration, and then the eval block would
shrink to a single function call? Maybe you could even always execute
that block for Org mode buffers by adding it to org-mode-hook?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 15:56 ` Yuri Khan
@ 2020-03-23 16:55   ` Dima Kogan
  0 siblings, 0 replies; 20+ messages in thread
From: Dima Kogan @ 2020-03-23 16:55 UTC (permalink / raw)
  To: Yuri Khan; +Cc: Emacs developers

Yuri Khan <yuri.v.khan@gmail.com> writes:

> Maybe your use case could be solved by using directory-local
> variables?

It would, actually. I didn't realize those could contain evel blocks
too. I should switch to that. Thanks for the pointer.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 15:54           ` Eli Zaretskii
@ 2020-03-23 17:03             ` Dima Kogan
  2020-03-23 17:24             ` Stefan Monnier
  1 sibling, 0 replies; 20+ messages in thread
From: Dima Kogan @ 2020-03-23 17:03 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Robert Pluim <rpluim@gmail.com>
>> Cc: dima@secretsauce.net,  monnier@iro.umontreal.ca,  emacs-devel@gnu.org
>> Date: Mon, 23 Mar 2020 16:28:49 +0100
>>
>> >>>>> On Mon, 23 Mar 2020 16:17:46 +0200, Eli Zaretskii <eliz@gnu.org> said:
>>
>>     >> From: Robert Pluim <rpluim@gmail.com>
>>     >> Date: Mon, 23 Mar 2020 09:25:28 +0100
>>     >> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
>>     >>
>>     >> Would providing a defcustom be such a hardship?
>>
>>     Eli> Given that "enlarging the limit is a bad idea", I'm not even sure we
>>     Eli> should provide a variable.  We definitely shouldn't document
>>     Eli> it.
>>
>> In that case we shouldnʼt even provide the variable, no?
>
> Possibly.  Stefan didn't say why he thought adding a variable was an
> improvement, but my guess would be ease of change in the future.

I think we should provide the variable, because even here the usual
reasons apply:

- With a variable the reader of the code knows that all uses of that
  variable refer to the same logical thing. If I see "3000" in two
  different places I don't know if they're related: it may just be a
  coincidence

- With a variable, the reader of the code knows where to find the
  documentation. If we document this.

- With a variable, the generated .tex docs and the value (3000) can't go
  out of sync



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 15:54           ` Eli Zaretskii
  2020-03-23 17:03             ` Dima Kogan
@ 2020-03-23 17:24             ` Stefan Monnier
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Monnier @ 2020-03-23 17:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Robert Pluim, dima, emacs-devel

> Possibly.  Stefan didn't say why he thought adding a variable was an
> improvement, but my guess would be ease of change in the future.

I explained that I don't really want it to be a *variable* but I think
we should remove the various occurrences of 3000 and replace them with
a reference to a centralized place where this *constant* is defined,
with a name that explains what it is.  For the usual software
engineering reasons that say that arbitrary constants should be named.

IIUC this constant is also used from Elisp so it has to be exported to
Elisp where we don't really have constants.  Also I don't see why we
should go out of our way to make it hard for the user to change it.

So an *internal variable* sounds good to me,


        Stefan




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Can we expand the valid location of "Local Variables" ?
  2020-03-23 15:28         ` Robert Pluim
  2020-03-23 15:54           ` Eli Zaretskii
@ 2020-03-24  2:20           ` Richard Stallman
  1 sibling, 0 replies; 20+ messages in thread
From: Richard Stallman @ 2020-03-24  2:20 UTC (permalink / raw)
  To: Robert Pluim; +Cc: eliz, dima, monnier, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I think there IS a safe way to allow other locations of the local
variable list.  Namely, to put something in the local variable list
which says to search further back for another additional local
variable list.

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2020-03-24  2:20 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-10 20:56 Can we expand the valid location of "Local Variables" ? Dima Kogan
2020-03-10 21:39 ` Stefan Monnier
2020-03-10 23:44   ` Dima Kogan
2020-03-11  2:01     ` Stefan Monnier
2020-03-22 23:08   ` Dima Kogan
2020-03-23  8:25     ` Robert Pluim
2020-03-23 14:17       ` Eli Zaretskii
2020-03-23 15:28         ` Robert Pluim
2020-03-23 15:54           ` Eli Zaretskii
2020-03-23 17:03             ` Dima Kogan
2020-03-23 17:24             ` Stefan Monnier
2020-03-24  2:20           ` Richard Stallman
2020-03-12  2:26 ` Richard Stallman
2020-03-14  5:54   ` Steve Youngs
2020-03-14  7:07     ` Stefan Monnier
2020-03-15  3:08     ` Richard Stallman
2020-03-15  6:41       ` Steve Youngs
2020-03-16  3:36         ` Richard Stallman
2020-03-23 15:56 ` Yuri Khan
2020-03-23 16:55   ` Dima Kogan

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).