¿Cómo establecer marca en elisp y tener selección de turno?

9

El comportamiento normal de Emacs cuando el modo de marca transitoria está activo es que cuando realiza una selección de desplazamiento, si el siguiente comando es un movimiento sin desplazamiento, la marca se desactiva. Por ejemplo, después de los comandos M-l(para marcar la línea actual con la función a continuación) y C-f, la marca se desactiva. ¿Cómo emular ese comportamiento de elisp después (set-mark-command nil)?

Por ejemplo:

(defun my-mark-current-line ()
  (interactive)
  (beginning-of-line)
  (set-mark-command nil)
  (end-of-line)
  (forward-char))

(global-set-key (kbd "M-l") 'my-mark-current-line)

Ahora haga Ml Cf y la región crecerá, pero en cambio, quiero el comportamiento predeterminado, es decir, la región se desactivará cuando Cf y crecerá con CSf.

EDITAR : ¿debería usar una función diferente a set-mark-command que permita esto? No pude encontrar ninguno.

mikl
fuente
Creo que eso no es posible (y podría estar equivocado). Mientras una región esté activa, los comandos de navegación cambiarán la selección. La selección de desplazamiento usando C-S-fes análoga a C-SPC(activar una región) + C-f(navegación). Probablemente pueda obtener lo que desea vinculando C-f a una función de contenedor que primero desactiva una región si está activa y luego procede a hacer lo que C-fhace ( forward-char); y se unen C-S-fdirectamente a forward-char. Tenga en cuenta que si alguna vez usa emacs en modo terminal, C-fy C-S-fambos se comportarán ya C-fque el terminal no puede distinguir entre los dos.
Kaushal Modi
Además, el contenedor y el enlace que hizo C-fse aplicarán a todos los demás comandos de navegación que use también.
Kaushal Modi
por cierto, C-fdespués M-lno extiende la región porque no hay una región activa al final de M-l(que está vinculada downcase-wordde forma predeterminada).
Kaushal Modi
1
@KaushalModi Creo que el M-lreferido por el OP no es el enlace predeterminado ( downcase-word), sino el enlace personalizado demy-mark-current-line
nispio
de hecho @nispio.
mikl

Respuestas:

8

Debido a que la traducción de turno y la activación temporal de la marca se manejan mediante el bucle de comando, deberá llamar a las versiones interactivas de las funciones de movimiento para obtener el comportamiento de selección de turno adecuado de ellas:

;; (source: http://emacs.stackexchange.com/a/22166/93)
(defun my-mark-current-line ()
  (interactive)
  (beginning-of-line)
  (setq this-command-keys-shift-translated t)
  (call-interactively 'end-of-line)
  (call-interactively 'forward-char))

(global-set-key (kbd "M-l") 'my-mark-current-line)

Actualizar:

Desde que escribí la respuesta anterior, me tomé el tiempo para aprender un poco más sobre cómo la selección de turnos realmente funciona bajo el capó. Establece el valor del símbolo de transient-mark-modeser una celda de contras del formulario (only . OLDVAL), donde OLDVALes el valor antes de la selección de turno.

La solución a continuación evita el uso call-interactivelyactivando la marca según sea necesario y estableciendo el valor apropiado de transient-mark-mode. Básicamente, considero que esta solución es menos pirata que la primera.

Como beneficio adicional, ahora tiene un recuento de repetición opcional y ampliará la selección actual en cualquier dirección si la marca ya está activa.

;; (source: http://emacs.stackexchange.com/a/22166/93)
(defun my-mark-current-line (&optional arg)
  "Uses shift selection to select the current line.
When there is an existing shift selection, extends the selection
in the appropriate direction to include current line."
  (interactive "p")
  (let ((oldval (or (cdr-safe transient-mark-mode) transient-mark-mode))
        (backwards (and mark-active (> (mark) (point))))
        (beg (and mark-active (mark-marker))))
    (unless beg
      (if backwards (end-of-line) (beginning-of-line))
      (setq beg (point-marker)))
    (if backwards (end-of-line (- 1 arg)) (beginning-of-line (+ 1 arg)))
    (unless mark-active
      (push-mark beg nil t))
    (setq transient-mark-mode (cons 'only oldval))))
nispio
fuente
1
¡Ambos funcionan perfectamente y lo viejo es muy útil! ¡muchas gracias!
mikl