Pon el nombre del archivo actual en el minibúfer

12

¿Cómo puedo insertar el nombre del archivo del búfer de archivo activo en un comando?

Cuando invoco un comando que necesita un nombre de archivo, a menudo lo hago desde un búfer de archivo y quiero el nombre de ese archivo mientras escribo el comando en el minibúfer.

Estoy buscando un hipotético C-xque pueda escribir durante la formación de una línea de comando en el minibúfer.

Entonces, si, mientras el búfer actual es un archivo llamado Lorem Ipsum.txt, escribo esto:

M-x grep RET 'foo' SPC C-x … RET

los M-xgrepRETpresentes un minibuffer solicita la greporden. En respuesta, escribí el argumento del patrón regex ( 'foo') e inserté el argumento del nombre de archivo ( C-x). Ese minibúfer terminará como:

grep -nH -e 'foo' 'Lorem Ipsum.txt'

¿Qué comando existente obtiene el nombre de archivo del búfer de archivo actual como este? ¿Cuál es su enlace de teclas predeterminado?

nariz grande
fuente
3
Me sorprende que nadie haya mencionado M-n. No funciona en todas partes, pero funciona en muchos lugares. Además, dado que estás haciendo grepping, es posible que te gusten lgrep y rgrep, que son un poco más interactivos, creo.
Malabarba

Respuestas:

18

¿Qué comando existente obtiene el nombre de archivo del búfer de archivo actual como este?

Desafortunadamente no hay un comando listo para esto, pero podemos hacer uno de la siguiente manera:

(defun name-of-the-file ()
  "Gets the name of the file the current buffer is based on."
  (interactive)
  (insert (buffer-file-name (window-buffer (minibuffer-selected-window)))))

La magia está en la función minibuffer-selected-window ; hace lo correcto al elegir el último búfer antes de activar el minibúfer. De lo contrario, usar solo el nombre de archivo del búfer no nos llevará el nombre de archivo al minibúfer. Curiosamente, la misma función se puede utilizar en un búfer regular o minibúfer para insertar el nombre del archivo. No se necesita un tratamiento especial.

¿Cuál es su enlace de teclas predeterminado?

No hay ninguno, pero puede elegir uno conveniente y asignarlo de la siguiente manera:

(global-set-key (kbd "C-c f") 'name-of-the-file)

Coloque las líneas de código lisp anteriores en su archivo init.el.

Esto funciona en la mayoría de los casos triviales, pero es difícil predecir qué conflictos podría tener con cualquier modo que tenga activo al invocar esta función.

¿Qué sucede si el búfer no visita un nombre de archivo válido, como el búfer de memoria virtual? Entonces este error se muestra en el área de eco:

name-of-the-file: Wrong type argument: char-or-string-p, nil

Elegir un búfer válido con un nombre de archivo adecuado antes de invocar el acceso directo evitará tales errores.

Hay varias otras soluciones como las anteriores, pero difieren principalmente en cómo manejan las excepciones o anulaciones para cualquier conflicto. Por ejemplo, algunos emplean ganchos de modo para que esta función esté disponible solo en ciertos modos.

Usuario de Emacs
fuente
Para que esto funcione, creo que uno debe hacerlo enable-recursive-minibuffers.
Dieter.Wilhelm
Si se supone que el comando solo se debe usar en el minibúfer, se puede usar el siguiente enlace en lugar de (define-key minibuffer-local-map (kbd "C-c f") 'name-of-the-file)'. In addition to this useful function I also created the function nombre-del-búfer 'al que lo enlacé para C-c bque inserte el nombre del búfer actual.
Dov Grobgeld
2

Cuando se utiliza dired-xel atajo de teclado C-x C-jestá vinculado dired-jump. Entonces, desde el búfer de su archivo, termina en la línea directa correcta y puede copiar su nombre de archivo con w. Y luego puedes pegarlo en el mini buffer.

Otra posibilidad para evitar escribir el nombre del archivo es la finalización estándar del mini archivo de memoria intermedia Emacs. Simplemente escriba los primeros caracteres de su nombre de archivo y luego TAB.

Dieter.Wilhelm
fuente
1
Puede copiar el nombre del archivo en la línea Dired actual simplemente usando w(comando dired-copy-filename-as-kill).
Dibujó el
-1

La pregunta solicita un comando Emacs existente para hacer esto.

Como se dijo anteriormente:

Desafortunadamente no hay un comando listo para esto

que resulta ser la respuesta a esta pregunta

nariz grande
fuente
Hay formas de aliviar su caso de uso y otras sugirieron soluciones de codificación a medida, por lo que creo que su declaración no es correcta. Usted no pidió específicamente para un out-of-the-box manera Emacs'!
Dieter.Wilhelm
Pedí específicamente un comando existente para ese propósito, así que sí, esta respuesta es correcta.
bignose el