4

I'm working on a project with all source files appended with this vim formating rule -- vim: et:sw=4:ts=8:sts=4:tw=80. Is there a way to make Emacs setup the correct indentation for me automatically?

The indentation options of vim are described at http://vimdoc.sourceforge.net/htmldoc/options.html. There follows a rough description of the used options:

  • et / expandtabs means to insert whitespaces instead of tabs. It should at least be similar to (setq indent-tabs-mode nil)

  • sw / shiftwidth is the number of spaces to use for each indent

  • sts / softtabstop Number of spaces that a counts for while performing editing operations, like inserting a or using . It "feels" like s are being inserted, while in fact a mix of spaces and s is used. This is useful to keep the ~ts~ setting at its standard value of 8, while being able to edit like it is set to ~sts~.

  • tw / textwidth corresponds to fill-column in emacs

  • 3
    It would help if you could translate what the vim code actually does for the benefit of Emacs users who don't also use vim. – Dan Nov 18 '17 at 14:24
  • What @Dan said. Please specify the behavior you want in English (or math). Do not specify it only with vim key sequences. Otherwise, the question is, for this site, unclear and incomplete. – Drew Nov 18 '17 at 20:19
  • The vim options are described at vimdoc.sourceforge.net/htmldoc/options.html. See stackoverflow.com/questions/742425/… for translating most indentation options and stackoverflow.com/questions/1450169/… for softtabstop (sts). textwidth (tw) is in emacs fill-column. – Tobias Nov 18 '17 at 22:27
  • @Dan You are right that it is not very polite to put just the short versions of the vim options in the question. But the word "translate" should be replaced by "explain". "Translation" (into a language more suitable for an emacs user) runs the risk of distorting the actual meaning of the vim options. I've tried to expand the question with the help of the vim manual and the cited stackoverflow-answers. – Tobias Nov 19 '17 at 0:13
4

I wouldn't be surprised if there's already a package out there that does it, but I couldn't find one. You should be able to cover most of it with something along the lines of the untested code below:

(advice-add 'hack-local-variables-prop-line
            :after-until
            #'my-hack-local-vim-props)
(defun my-hack-local-vim-props (&optional handle-mode)
  (unless (eq handle-mode t)
    (save-excursion
      (goto-char (point-max))
      (when (re-search-backward 
             "-- vim:[ \t]*"
             (max (point-min) (- (point) 1000)) t)
        (let ((opts ()))
          (while (looking-at "\\([[:alpha:]]+\\)\\(?:=\\([^:\n]+\\)[:\n]")
            (let ((var (match-string 1))
                  (val (match-string 2)))
              (pcase var
                ((or "et" "expandtabs")
                 (push '(indent-tabs-mode . t) opts))
                ((or "ts" "tabstop")
                 (push `(tab-width . ,(string-to-number val))
                       opts))
                ((or "tw" "textwidth")
                 (push '(fill-column . ,(string-to-number val))
                       opts))
                ((or "sts" "softtabstop")
                 (push `(tab-stop-list 0 ,(string-to-number val))
                       opts))
                (_ (message "Unhandled Vim option %s=%s"
                            var val)))))
          opts)))))

Notice:

  • I did not try to handle sw because which variable to set for that depends on the major mode. It could be c-basic-offset or sh-basic-offset, or octave-block-offset, or sml-indent-level, or smie-indent-basic, ...
  • the sts setting is "more or less equivalent", except that tab-stop-list is very rarely used.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.