如何在emacs lua-mode中配置缩进?

Ale*_*ysh 19 emacs lua lua-mode

在这里完成emacs新手.

我在Ubuntu上使用emacs 23.1.1和emacs入门套件.我主要在lua模式下工作(安装时package-install lua-mode).

我需要调整缩进的工作方式,因此它符合我的编码指南.

准则是:

  • 标签到空间;
  • 每个缩进两个空格;
  • 每行最多80个字符,没有尾随空格.

例:

local foo = function()
  print("Hello, world!")
end

如果我不尝试使用自动缩进来解决,我会使用emacs:

local foo = function()
               print("Hello, world")
end

更新:

(这属于评论,但由于它需要额外的格式,我必须把它放在这里.)

如果我尝试托马斯的解决方案,我得到这个:

local foo = function()
               print("Hello, world")
        end

请注意,end它使用制表符和四个空格缩进.不太有用......

更新2:

这件事也以错误的方式缩进:

local bar = foo(
    "one",
    "two",
   baz(), -- Note three spaces
   "quo"
)  

它应该是:

local bar = foo(
    "one",
    "two",
    baz(),
    "quo"
  )

更新3:

错误缩进的第三种情况:

local bar = foo(
    "one",
    "two"
  )

  local t = 5 -- This line should not be indented, 
              -- also note tab between local and t.

更新4:

以下是我从Thomas获得的当前版本:

local foo = function()
               print("Hello, world")
        end

            local bar = 5 -- Emacs put \t before 5

            local zzz = foo( -- Emacs put \t before foo
                "one", -- Pressed TAB here twice
                "two",
               three(),
               "four"
            )

除非明确指出,否则我没有为缩进做任何事情,只输入代码并RETURN在每行的末尾按下.我实际上没有输入任何评论.

它应该如下所示:

local foo = function()
  print("Hello, world")
end

local bar = 5

local zzz = foo(
    "one",
    "two",
    three(),
    "four"
  )

更新5:

还有一个错误的缩进案例:

local foo =
{
bar(); -- Did press a TAB here, but closing brace killed it
baz;
}

应该:

local foo =
{
  bar();
  baz;
}

更新6:

为了完整起见,这是我使用当前的Lua-mode的GIT HEAD得到的,没有Thomas的配置调优:

local foo = function()
               print("Hello, world!")
            end

local bar = 5

local foo = bar(
bar,
   baz(),
   quo(),
aaa
)

local t =
{
"one",
two(),
}

通过调整:

local foo = function()
           print("Hello, world!")
            end

            local bar = 5

            local foo = bar(
            bar,
               baz(),
               quo(),
               aaa
            )

            local t =
            {
            "one",
            two(),
         }

为了符合我的编码指南,它应该如下所示:

local foo = function()
  print("Hello, world!")
end

local bar = 5

local foo = bar(
    bar,
    baz(),
    quo(),
    aaa
  )

local t =
{
  "one",
  two(),
}

Tho*_*mas 9

好的,让我们再试一次......在浏览了lua-mode的源代码后,我想出了以下方法.

奇怪的默认缩进的原因是一个名为"lua-calculate-indentation"的函数,它计算缩进当前行的列.不幸的是,它返回的值与您想要的规格不符.

例如,如果您在一个新的.lua文件中输入一行,如下所示:

local foo = function()
Run Code Online (Sandbox Code Playgroud)

并按Enter键将点移动到第二行,您可以通过键入来调用上述功能M-: (lua-calculate-indentation).结果是15,这意味着lua-mode将第二列缩进到第15列.这就是你在原始问题中描述和例证的非正统缩进的原因.

现在,为了解决这个问题,我建议重新定义函数"lua-calculate-indentation",以便它返回你想要的缩进.为此,将以下代码放入另外的空文件中,并将其保存在名为"my-lua.el"的"lua-mode.el"所在的同一目录中.

;; use an indentation width of two spaces
(setq lua-indent-level 2)

;; Add dangling '(', remove '='
(setq lua-cont-eol-regexp
      (eval-when-compile
        (concat
         "\\((\\|\\_<"
         (regexp-opt '("and" "or" "not" "in" "for" "while"
                       "local" "function") t)
         "\\_>\\|"
         "\\(^\\|[^" lua-operator-class "]\\)"
         (regexp-opt '("+" "-" "*" "/" "^" ".." "==" "<" ">" "<=" ">=" "~=") t)
         "\\)"
         "\\s *\\=")))

(defun lua-calculate-indentation (&optional parse-start)
  "Overwrites the default lua-mode function that calculates the
column to which the current line should be indented to."
  (save-excursion
    (when parse-start
      (goto-char parse-start))

    ;; We calculate the indentation column depending on the previous
    ;; non-blank, non-comment code line. Also, when the current line
    ;; is a continuation of that previous line, we add one additional
    ;; unit of indentation.
    (+ (if (lua-is-continuing-statement-p) lua-indent-level 0)
       (if (lua-goto-nonblank-previous-line)
           (+ (current-indentation) (lua-calculate-indentation-right-shift-next))
         0))))

(defun lua-calculate-indentation-right-shift-next (&optional parse-start)
  "Assuming that the next code line is not a block ending line,
this function returns the column offset that line should be
indented to with respect to the current line."
  (let ((eol)
        (token)
        (token-info)
        (shift 0))
    (save-excursion
      (when parse-start
        (goto-char parse-start))

      ; count the balance of block-opening and block-closing tokens
      ; from the beginning to the end of this line.
      (setq eol (line-end-position))
      (beginning-of-line)
      (while (and (lua-find-regexp 'forward lua-indentation-modifier-regexp)
                  (<= (point) eol)
                  (setq token (match-string 0))
                  (setq token-info (assoc token lua-block-token-alist)))
        ; we found a token. Now, is it an opening or closing token?
        (if (eq (nth 2 token-info) 'open)
            (setq shift (+ shift lua-indent-level))
          (when (or (> shift 0)
                    (string= token ")"))
            (setq shift (- shift lua-indent-level))))))
    shift))
Run Code Online (Sandbox Code Playgroud)

此代码将缩进级别设置为两个空格(而不是3),修改一个正则表达式,该表达式检测语句是否延伸到多行,最后使用辅助重新定义缩进函数.

剩下要做的就是确保实际加载此代码.这必须加载原始lua-mode 之后发生,否则该代码将重新安装原始缩进函数.

我们这样做的方式有点hacky:我们安装一个回调函数,每次缓冲区将其主模式更改为lua模式时调用该函数.然后检查是否定义了之前提到的辅助功能 - 如果没有,则加载"my-lua.el".这有点脆弱,但只要你不使用lua源代码,你应该没问题.

将以下行添加到〜/ emacs.d/agladysh.el文件中(假设"agladysh"是您的用户名):

(add-hook 'lua-mode-hook 
          (lambda () (unless (fboundp 'lua-calculate-indentation-right-shift-next)
                       (load-file (locate-file "my-lua.el" load-path)))))
Run Code Online (Sandbox Code Playgroud)

我假设lua-mode在你的加载路径上,如果你按照lua-mode的安装说明应该是这样.

我希望这次对你有用,如果没有,请告诉我.


fhd*_*fhd 5

我知道自从有人问这个问题以来已经有一段时间了,但我只是想指出这仍然是一个问题,因为 lua 模式是通过 Emacs 软件包系统安装的。

不过, GitHub上的最新版本运行得很好,没有注意到任何缩进的奇怪现象。为了符合Lua 风格指南,您所要做的就是设置indent-tabs-modetonillua-indent-levelto 2