CopyWithoutSelection

Some years ago, I ran GNU Emacs in Cygwin on a Windows machine. So there must be some kind of non-Emacs programs, such as Microsoft Word, Excel, Lotus Notes and so on. So I used to copy and paste stuff between them.

It’s pretty boring to copy and paste so much stuff all the time. Because selecting what you want accurately is the most time-consuming. So I decided to leverage GNU Emacs to do it for me.

The simplest way to do this is just to put your point on the stuff and GNU Emacs will take over all the others.

As time went on, I do a lot of daily work in shell-mode. It gave me a new idea, that Emacs would even paste for me. Paste to the mark.

Introduction

The following functions will copy the word, the line, the paragraph and the string and the Parenthesis at point, and will paste them to the mark. If it is used in shell-mode, stuff will be pasted at end of shell prompt.

Give a prefix 1 will prevent paste.

And besides, there are also something to do with some basic shortcuts.

Selecting words or sexps without moving the cursor

You can select word or sexp after point and put it in the kill-ring by typing:

         C-M-SPC M-w

This does not move the cursor. If you want to select the next two words after point, just type C-M-SPC C-M-SPC M-w. Killing next word or sexp can be done with C-M-SPC C-w, or better with C-M-k.

the base functions

    (defun get-point (symbol &optional arg)
      "get the point"
      (funcall symbol arg)
      (point))
     
    (defun copy-thing (begin-of-thing end-of-thing &optional arg)
      "Copy thing between beg & end into kill ring."
      (save-excursion
        (let ((beg (get-point begin-of-thing 1))
              (end (get-point end-of-thing arg)))
          (copy-region-as-kill beg end))))
     
    (defun paste-to-mark (&optional arg)
      "Paste things to mark, or to the prompt in shell-mode."
      (unless (eq arg 1)
        (if (string= "shell-mode" major-mode)
            (comint-next-prompt 25535)
          (goto-char (mark)))
        (yank)))
     

Copy Word

     (defun copy-word (&optional arg)
      "Copy words at point into kill-ring"
       (interactive "P")
       (copy-thing 'backward-word 'forward-word arg)
       ;;(paste-to-mark arg)
     )

Key binding

     (global-set-key (kbd "C-c w")         (quote copy-word))

Copy backward word

 (defun copy-backward-word ()
  "copy word before point - rocky @ stackexchange"
   (interactive "")
   (save-excursion
    (let ((end (point))
      (beg (get-point 'backward-word 1)))
      (copy-region-as-kill beg end))))

Key binding

    (global-set-key (kbd "C-c W") 'copy-backward-word) 

Copy Line

     (defun copy-line (&optional arg)
      "Save current line into Kill-Ring without mark the line "
       (interactive "P")
       (copy-thing 'beginning-of-line 'end-of-line arg)
       (paste-to-mark arg)
     )

Key binding

      (global-set-key (kbd "C-c l")         (quote copy-line))

Tip: WholeLineOrRegion copies the current line when the region is not active. Thus, C-a M-w C-y C-y … duplicates the current line (similar to vi’s ‘yyp’), while C-w deletes it (‘dd’). When the region is active, M-w and C-w act as usual. 😊

Copy Paragraph

     (defun copy-paragraph (&optional arg)
      "Copy paragraphes at point"
       (interactive "P")
       (copy-thing 'backward-paragraph 'forward-paragraph arg)
       (paste-to-mark arg)
     )

key binding

      (global-set-key (kbd "C-c p")         (quote copy-paragraph))

Copy String

    (defun beginning-of-string (&optional arg)
      (when (re-search-backward "[ \t]" (line-beginning-position) :noerror 1)
        (forward-char 1)))
    (defun end-of-string (&optional arg)
      (when (re-search-forward "[ \t]" (line-end-position) :noerror arg)
        (backward-char 1)))
     
     (defun thing-copy-string-to-mark(&optional arg)
       " Try to copy a string and paste it to the mark
     When used in shell-mode, it will paste string on shell prompt by default "
       (interactive "P")
       (copy-thing 'beginning-of-string 'end-of-string arg)
       (paste-to-mark arg)
     )
     

Key binding

      (global-set-key (kbd "C-c s")         (quote thing-copy-string-to-mark))

Copy Parenthesis

Similar with new copy string to mark

    (defun beginning-of-parenthesis (&optional arg)
      (when (re-search-backward "[[<(?\"]" (line-beginning-position) :noerror)
        (forward-char 1)))
    (defun end-of-parenthesis (&optional arg)
      (when (re-search-forward "[]>)?\"]" (line-end-position) :noerror arg)
        (backward-char 1)))
     
     (defun thing-copy-parenthesis-to-mark (&optional arg)
       " Try to copy a parenthesis and paste it to the mark
     When used in shell-mode, it will paste parenthesis on shell prompt by default "
       (interactive "P")
       (copy-thing 'beginning-of-parenthesis 'end-of-parenthesis arg)
       (paste-to-mark arg)
     )
      (global-set-key (kbd "C-c a")         (quote thing-copy-parenthesis-to-mark))

Possible alternative: thing-edit.el

Have you see Lisp:thing-edit.el ? – AndyStewart

Thanks for your advice. It’s cool. I evaluated thing-edit.el. Yeah I actually modified some of my functions to leverage the thingatpt.el. I love to leverage build-in functions as much as possible than to write my own ones. But anyway, it does not give me what copy-string could do fo me.

I used to do my daily work in shell mode. So I used to need some information to be copied to the command line. For example something like this, when I issue runmqsc QMCOD in the command line, I would get a screen like this:

-bash-3.2# runmqsc QMCOD
5724-H72 (C) Copyright IBM Corp. 1994, 2009.  ALL RIGHTS RESERVED.
Starting MQSC for queue manager QMCOD.


DIS CHL(T*)
     1 : DIS CHL(T*)
AMQ8414: Display Channel details.
   CHANNEL(TO.QMCM.4.FTECA)                CHLTYPE(CLUSSDR)
AMQ8414: Display Channel details.
   CHANNEL(TO.QMCOD.4.FTECA)               CHLTYPE(CLUSRCVR)

START 

And now I would need a command like START CHANNEL(TO.QMCOD.4.FTECA) by copy a string like CHANNEL(TO.QMCOD.4.FTECA) and paste it after START

Or I would need a command like ALTER CHANNEL(TO.QMCOD.4.FTECA) CHLTYPE(CLUSRCVR) by copy above string as well as ‘ *CHLTYPE(CLUSRCVR)* and paste them after ALTER in the command line.

Both thing-copy-sexp and thing-copy-symbol do not work in this way. Maybe I am not actually understand how thing-copy-sexp works. I don’t find enough document for it in thingatpt.el.

– David Young


CategoryRegion CategoryEditing