Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What do you need to know about variables in Emacs

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

With regard to what variables in Emacs need to know, this article introduces the corresponding analysis and solutions in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.

Learn how Elisp handles variables and how to use them in your scripts and configurations.

GNU Emacs is written by C and Emacs Lisp (a dialect of the Elisp,Lisp programming language). It is an editor and happens to be sandboxie of Elisp. Therefore, it will be helpful to understand some of the basic programming concepts in Elisp.

If you are new to Emacs, please read Sacha Chua's "Resources for Emacs novice" article first. This article assumes that you are familiar with common Emacs terminology and can read and evaluate simple snippets of Elisp code. You'd better have heard of the concept of variable scope and its role in other programming languages. The examples in this article assume that you are using a relatively new version of Emacs (after v.25).

The Elisp manual covers all aspects of Elisp, but it is written for people who have a clear search target (it also does a great job in this respect). But many people want materials that can explain the concept of Elisp at a higher level and compress the information into the most essential parts. This article is also an attempt by me to respond to this call, giving the reader a general outline of the foundation. Enable them to use these techniques in the configuration and make it easier for them to query the details in the manual.

Global variable

User settings defined with defcustom and variables defined with defvar or defconst are global. One of the most important reasons for declaring variables using defcustom or defvar is that when a variable is already bound to bind, reevaluating them will not overwrite the existing values. Take Chestnut, if you bind my-var in the initialization file as follows:

(setq my-var nil)

Evaluating the following expression does not overwrite the variable as t:

(defvar my-var t)

Note that there is an exception here: if you evaluate the above declaration with the C-M-x shortcut, it will call the eval-defun function and override the variable to t. In this way, you can force variables to be overridden as needed. This behavior is deliberate: as you may know, many features in Emacs are loaded on demand, which can also be called automatic loading. If the declaration in those files overrides the variables to their default values, it also overrides the settings in your initialization file.

User option

The user option is the global variable declared using defcustom. Unlike variables declared using defvar, these variables can be configured using the Mmurx customize interface. As far as I know, most people don't use it often because they think it's expensive. Once you know how to set variables in your initialization file, there is no reason to use it. One detail that many users don't realize is that setting user options through customize allows you to execute code, and there is time to run additional configuration instructions:

(defcustom my-option t "My user option.": set (lambda (sym val) (set-default sym val) (message "Set% sto% s" sym val)

If you evaluate this code and type Mmurx customize-option RET my-option RET to run the customize interface, the lambda anonymous function will be called and the echo area will display the symbolic name and value of the option.

If you use setq to change the value of this option in the initialization file, the anonymous function will not run. To set an option correctly in Elisp, you need to use the function customize-set-variable. Or, people use various versions of csetq macros in their configuration files to handle them automatically (as you wish, you can find more complex variants through GitHub's code search).

(defmacro csetq (sym val) `(funcall (or (get', sym 'custom-set)' set-default)', sym, val))

If you are using use-package macros, the: custom keyword will handle the above for you.

After you put the above code in your initialization file, you can use the csetq macro to run any existing setter function while setting the variable. To prove this, you can use this macro to change the options defined above and observe the message output in the echo area.

(csetq my-option nil) dynamic binding and lexical binding

When you are using other programming languages, you may not realize the difference between dynamic binding and lexical binding. Most programming languages today use lexical binding, and there is no need to understand the difference between learning variable scope and variable lookup.

In this way, Emacs Lisp is special because dynamic binding is the default option, and lexical binding needs to be explicitly enabled. There are some historical reasons, but in practice, you should always enable lexical binding because it is faster and less error-prone. To enable lexical binding, simply use the following comment line as the first line of your Emacs Lisp file:

;-*-lexical-binding: t;-*-

Alternatively, you can call add-file-local-variable-prop-line and automatically insert the comment line above after you choose to set the variable lexical-binding to t.

When you load a file that contains specially formatted lines such as above, Emacs sets variables accordingly, which means that lexical binding is enabled when the code in the buffer is loaded. To be interactive, you can call the Mmurx eval-buffer command, which takes lexical binding into account.

Now that you know how to enable lexical binding, it's wise to understand the meaning of these terms. For dynamic bindings, the last binding established during program execution is used for variable lookup. You can test this by putting the following code in an empty buffer and executing Mmurx eval buffer:

(defun a-exists-only-in-my-body (a) (other-function)) (defun other-function () (message "I see `a', its value is% s" a)) (a-exists-only-in-my-body t)

You may be surprised to find that finding the variable an in other-function succeeds.

If you rerun the previous example after adding a special lexical binding comment at the top, the code will throw a variable is void error because other-functioin does not recognize the variable a. If you are using another programming language, this is the behavior you expect.

When lexical binding is enabled, the scope is defined by the surrounding code. This is not just for performance reasons, but time has also shown that lexical binding is more popular.

Special variables and dynamic binding

As you know, let is used to temporarily establish local bindings:

(let ((a "Hello m a") (b "I m b")) (message "Hello,% s. Hello% s" a b))

What's interesting next is that variables defined using defcustom, defvar, and defconst are called special variables, and they use dynamic binding regardless of whether lexical binding is enabled or not:

;-*-lexical-binding: t;-*-(defun some-other-function () (message "I see `a', its values is:% s" c)) (defvar ct) (let ((a "I'm lexically bound") (c "I'm special and therefore dynamically bound")) (some-other-function) (message "I see `a', its values is:% s" a)

Switch to the Messages buffer through Cmurh e to view the message output from the above example.

Local variables bound using let or function parameters follow the lookup rules defined by lexical-binding variables, but global variables defined by defvar, defconst, or defcustom can be modified in let expressions along the call stack.

This technique allows for special customization easily and is often used in Emacs. This is not surprising, after all, Emacs Lisp initially provided only dynamic binding as the only option. The following is a common example of how to temporarily write data to a read-only buffer:

(let ((inhibit-read-only t)) (insert...))

This is another common example of how to perform case-sensitive searches:

(let ((case-fold-search nil)) (some-function-which-uses-search...))

Dynamic binding allows you to modify functions in ways that the author did not expect. This is a powerful tool and feature for programs like Emacs.

One thing to note: you may accidentally use the local variable name, which is declared as a special variable elsewhere. One trick to prevent such conflicts is to avoid using underscores in local variable names. In my current Emacs session, the following code leaves only a few candidates for potential conflicts:

(let ((vars () (mapatoms (lambda (cand) (when (and (boundp cand) (not (keywordp cand)) (special-variable-p cand) (not (string-match "-" (symbol-name cand) (push cand vars)) vars) = > (t obarray noninteractive debugger nil) buffer local variable

Each buffer can have a local binding of a variable. This means that for any variable, the buffer local variable is first found in the current buffer to replace the default value. Local variables are a very important feature in Emacs, for example, they are used by the main mode to establish buffer-wide behaviors and settings.

In fact, you've seen buffer local variables in this article-- that is, special comment lines that set lexical-binding to t within the buffer range. In Emacs, a buffer local variable defined in a special comment line is also called a file local variable.

Any global variable can be masked by a buffer local variable, such as the variable my-var defined above. You can set the local variable as follows:

(setq-local my-var t); or (set (make-local-variable 'my-var) t)

At this point, my-var is a local variable for the buffer you correspond to when you evaluate the above code. If you call describe-variable on it, the document will tell you both local and global values. From a programming point of view, you can use buffer-local-value to get local values and default-value to get global values. To remove local values, you can call kill-local-variable.

Another important property to note is that once a variable becomes a buffer local variable, subsequent setq used in that buffer will only set a local value. To set the default value, you need to use setq-default.

Because local variables mean customization of buffers, they are often used in pattern hooks. A typical example is as follows:

(add-hook 'go-mode-hook (defun go-setup+ ()) (setq-local compile-command (if (string-suffix-p "_ test.go" buffer-file-name) "go test-v" (format "go run% s") (shell-quote-argument (file-name-nondirectory buffer-file-name)

This sets the compilation command used by Mmurx compile in the go-mode buffer.

Another important aspect is that some variables automatically become buffer local variables. This means that when you use setq to set such a variable, it sets local bindings for the current buffer. This feature should not be used frequently because this implicit behavior is not good. However, if you want, you can use the following methods to create automatic local variables:

(defvar-local my-automatical-local-var t);; or (make-variable-buffer-local 'my-automatical-local-var)

The variable indent-tabs-mode is an example of Emacs built-in. If you use setq to change the value of a variable in the initialization file, it will not affect the default value at all. Only the local value of the current buffer when you load the initialization file will be changed. Therefore, you need to use setq-default to change the default value of indent-tabs-mode.

Emacs is a powerful editor, and it will become more powerful as you customize it. Now you know how Elisp handles variables and how you should use them in your own scripts and configurations.

This is the answer to the question about what you need to know about the variables in Emacs. I hope the above content can be of some help to you. If you still have a lot of doubts to solve, you can follow the industry information channel for more related knowledge.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report