简体   繁体   中英

Vim doesn't use tabstop distance in insert-mode

I'm having problems with auto indentation in vim while programming in lisp.

My .vimrc had the following settings for tabs:

set noexpandtab
set autoindent
set softtabstop=0
set shiftwidth=8
set tabstop=8

When I type (if <enter> in insert-mode, a new line is created with an indentation of two spaces . None of my settings say anything about two spaces, so why don't I get a tab? What setting can I use to change the indentation while in insert-mode?

Thanks in advance!

Update: Thanks for the answers, the settings are not overwritten. It has to do with the "default lisp indenting". In the :help lisp it says something about changing the p flag in cpoptions . This is what it says in the help for the cpoptions flags:

p - Vi compatible Lisp indenting.  When not present, a slightly better algorithm is used.

Setting it does change the indent to one space instead of two spaces. Still not sure how to change this to something else though.

Looks like this is two-space indentation is a hard coded behavior of :set lisp mode which ignores shiftwidth .

We can trace this to the source code which contains a hard-coded amount += 2; increment statement.

It's that way for a good reason; it has come to be the predominant way of writing Lisp.

As I wrote this answer, I peeked at samples of source code the following projects (all Lisp or Lisp-like languages):

  • Steel Bank Common Lisp (SBCL);
  • Clozure Common Lisp (CCL);
  • GNU Emacs;
  • Clojure;
  • GNU Guile;
  • Racket;
  • and GNU CLISP.

I did not spot a single example of anything but two-space indentation! With two-space indentation, you are in good/large company. You might as well get used to that; even if you somehow get Vim to follow your way, if you upstream anything into anyone's Lisp project, you will likely have to reformat.

Now, I have seen Lisp code using four-space indentation, like in very old code bases and some books.

By the way, sometimes you see if indented like this:

(if (condition)
    (then)
    (else))

This is alignment, not four space indentation. This formatting is standard for functions, but controversial for operators such as if . Some people like it that way in their code bases. For instance, this institution's randomly found coding style guide recommends it.

Vim will do the above if you remove if from lispwords .

The :set lispwords=... parameter contains a comma-separated list of identifiers which follow operator-like indentation, meaning two spaces rather than function-like alignment: second and third lines align with argument. By default, if is found in lispwords .

Lisp mode also applies two space indentation to a function (ie form not listed in lispwords , if there is no argument):

(gobbledygook 1 2 
              2 3)

(gobbledygook
  1)

That's also "canonical". Sometimes this comes in handy if you're trying to conform to some maximum line length; a function call running past the limit can sometimes be made to fit by moving all its arguments down, and just giving them two space indentation.

Each filetype can have its own settings in vim. So your .vimrc values can be overwritten in filetype plugins. To learn the current values of the settings for lisp filetype open the lisp file and run the following commands in vim command line:

:set noexpandtab?
:set autoindent?
:set softtabstop?
:set shiftwidth?
:set tabstop?

If they are different from the ones in .vimrc, then your values are overwritten in some plugin.

In order to overwrite them again with your custom values, create the ~/.vim/after/ftplugin/lisp.vim file with the required values:

set noexpandtab
set autoindent
set softtabstop=0
set shiftwidth=8
set tabstop=8

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