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-fC-SPC(지역 활성화) + C-f(탐색) 과 유사합니다 . C-f 먼저 영역이 비활성화 된 경우 비활성화 한 다음 래퍼 함수 에 바인딩 하여 원하는 것을 얻을 수 있습니다 C-f( forward-char). 에 C-S-f직접 바인딩 합니다 forward-char. 참고 적 터미널 모드에서 이맥스를 사용하는 경우 그 C-fC-S-f같은 모두 동작합니다 C-f터미널로이 둘 사이에 구별 할 수 없습니다.
Kaushal Modi

또한 래퍼와 바인딩은 C-f사용하는 다른 모든 탐색 명령에도 적용됩니다.
Kaushal Modi

btw C-fafter M-l는 끝 부분에 활성 영역이 없기 때문에 영역을 확장하지 않습니다 M-l( downcase-word기본적으로 바인딩 됨 ).
Kaushal Modi

1
@KaushalModi M-lOP에 의해 참조되는 것은 기본 바인딩 ( downcase-word)이 아니라my-mark-current-line
nispio

실제로 @nispio.
mikl

답변:


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형식의 cons 셀로 설정합니다 (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
둘 다 완벽하게 작동하고 오래된 것은 매우 유용합니다! 고마워요!
mikl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.