emacs lua lua-mode

¿Cómo configurar la sangría en emacs lua-mode?



(6)

Completa el novato emacs aquí.

Estoy usando emacs 23.1.1 en Ubuntu con el kit de inicio emacs . Principalmente trabajo en el modo lua (instalado con el package-install lua-mode ).

Necesito ajustar cómo funciona la sangría, para que coincida con mis pautas de codificación.

Las pautas son:

  • pestañas a espacios;
  • dos espacios por sangría;
  • Máximo 80 caracteres por línea, sin espacios finales.

Ejemplo:

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

Lo que consigo con emacs si no trato de luchar con su sangría automática:

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

Actualizar:

(Esto pertenece a un comentario, pero como necesita un formato adicional, tengo que colocarlo aquí).

Si intento la solución de Thomas, obtengo esto:

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

Tenga en cuenta que el end está sangrado con una pestaña y cuatro espacios. No funciona del todo ...

Actualización 2:

Esta cosa también se sangra de manera incorrecta:

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

Debería ser:

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

Actualización 3:

Tercer caso de la sangría incorrecta:

local bar = foo( "one", "two" ) local t = 5 -- This line should not be indented, -- also note tab between local and t.

Actualización 4:

Esto es lo que obtengo con la versión actual de 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" )

Excepto donde se indicó explícitamente, no hice nada para la sangría, solo tecleé el código y presioné RETORNO al final de cada línea. En realidad no escribí ningún comentario.

Debería verse como sigue:

local foo = function() print("Hello, world") end local bar = 5 local zzz = foo( "one", "two", three(), "four" )

Actualización 5:

Un caso de sangrado más equivocado:

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

Debiera ser:

local foo = { bar(); baz; }

Actualización 6:

En aras de la integridad, esto es lo que obtengo con el Git HEAD actual de lua-mode , sin ajuste de configuración de Thomas:

local foo = function() print("Hello, world!") end local bar = 5 local foo = bar( bar, baz(), quo(), aaa ) local t = { "one", two(), }

Con tuning:

local foo = function() print("Hello, world!") end local bar = 5 local foo = bar( bar, baz(), quo(), aaa ) local t = { "one", two(), }

Para que coincida con mis directrices de codificación, debe verse como sigue:

local foo = function() print("Hello, world!") end local bar = 5 local foo = bar( bar, baz(), quo(), aaa ) local t = { "one", two(), }


Bueno, vamos a intentarlo de nuevo ... Después de examinar el código fuente de lua-mode, se me ocurrió el siguiente enfoque.

El motivo de la sangría por defecto, que es ciertamente extraña, es una función llamada "lua-calcula-sangría" que calcula la columna en la que se sangra la línea actual. Desafortunadamente, los valores que devuelve no coinciden con la especificación deseada.

Por ejemplo, si ingresa una sola línea en un archivo .lua nuevo como este:

local foo = function()

y pulsa enter para mover el punto a la segunda línea, puedes invocar la función anterior escribiendo M-: (lua-calculate-indentation) . El resultado es 15, lo que significa que lua-mode sangrará el segundo en la columna 15. Esta es la razón de la sangría poco ortodoxa que ha descrito y ejemplificado en su pregunta original.

Ahora, para solucionar esto, sugiero volver a definir la función "lua-Calculate-indentation" para que devuelva la sangría que desea. Para esto, coloque el siguiente código en un archivo vacío y guárdelo bajo el nombre "my-lua.el" en el mismo directorio donde vive "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))

Este código establece el nivel de sangría en dos espacios (en lugar de 3), modifica una expresión regular que detecta si una declaración se extiende sobre varias líneas y, finalmente, redefine la función de sangría utilizando un auxiliar.

Todo lo que queda por hacer es asegurarse de que este código esté realmente cargado. Esto debe suceder después de que se haya cargado el modo lua original, o de lo contrario el código volverá a instalar la función de sangría original.

La forma en que lo hacemos aquí es un poco intrincada: instalamos una función de devolución de llamada que se invoca cada vez que un búfer cambia su modo mayor a modo lua. Luego verifica si la función auxiliar mencionada anteriormente está definida; si no, carga "my-lua.el". Eso es un poco frágil, pero mientras no juegues con el código fuente de lua, deberías estar bien.

Agregue las siguientes líneas a su archivo ~ / emacs.d / agladysh.el (asumiendo que "agladysh" es su nombre de usuario):

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

Supongo que lua-mode está en su ruta de carga, que debería estar si usted siguió las instrucciones de instalación de lua-mode.

Espero que funcione para usted esta vez, si no, hágamelo saber.



No puedo ayudar mucho ahora mismo. Tengo una fecha límite en dos días, 8- (- pero esto es lo que uso en mis .emacs para hacer que el modo lua sea utilizable para mí ...

(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?

He sangrado mi código de una manera inusual - vea el ejemplo a continuación - y así me he disciplinado solo presionando TAB cuando lua-mode puede inferir la sangría correcta de las líneas de arriba ...

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


Sé que ha pasado un tiempo desde que se solicitó esto, pero solo quería señalar que esto sigue siendo un problema, con el modo lua instalado a través del sistema de paquetes Emacs.

Sin embargo, la última versión en GitHub funciona muy bien, no notó ninguna extraña sangría. Todo lo que tienes que hacer para cumplir con la guía de estilo de Lua es establecer indent-tabs-mode en nil y lua-indent-level en 2 .


Si ingresa el siguiente código en el archivo .emacs en su directorio de inicio, hará que lua-mode (y solo lua-mode) se comporte de la siguiente manera:

  • Si presiona ENTER, se insertará una nueva línea y, de manera predeterminada, la siguiente línea se sangrará como la línea anterior.
  • Cuando presiona TAB para sangrar la línea, el punto o salta al primer carácter que no sea un espacio en blanco de la línea o, si la línea está vacía o el punto ya está en ese carácter, se insertan dos espacios.

Especialmente este último puede no ser lo que quieres, pero quizás es una primera aproximación.

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

Reinicie Emacs para que estos cambios surtan efecto.


Soy el mantenedor (pero no autor) de lua-mode.el. Como soy mucho menos fluido en Emacs Lisp que otros colaboradores de este hilo, doy la bienvenida a los parches. Solo quiero señalar que no hay nada extraño o incorrecto en las reglas predeterminadas: la idea, por lo que puedo ver, es simplemente que cuando estás en una función anónima, la sangría debe tomar la palabra clave de función como su margen izquierdo. Esto tiene sentido cuando considera usar expresiones de función en otros lugares, por ejemplo, como parámetros de función.

Por lo tanto, una solución simple no es escribir

local f = función ...

pero

función local f ...

A menos que esté trabajando con una versión de Lua anterior a la sintaxis de la "función local".

Habiendo dicho eso, puedo ver por qué es posible que desee sangrar de manera diferente. En este caso, me parece razonable tener una variable de configuración lua-indent-function-from-function-keyword (¿mejor nombre, alguien?), Y me complacería aceptar un parche que lo implementó.