elispにマークを設定し、シフトを選択するにはどうすればよいですか?


9

トランジェントマークモードがアクティブなときのEmacsの通常の動作は、シフト選択を行うと、次のコマンドが非シフト移動の場合、マークが非アクティブ化されることです。たとえば、コマンドM-l(現在の行を以下の関数でC-fマークする)との後、マークは無効になります。後にelispからその動作をエミュレートするにはどうすればよい(set-mark-command nil)ですか?

例えば:

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

ここでMl Cfを実行すると、領域が拡大しますが、代わりにデフォルトの動作、つまりCfのときに領域を非アクティブ化し、CSfで拡大します。

編集:これを可能にするset-mark-commandとは異なる関数を使用する必要がありますか?何も見つかりませんでした。


私はそれは不可能だと信じています(そして私は間違っているかもしれません)。リージョンがアクティブである限り、ナビゲーションコマンドは選択を変更します。を使用したシフト選択C-S-fは、C-SPC(領域のアクティブ化)+ C-f(ナビゲーション)に類似しています。おそらくC-f 、アクティブな場合は最初に領域を非アクティブ化し、次に何をするかを続行するラッパー関数にバインドすることで、必要なものを取得できますC-fforward-char); にC-S-f直接バインドしforward-charます。注あなたはターミナルモードではemacsを使用し、その場合C-fC-S-fの両方動作しますC-f端末としては、2つを区別することはできません。
Kaushal Modi

また、実行したラッパーとバインディングは、C-f使用する他のすべてのナビゲーションコマンドにも適用されます。
Kaushal Modi、

btw C-fafter M-lは、末尾にアクティブなリージョンがないため、リージョンを拡張しませんM-ldowncase-wordデフォルトでバインドされています)。
Kaushal Modi

1
私はと思い@KaushalModi M-lOPによって参照すること(結合デフォルトではありませんdowncase-word)が、結合のカスタムmy-mark-current-line
nispio

確かに@nispio。
mikl 2016年

回答:


8

シフトの移動とマークの一時的なアクティブ化はコマンドループによって処理されるため、移動機能のインタラクティブバージョンを呼び出して、適切なシフト選択動作を取得する必要があります。

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

更新:

上記の回答を書いてから、シフト選択が実際にどのように機能するかについて少し時間をかけて学びました。のシンボル値をtransient-mark-modeの形式のコンスセルに設定します(only . OLDVAL)。ここで、OLDVALはシフト選択前の値です。

以下の解決策では、call-interactively必要に応じてマークをアクティブにし、適切な値をに設定することで、の使用を回避していますtransient-mark-mode。基本的に、私はこの解決策は最初の解決策よりもハックが少ないと考えています。

おまけとして、オプションのリピートカウントが追加され、マークがすでにアクティブになっている場合は、現在の選択がいずれかの方向に拡張されます。

;; (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
どちらも完全に機能し、oldvalは非常に便利です!どうもありがとう!
mikl 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.