all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Karl Fogel <kfogel@red-bean.com>
To: emacs-devel@gnu.org
Subject: yank-match.el -- yank matches for a regexp from kill-ring
Date: Sun, 02 Mar 2008 11:17:51 -0500	[thread overview]
Message-ID: <873ar9xfps.fsf@red-bean.com> (raw)
In-Reply-To: 87bqedqltf.fsf@red-bean.com

Yidong and Stefan (and everyone else),

A while ago, I posted suggesting that I install 'yank-match' (see
below) into Emacs.  There was some discussion of whether it overlaps
with any other functionality, but the general sentiment seemed to be
in favor of installing.  It would not be attached to a keybinding by
default, just available for people to custom bind.  The original
thread starts here:

   http://lists.gnu.org/archive/html/emacs-devel/2007-07/msg00778.html

For various reasons, I didn't get a chance to install it, and then
overall maintainership changed from RMS to Stefan and Yidong.  I'm now
ready to install it -- but it's been so long that I thought I should
check once more first.

Rather than stuffing it into simple.el, I guess I'd create a new file
yank-match.el (suggestions for other destinations welcome).

The FSF already has my papers; naturally I'd adjust the copyright
notice before installing.

-Karl

--------------------8-<-------cut-here---------8-<-----------------------
;;; -*- Mode: Emacs-Lisp -*-
;;; File: yank-match.el
;;; 
;;; Yanks matches for REGEXP from kill-ring.
;;; Copyright (C) 1997 Karl Fogel <kfogel@red-bean.com>
;;; 
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;; 
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;; 
;;; You should have received a copy of the GNU General Public License along
;;; with this program; if not, write to the Free Software Foundation, Inc.,
;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
;;;
;;; USAGE:
;;;
;;; Just call yank-match ("M-x yank-match" or whatever keybinding you 
;;; have installed for it) and supply a regular expression at the prompt.
;;; See documentation for `yank-match' for more details.

(defvar yank-match-modify-kill-ring nil "*Non-nil means place matches 
at the front of the kill-ring, thus making it not behave like a ring for
yank-match functions.  Instead you'd \"bounce back\" from one end of
the kill-ring to the other with repeated yank-matches.  However, each
match would then be available for immediate yanking with \\[yank].

If that was at all confusing, just leave this set to nil.")

(defvar yank-match-count 0 "Which match in kill ring yank-match will 
yank.")

(defvar yank-match-last-regexp nil "Last regexp used by yank-match.")

(defvar yank-match-inserted nil "Did we insert on last yank match?")

(defun yank-match (re)
  "Yank the first item in the kill-ring that contains a match for RE
\(a regular expression\).  Set point and mark just as \\[yank] does.

Repeated invocations with no intervening commands will run
successively through the matches for RE in the kill-ring,
replacing the previously-yanked text with the new match each
time, without prompting for a new regular expression,

See variable `yank-match-modify-kill-ring' for a way to make matches
automatically be put at the front of the kill-ring \(and thus be available
for immediate yanking\).  Normally, matches are not put at the front
of the kill ring, but if you do \\[copy-region-as-kill] or
\\[kill-ring-save] immediately after finding the match you wanted, it
will then be put at the front of the ring, and \\[yank] will default
to that match.

Because the kill-ring is a ring \(or a dead ringer for one, at
least\), it is okay to repeat this command more times than the number
of matches in the kill-ring.  It just means that previous matches will
come back to haunt you."
  (interactive (if (equal last-command 'yank-match)
		   (list yank-match-last-regexp)
		 (list (read-from-minibuffer "Yank match (regexp): "))))
  (let ((repeating (equal last-command 'yank-match)))
    (if repeating
	(progn
	  ;; if inserted on last yank, kill that region before yanking new
	  (if yank-match-inserted 
	      (progn
		(setq yank-match-inserted nil)
		(delete-region (mark) (point))))

	  ;; if repeating and successful match this time
	  (if (do-yank-match re yank-match-count)
		(setq yank-match-count (1+ yank-match-count))

	    ;; if repeating and unsuccessful match this time
	    (progn
	      (setq yank-match-count 1)
	      (do-yank-match re 0))))
		      
      ;; if not repeating
      (if (do-yank-match re 0)
	  (setq yank-match-count 1)
	(error "No match found for `%s' in kill ring." re))))
  (setq yank-match-last-regexp re)
  (setq this-command 'yank-match))


(defun do-yank-match (re num)
  (let ((found-one t))
    (catch 'done
      (let ((index 0)
	    (len (1- (length kill-ring))))
	(progn
	  (while (<= index len)
	    (let ((str (nth index kill-ring)))
	      (if (string-match re str)
		  (if (= num 0)
		      (progn (setq found-one nil)
			     (setq yank-match-inserted t)
			     (push-mark (point))
			     (insert str)
			     (if yank-match-modify-kill-ring
				 (setq 
				  kill-ring
				  (cons str (delq str kill-ring))))
			     (throw 'done nil))
		    (progn (setq found-one t)
			   (setq num (1- num))
			   (setq index (1+ index))))
		(setq index (1+ index))))))))
    (not found-one))) ; so it returns t on success! 

;;; yank-match.el ends here




  parent reply	other threads:[~2008-03-02 16:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-15 23:38 yank-match.el -- yank matches for a regexp from kill-ring Karl Fogel
2007-07-17 18:44 ` Mathias Dahl
2007-07-17 18:46   ` Karl Fogel
2007-07-17 19:29     ` Drew Adams
2007-07-17 20:40       ` Mathias Dahl
2007-07-28 20:32     ` T. V. Raman
2008-03-02 16:17 ` Karl Fogel [this message]
2008-03-02 17:59   ` Juri Linkov
2008-03-02 19:25     ` Stefan Monnier
2008-03-02 20:07       ` Juri Linkov
2008-03-02 23:50     ` Karl Fogel
2008-03-04  0:35       ` Juri Linkov
2008-03-04  1:16         ` Karl Fogel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=873ar9xfps.fsf@red-bean.com \
    --to=kfogel@red-bean.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.