all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Leo <sdl.web@gmail.com>
Cc: Davis Herring <herring@lanl.gov>,
	8415@debbugs.gnu.org,
	Daniel Colascione <dan.colascione@gmail.com>
Subject: bug#8415: 23.3.50; Extensible Emacs Registers
Date: Mon, 04 Apr 2011 18:19:12 -0400	[thread overview]
Message-ID: <jwvfwpxznqu.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <m1sjtx9av0.fsf@th041153.ip.tsinghua.edu.cn> (Leo's message of "Tue, 05 Apr 2011 01:37:07 +0800")

>> A more backward-compatible change would be to not use register-structs
>> for pre-existing cases (i.e. markers, strings, lists of string, and
>> win-confs).  I.e. only add register structs as a new accepted kind
>> of value (and move `name' out of the struct).
>> The patch would most likely be a lot smaller.

> The original register.el is very inflexible and does its work mostly by
> guess because it misses the best moment to decide how to
> jump/insert/print a register i.e. at the time of creating it.

AFAICT, the code currently doesn't guess: the different kinds of values
are mutually exclusive.  So the moment at which they decide which
code to use doesn't matter because it'll give the same answer (tho
as you point out there are errors in this code currently because it's
dispersed).

> So we will have to make almost all values a struct anyway to fix bugs
> like this.

Yes, all new types will use register structs.  That's not a problem.
And you can even later-on de-support old types and have them go through
register structs as well.

> As I said in another post, subsequent to this patch I will break down
> jump-to-register, describe-register-1, insert-register to take advantage
> of this new implementation.

That's good.  But I'd rather you break backward compatibility at *that*
point rather than right from the start.
I.e. start with a patch like the one below.  Of course, instead of
register structs, you can use functions (like we do for completion
tables) as in:

   === modified file 'lisp/register.el'
   --- lisp/register.el	2011-01-25 04:08:28 +0000
   +++ lisp/register.el	2011-04-04 22:16:56 +0000
   @@ -52,7 +52,10 @@
    
    (defvar register-alist nil
      "Alist of elements (NAME . CONTENTS), one for each Emacs register.
   -NAME is a character (a number).  CONTENTS is a string, number, marker or list.
   +NAME is a character (a number).  CONTENTS can take various forms:
   +A function that takes one argument (the action to perform).
   +  The action can be `print', `insert', or `jump'.  Any action it does not
   +  understand should result in signalling an error.
    A list of strings represents a rectangle.
    A list of the form (file . FILE-NAME) represents the file named FILE-NAME.
    A list of the form (file-query FILE-NAME POSITION) represents
   @@ -120,6 +123,7 @@
      (interactive "cJump to register: \nP")
      (let ((val (get-register register)))
        (cond
   +     ((functionp val) (funcall val 'jump))
         ((and (consp val) (frame-configuration-p (car val)))
          (set-frame-configuration (car val) (not delete))
          (goto-char (cadr val)))
   @@ -209,6 +213,7 @@
      (princ " contains ")
      (let ((val (get-register register)))
        (cond
   +     ((functionp val) (funcall val 'print))
         ((numberp val)
          (princ val))
    
   @@ -285,6 +290,7 @@
      (push-mark)
      (let ((val (get-register register)))
        (cond
   +     ((functionp val) (funcall val 'insert))
         ((consp val)
          (insert-rectangle val))
         ((stringp val)
   
   
-- Stefan


=== modified file 'lisp/register.el'
--- lisp/register.el	2011-01-25 04:08:28 +0000
+++ lisp/register.el	2011-04-04 22:10:11 +0000
@@ -52,7 +52,8 @@
 
 (defvar register-alist nil
   "Alist of elements (NAME . CONTENTS), one for each Emacs register.
-NAME is a character (a number).  CONTENTS is a string, number, marker or list.
+NAME is a character (a number).  CONTENTS can take various forms:
+A `register' structure, made with `register-make'.
 A list of strings represents a rectangle.
 A list of the form (file . FILE-NAME) represents the file named FILE-NAME.
 A list of the form (file-query FILE-NAME POSITION) represents
@@ -63,6 +64,18 @@
 A list of the form (FRAME-CONFIGURATION POSITION)
  represents a saved frame configuration plus a saved value of point.")
 
+(eval-when-compile (require 'cl))
+
+(defstruct
+  (register (:constructor nil)
+	    (:constructor register-make (value &key print-func
+                                               jump-func insert-func))
+	    (:copier nil))
+  (value       nil :read-only t)
+  (print-func  nil :read-only t)
+  (jump-func   nil :read-only t)
+  (insert-func nil :read-only t))
+
 (defun get-register (register)
   "Return contents of Emacs register named REGISTER, or nil if none."
   (cdr (assq register register-alist)))
@@ -120,6 +133,7 @@
   (interactive "cJump to register: \nP")
   (let ((val (get-register register)))
     (cond
+     ((register-p val) (funcall (register-jump-func val) val))
      ((and (consp val) (frame-configuration-p (car val)))
       (set-frame-configuration (car val) (not delete))
       (goto-char (cadr val)))
@@ -149,6 +163,7 @@
 
 (defun register-swap-out ()
   "Turn markers into file-query references when a buffer is killed."
+  ;; FIXME: Let register structures hook here as well.
   (and buffer-file-name
        (dolist (elem register-alist)
 	 (and (markerp (cdr elem))
@@ -177,6 +192,7 @@
 (defun increment-register (number register)
   "Add NUMBER to the contents of register REGISTER.
 Interactively, NUMBER is the prefix arg."
+  ;; FIXME: Let register structures hook here as well.
   (interactive "p\ncIncrement register: ")
   (or (numberp (get-register register))
       (error "Register does not contain a number"))
@@ -209,6 +225,7 @@
   (princ " contains ")
   (let ((val (get-register register)))
     (cond
+     ((register-p val) (funcall (register-print-func val) val))
      ((numberp val)
       (princ val))
 
@@ -285,6 +302,7 @@
   (push-mark)
   (let ((val (get-register register)))
     (cond
+     ((register-p val) (funcall (register-insert-func val) val))
      ((consp val)
       (insert-rectangle val))
      ((stringp val)
@@ -315,6 +333,7 @@
 With prefix arg, delete as well.
 Called from program, takes four args: REGISTER, START, END and DELETE-FLAG.
 START and END are buffer positions indicating what to append."
+  ;; FIXME: Let register structures hook here as well?
   (interactive "cAppend to register: \nr\nP")
   (let ((reg (get-register register))
         (text (filter-buffer-substring start end)))
@@ -329,6 +348,7 @@
 With prefix arg, delete as well.
 Called from program, takes four args: REGISTER, START, END and DELETE-FLAG.
 START and END are buffer positions indicating what to prepend."
+  ;; FIXME: Let register structures hook here as well?
   (interactive "cPrepend to register: \nr\nP")
   (let ((reg (get-register register))
         (text (filter-buffer-substring start end)))






  reply	other threads:[~2011-04-04 22:19 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-03 12:29 bug#8415: 23.3.50; Extensible Emacs Registers Leo
2011-04-03 17:21 ` Daniel Colascione
2011-04-04  1:29   ` Leo
2011-04-04 14:29 ` Stefan Monnier
2011-04-04 17:37   ` Leo
2011-04-04 22:19     ` Stefan Monnier [this message]
2011-04-04 22:27       ` Daniel Colascione
2011-04-05  1:41         ` Stefan Monnier
2011-04-05  1:49           ` Daniel Colascione
2011-04-05  3:07             ` Stefan Monnier
2011-04-05  5:42               ` Leo
2011-04-05 13:50                 ` Stefan Monnier
2011-04-06  5:00                   ` Leo
2011-04-06 15:38                     ` Stefan Monnier
2011-04-07  3:13                       ` Leo
2011-04-09  1:25                         ` Stefan Monnier
2011-06-23  8:11                           ` Leo
2011-06-25 13:19                             ` Stefan Monnier
2011-06-26  6:42                               ` Leo

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=jwvfwpxznqu.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=8415@debbugs.gnu.org \
    --cc=dan.colascione@gmail.com \
    --cc=herring@lanl.gov \
    --cc=sdl.web@gmail.com \
    /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.