Emacs: elimina espacios en blanco o una palabra

¿Cómo puedo configurar emacs para que funcionen de la misma manera que otros editores modernos donde al presionar Alt + D o Alt + Retroceso se eliminan los espacios en blanco adyacentes o una sola palabra? Por defecto, emacs siempre borra una palabra.

A lo largo de algún tiempo de uso de Emacs, pensé que aunque podía alterar la funcionalidad básica, por lo general no compensaba mucho en términos de eficiencia. De hecho, después de hacerlo varias veces, me arrepentí y lo deshice. Esto no es verdad todo el tiempo, algunas combinaciones de teclas son realmente incómodas o raramente útiles, pero no creo que este sea el caso de cómo funciona la palabra matar. De hecho, me acabo de dar cuenta de que: intenté enlazar con la clave en Eclipse, pero lo he estado utilizando con combinaciones de estilo Emacs desde siempre …

De todos modos, como acabo de decir, antes de que “arregles” esa funcionalidad, asegúrate de que esté realmente rota 🙂 Nunca me encuentro necesitando el tipo de función que describes, y tal vez por eso:

  1. M-SPC reduce el espacio entre palabras a solo un espacio. Esto es lo que habría usado si el punto estuviera entre las palabras y quisiera eliminar el espacio adicional que separa las palabras.

  2. M- \ elimina todo el espacio horizontal. Esto unirá dos palabras separadas por espacio.

  3. Si lo que intentas lograr es algún tipo de formateo “escaso”, como en:


 int foo = 42; unsigned int bar = 43; 

luego está Mx align-regexp para hacer eso.

  1. Nunca sucede que tenga a) largas ejecuciones consecutivas de whitepsace, a menos que sea la sangría, y en el caso de que sea la sangría, TAB generalmente lo maneja mejor. b) incluso si hay largas tiradas consecuentes de espacios en blanco, raramente muevo el punto de a un personaje a la vez, por lo que es difícil pensar en una situación en la que encontraría el punto rodeado de varios espacios en blanco. Cosas como el modo de artista, o diagtwigs de puntos vienen a la mente, pero no sucede durante la edición del código.

  2. Finalmente, si intentas, bueno, digamos que solo editas un archivo de texto arbitrario y quieres agregar o eliminar espacio horizontal entre palabras … De nuevo, hay Mx align-regexp para hacer eso, o podrías usar comandos que operan en rectangularjs, si son varias líneas en el momento. Bueno, Emacs incluso reconocerá las tabs ad hoc e intentará alinear el texto para que coincida con la última línea antes del punto, cuando toques TAB .

Finalmente, si por alguna razón no puedo entender 🙂 Realmente necesitaba hacer exactamente lo que describes, entonces lo haría así: k M- \ RETROCESO (puede ser cualquier otra tecla en lugar de “k” – es justo debajo de tu dedo, así que es rápido escribir 🙂 O, si soy flojo para pensarlo: M-SPC Mf Mb Cw – tal vez suene como mucho, pero estos son los comandos que usarías todos los tiempo de todos modos, por lo que no te impide en términos de velocidad.

 (defvar movement-syntax-table (let ((st (make-syntax-table))) ;; ` default = punctuation ;; ' default = punctuation ;; , default = punctuation ;; ; default = punctuation (modify-syntax-entry ?{ "." st) ;; { = punctuation (modify-syntax-entry ?} "." st) ;; } = punctuation (modify-syntax-entry ?\" "." st) ;; " = punctuation (modify-syntax-entry ?\\ "_" st) ;; \ = symbol (modify-syntax-entry ?\$ "_" st) ;; $ = symbol (modify-syntax-entry ?\% "_" st) ;; % = symbol st) "Syntax table used while executing custom movement functions.") (defun delete-word-or-whitespace (&optional arg) "http://stackoverflow.com/a/20456861/2112489" (interactive "P") (with-syntax-table movement-syntax-table (let* ( beg end (word-regexp "\\sw") (punctuation-regexp "\\s.") (symbol-regexp "\\s_\\|\\s(\\|\\s)")) (cond ;; Condition # 1 ;; right of cursor = word or punctuation or symbol ((or (save-excursion (< 0 (skip-syntax-forward "w"))) (save-excursion (< 0 (skip-syntax-forward "."))) (save-excursion (< 0 (skip-syntax-forward "_()")))) ;; Condition #1 -- Step 1 of 2 (cond ;; right of cursor = word ((save-excursion (< 0 (skip-syntax-forward "w"))) (skip-syntax-forward "w") (setq end (point)) (while (looking-back word-regexp) (backward-char)) (setq beg (point)) (delete-region beg end)) ;; right of cursor = punctuation ((save-excursion (< 0 (skip-syntax-forward "."))) (skip-syntax-forward ".") (setq end (point)) (while (looking-back punctuation-regexp) (backward-char)) (setq beg (point)) (delete-region beg end)) ;; right of cursor = symbol ((save-excursion (< 0 (skip-syntax-forward "_()"))) (skip-syntax-forward "_()") (setq end (point)) (while (looking-back symbol-regexp) (backward-char)) (setq beg (point)) (delete-region beg end))) ;; Condition #1 -- Step 2 of 2 (cond ;; right of cursor = whitespace ;; left of cursor = not word / not symbol / not punctuation = whitespace or bol ((and (save-excursion (< 0 (skip-chars-forward "\s\t"))) (not (save-excursion (> 0 (skip-syntax-backward "w")))) (not (save-excursion (> 0 (skip-syntax-backward ".")))) (not (save-excursion (> 0 (skip-syntax-backward "_()"))))) (setq beg (point)) (skip-chars-forward "\s\t") (setq end (point)) (delete-region beg end)) ;; right of cursor = whitespace ;; left of cursor = word or symbol or punctuation ((and (save-excursion (< 0 (skip-chars-forward "\s\t"))) (or (save-excursion (> 0 (skip-syntax-backward "w"))) (save-excursion (> 0 (skip-syntax-backward "."))) (save-excursion (> 0 (skip-syntax-backward "_()"))))) (fixup-whitespace)))) ;; Condition # 2 ;; right of cursor = whitespace ;; left of cursor = bol | left of cursor = whitespace | right of cursor = whitespace + eol ((and (save-excursion (< 0 (skip-chars-forward "\s\t"))) (or (bolp) (save-excursion (> 0 (skip-chars-backward "\s\t"))) (save-excursion (< 0 (skip-chars-forward "\s\t")) (eolp)))) (setq beg (point)) (skip-chars-forward "\s\t") (setq end (point)) (delete-region beg end)) ;; Condition # 3 ;; right of cursor = whitespace or eol ;; left of cursor = word or symbol or punctuation ;; not bol + word or symbol or punctuation ;; not bol + whitespace + word or symbol or punctuation ((and (or (save-excursion (< 0 (skip-chars-forward "\s\t"))) (eolp)) (or (save-excursion (> 0 (skip-syntax-backward "w"))) (save-excursion (> 0 (skip-syntax-backward "."))) (save-excursion (> 0 (skip-syntax-backward "_()")))) (not (save-excursion (> 0 (skip-syntax-backward "w")) (bolp))) (not (save-excursion (> 0 (skip-syntax-backward ".")) (bolp))) (not (save-excursion (> 0 (skip-syntax-backward "_()")) (bolp))) (not (save-excursion (and (> 0 (skip-syntax-backward "w")) (> 0 (skip-chars-backward "\s\t")) (bolp)))) (not (save-excursion (and (> 0 (skip-syntax-backward ".")) (> 0 (skip-chars-backward "\s\t")) (bolp)))) (not (save-excursion (and (> 0 (skip-syntax-backward "_()")) (> 0 (skip-chars-backward "\s\t")) (bolp))))) (setq end (point)) (cond ((save-excursion (> 0 (skip-syntax-backward "w"))) (while (looking-back word-regexp) (backward-char))) ((save-excursion (> 0 (skip-syntax-backward "."))) (while (looking-back punctuation-regexp) (backward-char))) ((save-excursion (> 0 (skip-syntax-backward "_()"))) (while (looking-back symbol-regexp) (backward-char)))) (setq beg (point)) (when (save-excursion (> 0 (skip-chars-backward "\s\t"))) (skip-chars-backward "\s\t") (setq beg (point))) (delete-region beg end) (skip-chars-forward "\s\t")) ;; Condition # 4 ;; not bol = eol ;; left of cursor = bol + word or symbol or punctuation | bol + whitespace + word or symbol or punctuation ((and (not (and (bolp) (eolp))) (or (save-excursion (> 0 (skip-syntax-backward "w")) (bolp)) (save-excursion (> 0 (skip-syntax-backward ".")) (bolp)) (save-excursion (> 0 (skip-syntax-backward "_()")) (bolp)) (save-excursion (and (> 0 (skip-syntax-backward "w")) (> 0 (skip-chars-backward "\s\t")) (bolp))) (save-excursion (and (> 0 (skip-syntax-backward ".")) (> 0 (skip-chars-backward "\s\t")) (bolp))) (save-excursion (and (> 0 (skip-syntax-backward "_()")) (> 0 (skip-chars-backward "\s\t")) (bolp))))) (skip-chars-forward "\s\t") (setq end (point)) (setq beg (point-at-bol)) (delete-region beg end)) ;; Condition # 5 ;; point = eol ;; not an empty line ;; whitespace to the left of eol ((and (not (and (bolp) (eolp))) (eolp) (save-excursion (> 0 (skip-chars-backward "\s\t")))) (setq end (point)) (skip-chars-backward "\s\t") (setq beg (point)) (delete-region beg end)) ;; Condition # 6 ;; point = not eob ;; point = bolp and eolp ;; universal argument = Cu = '(4) ((and (not (eobp)) (and (bolp) (eolp)) (equal arg '(4))) (delete-forward-char 1))) ))) 

Esto probablemente se haya resuelto antes, pero en lugar de buscar el código, podemos escribir el nuestro. ¡Muy divertido!

Así es como lo haría, espero que ayude.

 (defun kill-whitespace-or-word () (interactive) (if (looking-at "[ \t\n]") (let ((p (point))) (re-search-forward "[^ \t\n]" nil :no-error) (backward-char) (kill-region p (point))) (kill-word 1))) 

A continuación, vincúlalo a una clave:

 (global-set-key (kbd "Md") 'kill-whitespace-or-word) 

Si está utilizando un búfer basado en CC-Mode, probablemente esté buscando el Hungry Delete Mode menor de Hungry Delete Mode .

Pruebe Cc DEL y Cc DELETE en varios lugares para hacerse una idea de la diferencia.

Si le gusta la forma en que funciona, puede alternar la eliminación hambrienta para trabajar con las claves estándar haciendo Mx c-toggle-hungry-state o simplemente vuelva a enlazar las funciones de eliminación hambrientas con su encuadernación preferida.

Si todavía crees que necesitas utilizar una de las teclas para hacer avanzar la palabra o el espacio en blanco, puedes hacer algo similar a c-hungry-delete-forward , o simplemente re c-delete-function vincular temporalmente la función c-delete-function y llamarlo.

 (defun c-hungry-delete-forward-word () "Delete the following word or all following whitespace up to the next non-whitespace character. See also \\[c-hungry-delete-backwards]." (interactive) (let ((c-delete-function (function kill-word))) (c-hungry-delete-forward))) 

Echa un vistazo a la página de información (ccmode) Hungry WS Deletion para más.