92

I'd like to just delete some text so I can yank some other text instead of it. How can I do that? C-w cuts the selected text to kill ring and I end up without the text I wanted to yank.

Also, is it possible to yank text directly instead of some text without even pressing buttons to kill it?

mannicken
  • 6,885
  • 4
  • 31
  • 38

15 Answers15

58

I type M-x delete-region quite often, but you can bind it it to a key.

With Delete Selection Mode in newer versions of Emacs you don't have to type a command just start typing:

By default, text insertion occurs normally even if the mark is active—for example, typing a inserts the character ‘a’, then deactivates the mark. Delete Selection mode, a minor mode, modifies this behavior: if you enable that mode, then inserting text while the mark is active causes the text in the region to be deleted first. Also, commands that normally delete just one character, such as C-d or DEL, will delete the entire region instead. To toggle Delete Selection mode on or off, type M-x delete-selection-mode.

ashawley
  • 4,195
  • 1
  • 27
  • 40
  • 41
    Also, with the latest version of Emacs, you don't even need to bind `delete-region` to a key because Backspace does that now. Backspace deletes the selected region instead of killing it, in other words, Backspace erases the selected text without saving/pushing it to the kill ring. This is because the value of `delete-active-region` is `t` unless you customize it to some other value. – Jisang Yoo Mar 15 '13 at 12:26
39

You can use M-y after C-y to insert previous item from the kill ring, or use browse-kill-ring package.

As for the second question, see DeleteSelectionMode.

Eugene Morozov
  • 15,081
  • 3
  • 25
  • 32
21

I have had the same issue. The closest thing I've got so far is to just make a small function that's essentially:

(defun ruthlessly-kill-line ()
  "Deletes a line, but does not put it in the kill-ring. (kinda)"
  (interactive)
  (move-beginning-of-line 1)
  (kill-line 1)
  (setq kill-ring (cdr kill-ring)))
Haakon Løtveit
  • 277
  • 3
  • 2
  • 2
    Why not just (delete-region (line-beginning-position) (line-end-position))? – CodyChan Mar 08 '17 at 06:22
  • The listed function sounded good, but did not work for me in general. In particular, I found that it would cause the yank pointer to point at the other end of the kill-ring, which in general (in fact almost always?) is not the next element on the list! (Stll trying to hack up a function that works reliably via delegation to `kill-line'... maybe I will just resort to delete-region as others have done...) – pnkfelix Feb 15 '18 at 12:23
15

Taken from the EmacsWiki:

The equivalent of ‘kill-line’ (‘C-k’) but without kill-ring side effects:

(delete-region (point) (line-end-position))
John J. Camilleri
  • 4,171
  • 5
  • 31
  • 41
  • 1
    Best answer IMO. And I bound ctrl-shift-W to delete region: (global-set-key (kbd "C-S-w") 'delete-region) – Tongfa Jan 12 '17 at 15:18
5

M-x eval-expression (setq kill-ring (cdr kill-ring)) - removes last item from kill-ring

Evgeny
  • 51
  • 1
  • 2
4

Most kill functions use kill-region to do the actual work of killing text. I use a lisp macro to create delete functions from kill functions.

(defmacro jpk/delete-instead-of-kill (&rest body)
  "Replaces `kill-region' with `delete-region' in BODY."
  `(cl-letf (((symbol-function 'kill-region)
              (lambda (beg end &optional yank-handler)
                (delete-region beg end))))
     ,@body))

(defun jpk/delete-word (arg)
  "Like `kill-word', but does not save to the `kill-ring'."
  (interactive "*p")
  (jpk/delete-instead-of-kill (kill-word arg)))
jpkotta
  • 9,237
  • 3
  • 29
  • 34
  • How does it work? Do you have more information on this? This is amazing. – sinekonata Aug 27 '20 at 17:58
  • 1
    `cl-letf` can create a local binding of a function with dynamic scope. That means it's only in effect for code inside the `cl-letf`, but it applies to the entire call tree (e.g. `kill-region` doesn't appear directly in `body`, but `kill-word` calls `kill-region` and that is replaced with `delete-region`). – jpkotta Aug 28 '20 at 19:47
  • You can even call the original function from its replacement if you first bind it to a different name in the `cl-letf`. `cl-letf` works like `let*` in that sense. – jpkotta Aug 28 '20 at 19:50
  • I get the gist of it, it's still too technical for me. I barely have intermediate experience with python. What's general name for this "overwriting"/rewriting/forking functions? Is it a specific feature of languages like lisp? – sinekonata Nov 09 '20 at 13:09
  • 1
    I'm not exactly sure what the general name for this technique is. I think I would describe it as dynamic scope for functions, and is not common in most languages because it can be very easy to abuse. Emacs is slowly moving to lexical scope which is what most languages use. I'm not sure you can do it in Python in general, you'd have to design your code to allow overriding the function in a particular scope. – jpkotta Nov 10 '20 at 01:16
4

For your second question, alternatively to DeleteSelectionMode you can enable CUA Mode which additionally gives you a nice rectangle selection mode enabled by C-Return. CUA mode is part of emacs since 22.1.

danielpoe
  • 3,756
  • 23
  • 18
3

Found an answer to this.

Posted it first here.

;; Ctrl-K with no kill
(defun delete-line-no-kill ()
  (interactive)
  (delete-region
   (point)
   (save-excursion (move-end-of-line 1) (point)))
 (delete-char 1)
)
(global-set-key (kbd "C-k") 'delete-line-no-kill)
Community
  • 1
  • 1
Ole
  • 487
  • 7
  • 20
  • The problem is that this command always deletes the newline as well, whereas kill-line only deletes the newline if the value of the variable kill-whole-line is non-nil. It would be better to change the "(delete-char 1)" to "(if kill-whole-line (delete-char 1))". – Alan Jan 04 '16 at 23:28
2

Technically, the other answers are wrong on the first part.

Here is my implementation and motivation:

(defun delete-word (arg)
  "Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
  (interactive "p")
  (delete-region (point) (progn (backward-word arg) (point))))

I adapted the code here from "kill-word" in simple.el. I switched kill-region with delete-region and forward-word for backward-word. This way it TRUELY does not affect the kill-ring, unlike the other situations where, outside of emacs, I noticed that the kill-ring was influenced.

Community
  • 1
  • 1
PascalVKooten
  • 20,643
  • 17
  • 103
  • 160
  • 2
    I prefer this answer because it doesn't screw up pasting from the OS clipboard (where dropping the last thing from the kill ring doesn't help because what's in the OS clipboard is lost) – Brel Oct 21 '13 at 20:17
  • Check out my answer for a way to do this without copying the kill function's definition. – jpkotta Dec 22 '15 at 20:16
1

My answer to first question: mark the text in emacs (using either mouse or set mark C-SPC), and press "<- Backspace" button on keyboard instead of C-w. This way you can still paste over text in system clipboard, without worrying that the clipboard got overridden by text killed by C-w

Background for this answer: sometimes when I got text outside emacs that I want to use to replace a region in emacs, I often made a mistake by first copying that text into system clipboard (i.e. on Windows Ctrl + C) , then doing a C-w in emacs to "delete" the region of text I want to replace, with the hope that a later M-w could recover my text in clipboard from kill-ring. Unfortunately the clipboard would be simply overridden by text killed by C-w, and original message in clipboard would never show in kill-ring.

For 2nd question, yes you can always mark the text in emacs first and then directly C-y

Kevin Zhu
  • 2,746
  • 26
  • 23
1

how to delete text without kill ring?

the delete-region function will delete the selected region without adding it to the kill ring

Also, is it possible to yank text directly instead of some text without even pressing buttons to kill it?

I think you are asking how to replace the text in a selected region with something that you have already put on the kill ring.

Setting (delete-selection-mode 1) will allow you to yank/paste over a selected region. It also allows you to just type and replace a selected region.

On version 25.1.1 on OS X I also had to add (setq select-enable-primary nil) to prevent it from copying the selected region to the kill ring

kevincasey
  • 249
  • 2
  • 12
1
(defun copy-to-register-z (p1 p2)
  "Copy text selection to register named “z”."
  (interactive "r")
  (copy-to-register ?z p1 p2))
(defun replace-register-content-z (p1 p2)
  "Replace register named “z”'s content."
  (interactive "r")
  (delete-region p1 p2)
  (insert-register ?z))
(global-set-key (kbd "C-c c") 'copy-to-register-z)
(global-set-key (kbd "C-c v") 'replace-register-content-z)
Geo
  • 93,257
  • 117
  • 344
  • 520
ZBeginner
  • 11
  • 1
  • I like this, but because I don't use transient mark mode, I prefer an "insert-register-content-z" with all but the delete-region line. – Joshua Goldberg Mar 21 '12 at 17:11
1

As a complement to all answers. If you write elisp code to delete, you can call functions that kill as long as you use a local kill-ring object like this:

(defun delete-something()
  "Delete something without storing in kill ring."
  (let (kill-ring)
     (kill-something)))

Use any function that kill something in place of the kill-something. The function will then delete and nothing will be remembered in the real kill-ring.

PRouleau
  • 150
  • 6
1

Add a delete equivalent of kill-region and kill-line keys C-w and C-k as follows. Bound to keys C-v and C-z.

;; A keybinding to delete-region gives a good "Windows CUT Ctrl-x equivalent".
;; What keybinding to use is awkward to choose.
;; using C-v "Windows PASTE Ctrl-v" is quite a subversive option.
;;  C-v = scroll up in emacs which I have no use for.
(global-set-key (kbd "C-v") 'delete-region)

;; To have also a "Windows CUT" alternative to C-k (kill-line) this can be done:
(defun delete-line () "delete line, take it out of kill ring. bind this func to C-z"
 (interactive)
 (setq last-command 'delete-line)
 (kill-line)
 (setq kill-ring (cdr kill-ring))
 (setq kill-ring-yank-pointer kill-ring)
 (setq last-command 'delete-line)
)
(global-set-key (kbd "C-z") 'delete-line)
;; without setting of last-command 2+ C-zs mess up kill-ring
0

Here's a version of kill-region that doesn't force values into the kill-ring.

(defun kill-or-delete-region (beg end prefix)
  "Delete the region, storing it in the kill-ring.
If a prefix argument is given, don't change the kill-ring."
  (interactive "r\nP")
  (if prefix
      (delete-region beg end)
    (kill-region beg end)))

(global-set-key (kbd "C-w") 'kill-or-delete-region)

This enables you to do C-w as before, but C-u C-w now deletes text without changing the kill-ring.

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192