Why customize Emacs variable sgml-xml-mode in sgml-mode.el? - emacs

As the title asks, why customize Emacs variable "sgml-xml-mode" (from file "sgml-mode.el")? In "(define-derived-mode sgml-mode text-mode '(sgml-xml-mode "XML" "SGML")" there is the line " (set (make-local-variable 'sgml-xml-mode) (sgml-xml-guess))" which makes that variable buffer local and which uses function "sgml-xml-guess" to give it a value, so what is customizing that variable good for?
For example, creating a buffer "new" and setting its mode to "html-mode" has the result that "sgml-xml-mode" has the local value nil--even if customization sets the global value to t.
The variable is defined thusly:
(defcustom sgml-xml-mode nil
"When non-nil, tag insertion functions will be XML-compliant.
It is set to be buffer-local when the file has
a DOCTYPE or an XML declaration."
:type 'boolean
:version "22.1"
:group 'sgml)
I am using:
GNU Emacs 23.3.1 (i386-mingw-nt5.1.2600) of 2011-03-10 on 3249CTO
A related question is Make emacs always close html tags.

It's just a historical accident. I"m not sure this question is appropriate here, BTW.

Related

Change emacs comment markers from ;; to //

When I am using Emacs to edit a ".s" file, I want to change the comment from ";;" to "//". I can't seem to find out how to change the comment identifiers?
For example, when I comment-region.
More information:
I appear to be in ASM-MODE which is the default mode for editing assembler files. I made sure that I was in asm-mode by
(setq auto-mode-alist
(append '(("\\.s$" . asm-mode)auto-mode-alist))
Because assembly programs typically use ; as the comment indicator, asm-mode uses this. However, for some reason I cannot figure the GNU assembler (GNU Binutils for Raspbian) 2.35.2 uses // or # or # for comments NOT a ;
Therefore, I would like to change the behaviour such that when I select a region and M-X comment-region it uses either // or # for comments. I cannot use the default comment character, I need to change it to either double-slashes // or an at symbol #
The question is really how do I go about changing the default comment character for in a mode?
Assuming that the major mode of the .s file is asm-mode, you can use the mode hook to tweak the comment start string:
(defun my/asm-comment-tweak ()
(setq-local comment-start "// "))
(eval-after-load "asm"
(add-hook 'asm-mode-hook #'my/asm-comment-tweak))
Adding the above to your init file should let you open a .s file, which will be in asm-mode. The last thing that is done by asm-mode is to run the mode hook which will call the function my/asm-comment-tweak: the function will set the buffer-local variable comment-start to the string you specified.
This pattern is very common: many problems in customizing emacs are solved in exactly the same way. You define a function that tweaks a variable and you arrange for the function to be called by the appropriate mode hook.

Variable definition for Invisible Text

I'm reading about Invisible Text in the Elisp manual. It defines the variable my-symbol to add or not add ... in place of the hidden text.
;; If you want to display an ellipsis:
(add-to-invisibility-spec '(my-symbol . t))
;; If you don't want ellipsis:
(add-to-invisibility-spec 'my-symbol)
However, I don't get it. How is it that you don't use (setq my-symbol "..."). What is the difference in syntax between (setq my-symbol "...") and '(my-symbol . t).
This might be a silly question but I'm not an expert or anything in Lisp and I'm playing around with Emacs configurations.
If you were to do (setq my-symbol "...") that would just set the value of variable my-symbol to that string.
What the Elisp manual is describing is the form of a specification, that is, a Lisp data structure (in this case a list) that causes certain parts of the buffer text to be invisible. It causes that behavior because such a spec is handled by Emacs automatically.
As #jenesaisquoi said in a comment, it is the C code of Emacs that does that automatic handling of the buffer invisibility spec. To use the spec, refer to the Elisp manual, node Invisible Text.

M-x set-variable does not work in Emacs 24.5.1

I recently upgraded Emacs 24.5.1 from 24.1 on my OSX machine. I use the native Cocoa Emacs application.
Since the upgrade, I have been unable to use M-x set-variable to change the value of a variable. The variable is defined in my .emacs with the syntax:
(defvar project-root-directory nil)
With the above definition, after Emacs starts up and the .emacs file is loaded without errors, when I hit M-x set-variable, Emacs complains that project-root-directory variable does not exist.
Did anything change with defvar syntax in Emacs 24.5 that disallows setting a variable using M-x?
The answer to your question is yes, something did change for Emacs 24.5 that broke this feature. More precisely, the breakage was introduced in Emacs 24.3, not 24.5.
Prior to Emacs 24.3 (that is, for decades!), it was enough to just put * as the first character of the doc string, to make a variable into a user variable, so it could be used with set-variable. (The * does not show as part of the displayed doc string.)
In other words, prior to Emacs 24.3, all you needed to do was this, to be able to use M-x set-variable:
(defvar foo 42 "*This is a user variable.")
Was it a good idea for Emacs to drop this feature? Some think so. (I don't.)
What is the current situation?
As #Thomas said, set-variable works for variables that are defined using defcustom. More precisely, however, it is defined for variables for which custom-variable-p returns non-nil.
So you can still use M-x set-variable with a variable that was defined using defvar, provided you give it a non-nil standard-value property (this makes it satisfy custom-variable-p):
(defvar foo 42 "This is a user variable.")
(put 'foo 'standard-value 42)
Your variable should be a user option variable name, i.e., a Lisp variable
meant to be customized by users. Thus, use defcustom instead of defvar:
(defcustom project-root-directory nil
"The root directory of the project.")
You might want to come up with a better documentation string for the variable than the one in this example.
(This was already the case prior to Emacs24.)

How can I set buffer-local value for a variable defined by defcustom?

In emacs, we can define customizable user option variable.
defcustom - Programming in Emacs Lisp http://www.gnu.org/software/emacs/manual/html_node/eintr/defcustom.html
And we can make variable to have buffer-local binding.
Creating Buffer-Local - GNU Emacs Lisp Reference Manual http://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Buffer_002dLocal.html#Creating-Buffer_002dLocal
If I want to make non-customizable variable, I can use make-local-variable or setq-local.
But I can't find any ways how to make customizable variable to have buffer-local binding.
Even if I call make-local-variable for variable defined by defcustom, custom-set-variables set to global-value.
If I call setq-local, value is set to local-variable. It is better. But I don't think this is best practice.
Is there any valid ways how to set buffer-local value for a variable defined by defcustom?
The answer is: You can't, at least not using the Customize UI.
What you can do is add a sexp that sets the buffer-local value of the variable to your init file.
Do one of the following:
Make it always buffer-local, no matter what the buffer is:
(make-variable-buffer-local 'the-variable)
You can put this anywher in your init file.
Make it buffer-local only for the current buffer, i.e., for some buffer after you select it:
(make-local-variable 'the-variable)
For that, you need to put the sexp in a sexp that selects the buffer you want. That could be, for example:
(with-current-buffer (get-buffer-create "the-buffer-name")
(make-local-variable 'the-variable))
That assumes that the buffer can be reasonably created or already exists. If you do this, do it after your custom-file has been loaded. That is, in your init file, either after loading custom-file (which I recommend) or, if you do not use custom-file, after any code generated automatically by Customize (e.g., custom-set-variables).
You can alternatively put the make-local-variable sexp on a mode hook, so whenever you are in a buffer that has a particular mode, it is executed.
All of that said, I submitted an enhancement request to Emacs Dev in 2012, requesting that user's be able to use the Customize UI to set (and possibly save) buffer-local values of user options. It sleeps in category "wishlist", so far.
After defcustom form write
(make-variable-buffer-local 'my-var)
Now, if you change the value in some buffer, other buffers will keep resp. deliver the old customized one.
The problem is that Customize is mostly designed for persistent configuration, i.e. configuration that is saved in the config file so it also applies to future Emacs sessions. But buffers are not persistent: when you restart Emacs you get a new buffer object.
So persistent customization "per-buffer" is not a clearly defined concept. We could/should add Customize support for settings that are specific to some major modes (i.e. "per-mode" settings), on the other hand.

Emacs Lisp: Can't set any value to variable named 's'

This is rather queer. I can't set any value to a variable if it is named 's' in an interactive session:
(setq s 'foo)
=> foo
s
=> nil
Why?
Update 1:
Here is the output from describe-variable on s:
s is void as a variable.
Documentation:
Not documented as a variable.
Why is it that s is kept void in emacs lisp as a global variable?
Update 2:
Turned out, it doesn't happen on a vanilla emacs (meaning one of the modules I load in .emacs or some code in .emacs is causing this).
So the question now is:
What would the original source look like when describe-variable yields "<var> is void as a variable"?
I tried it with setq, defconst, defvar, and defcustom, but none of those produced the message I'm showing.
Update 3:
The message shown above is produced when the variable is literally not bound (though it can be fbound).
(describe-variable 'non-existent)
=> "non-existent is void as a variable.
Documentation:
Not documented as a variable."
So latest question is: Is there any way to prevent a certain variable name
from being bound?
An answer to your revised question:
(defvar s)
The only thing is that this won't let you use describe-variable on it interactively.
(You could then do something like (setplist 's '(variable-documentation "Meh")) to set a description for it without going through defvar.
Just bisect your init file (~/.emacs) recursively until you find the sexp that causes the problem. If it is a sexp that loads another library then either don't use that library or fix it by first finding out what its problem is, the same way: bisect the code in that library recursively, etc.
This is a binary search, and it is very quick. You can quickly comment out half, then 3/4, 7/8, etc. of your file, using M-x comment-region (I bind it to C-x ;). with a prefix arg, comment-region uncomments.
With Emacs 23.1, running the following code makes C-h v s RET show “s is void as a variable.”, but I can't reproduce the inconsistency between setq and retrieving the value of the variable (which I agree is weird).
(setq s t)
(make-local-variable 's)
(makunbound 's)
I suspect an Emacs 24-specific feature or bug.