Come impostare mark in elisp e avere la selezione dei turni?


9

Il comportamento normale di Emacs quando è attiva la modalità contrassegno transitorio è che quando si effettua una selezione a turni, quindi se il comando successivo è un movimento non a turni, il contrassegno viene disattivato. Ad esempio, dopo i comandi M-l(per contrassegnare la riga corrente con la funzione seguente) e C-f, il segno è disattivato. Come emulare quel comportamento da elisp after (set-mark-command nil)?

Per esempio:

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

Ora ml Cf e la regione crescerà, ma invece voglio il comportamento predefinito, ovvero la regione che si disattiva quando Cf, e cresce con CSf.

EDIT : dovrebbe usare una funzione diversa da set-mark-command che lo consente? Non ne ho trovato nessuno.


Credo che non sia possibile (e potrei sbagliarmi). Finché una regione è attiva, i comandi di navigazione cambieranno la selezione. La selezione del turno usando C-S-fè analoga a C-SPC(attivazione di una regione) + C-f(navigazione). Probabilmente puoi ottenere quello che vuoi legando C-f a una funzione wrapper che disattiva prima una regione se attiva e quindi procede a fare ciò che C-ffa ( forward-char); e si legano C-S-fdirettamente a forward-char. Nota che se mai usi emacs in modalità terminale, C-fe C-S-fti comporterai entrambi come C-fse il terminale non fosse in grado di distinguere tra i due.
Kaushal Modi,

Anche il wrapper e l'associazione che hai fatto C-fsi applicheranno anche a tutti gli altri comandi di navigazione che usi.
Kaushal Modi,

btw C-fafter M-lnon estende la regione perché non esiste una regione attiva alla fine di M-l(che è vincolata per downcase-wordimpostazione predefinita).
Kaushal Modi,

1
@KaushalModi Penso che il M-lcitato dall'OP non sia l'associazione predefinita ( downcase-word), ma l'associazione personalizzata dimy-mark-current-line
nispio

anzi @nispio.
mikl,

Risposte:


8

Poiché la traduzione dei turni e l'attivazione temporanea del segno sono gestite dal ciclo di comando, sarà necessario chiamare le versioni interattive delle funzioni di movimento per ottenere da esse il comportamento di selezione dei turni appropriato:

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

Aggiornare:

Da quando ho scritto la risposta sopra, mi sono preso il tempo di imparare un po 'di più su come la selezione dei turni funziona davvero sotto il cofano. Imposta il valore del simbolo transient-mark-modecome cella di contro del modulo (only . OLDVAL), dove OLDVALè il valore prima di spostare la selezione.

La soluzione seguente evita l'uso call-interactivelyattivando il segno secondo necessità e impostando il valore appropriato di transient-mark-mode. Fondamentalmente, considero questa soluzione meno di un hack rispetto alla prima.

Come bonus, ora ha un conteggio delle ripetizioni opzionale e estenderà la selezione corrente in entrambe le direzioni se il segno è già attivo.

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

1
Entrambi funzionano perfettamente e la cosa oldval è molto utile! molte grazie!
mikl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.