최소한의 키 입력으로 현재 줄을 죽이거나 복사


32

나는 C-a C-k C-k전체 라인 포인트가 죽이고 있습니다.

줄을 죽이지 않고 복사 하고 싶다면 C-/ C-/ 위의 순서를 입력 한 후 바로 칠 수 있습니다 .

또는 할 수 있습니다 C-a C-SPC C-n M-w.

전체 라인 포인트가 켜져 있거나 복사하는 더 빠른 방법이 있습니까?


1
와우! 이 답변은 사람들이 내장 사용을 피하기 위해 갈 길이 멀다는 것을 보여줍니다 kill-whole-line. :)
Omar

아래 제안 된대로을 사용하십시오 evil-mode. Vim 명령을 배우면 후회하지 않을 것입니다!
A. 블리자드

답변:


44

당신은 kill-whole-line전체 라인 포인트가 켜져 죽일 수 있습니다 . 포인트의 위치는 중요하지 않습니다. 이 명령은 C-S-DEL기본적으로 바인딩되어 있습니다.

변수 를 값 이 아닌 값 으로 설정하여 전체 줄을 강제 종료 kill-line하도록 지시 할 수도 있습니다 ( C-k) . kill-whole-linenil

(setq kill-whole-line t)

이것이 작동하려면 지점이 줄의 시작 부분에 있어야합니다.


그런 다음 emacs-fu 를 통해 다음 두 가지 보석 이 있습니다 .

(defadvice kill-region (before slick-cut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-beginning-position 2)))))

(defadvice kill-ring-save (before slick-copy activate compile)
  "When called interactively with no active region, copy a single line instead."
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position) (line-beginning-position 2)))))

이것들을 사용하면 한 번의 키 입력으로 라인 포인트를 죽이거나 복사 할 수 있습니다 .

  • C-w 현재 줄을 죽인다
  • M-w 현재 줄을 복사

활성 영역이 kill-region있고 kill-ring-save정상적으로 수행하는 작업이 계속 진행되는 경우 : 죽이거나 복사하십시오.


포팅 slick-cutslick-copy새로운 조언 시스템

Emacs 24.4는 새로운 조언 시스템을 도입했습니다 . defadvice 여전히 작동 하지만 향후 버전의 Emacs에서는 새로운 시스템을 위해 사용되지 않을 가능성이 있습니다. 그 준비하려면 업데이트 된 버전의 사용 할 수 있습니다 slick-cutslick-copy:

(defun slick-cut (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-beginning-position 2)))))

(advice-add 'kill-region :before #'slick-cut)

(defun slick-copy (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position) (line-beginning-position 2)))))

(advice-add 'kill-ring-save :before #'slick-copy)

2
참고 그 kill-regionkill-ring-save계속 작업 영역이 아닙니다 경우에도 "활성." 이는 해당 동작을 무시합니다. 나는 때때로 그 행동을 사용하지만, 당신이 이런 식으로 사용하는 데 익숙하지 않다면 아마도 그 차이를 알지 못할 것입니다.
nispio

@nispio 때 / 방법에 확장하십시오 kill-region사용할 수 등 / 유용 할 때 mark-active입니다 nil.
Phil Hudson

1
@PhilHudson 마크를 활성화하지 않고 설정할 수 있습니다. C-SPC마크를 활성화 한 다음 비활성화하려면 두 번 시도하십시오 . 커서를 파일의 다른 곳으로 이동하고 실행 kill-region하면 마크가 활성화되어 있지 않더라도 포인트와 마크 사이의 영역이 종료됩니다. 마크를 설정 (하지만 활성화하지는 않음)하는 명령의 몇 가지 예는 yankisearch입니다. 이러한 정렬 명령을 수행 한 후에는 마크가 활성화되어 있지 않더라도 마크가 어디에 있는지 알고 있으며,를 포함한 많은 명령을 kill-region사용하면 마크를 명시 적으로 활성화하지 않고 마크를 사용할 수 있습니다.
nispio

감사합니다 @nispio. 당연하지. 이것이 가시 영역 강조 표시가 기본 릴리스가되기 전에 독점적으로 사용되었던 방식이었습니다. "active"와 "set"을 혼동하고있었습니다.
Phil Hudson

1
이것은 SX에 게시 된 최고의 답변입니다. 진심으로.
Benjamin Lindqvist

15

내가 찾은 해결책 은 접두사 인수를 사용 하는 것 입니다.

나에게 한 줄을 죽이는 것이 유용한 기능이지만 전체 줄을 더 쉽게 죽일 수있는 방법을 원합니다. 그래서 나는 kill-line접두사 인수가 주어질 때 모든 것을 눈에 띄게 살해 하도록 만들었습니다 .

(defmacro bol-with-prefix (function)
  "Define a new function which calls FUNCTION.
Except it moves to beginning of line before calling FUNCTION when
called with a prefix argument. The FUNCTION still receives the
prefix argument."
  (let ((name (intern (format "endless/%s-BOL" function))))
    `(progn
       (defun ,name (p)
         ,(format 
           "Call `%s', but move to BOL when called with a prefix argument."
           function)
         (interactive "P")
         (when p
           (forward-line 0))
         (call-interactively ',function))
       ',name)))

(global-set-key [remap paredit-kill] (bol-with-prefix paredit-kill))
(global-set-key [remap org-kill-line] (bol-with-prefix org-kill-line))
(global-set-key [remap kill-line] (bol-with-prefix kill-line))
(global-set-key "\C-k" (bol-with-prefix kill-line))

이 작은 매크로를 사용하면 C-k여전히 지점에서 죽이지 만 C-3 C-k세 줄을 모두 삼 킵니다 . 보너스로, 우리는 kill-whole-line행동을 통해 행동을 얻습니다 C-1 C-k.


공유해 주셔서 감사합니다. :) 하나 이상의 행을 복사하기 위해이 솔루션을 어떻게 적용 하시겠습니까? kill-ring-save접두사 인수를 허용하지 않습니다 ...
itsjeyd

@itsjeyd 두 답변을 병합하기 위해 비슷한 것을 할 수 있다고 확신합니다. 그러나 조금 더 많은 작업이 필요합니다.
Malabarba

마지막 줄은 paredit-kill을 나타냅니다. 의도 된 것입니까?
Boccaperta-IT 2013

1
오, 고마워 그래도 예상되는 동작을 얻지 못했습니다. 줄 중간에 포인터를 놓고 C-3 Ck를 누르면 첫 번째 줄이 완전히 종료되지는 않습니다. 이것이 작동하는 방식입니까 아니면 내가 잘못하고 있습니까?
Boccaperta-IT 2013

1
@Malabarba 당신이 맞아, kill-visual-line에 바인딩됩니다 C-k. 내가 고칠 게 다시 감사합니다.
Boccaperta-IT 2014

15

whole-line-or-region지역이 활성화되어 있지 않은 경우 현재 라인에서 작동하도록 다양한 내장 명령을 알려주 는 패키지 가 있습니다. 예를 들어 M-w현재 라인을 복사하여 C-w죽일 수 있습니다. 나는 수년간 패키지를 사용해 왔으며 필수 불가결 한 것을 발견했습니다.

또한이 패키지는 숫자 접두어가 실행할 행 수를 나타내므로 M-2 M-w두 행을 복사합니다. 다른 답변은 편리한 기능을 제공하지 않습니다.

작성자가 패키지 유지 관리를 중단하고 응답하지 않을 때 github 계정에서 패키지 유지 관리를 담당했습니다.

whole-line-or-region 필요한 경우이 명령을 추가 명령에 추가 할 수있는 기능도 제공합니다.


무슨 의미인지 잘 모르겠 기 때문에 MELPA 문제를 제기하십시오.이 패키지는 문제없이 항상 MELPA에서 설치합니다.
sanityinc

9

이것은 정통 이맥스에 대한 답변이 아닙니다. 그러나 evil의 모달 편집 으로 모독하려는 경우 다음을 수행 할 수 있습니다.

  • dd 킬 라인
  • cc 복사 라인

둘 다 킬 / 복사 할 행 수를 앞에 붙일 수 있습니다 (예 : 4cc다음 4 행을 복사합니다).


5

@itsjeyd 답변 외에도 두 가지 기능을 제안해도 될까요?

(defun xah-copy-line-or-region ()
  "Copy current line, or text selection.
When `universal-argument' is called first, copy whole buffer (but respect `narrow-to-region')."
  (interactive)
  (let (p1 p2)
    (if (null current-prefix-arg)
        (progn (if (use-region-p)
                   (progn (setq p1 (region-beginning))
                          (setq p2 (region-end)))
                 (progn (setq p1 (line-beginning-position))
                        (setq p2 (line-end-position)))))
      (progn (setq p1 (point-min))
             (setq p2 (point-max))))
    (kill-ring-save p1 p2)))

(defun xah-cut-line-or-region ()
  "Cut current line, or text selection.
When `universal-argument' is called first, cut whole buffer (but respect `narrow-to-region')."
  (interactive)
  (let (p1 p2)
    (if (null current-prefix-arg)
        (progn (if (use-region-p)
                   (progn (setq p1 (region-beginning))
                          (setq p2 (region-end)))
                 (progn (setq p1 (line-beginning-position))
                        (setq p2 (line-beginning-position 2)))))
      (progn (setq p1 (point-min))
             (setq p2 (point-max))))
    (kill-region p1 p2)))

그런 다음 주요 정의 (아마도 조정하고 싶을 것입니다) :

(global-set-key (kbd "<f2>") 'xah-cut-line-or-region) ; cut

(global-set-key (kbd "<f3>") 'xah-copy-line-or-region) ; copy

(global-set-key (kbd "<f4>") 'yank) ; paste

Ergo의 의례


답변 주셔서 감사합니다! 이 명령이 여기에 게시 된 다른 솔루션과 어떻게 다른지 설명하여 약간 확장하는 것이 좋습니다. 예,이 정보가 문서화 문자열에서 사용할 수 있지만 미래의 독자들에게 더 볼 수 있도록 할 다치게하지 않습니다 :)
itsjeyd

1
이 작업을 수행 할 수는 있지만 아래 @Jonathan 게시물과 같이 수정하여 먼저 sexp 또는 단어를 취한 다음 다시 호출하면 라인을 가져옵니다.
J Spen

@ JSpen 내가하고있는 일은 바로 가기 키를 기능에 할당하는 것입니다. Jonathan이하는 일은 함수에 대한 조언을 정의하는 것입니다. 따라서 기능에 조언을 한 다음 조언 기능에 대한 바로 가기 키를 정의 할 수 있습니다. 결과가 나옵니다. 지연 죄송합니다;)
Nsukami _

4

위의 @itsjeyd 답변에 대한 확장으로 다음과 같은 내용이 있습니다. (논리는 아마 약간 정리 될 수있는 내가 새로운 상담 시스템 포트, I 가능성 또한으로 확장하는 확장거야 언제 sexp/ paragraph다시 반복되는 경우).

이니셜 C-w/ M-w는 특정 시점의 단어 만 잡고, 두 번째로 호출하면 전체 줄을 잡습니다.

;; *** Copy word/line without selecting
(defadvice kill-ring-save (before slick-copy-line activate compile)
  "When called interactively with no region, copy the word or line

Calling it once without a region will copy the current word.
Calling it a second time will copy the current line."
    (interactive
     (if mark-active (list (region-beginning) (region-end))
       (if (eq last-command 'kill-ring-save)
           (progn
             ;; Uncomment to only keep the line in the kill ring
             ;; (kill-new "" t)
             (message "Copied line")
             (list (line-beginning-position)
                   (line-beginning-position 2)))
         (save-excursion
           (forward-char)
           (backward-word)
           (mark-word)
           (message "Copied word")
           (list (mark) (point)))))))

;; *** Kill word/line without selecting
(defadvice kill-region (before slick-cut-line first activate compile)
  "When called interactively kill the current word or line.

Calling it once without a region will kill the current word.
Calling it a second time will kill the current line."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
    (if (eq last-command 'kill-region)
        (progn
          ;; Return the previous kill to rebuild the line
          (yank)
          ;; Add a blank kill, otherwise the word gets appended.
          ;; Change to (kill-new "" t) to remove the word and only
          ;; keep the whole line.
          (kill-new "")
          (message "Killed Line")
          (list (line-beginning-position)
                (line-beginning-position 2)))
      (save-excursion
        (forward-char)
        (backward-word)
        (mark-word)
        (message "Killed Word")
        (list (mark) (point)))))))

이것을 업데이트 했습니까? 그렇다면 사본이 어디에 있습니까? 또한 마크 링에 많은 마크가 추가됩니다. 복사 시작 부분에 마크 하나만 추가 할 수 있습니까? 단어의 시작이나 줄의 시작입니다. 이제는 매번 네 개의 마크를 추가하여 성가시다. 실제로 (역방향으로) 사용하도록 변경했지만 때로는 찾을 수 없어 오류가 발생합니다. 줄을 찾지 못하면 그냥 복사 할 수 있습니까? 이 작업을 수행하는 방법을 모르거나 오류를 무시하고 소음을 내지 않습니다. 죄송합니다, lisp에서 최고가 아닙니다.
J Spen

1

최소한의 키 입력만으로 작업하고 싶기 때문에 David Andersson의 탁월한 키 코드 패키지를 사용할 수 있습니다 . "키 코드"는 두 개의 키를 동시에 누르거나 한 키를 두 번 누르는 것입니다.

모든 키 코드를 해당 기능에 바인딩 할 수 있습니다.

(require 'key-chord)
(key-chord-mode 1)
(key-chord-define-global "dd"  'kill-whole-line)
(key-chord-define-global "cc"  'yank-whole-line)

대답 해 주셔서 감사합니다 :) 과거에 주요 코드를 두 번 시도했지만 실제로 익숙해지지 못했습니다. 그러나 여기에 답변이 모이면 세트에 유용한 추가 기능입니다!
itsjeyd

1

덜 임시적 인 방법은을 정의 mark-whole-line하는 것입니다. 이멕스는 실제로 기본 명령을 가져야합니다.

(defun mark-whole-line ()               
    "Combinition of C-a, mark, C-e"
    (interactive)
    (move-beginning-of-line nil)
    (set-mark-command nil)
    (move-end-of-line nil)
)
(global-set-key (kbd "C-2") 'mark-whole-line) ; 2 is near w

그런 다음 C-2 C-w작업을 수행합니다.

또한 현재 전체 라인에 주석을 달는 것과 같은 일을 더 쉽게 만듭니다.


0

이것은 itsjeyd의 답변을 수정 한 것으로, 현재 가장 높은 투표 답변이며 몇 년 동안 사용한 답변입니다. 그러나 문제가 있습니다 : kill-ring-save마크가 설정되지 않았기 때문에 (보통 새 버퍼에) 조언 된 버전 이 때때로 실패하고 작동했을 때조차도 커서를 사용하여 단일 행을 복사하는 기능을 사용한 후 이상한 춤을 추었습니다. . 약간의 파기 후에, 그것은 그것이 일을 한 후의 kill-ring-save호출로 인해 발생 indicate-copied-region하지만 포인트와 마크가 복사 된 영역과 일치하지 않아 indicate-copied-region잘못된 영역을 표시 했기 때문에 발생 했습니다 .

충분했다. 이를 해결하는 솔루션은 다음과 같습니다.

(define-advice kill-ring-save
    (:before-while (beg end &optional region) slick)
  (or mark-active
      (not (called-interactively-p 'interactive))
      (prog1 nil
    (copy-region-as-kill
     (line-beginning-position) (line-beginning-position 2))
    (message "Copied current line"))))

에 대한 jeje의 조언에는 아무런 문제가 없습니다 kill-region. 어쨌든 위의 내용과 스타일이 더 일치하는 변형이 있습니다.

(define-advice kill-region
    (:around (kill-region beg end &optional region) slick)
  (if (or mark-active (not region))
      (funcall kill-region beg end region)
    (funcall kill-region
             (line-beginning-position) (line-beginning-position 2))
    (message "Killed current line")))

참고 경우 것으로 transient-mark-mode설정되어 있지, 이러한 조언은 아무것도하지 않습니다.


보다 포괄적 인 솔루션을 원한다면 whole-line-or-region대신 패키지 사용을 고려하십시오 . @sanityinc의 답변을 참조하십시오.
Harald Hanche-Olsen

0

composable.el 이라는 패키지를 사용합니다 . 패키지에 대한 깔끔한 점은 Mw 및 Cw (복사 및 종료 명령)를 기존의 emacs 명령을 대신 사용하여 더 Vim과 비슷하게 수정하는 것입니다. 따라서 C-w l전체 라인을 죽입니다. 그러나 C-w M->파일 끝을 죽이는 것과 같은 일을 할 수도 있습니다. 영역을 표시 할 때 두 명령 모두 정상적으로 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.