2010-11-12 15 views
23

Por favor, ayudarme a configurar sangrado adecuado en Haskell en modo EmacsEmacs Haskell muesca

Cuando estoy tratando de escribir algo así como hacia abajo ADT o un registro, me estoy poniendo en la columna equivocada después de pulsar <ENTER>, y presionando <TAB>no cambie a la derecha hasta que ingrese | o ';'!

data MyADT = Oh 
      | Hi 
      | Hello 
      | <- the cursor is here again! 

Tratando de resolver el problema que establecer

(define-key global-map (kbd "RET") 'reindent-then-newline-and-indent) 

en mi archivo .emacs, pero no va a sangrar la línea actual al pulsar <enter> también!

Otro comportamiento extraño: sangría del caso

oneChar c = case lookup c simpleEscapes of 
    | <- what? here?! 
+1

El caso 'case' es el comportamiento correcto. – jrockway

+1

Si presiona tab dos veces, inserta un '|' en la sangría correcta. – edon

+0

si todavía no hay '|', no es así. Así que tengo que escribir algo en la línea antes de presionar la pestaña –

Respuesta

3

Comenté la línea

;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) 

y ahora estoy haciendo un buen comportamiento "pestaña": por lo menos, que me permite elegir una columna y no me ata a la que le gusta. Pero no auto-guión en absoluto me molesta un poco, así que estoy esperando es una solución temporal

9

Suena como que escribe <Enter> y luego "|" y luego <Tab>. Si hago eso, obtengo los mismos resultados. Pero si escribo <Enter> y luego <Tab> y luego <Tab> vez más inserta automáticamente el "|" y líneas él para arriba correctamente, así:

data MyADT = Oh 
      | Hi 
      |<Cursor> 

Cuando compruebo mi versión en modo Haskell usando M-x eval-expression haskell-version <Enter> me sale "v2_4" .

Emacs haskell-mode no analiza completamente el código fuente, por lo que las características "automáticas" son aproximadas, creo. Escribir <Tab> varias veces en una nueva línea recorre varias posibles sangrías, y también a veces inserta texto como "|" para tipos de datos algebraicos.

4

Advertencia: No soy un usuario de Haskell, así que tome esto con un grano de sal.

Al pulsar RET después de la Hello, Emacs no sabe que va a añadir un | (quick search muestra puede tener otros símbolos). La gente de Haskell ha considerado que la sangría correcta se alineará directamente debajo del H en Hello. Si la sangría se alineara automáticamente con el | en la línea superior, entonces todos los casos en los que no se escriba un | dará como resultado una indentación incorrecta. Maldito si lo haces, maldito si no lo haces ...

Otros modos de programación (C/C++, Lisp, Tcl, ...) tienen el mismo problema: no pueden saber con anticipación a qué te diriges. para poner en la siguiente línea, para que la sangría no sea lo que esperabas.

Una solución es usar las claves "electric", es decir que insertan caracteres y también fuerzan la redención. Usted podría definir fácilmente | a ser eléctrico con el siguiente código:

(defun haskell-electric-|() 
    "it's electric! (insert | and indent as long as the | follows whitespace)" 
    (interactive) 
    (insert "|") 
    (if (string-match-p "^\\s-*|" (buffer-substring (line-beginning-position) 
                (point))) 
     (haskell-indentation-indent-line))) 
(define-key haskell-mode-map "|" 'haskell-electric-|) 

he añadido una comprobación para asegurarse de que el | insertada está precedido por un sólo espacio en blanco, puede personalizar cualquiera que quieran o quite la marca por completo.

Supongo que también podría haber otros símbolos en Haskell que valdría la pena hacer eléctricos.