如何在emacs lua模式下配置缩进? [英] How to configure indentation in emacs lua-mode?

查看:131
本文介绍了如何在emacs lua模式下配置缩进?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在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

更新:



(这属于一个评论,但由于需要额外的格式,我必须将其放在这里。)



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

 
local foo = function()
print(Hello,世界)
end

请注意, end 缩进为标签和四个空格。
不太可行...



更新2:



这个东西也是以错误的方式缩进:

 
local bar = foo(
one,
two,
baz(), - 注意三个空格
quo

应该是:

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

更新3:



缩进错误的第三种情况:

 
local bar = foo
一,



本地t = 5 - 此行不应缩进,
- 还注意选项卡在本地和t之间。

更新4:



我从Thomas获得当前版本:

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

local bar = 5 - Emacs put \t before 5

local zzz = foo( - Emacs put \ before foo
一, - 按下TAB这里两次
两,
三(),


除非明确指出,我没有做任何缩进,只输入代码,并在每行结尾按下 RETURN 。我没有真正输入任何意见。



应该如下所示:

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

local bar = 5

local zzz = foo(
一,
两,
三(),


更新5:



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

 
local foo =
{
bar(); - 在这里按一个TAB,但关闭大括号杀死了
baz;
}

应该是:

 
local foo =
{
bar();
baz;
}

更新6:



为了完整起见,以下是当前的Git HEAD的lua模式,没有托马斯的配置调整:

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

local bar = 5

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


本地t =
{
一,
二),
}

调整:

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

local bar = 5

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


local t =
{
on e,
two(),
}

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

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

local bar = 5

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


本地t =
{
一,
两(),
}


解决方案

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



无疑是奇怪的默认缩进的原因是一个名为lua-calculate-indentation的函数,它计算要缩进当前行的列。不幸的是,它返回的值不符合您所需的规格。



例如,如果您将一行输入到这样一个新鲜的.lua文件中: p>

  local foo = function()

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



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

  ;;使用两个空格的缩进宽度
(setq lua-indent-level 2)

;;添加dangling'(',remove'='
(setq lua-cont-eol-regexp
(eval-when-compile
(concat
\\ $
本地功能$
(regexp-opt(和或 )t)
\\_> \\ | |
\\(^ \\ | [^lua-operator-class] \\ )
(regexp-opt'(+ - */^..==& ; =〜=)t)
\\)
\\s * \\ =)))

defun lua-calculate-indentation(&可选parse-start)
覆盖计算当前行应缩进到的
列的默认lua模式函数。
save-excursion
(当parse-start
(goto-char parse-start))

;;我们根据以前的
;;计算缩进列。非空白,非c另外,当前行
;;是上一行的延续,我们再添加一个
;;缩进单位
(+(if(lua-is-continuation-statement-p)lua-indent-level 0)
(if(lua-goto-nonblank-previous-line)
(+当前缩进)(lua-calculate-indentation-right-shift-next))
0))))

(defun lua-calculate-indentation-right-shift-next(& ;可选的parse-start)
假设下一个代码行不是一个块结束行,
这个函数返回列偏移量,这个行的值应该是
缩进到当前行
(let((eol)
(令牌)
(令牌信息)
(shift 0))
(save-excursion
当parse-start
(goto-char parse-start))

;计算块开放和块截止令牌​​
的余额;从开始到结束
(setq eol(line-end-position))
(行首)
(while(和(lua-find-regexp'forward lua-indentation-modifier -regexp)
(&
(setq token(match-string 0))
(setq token-info(assoc token lua-block-token-alist)))
;我们发现了一个令牌。现在,这是一个打开还是关闭的令牌?
(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))

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



剩下要做的是确保此代码实际加载。在原始lua模式被加载之后,必须发生,否则该代码将重新安装原始缩进功能。



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



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

  (加号文件(locate-filemy- luaelload-path))))))

我假设lua模式在你的如果你遵循lua-mode的安装说明,它应该是一个加载路径。



我希望这次对你有用,如果没有,让我知道。 p>

Complete emacs newbie here.

I'm using emacs 23.1.1 on Ubuntu with emacs starter kit. I primarily work in the lua-mode (installed with package-install lua-mode).

I need to tune how indentation works, so it would match my coding guidelines.

The guidelines are:

  • tabs-to-spaces;
  • two spaces per indent;
  • 80 chars per line maximum, without trailing spaces.

Example:

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

What I get with emacs if I don't try to fight with its auto-indent:

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

Update:

(This belongs to a comment, but since it needs extra formatting, I have to place it here.)

If I try solution by Thomas, I get this:

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

Note that end is indented with a tab and four spaces. Does not quite work...

Update 2:

This thing is also gets indented in the wrong way:

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

It should be:

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

Update 3:

Third case of the wrong indentation:

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

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

Update 4:

Here is what I get with the current version from 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"
            )

Except where explicitly noted, I did not do anything for indentation, only typed in the code and pressed RETURN at the end of each line. I did not actually type any comments.

It should look as follows:

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

local bar = 5

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

Update 5:

One more wrong indentation case:

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

Should be:

local foo =
{
  bar();
  baz;
}

Update 6:

For the sake of completeness, here is what I get with the current Git HEAD of lua-mode, without Thomas's configuration tuning:

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

local bar = 5

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

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

With tuning:

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

            local bar = 5

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

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

To match my coding guidelines, it should look as follows:

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

local bar = 5

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

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

解决方案

Okay, let's give this another try... After browsing through the source code of lua-mode, I've come up with the following approach.

The reason for the admittedly strange default indentation is a function called "lua-calculate-indentation" which computes the column to which to indent the current line. Unfortunately, the values returned by it do not match your desired specification.

For instance, if you enter a single line into a fresh .lua file like this one:

local foo = function()

and hit enter to move the point to the second line, you can invoke the above function by typing M-: (lua-calculate-indentation). The result is 15, which means that lua-mode will indent the second to column 15. This is the reason for the unorthodox indentation you've described and exemplified in your original question.

Now, to fix this I suggest re-defining the function "lua-calculate-indentation" so that it returns the indentation you want. For this, put the following code into an otherwise empty file, and save it under the name "my-lua.el" in the same directory where "lua-mode.el" lives.

;; 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))

This code sets the indentation level to two spaces (instead of 3), modifies a regular expression that detects if a statement stretches over multiple lines, and finally redefines the indentation function using an auxiliary.

All that's left to do is make sure this code is actually loaded. That must happen after the original lua-mode is loaded, or else that code would re-install the original indentation function.

The way we do that here is a little hacky: we install a call-back function that is invoked each time a buffer changes its major-mode to lua-mode. It then checks if the auxiliary function mentioned before is defined - if not, it loads "my-lua.el". That is a little fragile, but as long as you don't play around with the lua source code, you should be fine.

Add the following lines to your ~/emacs.d/agladysh.el file (assuming that "agladysh" is your username):

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

I assume that lua-mode is on your load-path which it should be if you followed lua-mode's installation instructions.

I hope that it works for you this time, if not, let me know.

这篇关于如何在emacs lua模式下配置缩进?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆