Elisp pour appliquer la commande uniquement à la région sélectionnée

18

Dis, j'ai un code comme celui-ci:

(defun some-function ()
  (interactive)
  ;; do something
  )

Maintenant, je veux some-functionopérer uniquement sur la région sélectionnée dans le tampon? Comment puis je faire ça ? En outre, peut-il y avoir deux chemins de code distincts pour faire quelque chose si j'ai sélectionné une région et faire autre chose si je ne l'ai pas sélectionné.

Sibi
la source

Réponses:

22
(defun some-function (beginning end)
  (interactive "r")
  (if (use-region-p)
      (message "The region is active, and is from %d to %d" beginning end)
    (message "The region is still there (from % d to %d), but it is inactive" 
             beginning end)))

L'utilisation de (interactive "r")signifie que les paramètres beginninget endrecevront automatiquement les valeurs du début et de la fin de la région, respectivement, lorsque la fonction est invoquée. (Vous pouvez également obtenir ces valeurs à tout moment à l'aide des fonctions region-beginninget region-end, respectivement.)

La région est toujours présente (s'il y a une marque dans le tampon actuel), mais vous ne le pensez peut-être pas. La région est active lorsqu'elle est mise en surbrillance (le texte est sélectionné). Vous pouvez tester si la région est active à l'aide d'un prédicat region-active-p. Mais le meilleur test est généralement use-region-p, car (par défaut) il ne retourne vrai (non nil) que lorsque la région est à la fois active et non vide (le point et la marque sont différents).

À l'origine, il n'y avait pas de mise en évidence de la région. Et pendant longtemps, même si la mise en évidence était disponible, ce n'était pas le comportement par défaut. Pour que la mise en évidence se produise, vous devez avoir transient-mark-modeactivé (ou activé au moins temporairement). Par défaut, il transient-mark-modeest activé dans les versions récentes d'Emacs.

Il est utile de regarder la définition du prédicat use-region-p:

(defun use-region-p ()
  (and (region-active-p)
       (or use-empty-active-region
           (> (region-end) (region-beginning)))))

use-empty-active-regionest une option utilisateur, dont la valeur par défaut est nil(true), ce qui signifie que par défaut use-region-pne retournera pas true si la région est vide. Dans ce cas, pour qu'il revienne vrai, la fin de la région doit être supérieure au début (le comportement que j'ai décrit ci-dessus).

Et si nous regardons la définition de region-active-p:

(defun region-active-p ()
  (and transient-mark-mode
       mark-active
       (mark)))

Nous voyons qu'il retourne vrai (non nil) lorsque tous ces éléments sont vrais:

  • transient-mark-mode est activé.
  • La marque est active ( mark-active).
  • Il y a une marque dans le tampon actuel.

La marque d'être actif est vraiment ce qu'est la région active. Lorsqu'il est actif, en supposant qu'il est activé transient-mark-modeet qu'il y ait une marque dans le tampon actuel, la région est mise en surbrillance.

A dessiné
la source
AFAICS si la marque est définie sur point, c'est-à-dire que la région ne s'est pas étendue, la marque active est nulle. Donc, le mode marque active et le mode marque transitoire sont les seules choses qui ajoutent de la valeur à ces fonctions assez redondantes.
Andreas Röhler
1
@ AndreasRöhler: Non. C-SPC M-: mark-active=> t. Vous pouvez certainement avoir une région vide qui est néanmoins active.
Drew
D'accord merci. Toujours penser que mark-active et region-active-p - définis comme étendent un zéro supérieur - devraient être tous nécessaires.
Andreas Röhler