Подтвердить что ты не робот

Как настроить отступ в emacs lua-mode?

Запустит нового участника emacs.

Я использую emacs 23.1.1 на Ubuntu с стартовый комплект emacs. В основном я работаю в режиме lua (установлен с package-install lua-mode).

Мне нужно настроить, как работает отступ, поэтому он будет соответствовать моим правилам кодирования.

Руководящие принципы:

  • вкладка к пространствам;
  • два пробела на отступ;
  • 80 символов на строку, без конечных пробелов.

Пример:

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

Что я получаю с emacs, если я не пытаюсь бороться с его автоматическим отступом:

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

Update:

(Это относится к комментарию, но поскольку для его форматирования требуется дополнительное форматирование, я должен разместить его здесь.)

Если я попробую решение Томаса, я получаю следующее:

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:

Для полноты, вот что я получаю от текущего Git HEAD lua-mode без настройки конфигурации 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(),
}
4b9b3361

Ответ 1

Хорошо, давайте еще раз попробуем... После просмотра исходного кода lua-mode у меня появился следующий подход.

Причиной, по общему признанию, странного дефолтного отступа является функция, называемая "lua-calculate-indentation", которая вычисляет столбец, на который делается отступ текущей строки. К сожалению, возвращаемые им значения не соответствуют требуемой спецификации.

Например, если вы введете одну строку в новый файл .lua, такой как этот:

local foo = function()

и нажмите 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))

Этот код устанавливает уровень отступа в два пробела (вместо 3), изменяет регулярное выражение, которое обнаруживает, что оператор растягивается на несколько строк, и, наконец, переопределяет функцию отступа с использованием вспомогательной.

Все, что осталось сделать, это убедиться, что этот код загружен. Это должно произойти после загрузки исходного режима lua, иначе код переустановит исходную функцию отступов.

Как мы это делаем, здесь немного взломано: мы устанавливаем функцию обратного вызова, которая вызывается каждый раз, когда буфер меняет свой основной режим на lua-mode. Затем он проверяет, определена ли вспомогательная функция, упомянутая ранее, если нет, она загружает "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)))))

Я предполагаю, что lua-mode находится на вашем пути загрузки, который должен быть, если вы следовали инструкциям по установке в режиме lua.

Я надеюсь, что это сработает для вас на этот раз, если нет, сообщите мне.

Ответ 2

Если вы введете следующий код в файл .emacs в своем домашнем каталоге, он сделает lua-mode (и только lua-mode) будет вести себя следующим образом:

  • Если вы нажмете ENTER, будет вставлена ​​новая строка, и по умолчанию следующая строка будет отступом, как и предыдущая строка.
  • Всякий раз, когда вы нажимаете TAB, чтобы отступать от строки, укажите либо переход к первому небездельному символу строки, либо, если строка пуста от точки уже на этом символе, будут вставлены два пробела.

Особенно последнее может быть не тем, что вы хотите, но, возможно, в первом приближении.

(defvar my-lua-indent 2
  "The number of spaces to insert for indentation")

(defun my-lua-enter ()
  "Inserts a newline and indents the line like the previous
non-empty line."
  (interactive)
  (newline)
  (indent-relative-maybe))

(defun my-lua-indent ()
  "Moves point to the first non-whitespace character of the
line if it is left of it. If point is already at that
position, or if it is at the beginning of an empty line,
inserts two spaces at point."
  (interactive)
  (when (looking-back "^\\s *")
    (if (looking-at "[\t ]")
        (progn (back-to-indentation)
               (when (looking-at "$")
                 (kill-line 0)
                 (indent-relative-maybe)
                 (insert (make-string my-lua-indent ? ))))
      (insert (make-string my-lua-indent ? )))))

(defun my-lua-setup ()
  "Binds ENTER to my-lua-enter and configures indentation the way
I want it. Makes sure spaces are used for indentation, not tabs."
  (setq indent-tabs-mode nil)
  (local-set-key "\r" 'my-lua-enter)
  (setq indent-line-function 'my-lua-indent))

;; add `my-lua-setup' as a call-back that is invoked whenever lua-mode
;; is activated.
(add-hook 'lua-mode-hook 'my-lua-setup)

Перезапустите Emacs, чтобы эти изменения вступили в силу.

Ответ 3

Я знаю, что прошло некоторое время с тех пор, как это было задано, но я просто хотел указать, что это все еще проблема, с lua-mode, установленным через систему пакетов Emacs.

Однако последняя версия GitHub работает очень хорошо, не заметила какой-либо отпечаток. Все, что вам нужно сделать, чтобы соответствовать Руководству по стилю Lua - установить indent-tabs-mode в nil и lua-indent-level в 2.

Ответ 4

Я думаю, что многое из того, что вы ищете, можно найти в руководстве emacs в пользовательских определениях отступов C, которое подпадает под общий описания отступа.

Вы можете заставить его делать все, что вы можете себе представить, что было бы предпочтительнее всего делать все, что вы себе представляете.

Ответ 5

Я не могу сейчас сильно помочь - у меня есть крайний срок через два дня 8- (- но вот что я использую в своих .emacs, чтобы сделать lua-mode пригодным для меня...

(setq lua-indent-level 2)
(setq lua-electric-flag nil)
(defun lua-abbrev-mode-off () (abbrev-mode 0))
(add-hook 'lua-mode-hook 'lua-abbrev-mode-off)
(setq save-abbrevs nil)   ;; is this still needed?

Я вставляю свой код необычным способом - см. пример ниже - и так Я дисциплинировал себя только для нажатия TAB, когда lua-mode может вывести правильно отступать от строчек выше...

map = function (f, A, n)
    local B = {}                 -- TAB here doesn't work
    for i=1,(n or #A) do         -- TAB here works
      table.insert(B, f(A[i]))   -- TAB here works
    end                          -- TAB here works
    return B                     -- TAB here works
  end                            -- TAB here works

Ответ 6

Я поддерживающий (но не автор) lua-mode.el. Поскольку я намного менее свободен в Emacs Lisp, чем другие участники этой темы, я приветствую патчи. Я просто хотел бы отметить, что в правилах по умолчанию нет ничего странного или неправильного: идея, насколько я могу судить, заключается в том, что когда вы находитесь в анонимной функции, отступ должен принимать ключевое слово function как его левое поле. Это имеет смысл, если вы рассматриваете использование выражений функций в других местах, например. как параметры функции.

Итак, одним простым обходным решением является не писать

локальная функция f =...

но

локальная функция f...

Если, возможно, вы работаете с версией Lua, которая предшествует синтаксису "локальная функция".

Сказав это, я могу понять, почему вы, возможно, захотите отступать по-другому. В этом случае мне кажется разумным иметь переменную конфигурации lua-indent-function-from-function-keyword (лучшее имя, кто-нибудь?), И я был бы рад принять исправление, которое его реализовало.