Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

delete (NOT kill) a line in emacs. External clipboard is not appended to the kill ring

Tags:

emacs

Many times I find myself in need of pasting a path from wherever to emacs' minibuffer. To clear the minibuffer fast I navigate to the beginning and do C-k (kill line).

This effectively overrides whatever path I had in the system clipboard with the temporary path I just killed in the minibuffer. Navigating the kill ring with M-y won't bring the path I had in the system clipboard.

Is there a way to delete the current line without killing it( i.e. removing it and adding it to the kill ring)?

So far I'm marking the line and pressing delete having delete-selection-mote active. I would like a one key solution similar to C-k.

like image 786
octi Avatar asked Dec 07 '11 20:12

octi


3 Answers

As of Emacs 23.2, you can set save-interprogram-paste-before-kill to a non-nil value (hat tip Tyler) to copy the clipboard selection onto the kill ring, so that it is available via C-y M-y:

(setq save-interprogram-paste-before-kill t)

If you're on an older Emacs, the following advice has the same functionality:

(defadvice kill-new (before kill-new-push-xselection-on-kill-ring activate)
  "Before putting new kill onto the kill-ring, add the clipboard/external selection to the kill ring"
  (let ((have-paste (and interprogram-paste-function
                         (funcall interprogram-paste-function))))
    (when have-paste (push have-paste kill-ring))))

And, you could do something like this (horrible keybinding, customize to suit) to delete the line from the point forward:

(define-key minibuffer-local-map (kbd "C-S-d") 'delete-line)
(defun delete-line (&optional arg)
  (interactive "P")
  ;; taken from kill-line
  (delete-region (point)
                 ;; It is better to move point to the other end of the kill
                 ;; before killing.  That way, in a read-only buffer, point
                 ;; moves across the text that is copied to the kill ring.
                 ;; The choice has no effect on undo now that undo records
                 ;; the value of point from before the command was run.
                 (progn
                   (if arg
                       (forward-visible-line (prefix-numeric-value arg))
                     (if (eobp)
                         (signal 'end-of-buffer nil))
                     (let ((end
                            (save-excursion
                              (end-of-visible-line) (point))))
                       (if (or (save-excursion
                                 ;; If trailing whitespace is visible,
                                 ;; don't treat it as nothing.
                                 (unless show-trailing-whitespace
                                   (skip-chars-forward " \t" end))
                                 (= (point) end))
                               (and kill-whole-line (bolp)))
                           (forward-visible-line 1)
                         (goto-char end))))
                   (point))))
like image 178
Trey Jackson Avatar answered Oct 13 '22 18:10

Trey Jackson


As of Emacs 23.2, this problem can be addressed with save-interprogram-paste-before-kill. If you set this variable to t then stuff in the clipboard gets added to the kill-ring, and isn't discarded by your next kill.

The documentation:

Save clipboard strings into kill ring before replacing them. When one selects something in another program to paste it into Emacs, but kills something in Emacs before actually pasting it, this selection is gone unless this variable is non-nil, in which case the other program's selection is saved in the `kill-ring' before the Emacs kill and one can still paste it using C-y M-y.

like image 31
Tyler Avatar answered Oct 13 '22 16:10

Tyler


From Xahlee's page, it shows several commands that are annoying.

(defun my-delete-word (arg)
  "Delete characters forward until encountering the end of a word.
With argument, do this that many times.
This command does not push erased text to kill-ring."
  (interactive "p")
  (delete-region (point) (progn (forward-word arg) (point))))

(defun my-backward-delete-word (arg)
  "Delete characters backward until encountering the beginning of a word.
With argument, do this that many times.
This command does not push erased text to kill-ring."
  (interactive "p")
  (my-delete-word (- arg)))

(defun my-delete-line ()
  "Delete text from current position to end of line char."
  (interactive)
  (delete-region
   (point)
   (save-excursion (move-end-of-line 1) (point)))
  (delete-char 1)
)

(defun my-delete-line-backward ()
  "Delete text between the beginning of the line to the cursor position."
  (interactive)
  (let (x1 x2)
    (setq x1 (point))
    (move-beginning-of-line 1)
    (setq x2 (point))
    (delete-region x1 x2)))

; Here's the code to bind them with emacs's default shortcut keys:

(global-set-key (kbd "M-d") 'my-delete-word)
(global-set-key (kbd "<M-backspace>") 'my-backward-delete-word)
(global-set-key (kbd "C-k") 'my-delete-line)
(global-set-key (kbd "C-S-k") 'my-delete-line-backward)
like image 1
CodyChan Avatar answered Oct 13 '22 17:10

CodyChan