简体   繁体   中英

Emacs: Set tab indent for just one file on the fly

I work on an open source project where the creator sets his tab-indents to 2 spaces.

I'd like to just enable it on the fly for the one file I work on and not other files of the same type. There must be something like Mx set-tab-indent . It is a JavaScript file ending in .js .

I know I can use:

(setq-default tab-width int)

inside my .emacs file, but I rather just call an Mx command to set it and forget it during my duration of working on this file. I tried Mx apropos and Google but couldn't find the specific command.

Thanks.

You can make the variable js-indent-level local to the buffer using:

Mx make-variable-buffer-local <RET> js-indent-level <RET>

Then you can set that variable in the buffer using:

Mx set-variable <RET> js-indent-level <RET> 2

You could also use file local variables to automate omrib's solution for that one file, by adding this to it:

// Local Variables:
// js-indent-level: 2
// indent-tabs-mode: nil
// End:

The easiest way to do this for a single buffer is to use Mx set-variable .

  1. Type Mx set-variable and press enter
  2. When prompted for the variable to set, set tab-width then press enter
  3. You'll be prompted with the line Set tab-width (buffer-local) to value: . Put the value you want, then hit enter

The buffer should instantly be updated with the new value.

Create a file ".dir-locals.el" in the project's directory and fill it like this:

((nil . ((tab-width . 2))))

This will take care of setting tab-width automatically and you don't have to modify the actual file (which is likely version-controlled.)

See the manual for more information about the format. I believe this requires Emacs 23.

As indicated by others, one issue with the File Local Variables approach is that you need to modify the file, and that's not ideal if you need to keep those declarations out of version control.

If you want the variables to apply to all files under a given directory, then Directory Local Variables is obviously the way to go, and you can implement that with either a .dir-locals.el file, or by calling (dir-locals-set-directory-class) :

I prefer the directory class approach myself, and I was thinking that it's a shame that there isn't an analogous approach for file local variables, but I found that the directory class code actually works perfectly with files, and the only issue is that dir-locals-set-directory-class calls file-name-as-directory on its argument, which prevents it from being matched, due to the trailing slash.

The following therefore is a way to configure directory local variables for a single file, without modifying the file itself, or affecting other files under the same parent directory.

(defun my-file-locals-set-directory-class (file class &optional mtime)
  "Enable 'directory local' classes for individual files,
by allowing non-directories in `dir-locals-directory-cache'.
Adapted from `dir-locals-set-directory-class'."
  (setq file (expand-file-name file))
  (unless (assq class dir-locals-class-alist)
    (error "No such class `%s'" (symbol-name class)))
  (push (list file class mtime) dir-locals-directory-cache))

(dir-locals-set-class-variables
 'my-javascript-class
 '((nil . ((js-indent-level . 2)
           (indent-tabs-mode . nil)))))

(my-file-locals-set-directory-class
 "path/to/the/file.js" 'my-javascript-class)

I use a snippet of code in my init.el that tries to auto-detect files that use 2-space indents, and switch Emacs's indentation for that file to 2 spaces when it sees such files:

(add-hook 'js-mode-hook
          (lambda ()
            (when (string-match-p "^  [A-Za-z]" (buffer-string))
              (make-variable-buffer-local 'js-indent-level)
              (set-variable 'js-indent-level 2))))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM