From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 03 08:29:42 2011 Received: (at submit) by debbugs.gnu.org; 3 Apr 2011 12:29:43 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6MR4-0007Wi-5T for submit@debbugs.gnu.org; Sun, 03 Apr 2011 08:29:42 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6MR2-0007WW-2P for submit@debbugs.gnu.org; Sun, 03 Apr 2011 08:29:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q6MQp-0001Ap-Ih for submit@debbugs.gnu.org; Sun, 03 Apr 2011 08:29:34 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, T_TO_NO_BRKTS_FREEMAIL, T_TVD_MIME_NO_HEADERS autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([199.232.76.165]:39722) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q6MQp-0001Aj-D9 for submit@debbugs.gnu.org; Sun, 03 Apr 2011 08:29:27 -0400 Received: from [140.186.70.92] (port=37641 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6MQj-0003MS-RS for bug-gnu-emacs@gnu.org; Sun, 03 Apr 2011 08:29:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q6MQd-000190-Ig for bug-gnu-emacs@gnu.org; Sun, 03 Apr 2011 08:29:21 -0400 Received: from mail-iw0-f169.google.com ([209.85.214.169]:47875) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q6MQd-00018o-AP for bug-gnu-emacs@gnu.org; Sun, 03 Apr 2011 08:29:15 -0400 Received: by iwg8 with SMTP id 8so6449382iwg.0 for ; Sun, 03 Apr 2011 05:29:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:subject:x-debbugs-cc:date:message-id :mime-version:content-type; bh=zDxDntD3yjyP3VazCD37WdG+CPcbqrWcwlRmrhhAfRw=; b=tktgZLxHDXCk1ft0x94u0uMDgeQtUe8iAWcUWO+XuMQ1aa8COIJ2aZk5LKU1XQtrX7 9fPi41Uf5YSHTRyZvny0wVH3dftwGz8BxjfZOSXam3YrMMG6nnbKiyJ59S1w9pLG/f3d dDJ5l+jbFq9LfVtwtlPim81kkCQgPoJaOQMFA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:x-debbugs-cc:date:message-id:mime-version :content-type; b=KkWFyyD73w3Bbt2b2ofnjkcvHsXHOEGciKYxSgKSwQuZ7QHUY7g8l+WhNiYQ7YUAvh pKJwD12SD52FmKEksTgjTKYC7pTbQ1fUZo3WXrNw9RmLB31NiLE8rySXcpfmw1frrvmw l+DLdX2I+KFk1FG+hKzt6QmJF6ibo4i+5k6V8= Received: by 10.43.53.200 with SMTP id vr8mr3175415icb.43.1301833754745; Sun, 03 Apr 2011 05:29:14 -0700 (PDT) Received: from th041156.ip.tsinghua.edu.cn ([114.249.16.204]) by mx.google.com with ESMTPS id i20sm2948777iby.14.2011.04.03.05.29.10 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 03 Apr 2011 05:29:13 -0700 (PDT) From: Leo To: bug-gnu-emacs@gnu.org Subject: 23.3.50; Extensible Emacs Registers X-Debbugs-CC: Daniel Colascione , Davis Herring Date: Sun, 03 Apr 2011 20:29:02 +0800 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 199.232.76.165 X-Spam-Score: -5.1 (-----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -5.2 (-----) --=-=-= I would like to propose the following patch that makes the register system easier to hook into. With this change, for example, if one wants to make a command to save a keyboard macro to a register. There is no need to change register.el. 3rd party libraries such as undo-tree.el can add registers of undo state that one can jump to with C-x r j. With this change, register is now a compound data structure. I have also removed one inconsistent use of the argument REGISTER. In the new code it always refers to the register object and never the name. There is only one small incompatible change, set-register now returns the register object but the return value of register-set is rarely used. Other than that it should be 100% backward compatible. Let me know if not. Leo --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=register.diff Content-Description: register.diff === modified file 'lisp/register.el' --- lisp/register.el 2011-01-25 04:08:28 +0000 +++ lisp/register.el 2011-04-03 12:00:44 +0000 @@ -28,6 +28,8 @@ ;; pieces of buffer state to named variables. The entry points are ;; documented in the Emacs user's manual. +(eval-when-compile (require 'cl)) + (declare-function semantic-insert-foreign-tag "semantic/tag" (foreign-tag)) (declare-function semantic-tag-buffer "semantic/tag" (tag)) (declare-function semantic-tag-start "semantic/tag" (tag)) @@ -50,9 +52,27 @@ ;;; Code: -(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. +;;; in-memeory persistency +(defvar register-hash-table (make-hash-table)) + +;;; immutable register object +(defstruct + (register (:constructor nil) + (:constructor register--make (name &optional value print-func + jump-func insert-func extra)) + (:copier nil) + (:type list) + :named) + (name nil :read-only t) + (value nil :read-only t) + (print-func nil :read-only t) + (jump-func nil :read-only t) + (insert-func nil :read-only t) + (extra nil :read-only t)) + +(defun* register-make (name value &key print-func jump-func insert-func extra) + "Return a newly created register with NAME and VALUE. +VALUE may be a string, number, marker or list. 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 @@ -61,53 +81,78 @@ A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point.") + represents a saved frame configuration plus a saved value of point. -(defun get-register (register) - "Return contents of Emacs register named REGISTER, or nil if none." - (cdr (assq register register-alist))) - -(defun set-register (register value) - "Set contents of Emacs register named REGISTER to VALUE. Returns VALUE. -See the documentation of the variable `register-alist' for possible VALUEs." - (let ((aelt (assq register register-alist))) - (if aelt - (setcdr aelt value) - (push (cons register value) register-alist)) - value)) +VALUE may also be any customized data. -(defun point-to-register (register &optional arg) - "Store current location of point in register REGISTER. +PRINT-FUNC if provided controls how `list-registers' and +`view-register' print the register. It should be a function +recieving one argument VALUE and print text that completes +this sentence: + Register `X' contains [TEXT PRINTED BY PRINT-FUNC] + +JUMP-FUNC if provided, controls how `jump-to-register' jumps to the register. +INSERT-FUNC if set, controls how `insert-register' insert the register. +They both receive the VALUE of the register as argument." + (let ((register (register--make name value print-func + jump-func insert-func extra))) + (puthash name register register-hash-table) + register)) + +(defsubst register-find (name &optional if-does-not-exist) + "Find the register named NAME and return it. +If IF-DOES-NOT-EXIST is :error, signal an error; otherwise return nil." + (let ((register (gethash name register-hash-table))) + (or register (case if-does-not-exist + (:error (error "Register named `%s' does not exist" + (single-key-description name))) + (otherwise nil))))) + +(defsubst register-map (function) + "Apply FUNCTION to each register for side effects only. +FUNCTION should accept one argument - the register." + (maphash (lambda (name register) + (funcall function register)) register-hash-table)) + +(define-obsolete-function-alias 'set-register 'register-make "24.1") +(make-obsolete 'get-register "use `register-find' and `register-value'." "24.1") + +(defun get-register (name) + "Return the value of register named NAME or nil if none." + (ignore-errors (register-value (register-find name :error)))) + +(defun point-to-register (name &optional arg) + "Store current location of point in a register. With prefix argument, store current frame configuration. Use \\[jump-to-register] to go to that location or restore that configuration. Argument is a character, naming the register." (interactive "cPoint to register: \nP") ;; Turn the marker into a file-ref if the buffer is killed. (add-hook 'kill-buffer-hook 'register-swap-out nil t) - (set-register register - (if arg (list (current-frame-configuration) (point-marker)) - (point-marker)))) + (register-make name + (if arg (list (current-frame-configuration) (point-marker)) + (point-marker)))) -(defun window-configuration-to-register (register &optional arg) - "Store the window configuration of the selected frame in register REGISTER. +(defun window-configuration-to-register (name &optional arg) + "Store the window configuration of the selected frame in a register. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." (interactive "cWindow configuration to register: \nP") ;; current-window-configuration does not include the value ;; of point in the current buffer, so record that separately. - (set-register register (list (current-window-configuration) (point-marker)))) + (register-make name (list (current-window-configuration) (point-marker)))) -(defun frame-configuration-to-register (register &optional arg) - "Store the window configuration of all frames in register REGISTER. +(defun frame-configuration-to-register (name &optional arg) + "Store the window configuration of all frames in a register. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." (interactive "cFrame configuration to register: \nP") ;; current-frame-configuration does not include the value ;; of point in the current buffer, so record that separately. - (set-register register (list (current-frame-configuration) (point-marker)))) + (register-make name (list (current-frame-configuration) (point-marker)))) (defalias 'register-to-point 'jump-to-register) -(defun jump-to-register (register &optional delete) +(defun jump-to-register (name &optional delete) "Move point to location stored in a register. If the register contains a file name, find that file. \(To put a file name in a register, you must use `set-register'.) @@ -118,8 +163,11 @@ delete any existing frames that the frame configuration doesn't mention. \(Otherwise, these frames are iconified.)" (interactive "cJump to register: \nP") - (let ((val (get-register register))) + (let* ((register (register-find name :error)) + (val (register-value register)) + (jump-func (register-jump-func register))) (cond + (jump-func (funcall jump-func val)) ((and (consp val) (frame-configuration-p (car val))) (set-frame-configuration (car val) (not delete)) (goto-char (cadr val))) @@ -150,65 +198,71 @@ (defun register-swap-out () "Turn markers into file-query references when a buffer is killed." (and buffer-file-name - (dolist (elem register-alist) - (and (markerp (cdr elem)) - (eq (marker-buffer (cdr elem)) (current-buffer)) - (setcdr elem - (list 'file-query - buffer-file-name - (marker-position (cdr elem)))))))) + (register-map + (lambda (register) + (let ((val (register-value register))) + (and (markerp val) + (eq (marker-buffer val) (current-buffer)) + (register-make (register-name register) + (list 'file-query + buffer-file-name + (marker-position val))))))))) -(defun number-to-register (number register) +(defun number-to-register (number name) "Store a number in a register. -Two args, NUMBER and REGISTER (a character, naming the register). +Two args, NUMBER and NAME (a character, naming the register). If NUMBER is nil, a decimal number is read from the buffer starting at point, and point moves to the end of that number. Interactively, NUMBER is the prefix arg (none means nil)." (interactive "P\ncNumber to register: ") - (set-register register - (if number - (prefix-numeric-value number) - (if (looking-at "\\s-*-?[0-9]+") - (progn - (goto-char (match-end 0)) - (string-to-number (match-string 0))) - 0)))) + (register-make name + (if number + (prefix-numeric-value number) + (if (looking-at "\\s-*-?[0-9]+") + (progn + (goto-char (match-end 0)) + (string-to-number (match-string 0))) + 0)))) -(defun increment-register (number register) - "Add NUMBER to the contents of register REGISTER. +(defun increment-register (number name) + "Add NUMBER to the value of the register named NAME. Interactively, NUMBER is the prefix arg." (interactive "p\ncIncrement register: ") - (or (numberp (get-register register)) - (error "Register does not contain a number")) - (set-register register (+ number (get-register register)))) - -(defun view-register (register) - "Display what is contained in register named REGISTER. -The Lisp value REGISTER is a character." + (let ((register (register-find name :error))) + (or (numberp (register-value register)) + (error "Register does not contain a number")) + (register-make name (+ number (register-value register))))) + +(defun view-register (name) + "Display what is contained in register named NAME." (interactive "cView register: ") - (let ((val (get-register register))) - (if (null val) - (message "Register %s is empty" (single-key-description register)) - (with-output-to-temp-buffer "*Output*" - (describe-register-1 register t))))) + (let* ((register (register-find name :error)) + (val (register-value register))) + (with-output-to-temp-buffer "*Output*" + (describe-register-1 register t)))) (defun list-registers () "Display a list of nonempty registers saying briefly what they contain." (interactive) - (let ((list (copy-sequence register-alist))) - (setq list (sort list (lambda (a b) (< (car a) (car b))))) + (let (names register) + (register-map (lambda (r) (push (register-name r) names))) + (setq names (sort names '<)) (with-output-to-temp-buffer "*Output*" - (dolist (elt list) - (when (get-register (car elt)) - (describe-register-1 (car elt)) + (dolist (name names) + (setq register (register-find name)) + (when (and register (register-value register)) + (describe-register-1 register) (terpri)))))) (defun describe-register-1 (register &optional verbose) (princ "Register ") - (princ (single-key-description register)) + (princ (single-key-description (register-name register))) (princ " contains ") - (let ((val (get-register register))) + (let ((val (register-value register)) + (print-func (register-print-func register))) (cond + (print-func (funcall print-func val)) + ((numberp val) (princ val)) @@ -276,17 +330,18 @@ (princ "Garbage:\n") (if verbose (prin1 val)))))) -(defun insert-register (register &optional arg) - "Insert contents of register REGISTER. (REGISTER is a character.) +(defun insert-register (name &optional arg) + "Insert the value of the register named NAME. Normally puts point before and mark after the inserted text. If optional second arg is non-nil, puts mark before and point after. Interactively, second arg is non-nil if prefix arg is supplied." (interactive "*cInsert register: \nP") - (push-mark) - (let ((val (get-register register))) + (let* ((register (register-find name :error)) + (val (register-value register)) + (insert-func (register-insert-func register))) + (push-mark) (cond - ((consp val) - (insert-rectangle val)) + (insert-func (funcall insert-func val)) ((stringp val) (insert-for-yank val)) ((numberp val) @@ -301,55 +356,54 @@ (error "Register does not contain text")))) (if (not arg) (exchange-point-and-mark))) -(defun copy-to-register (register start end &optional delete-flag) - "Copy region into register REGISTER. +(defun copy-to-register (name start end &optional delete-flag) + "Copy region into register named NAME. 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 copy." (interactive "cCopy to register: \nr\nP") - (set-register register (filter-buffer-substring start end)) + (register-make name (filter-buffer-substring start end)) (if delete-flag (delete-region start end))) -(defun append-to-register (register start end &optional delete-flag) - "Append region to text in register REGISTER. +(defun append-to-register (name start end &optional delete-flag) + "Append region to text in register named NAME. 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." (interactive "cAppend to register: \nr\nP") - (let ((reg (get-register register)) - (text (filter-buffer-substring start end))) - (set-register - register (cond ((not reg) text) - ((stringp reg) (concat reg text)) - (t (error "Register does not contain text"))))) + (let* ((register (register-find name)) + (val (and register (register-value register))) + (text (filter-buffer-substring start end))) + (assert (string-or-null-p val) nil "Register does not contain text") + (register-make name (concat val text))) (if delete-flag (delete-region start end))) -(defun prepend-to-register (register start end &optional delete-flag) - "Prepend region to text in register REGISTER. +(defun prepend-to-register (name start end &optional delete-flag) + "Prepend region to text in register named NAME. 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." (interactive "cPrepend to register: \nr\nP") - (let ((reg (get-register register)) - (text (filter-buffer-substring start end))) - (set-register - register (cond ((not reg) text) - ((stringp reg) (concat text reg)) - (t (error "Register does not contain text"))))) + (let* ((register (register-find name)) + (val (and register (register-value register))) + (text (filter-buffer-substring start end))) + (assert (string-or-null-p val) nil "Register does not contain text") + (register-make name (concat text val))) (if delete-flag (delete-region start end))) -(defun copy-rectangle-to-register (register start end &optional delete-flag) - "Copy rectangular region into register REGISTER. +(defun copy-rectangle-to-register (name start end &optional delete-flag) + "Copy rectangular region into register named NAME. With prefix arg, delete as well. To insert this register in the buffer, use \\[insert-register]. Called from a program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions giving two corners of rectangle." (interactive "cCopy rectangle to register: \nr\nP") - (set-register register - (if delete-flag - (delete-extract-rectangle start end) - (extract-rectangle start end)))) + (register-make name + (if delete-flag + (delete-extract-rectangle start end) + (extract-rectangle start end)) + :insert-func #'insert-rectangle)) (provide 'register) ;;; register.el ends here --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 03 08:34:54 2011 Received: (at control) by debbugs.gnu.org; 3 Apr 2011 12:34:54 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6MW5-0007dt-TG for submit@debbugs.gnu.org; Sun, 03 Apr 2011 08:34:54 -0400 Received: from mail-iy0-f172.google.com ([209.85.210.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6MW3-0007dg-VZ for control@debbugs.gnu.org; Sun, 03 Apr 2011 08:34:52 -0400 Received: by iye19 with SMTP id 19so5027931iye.3 for ; Sun, 03 Apr 2011 05:34:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:subject:date:message-id:user-agent :mime-version:content-type; bh=qMZr5/5VagzvrjO8UYFrE1zkX3ja2oinc/arWtGuZF0=; b=qSvVlZAtkwUOzz6THyBF3Ds1+76aIqmsaOoQvCaKTcgNDBzmlLjnBA+l1mWuKTQEeX OMH2+nvCrNt/hM1gjbnCKtmsi8XzEIJ7+az5kB+TdN2lxoxm/AHxS3c9L/VIArG62Pds TUy1T258njKv1WnnDzjL5ZKWg7vS5ngwRsO2E= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:message-id:user-agent:mime-version :content-type; b=iZowV8+TtSWNXAHaVEitkgAgopHxNL9bQhk1omLmOcbstiVji7C5eMsS0fDcHZcee5 pGSl1DIRb+rsWUyeqkFVaUScDwFhOJkQpyXGwkaNZHq1+IPTRTRj8A7tDMhU8Nk5giVs s9cXYGEwQ4v10+TkUHV+W0R/+9sl5vlKfINdo= Received: by 10.43.49.201 with SMTP id vb9mr8807400icb.436.1301834086192; Sun, 03 Apr 2011 05:34:46 -0700 (PDT) Received: from th041156.ip.tsinghua.edu.cn ([114.249.16.204]) by mx.google.com with ESMTPS id y10sm2953282iba.63.2011.04.03.05.34.43 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 03 Apr 2011 05:34:45 -0700 (PDT) From: Leo To: control@debbugs.gnu.org Subject: nothing Date: Sun, 03 Apr 2011 20:34:39 +0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Score: -4.1 (----) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.0 (----) tags 8415 patch From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 03 13:22:06 2011 Received: (at 8415) by debbugs.gnu.org; 3 Apr 2011 17:22:06 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6R01-0006Dw-H2 for submit@debbugs.gnu.org; Sun, 03 Apr 2011 13:22:05 -0400 Received: from mail-px0-f170.google.com ([209.85.212.170]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6Qzv-0006DO-D0 for 8415@debbugs.gnu.org; Sun, 03 Apr 2011 13:22:04 -0400 Received: by pxi19 with SMTP id 19so2245953pxi.29 for <8415@debbugs.gnu.org>; Sun, 03 Apr 2011 10:21:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:message-id:date:from:user-agent:mime-version:to :cc:subject:references:in-reply-to:x-enigmail-version:content-type; bh=qtTlE2eBIm9RPbHqbGCIk+/e6eOtGBlYgFBu5RvsKxY=; b=kr8swc0s2BQYYmVrjHjV5Gjp+aBDHBb3rySNqRXemgKls7Samv0Sr6gI6gF54S0BHS iv7p+vrmnv2ZyiNifZKm3/J6oJmalWQWA095IcN17fv9fY9imQqgzy3nSgboE6+N6g2v rTvfxYeUCihIwkeErSMXJgxzNrPd71ycQVkYM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:x-enigmail-version:content-type; b=whfmxKvfTXZhDPwO+Qj+OB2aruAXW2ZTTMI3QX7zUR8zrJNTxSuNc7D5WI6VQbLeDL hhN06jeEszKehgEVzFS6pHZbmA8qda2xYxutOZNG32VVbGHyISjx5YaG4poXtBHXpA4k hp5yvQWQHPtP8dbs6scf8G1HqAKVZ6w0iDzVA= Received: by 10.143.21.31 with SMTP id y31mr5531607wfi.377.1301851313342; Sun, 03 Apr 2011 10:21:53 -0700 (PDT) Received: from [192.168.1.2] (c-67-183-23-114.hsd1.wa.comcast.net [67.183.23.114]) by mx.google.com with ESMTPS id n4sm6315432wfl.14.2011.04.03.10.21.51 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 03 Apr 2011 10:21:52 -0700 (PDT) Message-ID: <4D98ACA9.6040207@gmail.com> Date: Sun, 03 Apr 2011 10:21:45 -0700 From: Daniel Colascione User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 MIME-Version: 1.0 To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: In-Reply-To: X-Enigmail-Version: 1.1.1 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig91C229ED1D035B1BA341F571" X-Spam-Score: -4.4 (----) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.3 (----) This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig91C229ED1D035B1BA341F571 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Leo, On 4/3/11 5:29 AM, Leo wrote: > I would like to propose the following patch that makes the register > system easier to hook into. With this change, for example, if one wants= > to make a command to save a keyboard macro to a register. There is no > need to change register.el. 3rd party libraries such as undo-tree.el ca= n > add registers of undo state that one can jump to with C-x r j. >=20 > With this change, register is now a compound data structure. I have als= o > removed one inconsistent use of the argument REGISTER. In the new code > it always refers to the register object and never the name. Thanks for doing this work. Why is window configuration special-cased instead of going through the function hooking mechanism? "Any customized data" might be parsed as referring to the customize mechanism; "any value" would suffice. increment and append don't have extension points. It'd be reasonable for a non-text register type to support these operations in some sense. Other than that, it good okay to me. Thanks, Daniel Colascione --------------enig91C229ED1D035B1BA341F571 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (Darwin) iEYEARECAAYFAk2YrK4ACgkQ17c2LVA10VvWygCgukfUR6g43LZivn+vQOKiQ0GB /lkAoLFHyqDfY47szmy5SiPp6Cnzr7SY =KX0H -----END PGP SIGNATURE----- --------------enig91C229ED1D035B1BA341F571-- From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 03 21:29:46 2011 Received: (at 8415) by debbugs.gnu.org; 4 Apr 2011 01:29:46 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6Ybx-0001M3-TN for submit@debbugs.gnu.org; Sun, 03 Apr 2011 21:29:46 -0400 Received: from mail-iw0-f172.google.com ([209.85.214.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6Ybv-0001Lq-Aq for 8415@debbugs.gnu.org; Sun, 03 Apr 2011 21:29:44 -0400 Received: by iwn39 with SMTP id 39so5227670iwn.3 for <8415@debbugs.gnu.org>; Sun, 03 Apr 2011 18:29:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=gs8OVV/4KfVik+ylosQzhDJAGkJIOoE7/720iQVAfJc=; b=KDewuO19AJjLR4wAl249hzE1/NiLicIyolUD3J8JPRsWeRw2N54ceXMx3J4TGC6J+q q+GWHNUH50fRdmJCEwqcNm0mu2aOsSZ14eb+rQnFQxjakDOewbvCFpopv8IkBxCTXmun ICRkfj7rcbNUZ+ZvigEyCuwzyBh5Opsx/QYNQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=Jm6DLuG9pbUrx9x89zS3f2aogzX5huUPsXOhuEXH0bhBpvm1Nx6HC7M4gIvst/dIxo jTS7hPcxwGOZC2mgybRaOVLJdwbKG3v/UqViRG/WGIJtgNyiJC10uHQs1h5xw4mA5+e9 9/Jcy5OjuEILeiIbxEN5JDYlfadY5Ele9mCzw= Received: by 10.42.146.133 with SMTP id j5mr9516274icv.327.1301880577480; Sun, 03 Apr 2011 18:29:37 -0700 (PDT) Received: from th041153.ip.tsinghua.edu.cn (th041085.ip.tsinghua.edu.cn [59.66.41.85]) by mx.google.com with ESMTPS id gy41sm3367849ibb.39.2011.04.03.18.29.34 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 03 Apr 2011 18:29:36 -0700 (PDT) From: Leo To: Daniel Colascione Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D98ACA9.6040207@gmail.com> Date: Mon, 04 Apr 2011 09:29:31 +0800 In-Reply-To: <4D98ACA9.6040207@gmail.com> (Daniel Colascione's message of "Sun, 03 Apr 2011 10:21:45 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Score: -4.0 (----) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.0 (----) On 2011-04-04 01:21 +0800, Daniel Colascione wrote: > Thanks for doing this work. Why is window configuration special-cased > instead of going through the function hooking mechanism? I plan (in a subsequent patch to this) to break down jump-to-register, describe-register-1 etc and move the pieces to where they belong using the new implementation including moving semantic tag support back to cedet. > "Any customized data" might be parsed as referring to the customize > mechanism; "any value" would suffice. Thanks. I have changed this as suggested. > increment and append don't have extension points. It'd be reasonable > for a non-text register type to support these operations in some > sense. Agreed. On the other hand, we could add these support very quickly should someone ask for them. I don't know what to do here. Should we add them now? An updated patch can be found here: http://paste.pocoo.org/show/365119 (only small tweaks). Leo From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 10:29:20 2011 Received: (at 8415) by debbugs.gnu.org; 4 Apr 2011 14:29:20 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6kmO-0002xi-Er for submit@debbugs.gnu.org; Mon, 04 Apr 2011 10:29:20 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.181] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6kmM-0002xU-QT for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 10:29:19 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAE/VmU1Ld/Y6/2dsb2JhbAClXniIebcEhWsElj8 X-IronPort-AV: E=Sophos;i="4.63,297,1299474000"; d="scan'208";a="103075220" Received: from 75-119-246-58.dsl.teksavvy.com (HELO pastel.home) ([75.119.246.58]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 04 Apr 2011 10:29:11 -0400 Received: by pastel.home (Postfix, from userid 20848) id 8FDDA58DF1; Mon, 4 Apr 2011 10:29:11 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: Date: Mon, 04 Apr 2011 10:29:11 -0400 In-Reply-To: (Leo's message of "Sun, 03 Apr 2011 20:29:02 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , Daniel Colascione , 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) > I would like to propose the following patch that makes the register > system easier to hook into. With this change, for example, if one wants > to make a command to save a keyboard macro to a register. There is no > need to change register.el. 3rd party libraries such as undo-tree.el can > add registers of undo state that one can jump to with C-x r j. Sounds good. > -(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. > +;;; in-memeory persistency Please capitalize your comments and add a closing ".". Why "memeory"? ;-) > +(defvar register-hash-table (make-hash-table)) Why change it to a hash-table? > +;;; immutable register object > +(defstruct > + (register (:constructor nil) > + (:constructor register--make (name &optional value print-func > + jump-func insert-func extra)) > + (:copier nil) > + (:type list) > + :named) > + (name nil :read-only t) > + (value nil :read-only t) > + (print-func nil :read-only t) > + (jump-func nil :read-only t) > + (insert-func nil :read-only t) > + (extra nil :read-only t)) Remove `extra': it's unused, undocumented, and doesn't seem to be any use (there's already `value'). > +VALUE may be a string, number, marker or list. IIUC this is not true any more, it can be any value. > +(define-obsolete-function-alias 'set-register 'register-make "24.1") > +(make-obsolete 'get-register "use `register-find' and `register-value'." "24.1") 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. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 13:37:27 2011 Received: (at 8415) by debbugs.gnu.org; 4 Apr 2011 17:37:27 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6niQ-0007BB-Hi for submit@debbugs.gnu.org; Mon, 04 Apr 2011 13:37:27 -0400 Received: from mail-iy0-f172.google.com ([209.85.210.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6niN-0007Av-Dj for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 13:37:24 -0400 Received: by iye19 with SMTP id 19so6041893iye.3 for <8415@debbugs.gnu.org>; Mon, 04 Apr 2011 10:37:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=9mk6gxbscPoFZZ3Y4lZl0KXYCFG4HiT6c7QsksOSVLA=; b=pZAXTkn1ipIdBuF8dBiROtGBF1TgfJhDjeD4MuXuKwWCosHOkB/KyhJ6whP4yyU9yf RSObGJuSI6bm4KgS9sm9xYUM9ubD1c1ikLWONAdSAWCtRFhP687/abEI/IDI23Ffq12h tBnD1j66n0OiyLx7tReX5M2KZZiUy8TllZZek= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=PY5fDJoS6/EzUOupf1MtHN2MqY4Jm/E2KIdghdlWk9tPlnA5UsXNpDSPdbJ9OWWXa4 uAOm36/LfqMoU7W/TwEZCK7rakcNuY+NTWVH/NzPNETbLZwoVYiSUll9hHRXOkWl4M+g zMNo/isRYh2XFnpYJ+uKBxv/93uaqj46VeEvI= Received: by 10.42.56.75 with SMTP id y11mr252485icg.295.1301938637775; Mon, 04 Apr 2011 10:37:17 -0700 (PDT) Received: from th041153.ip.tsinghua.edu.cn (th041107.ip.tsinghua.edu.cn [59.66.41.107]) by mx.google.com with ESMTPS id mv26sm3878140ibb.45.2011.04.04.10.37.11 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 04 Apr 2011 10:37:14 -0700 (PDT) From: Leo To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: Date: Tue, 05 Apr 2011 01:37:07 +0800 In-Reply-To: (Stefan Monnier's message of "Mon, 04 Apr 2011 10:29:11 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -4.0 (----) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , Daniel Colascione , 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.0 (----) --=-=-= On 2011-04-04 22:29 +0800, Stefan Monnier wrote: > Please capitalize your comments and add a closing ".". > Why "memeory"? ;-) Fixed. >> +(defvar register-hash-table (make-hash-table)) > > Why change it to a hash-table? It is simpler to work with. No need to check if a register named ?a is defined or not, just override it whenever making a new register. > Remove `extra': it's unused, undocumented, and doesn't seem to be any > use (there's already `value'). Done. >> +VALUE may be a string, number, marker or list. > > IIUC this is not true any more, it can be any value. It can be any value but all the user commands may not be able to deal with it. This patch removes this limit (for the major user commands). >> +(define-obsolete-function-alias 'set-register 'register-make "24.1") >> +(make-obsolete 'get-register "use `register-find' and `register-value'." "24.1") > > 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. So we will have to make almost all values a struct anyway to fix bugs like this: the original insert-register checks a value is a cons cell and called insert-rectangle on it, which fails for file-query registers and possible other values too. 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. > Stefan --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=register2.diff Content-Description: register2.diff === modified file 'lisp/register.el' --- lisp/register.el 2011-01-25 04:08:28 +0000 +++ lisp/register.el 2011-04-04 17:31:27 +0000 @@ -28,6 +28,8 @@ ;; pieces of buffer state to named variables. The entry points are ;; documented in the Emacs user's manual. +(eval-when-compile (require 'cl)) + (declare-function semantic-insert-foreign-tag "semantic/tag" (foreign-tag)) (declare-function semantic-tag-buffer "semantic/tag" (tag)) (declare-function semantic-tag-start "semantic/tag" (tag)) @@ -50,9 +52,26 @@ ;;; Code: -(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. +;;; In-memory persistency. +(defvar register-hash-table (make-hash-table)) + +;;; Immutable register object. +(defstruct + (register (:constructor nil) + (:constructor register--make (name &optional value print-func + jump-func insert-func)) + (:copier nil) + (:type list) + :named) + (name nil :read-only t) + (value nil :read-only t) + (print-func nil :read-only t) + (jump-func nil :read-only t) + (insert-func nil :read-only t)) + +(defun* register-make (name value &key print-func jump-func insert-func) + "Return a newly created register with NAME and VALUE. +VALUE may be a string, number, marker or list. 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 @@ -61,53 +80,79 @@ A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point.") + represents a saved frame configuration plus a saved value of point. -(defun get-register (register) - "Return contents of Emacs register named REGISTER, or nil if none." - (cdr (assq register register-alist))) - -(defun set-register (register value) - "Set contents of Emacs register named REGISTER to VALUE. Returns VALUE. -See the documentation of the variable `register-alist' for possible VALUEs." - (let ((aelt (assq register register-alist))) - (if aelt - (setcdr aelt value) - (push (cons register value) register-alist)) - value)) +VALUE may also be any value. -(defun point-to-register (register &optional arg) - "Store current location of point in register REGISTER. +PRINT-FUNC if provided controls how `list-registers' and +`view-register' print the register. It should be a function +recieving one argument VALUE and print text that completes +this sentence: + Register X contains [TEXT PRINTED BY PRINT-FUNC] + +JUMP-FUNC if provided, controls how `jump-to-register' jumps to the register. +INSERT-FUNC if provided, controls how `insert-register' insert the register. +They both receive the VALUE of the register as argument." + (let ((register (register--make name value print-func + jump-func insert-func))) + (puthash name register register-hash-table) + register)) + +(defun register-find (name &optional if-does-not-exist) + "Find the register named NAME and return it. +If IF-DOES-NOT-EXIST is :error, signal an error; otherwise return nil." + (let ((register (gethash name register-hash-table))) + (or register (case if-does-not-exist + (:error (error "Register named `%s' does not exist" + (single-key-description name))) + (otherwise nil))))) + +(defun register-map (function) + "Apply FUNCTION to each register for side effects only. +FUNCTION should accept one argument - the register." + (maphash (lambda (name register) + (funcall function register)) register-hash-table)) + +(define-obsolete-function-alias 'set-register 'register-make "24.1") +(make-obsolete 'get-register "\ +use `register-find' and `register-value' instead." "24.1") + +(defun get-register (name) + "Return the value of register named NAME or nil if none." + (ignore-errors (register-value (register-find name :error)))) + +(defun point-to-register (name &optional arg) + "Store current location of point in a register. With prefix argument, store current frame configuration. Use \\[jump-to-register] to go to that location or restore that configuration. Argument is a character, naming the register." (interactive "cPoint to register: \nP") ;; Turn the marker into a file-ref if the buffer is killed. (add-hook 'kill-buffer-hook 'register-swap-out nil t) - (set-register register - (if arg (list (current-frame-configuration) (point-marker)) - (point-marker)))) + (register-make name + (if arg (list (current-frame-configuration) (point-marker)) + (point-marker)))) -(defun window-configuration-to-register (register &optional arg) - "Store the window configuration of the selected frame in register REGISTER. +(defun window-configuration-to-register (name &optional arg) + "Store the window configuration of the selected frame in a register. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." (interactive "cWindow configuration to register: \nP") ;; current-window-configuration does not include the value ;; of point in the current buffer, so record that separately. - (set-register register (list (current-window-configuration) (point-marker)))) + (register-make name (list (current-window-configuration) (point-marker)))) -(defun frame-configuration-to-register (register &optional arg) - "Store the window configuration of all frames in register REGISTER. +(defun frame-configuration-to-register (name &optional arg) + "Store the window configuration of all frames in a register. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." (interactive "cFrame configuration to register: \nP") ;; current-frame-configuration does not include the value ;; of point in the current buffer, so record that separately. - (set-register register (list (current-frame-configuration) (point-marker)))) + (register-make name (list (current-frame-configuration) (point-marker)))) (defalias 'register-to-point 'jump-to-register) -(defun jump-to-register (register &optional delete) +(defun jump-to-register (name &optional delete) "Move point to location stored in a register. If the register contains a file name, find that file. \(To put a file name in a register, you must use `set-register'.) @@ -118,8 +163,11 @@ delete any existing frames that the frame configuration doesn't mention. \(Otherwise, these frames are iconified.)" (interactive "cJump to register: \nP") - (let ((val (get-register register))) + (let* ((register (register-find name :error)) + (val (register-value register)) + (jump-func (register-jump-func register))) (cond + (jump-func (funcall jump-func val)) ((and (consp val) (frame-configuration-p (car val))) (set-frame-configuration (car val) (not delete)) (goto-char (cadr val))) @@ -150,65 +198,71 @@ (defun register-swap-out () "Turn markers into file-query references when a buffer is killed." (and buffer-file-name - (dolist (elem register-alist) - (and (markerp (cdr elem)) - (eq (marker-buffer (cdr elem)) (current-buffer)) - (setcdr elem - (list 'file-query - buffer-file-name - (marker-position (cdr elem)))))))) + (register-map + (lambda (register) + (let ((val (register-value register))) + (and (markerp val) + (eq (marker-buffer val) (current-buffer)) + (register-make (register-name register) + (list 'file-query + buffer-file-name + (marker-position val))))))))) -(defun number-to-register (number register) +(defun number-to-register (number name) "Store a number in a register. -Two args, NUMBER and REGISTER (a character, naming the register). +Two args, NUMBER and NAME (a character, naming the register). If NUMBER is nil, a decimal number is read from the buffer starting at point, and point moves to the end of that number. Interactively, NUMBER is the prefix arg (none means nil)." (interactive "P\ncNumber to register: ") - (set-register register - (if number - (prefix-numeric-value number) - (if (looking-at "\\s-*-?[0-9]+") - (progn - (goto-char (match-end 0)) - (string-to-number (match-string 0))) - 0)))) + (register-make name + (if number + (prefix-numeric-value number) + (if (looking-at "\\s-*-?[0-9]+") + (progn + (goto-char (match-end 0)) + (string-to-number (match-string 0))) + 0)))) -(defun increment-register (number register) - "Add NUMBER to the contents of register REGISTER. +(defun increment-register (number name) + "Add NUMBER to the value of the register named NAME. Interactively, NUMBER is the prefix arg." (interactive "p\ncIncrement register: ") - (or (numberp (get-register register)) - (error "Register does not contain a number")) - (set-register register (+ number (get-register register)))) - -(defun view-register (register) - "Display what is contained in register named REGISTER. -The Lisp value REGISTER is a character." + (let ((register (register-find name :error))) + (or (numberp (register-value register)) + (error "Register does not contain a number")) + (register-make name (+ number (register-value register))))) + +(defun view-register (name) + "Display what is contained in register named NAME." (interactive "cView register: ") - (let ((val (get-register register))) - (if (null val) - (message "Register %s is empty" (single-key-description register)) - (with-output-to-temp-buffer "*Output*" - (describe-register-1 register t))))) + (let* ((register (register-find name :error)) + (val (register-value register))) + (with-output-to-temp-buffer "*Output*" + (describe-register-1 register t)))) (defun list-registers () "Display a list of nonempty registers saying briefly what they contain." (interactive) - (let ((list (copy-sequence register-alist))) - (setq list (sort list (lambda (a b) (< (car a) (car b))))) + (let (names register) + (register-map (lambda (r) (push (register-name r) names))) + (setq names (sort names '<)) (with-output-to-temp-buffer "*Output*" - (dolist (elt list) - (when (get-register (car elt)) - (describe-register-1 (car elt)) + (dolist (name names) + (setq register (register-find name)) + (when (and register (register-value register)) + (describe-register-1 register) (terpri)))))) (defun describe-register-1 (register &optional verbose) (princ "Register ") - (princ (single-key-description register)) + (princ (single-key-description (register-name register))) (princ " contains ") - (let ((val (get-register register))) + (let ((val (register-value register)) + (print-func (register-print-func register))) (cond + (print-func (funcall print-func val)) + ((numberp val) (princ val)) @@ -276,17 +330,18 @@ (princ "Garbage:\n") (if verbose (prin1 val)))))) -(defun insert-register (register &optional arg) - "Insert contents of register REGISTER. (REGISTER is a character.) +(defun insert-register (name &optional arg) + "Insert the value of the register named NAME. Normally puts point before and mark after the inserted text. If optional second arg is non-nil, puts mark before and point after. Interactively, second arg is non-nil if prefix arg is supplied." (interactive "*cInsert register: \nP") - (push-mark) - (let ((val (get-register register))) + (let* ((register (register-find name :error)) + (val (register-value register)) + (insert-func (register-insert-func register))) + (push-mark) (cond - ((consp val) - (insert-rectangle val)) + (insert-func (funcall insert-func val)) ((stringp val) (insert-for-yank val)) ((numberp val) @@ -301,55 +356,54 @@ (error "Register does not contain text")))) (if (not arg) (exchange-point-and-mark))) -(defun copy-to-register (register start end &optional delete-flag) - "Copy region into register REGISTER. +(defun copy-to-register (name start end &optional delete-flag) + "Copy region into register named NAME. 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 copy." (interactive "cCopy to register: \nr\nP") - (set-register register (filter-buffer-substring start end)) + (register-make name (filter-buffer-substring start end)) (if delete-flag (delete-region start end))) -(defun append-to-register (register start end &optional delete-flag) - "Append region to text in register REGISTER. +(defun append-to-register (name start end &optional delete-flag) + "Append region to text in register named NAME. 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." (interactive "cAppend to register: \nr\nP") - (let ((reg (get-register register)) - (text (filter-buffer-substring start end))) - (set-register - register (cond ((not reg) text) - ((stringp reg) (concat reg text)) - (t (error "Register does not contain text"))))) + (let* ((register (register-find name)) + (val (and register (register-value register))) + (text (filter-buffer-substring start end))) + (assert (string-or-null-p val) nil "Register does not contain text") + (register-make name (concat val text))) (if delete-flag (delete-region start end))) -(defun prepend-to-register (register start end &optional delete-flag) - "Prepend region to text in register REGISTER. +(defun prepend-to-register (name start end &optional delete-flag) + "Prepend region to text in register named NAME. 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." (interactive "cPrepend to register: \nr\nP") - (let ((reg (get-register register)) - (text (filter-buffer-substring start end))) - (set-register - register (cond ((not reg) text) - ((stringp reg) (concat text reg)) - (t (error "Register does not contain text"))))) + (let* ((register (register-find name)) + (val (and register (register-value register))) + (text (filter-buffer-substring start end))) + (assert (string-or-null-p val) nil "Register does not contain text") + (register-make name (concat text val))) (if delete-flag (delete-region start end))) -(defun copy-rectangle-to-register (register start end &optional delete-flag) - "Copy rectangular region into register REGISTER. +(defun copy-rectangle-to-register (name start end &optional delete-flag) + "Copy rectangular region into register named NAME. With prefix arg, delete as well. To insert this register in the buffer, use \\[insert-register]. Called from a program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions giving two corners of rectangle." (interactive "cCopy rectangle to register: \nr\nP") - (set-register register - (if delete-flag - (delete-extract-rectangle start end) - (extract-rectangle start end)))) + (register-make name + (if delete-flag + (delete-extract-rectangle start end) + (extract-rectangle start end)) + :insert-func #'insert-rectangle)) (provide 'register) ;;; register.el ends here --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 18:19:25 2011 Received: (at 8415) by debbugs.gnu.org; 4 Apr 2011 22:19:25 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6s7J-0005fa-7K for submit@debbugs.gnu.org; Mon, 04 Apr 2011 18:19:25 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.183] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6s7H-0005fP-Qz for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 18:19:24 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAHhDmk1Ld/Y6/2dsb2JhbAClY3iIeboShWsElj8 X-IronPort-AV: E=Sophos;i="4.63,299,1299474000"; d="scan'208";a="103160661" Received: from 75-119-246-58.dsl.teksavvy.com (HELO pastel.home) ([75.119.246.58]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 04 Apr 2011 18:19:13 -0400 Received: by pastel.home (Postfix, from userid 20848) id F1F6858C5B; Mon, 4 Apr 2011 18:19:12 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: Date: Mon, 04 Apr 2011 18:19:12 -0400 In-Reply-To: (Leo's message of "Tue, 05 Apr 2011 01:37:07 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , Daniel Colascione , 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) >> 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))) From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 18:27:39 2011 Received: (at 8415) by debbugs.gnu.org; 4 Apr 2011 22:27:39 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6sFG-0005qV-Mr for submit@debbugs.gnu.org; Mon, 04 Apr 2011 18:27:39 -0400 Received: from mail-pv0-f172.google.com ([74.125.83.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6sFE-0005qI-8C for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 18:27:37 -0400 Received: by pvh1 with SMTP id 1so788080pvh.3 for <8415@debbugs.gnu.org>; Mon, 04 Apr 2011 15:27:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:message-id:date:from:user-agent:mime-version:to :cc:subject:references:in-reply-to:content-type :content-transfer-encoding; bh=XZtYl4YX/hsGByxdtg2NHYNDYhLff/tdVJNTiJh+Pn8=; b=S/a1FBQlptRNGMKaZWbj+WklkkVY3hDsrlYsMttHd3XIb/+2UVZpCRNsDMSNiSQLBc z9b1cRC/SRZoAnhelaBmdN1uJZ82jI+iLmmDG3A/T7Y61SXFe/MJBXPoFU2eg7Ggxfux 36Ct3zNkn6YJVCicbr48YjfhlqJZcwJ23K/mI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=SCGfh89pnq+jtCBGRqw5wBhvY8NFVJEYdfmdl2jO+h846Q8mn45DQgdy4Qw6CxaxY6 /iT16PB/e43+eXLAkwIxApNyiMEZ1Ld199WqsKh91SGpeEOkSkqwXlt4tQyCMHqji8Bn udf7TODPcxfuwN3b4j/dHGsRxctCiKIJNW/TU= Received: by 10.142.250.20 with SMTP id x20mr6598799wfh.391.1301956050187; Mon, 04 Apr 2011 15:27:30 -0700 (PDT) Received: from [0.0.0.0] (c-67-183-23-114.hsd1.wa.comcast.net [67.183.23.114]) by mx.google.com with ESMTPS id n4sm8115947wfl.14.2011.04.04.15.27.27 (version=SSLv3 cipher=OTHER); Mon, 04 Apr 2011 15:27:28 -0700 (PDT) Message-ID: <4D9A45CD.4030808@gmail.com> Date: Mon, 04 Apr 2011 15:27:25 -0700 From: Daniel Colascione User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -4.3 (----) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Leo X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.3 (----) On 4/4/2011 3:19 PM, Stefan Monnier wrote: >>> 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). Polymorphism-via-typecase is delicate at best no matter what language we're working in. >> 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. What's wrong with getting it over with now? >> 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: I'd still prefer Leo's approach here. Accessing register values directly wasn't common anyway, so the change shouldn't affect user code. If we're going to change the code, then IMHO it's better to start with a clean, orthogonal design where both existing cases and extensions use the same polymorphic system. All other things being equal, it's better to have one code path than two. I'd also slightly prefer Leo's structure approach to the dispatcher-function one below. Using separate struct fields leads to register-value-creating code more explicitly showing which operations are supported, and it also allows the register operation code to do something consistent when a particular register doesn't support some particular operation. Under the dispatcher function approach, the common register code has no idea whether a register value is going to do something intelligent with the given operation. > > === 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))) > From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 21:41:39 2011 Received: (at 8415) by debbugs.gnu.org; 5 Apr 2011 01:41:39 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6vH1-0001Ye-L0 for submit@debbugs.gnu.org; Mon, 04 Apr 2011 21:41:39 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.183] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6vGy-0001YR-TK for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 21:41:37 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAFhymk1Ld/Y6/2dsb2JhbAClaHiIebovhWsElkU X-IronPort-AV: E=Sophos;i="4.63,300,1299474000"; d="scan'208";a="103194464" Received: from 75-119-246-58.dsl.teksavvy.com (HELO ceviche.home) ([75.119.246.58]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 04 Apr 2011 21:41:30 -0400 Received: by ceviche.home (Postfix, from userid 20848) id 9C82E660B0; Mon, 4 Apr 2011 21:41:30 -0400 (EDT) From: Stefan Monnier To: Daniel Colascione Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> Date: Mon, 04 Apr 2011 21:41:30 -0400 In-Reply-To: <4D9A45CD.4030808@gmail.com> (Daniel Colascione's message of "Mon, 04 Apr 2011 15:27:25 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Leo X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) >> 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). > Polymorphism-via-typecase is delicate at best no matter what language we're > working in. [ Irrelevant side-comment: Completely depends on the problem at hand: it makes adding "methods" much easier. ] >>> 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. > What's wrong with getting it over with now? It's the difference between "one simple obviously correct change" and "one big change that might be correct". > I'd also slightly prefer Leo's structure approach to the > dispatcher-function one below. I tend to agree, tho both kind of suck: we'd want real objects with dynamic dispatch instead. Stefan From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 21:49:58 2011 Received: (at 8415) by debbugs.gnu.org; 5 Apr 2011 01:49:58 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6vP3-0001jn-SR for submit@debbugs.gnu.org; Mon, 04 Apr 2011 21:49:58 -0400 Received: from mail-yx0-f172.google.com ([209.85.213.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6vP1-0001jb-Us for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 21:49:56 -0400 Received: by yxk30 with SMTP id 30so2349517yxk.3 for <8415@debbugs.gnu.org>; Mon, 04 Apr 2011 18:49:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:message-id:date:from:user-agent:mime-version:to :cc:subject:references:in-reply-to:x-enigmail-version:content-type; bh=mtFgeROog1EqyDxDBTXAGj4SAZuexI+sZvetxt1EfOA=; b=bbmK372w3jsYa7lIlDuy1EDQ0rFQNiF2S3Y5ZtuZ5+uId/FdP0s/UhYUeBQGPt3+NU CQDRteyrEtupIit4Bo8aQx/bqcQjAtclPPb+e5WI6xQ/51AEIeSdyJa8YW+AgV80C8GS wRzVBuLeV4nH1yilOS4iLDZuO9wAnj86QoeZQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:x-enigmail-version:content-type; b=hWoXTZgdzKXineXE2xmr/7/mMnE2hr6QXSUq0OIFtXSew7uMeW9gkPp9CIvGZXcBd+ pq+gJzih4YBIBGeS/I1L2EWqLj99SPJ0uJhfABEW36VqUnfAx/z/eJw1OoxFsulGtXDw NXyO+cMV4f2VfzguZhi6CKE2G4WjcRERP91HY= Received: by 10.150.62.1 with SMTP id k1mr7252761yba.382.1301968190278; Mon, 04 Apr 2011 18:49:50 -0700 (PDT) Received: from edith.local (c-67-183-23-114.hsd1.wa.comcast.net [67.183.23.114]) by mx.google.com with ESMTPS id y5sm2623467yhc.83.2011.04.04.18.49.48 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 04 Apr 2011 18:49:49 -0700 (PDT) Message-ID: <4D9A7537.5030005@gmail.com> Date: Mon, 04 Apr 2011 18:49:43 -0700 From: Daniel Colascione User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 MIME-Version: 1.0 To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D9A45CD.4030808@gmail.com> In-Reply-To: X-Enigmail-Version: 1.1.1 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigA2E182B906140D7A46DAC46C" X-Spam-Score: -4.3 (----) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Leo X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.3 (----) This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigA2E182B906140D7A46DAC46C Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 4/4/11 6:41 PM, Stefan Monnier wrote: >> Polymorphism-via-typecase is delicate at best no matter what language = we're >> working in. >=20 > [ Irrelevant side-comment: Completely depends on the problem at hand: i= t > makes adding "methods" much easier. ] IMHO, those situations are the exceptions. >>>> So we will have to make almost all values a struct anyway to fix bug= s >>>> 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 throu= gh >>> register structs as well. >> What's wrong with getting it over with now? >=20 > It's the difference between "one simple obviously correct change" and > "one big change that might be correct". I see your point, though both approaches would be pretty small changes in the scheme of things. If you want to split the change into smaller steps, that's fine so long as we eventually aim to get rid of the typecase polymorphism. >> I'd also slightly prefer Leo's structure approach to the >> dispatcher-function one below. >=20 > I tend to agree, tho both kind of suck: we'd want real objects with > dynamic dispatch instead. Well, there's EIEIO. It gives you the ability to easily add methods while not baking the dispatch into each one. On the other hand, it's a quite a bit of code to pull into the core at runtime. --------------enigA2E182B906140D7A46DAC46C Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (Darwin) iEYEARECAAYFAk2adToACgkQ17c2LVA10Vs28gCfaPTpqbzouL/4SIZlaEe9Yh/H MyAAoLok1BmMKW9ib665aDRgE0d8NyA4 =586L -----END PGP SIGNATURE----- --------------enigA2E182B906140D7A46DAC46C-- From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 04 23:07:19 2011 Received: (at 8415) by debbugs.gnu.org; 5 Apr 2011 03:07:19 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6wbu-0003P4-SW for submit@debbugs.gnu.org; Mon, 04 Apr 2011 23:07:19 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.183] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6wbo-0003Om-LX for 8415@debbugs.gnu.org; Mon, 04 Apr 2011 23:07:17 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAEKGmk1Ld/Y6/2dsb2JhbAClZ3iIebl9hWsElkU X-IronPort-AV: E=Sophos;i="4.63,301,1299474000"; d="scan'208";a="103208940" Received: from 75-119-246-58.dsl.teksavvy.com (HELO ceviche.home) ([75.119.246.58]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 04 Apr 2011 23:07:05 -0400 Received: by ceviche.home (Postfix, from userid 20848) id 3F814660B0; Mon, 4 Apr 2011 23:07:05 -0400 (EDT) From: Stefan Monnier To: Daniel Colascione Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Mon, 04 Apr 2011 23:07:05 -0400 In-Reply-To: <4D9A7537.5030005@gmail.com> (Daniel Colascione's message of "Mon, 04 Apr 2011 18:49:43 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Leo X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) >> It's the difference between "one simple obviously correct change" and >> "one big change that might be correct". > I see your point, though both approaches would be pretty small changes > in the scheme of things. If you want to split the change into smaller > steps, that's fine so long as we eventually aim to get rid of the > typecase polymorphism. The end point is pretty much the same, but all the intermediate steps are safe and easy to check. > Well, there's EIEIO. It gives you the ability to easily add methods > while not baking the dispatch into each one. On the other hand, it's a > quite a bit of code to pull into the core at runtime. Indeed. Stefan From debbugs-submit-bounces@debbugs.gnu.org Tue Apr 05 01:42:36 2011 Received: (at 8415) by debbugs.gnu.org; 5 Apr 2011 05:42:36 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6z2C-0006ka-7e for submit@debbugs.gnu.org; Tue, 05 Apr 2011 01:42:36 -0400 Received: from mail-iy0-f172.google.com ([209.85.210.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q6z2A-0006kO-4D for 8415@debbugs.gnu.org; Tue, 05 Apr 2011 01:42:34 -0400 Received: by iye19 with SMTP id 19so36113iye.3 for <8415@debbugs.gnu.org>; Mon, 04 Apr 2011 22:42:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=/SiyOYZal1AwURY7qTz2onhB/AQxcthUaP5Gtra8u7c=; b=FOn7KjFuO+yWUQLMJwj3gMFBpVxQR4Y4VDfHbUcCGoez98g9oUpuz9jDbRZGDC8Hsy SiefFloWxsCMwDepwKaUoqH+VJAW4l0Uvtwvx2OFBM4BwEvfrrAsra5Yv6lO6kTi2Rl6 Ehdlvvv5okZjQP3mcMhdGl6H3XKA2XF9P8boc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=X890STDOpXw/O6NfFNVUVtOXTFXajqQLTHljoCbEgzXbrumtkFMpQL30mBMM39AfQb KSrElA6/cbqVSKs673OaTI8+L3dDd80GM08lZ8ALMTAcziGKq9z3fJ5CsbewxOU9V8ZJ 6EmyFYDW1YQn2OmugfF1zfaT4rAWPSuR+77sA= Received: by 10.42.1.81 with SMTP id 17mr2140425icf.465.1301982148115; Mon, 04 Apr 2011 22:42:28 -0700 (PDT) Received: from th041153.ip.tsinghua.edu.cn ([111.194.93.79]) by mx.google.com with ESMTPS id va4sm3935323icb.15.2011.04.04.22.42.24 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 04 Apr 2011 22:42:27 -0700 (PDT) From: Leo To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Tue, 05 Apr 2011 13:42:20 +0800 In-Reply-To: (Stefan Monnier's message of "Mon, 04 Apr 2011 23:07:05 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Score: -3.6 (---) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Daniel Colascione X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.6 (---) On 2011-04-05 11:07 +0800, Stefan Monnier wrote: > The end point is pretty much the same, but all the intermediate steps > are safe and easy to check. I think a structure still is a better approach. It offers uniformity and allows access to the value stored in each slot so one can easily build a new register reusing values from an old one which, in some use cases (defadvice), can be convenient. >> Well, there's EIEIO. It gives you the ability to easily add methods >> while not baking the dispatch into each one. On the other hand, it's a >> quite a bit of code to pull into the core at runtime. > > Indeed. I have thought about using EIEIO in the beginning and ruled it out since it is required at run time. Leo From debbugs-submit-bounces@debbugs.gnu.org Tue Apr 05 09:50:25 2011 Received: (at 8415) by debbugs.gnu.org; 5 Apr 2011 13:50:25 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q76eH-0001Qs-62 for submit@debbugs.gnu.org; Tue, 05 Apr 2011 09:50:25 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.181] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q76eE-0001Qf-Tl for 8415@debbugs.gnu.org; Tue, 05 Apr 2011 09:50:24 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEAGcdm01FpZU1/2dsb2JhbAClaHiIebovhWsElkY X-IronPort-AV: E=Sophos;i="4.63,304,1299474000"; d="scan'208";a="103269377" Received: from 69-165-149-53.dsl.teksavvy.com (HELO pastel.home) ([69.165.149.53]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 05 Apr 2011 09:50:16 -0400 Received: by pastel.home (Postfix, from userid 20848) id 9C55558C65; Tue, 5 Apr 2011 09:50:16 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Tue, 05 Apr 2011 09:50:16 -0400 In-Reply-To: (Leo's message of "Tue, 05 Apr 2011 13:42:20 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Daniel Colascione X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) >> The end point is pretty much the same, but all the intermediate steps >> are safe and easy to check. > I think a structure still is a better approach. I already agreed in the previous message. Stefan From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 06 01:00:24 2011 Received: (at 8415) by debbugs.gnu.org; 6 Apr 2011 05:00:24 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7Kqt-0005QL-Nm for submit@debbugs.gnu.org; Wed, 06 Apr 2011 01:00:24 -0400 Received: from mail-iy0-f172.google.com ([209.85.210.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7Kqr-0005QA-TN for 8415@debbugs.gnu.org; Wed, 06 Apr 2011 01:00:22 -0400 Received: by iye19 with SMTP id 19so1052304iye.3 for <8415@debbugs.gnu.org>; Tue, 05 Apr 2011 22:00:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=0W63zKyBvP7hVeiKvHV91pdnvNnWIDDnZatrPOgPARw=; b=GOSMLUN1TWKicwrixA+XlsHPTXeikLtfOtJ+7Mt4GgwhxLIwIIbip4Mh2gwlPak0zO VnDYlt/4e96c/Ws6xFWH1zd5NIE/PfDlrjYybLI/KjWl2DIQZTHI+Zk7xKZw0aXPtjRF tOSvJszvkc4fsAyjcsX7OlJrO9E/XZtG55MAU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=dfutmpVsbC5HoRGZjWLVh/WzM8wTqPKS4bgXmHL4epdTXO/ofF8KDlZhh/Wb95Bv3Q hvlz3vpqFfHPIt80os5zTP5kL0Py0bK1uriS1oaTvGsf2QCDJFSnq+H1fRRkky21xnFN jnz3GqB7ZL5U6j0iltvhlIuQvaMwf8XGTQvSA= Received: by 10.42.141.198 with SMTP id p6mr849696icu.100.1302066016253; Tue, 05 Apr 2011 22:00:16 -0700 (PDT) Received: from th041153.ip.tsinghua.edu.cn (th041093.ip.tsinghua.edu.cn [59.66.41.93]) by mx.google.com with ESMTPS id mv26sm156650ibb.11.2011.04.05.22.00.10 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 05 Apr 2011 22:00:14 -0700 (PDT) From: Leo To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Wed, 06 Apr 2011 13:00:04 +0800 In-Reply-To: (Stefan Monnier's message of "Tue, 05 Apr 2011 09:50:16 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Score: -3.9 (---) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Daniel Colascione X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.9 (---) On 2011-04-05 21:50 +0800, Stefan Monnier wrote: >>> The end point is pretty much the same, but all the intermediate steps >>> are safe and easy to check. >> I think a structure still is a better approach. > > I already agreed in the previous message. > > > Stefan Sorry if I have missed that. The alternative you propose, i.e. making the value a structure is actually the first approach I attempted in http://article.gmane.org/gmane.emacs.devel/137781. 1. all existing register-creating commands need to use the new implementation, so the patch won't be any smaller. 2. needs explicitly creating a register-value struct i.e. (register-set ?a (register-value-make ....)). If change register-set to implicitly convert to a struct then it has the same incompatible change as I proposed in this bug report. So the alternative doesn't offer anything better. If you are agreeable to the patch in http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8415#19, I am ready to watch closely for any incoming bugs that related to register.el and fix them as quickly as I can. Leo From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 06 11:38:53 2011 Received: (at 8415) by debbugs.gnu.org; 6 Apr 2011 15:38:53 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7Uom-0003ef-9l for submit@debbugs.gnu.org; Wed, 06 Apr 2011 11:38:52 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.181] helo=ironport2-out.pppoe.ca) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7Uoj-0003eN-AJ for 8415@debbugs.gnu.org; Wed, 06 Apr 2011 11:38:50 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvsEALuInE1FpZU1/2dsb2JhbACld3iIebhkhWwElFmCEg X-IronPort-AV: E=Sophos;i="4.63,310,1299474000"; d="scan'208";a="103426173" Received: from 69-165-149-53.dsl.teksavvy.com (HELO pastel.home) ([69.165.149.53]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 06 Apr 2011 11:38:43 -0400 Received: by pastel.home (Postfix, from userid 20848) id 0DCF858C65; Wed, 6 Apr 2011 11:38:43 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Wed, 06 Apr 2011 11:38:43 -0400 In-Reply-To: (Leo's message of "Wed, 06 Apr 2011 13:00:04 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.1 (--) X-Debbugs-Envelope-To: 8415 Cc: Davis Herring , 8415@debbugs.gnu.org, Daniel Colascione X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.1 (--) >>>>> "Leo" == Leo writes: > On 2011-04-05 21:50 +0800, Stefan Monnier wrote: >>>> The end point is pretty much the same, but all the intermediate steps >>>> are safe and easy to check. >>> I think a structure still is a better approach. >> >> I already agreed in the previous message. >> >> >> Stefan > Sorry if I have missed that. > The alternative you propose, i.e. making the value a structure is > actually the first approach I attempted in > http://article.gmane.org/gmane.emacs.devel/137781. I think that's a better approach, yes (tho I'd pass the register object to the functions, so instead of: (let* ((object (register-get register)) (val (if (register-p object) (register-info object) object)) (jump (and (register-p object) (register-jump-func object)))) (cond (jump (funcall jump val)) you just have (let* ((object (register-get register)) (jump (and (register-p object) (register-jump-func object)))) (cond (jump (funcall jump object)) or (let* ((object (register-get register))) (cond ((register-p object) (funcall (or (register-jump-func object) (error "Don't know how to jump")) object)) > 1. all existing register-creating commands need to use the new > implementation, so the patch won't be any smaller. That's for subsequent patches. > 2. needs explicitly creating a register-value struct i.e. > (register-set ?a (register-value-make ....)). I see that as a feature. Stefan From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 06 23:15:39 2011 Received: (at submit) by debbugs.gnu.org; 7 Apr 2011 03:15:39 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7fh5-0003EM-Fz for submit@debbugs.gnu.org; Wed, 06 Apr 2011 23:15:39 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q7fgy-0003E3-0X for submit@debbugs.gnu.org; Wed, 06 Apr 2011 23:15:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q7fgr-0001pm-M3 for submit@debbugs.gnu.org; Wed, 06 Apr 2011 23:15:26 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_RP_MATCHES_RCVD, T_TO_NO_BRKTS_FREEMAIL autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([199.232.76.165]:36913) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q7fgr-0001ph-Hx for submit@debbugs.gnu.org; Wed, 06 Apr 2011 23:15:25 -0400 Received: from [140.186.70.92] (port=35553 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q7fgq-00069a-6l for bug-gnu-emacs@gnu.org; Wed, 06 Apr 2011 23:15:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q7ffc-0001XI-Jw for bug-gnu-emacs@gnu.org; Wed, 06 Apr 2011 23:14:09 -0400 Received: from lo.gmane.org ([80.91.229.12]:54455) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q7ffc-0001XB-74 for bug-gnu-emacs@gnu.org; Wed, 06 Apr 2011 23:14:08 -0400 Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1Q7ffZ-0007XR-Fz for bug-gnu-emacs@gnu.org; Thu, 07 Apr 2011 05:14:05 +0200 Received: from th041122.ip.tsinghua.edu.cn ([59.66.41.122]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 07 Apr 2011 05:14:05 +0200 Received: from sdl.web by th041122.ip.tsinghua.edu.cn with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 07 Apr 2011 05:14:05 +0200 X-Injected-Via-Gmane: http://gmane.org/ To: bug-gnu-emacs@gnu.org From: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Date: Thu, 07 Apr 2011 11:13:49 +0800 Lines: 60 Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Complaints-To: usenet@dough.gmane.org X-Gmane-NNTP-Posting-Host: th041122.ip.tsinghua.edu.cn Face: iVBORw0KGgoAAAANSUhEUgAAACgAAAAoBAMAAAB+0KVeAAAAElBMVEUAAAAAAP+LRRP0pGC+ vr7///+7mT1iAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9cBBwMO DhglKe4AAAEsSURBVCjPbZNBboQwDEV/Cd4X9QJRThApmn0XYW+Jyf2v0m+HhqDBgiAe9rcTG7QH w/1Vn2Ar8gBb/ocywSN3qK9T3z4eFDB4eApocBpeBs1RSykoJd8gQcm8pGmHXFso3ajnmsqV0TnY DQkOfXUfN5NwaI7AWTVOyEhcu1aHmdWItHddUVUcUgUBCkitu8V6ditHVOVdqzl2EQ1ZVGTbdK0V 7cqn8vWzoU5Q/bF9Y/Y0cRU1xwkys5dJ+Dt6pBDWifcNQml8Gh2JVmPSoQzo7en0grswkxrUGYJ7 0hSxxAGr7ZMwYcHIzprpi7TENEE1xtiYxixRlCfPBsUUrwHD7uGIwATrbnODJcVrPpVn3hxiGloe m/S+z3CtuzUSMo83N4DPH+F0evwR3P4A2k+75838OKQAAAAASUVORK5CYII= User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) Cancel-Lock: sha1:1Zl1/s5ffQxgSayswmiWoHl/MPQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 199.232.76.165 X-Spam-Score: -5.1 (-----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -5.1 (-----) On 2011-04-06 23:38 +0800, Stefan Monnier wrote: > I think that's a better approach, yes (tho I'd pass the register object > to the functions, so instead of: > > (let* ((object (register-get register)) > (val (if (register-p object) > (register-info object) > object)) > (jump (and (register-p object) > (register-jump-func object)))) > (cond > (jump (funcall jump val)) > > you just have > > (let* ((object (register-get register)) > (jump (and (register-p object) > (register-jump-func object)))) > (cond > (jump (funcall jump object)) > > or > > (let* ((object (register-get register))) > (cond > ((register-p object) (funcall (or (register-jump-func object) > (error "Don't know how to jump")) > object)) I am lost here. VAL is needed in the rest of the function, the old code. So you can't just omit it. >> 1. all existing register-creating commands need to use the new >> implementation, so the patch won't be any smaller. > > That's for subsequent patches. The intention is to have a clean uniform extensible internal representation of registers so subsequent patches are completely trivial which I opted to omit for now so that people can focus on more important changes. Somehow that didn't work out well. >> 2. needs explicitly creating a register-value struct i.e. >> (register-set ?a (register-value-make ....)). > > I see that as a feature. If register-value-make is not used, 'typecase polymorphism' has to be used. If we were to eliminate 'typecase polymorphism', register-value-make is required. For me, (register-make ...) is just simpler. One of the reasons that the first patch I posted to emacs-devel evolved to the one I submitted in this bug report. It just has selectors and three public function register-make, register-find, register-map. The rest of code can just build on top of them. Leo From debbugs-submit-bounces@debbugs.gnu.org Fri Apr 08 21:25:18 2011 Received: (at submit) by debbugs.gnu.org; 9 Apr 2011 01:25:18 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q8MvO-0001qm-0N for submit@debbugs.gnu.org; Fri, 08 Apr 2011 21:25:18 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Q8MvL-0001qa-Nz for submit@debbugs.gnu.org; Fri, 08 Apr 2011 21:25:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q8MvF-0003Pc-VG for submit@debbugs.gnu.org; Fri, 08 Apr 2011 21:25:10 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([199.232.76.165]:60599) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q8MvF-0003PT-Sp for submit@debbugs.gnu.org; Fri, 08 Apr 2011 21:25:09 -0400 Received: from [140.186.70.92] (port=58267 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q8MvE-0001DT-VL for bug-gnu-emacs@gnu.org; Fri, 08 Apr 2011 21:25:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q8MvC-0003ON-Mt for bug-gnu-emacs@gnu.org; Fri, 08 Apr 2011 21:25:08 -0400 Received: from fencepost.gnu.org ([140.186.70.10]:33269) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q8MvC-0003O9-CY for bug-gnu-emacs@gnu.org; Fri, 08 Apr 2011 21:25:06 -0400 Received: from 213-159-126-200.fibertel.com.ar ([200.126.159.213]:56038 helo=ceviche.home) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Q8MvB-0005qW-UM; Fri, 08 Apr 2011 21:25:06 -0400 Received: by ceviche.home (Postfix, from userid 20848) id F2405660B0; Fri, 8 Apr 2011 21:25:02 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Fri, 08 Apr 2011 22:25:02 -0300 In-Reply-To: (Leo's message of "Thu, 07 Apr 2011 11:13:49 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 199.232.76.165 X-Spam-Score: -6.0 (------) X-Debbugs-Envelope-To: submit Cc: bug-gnu-emacs@gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.0 (------) >> I think that's a better approach, yes (tho I'd pass the register object >> to the functions, so instead of: >> >> (let* ((object (register-get register)) >> (val (if (register-p object) >> (register-info object) >> object)) >> (jump (and (register-p object) >> (register-jump-func object)))) >> (cond >> (jump (funcall jump val)) >> >> you just have >> >> (let* ((object (register-get register)) >> (jump (and (register-p object) >> (register-jump-func object)))) >> (cond >> (jump (funcall jump object)) >> >> or >> >> (let* ((object (register-get register))) >> (cond >> ((register-p object) (funcall (or (register-jump-func object) >> (error "Don't know how to jump")) >> object)) > I am lost here. VAL is needed in the rest of the function, the old code. > So you can't just omit it. In the rest of the function register-p is false, so `val' = `object'. >>> 1. all existing register-creating commands need to use the new >>> implementation, so the patch won't be any smaller. >> That's for subsequent patches. > The intention is to have a clean uniform extensible internal > representation of registers so subsequent patches are completely trivial > which I opted to omit for now so that people can focus on more important > changes. Somehow that didn't work out well. The patches will be just as clean with the other approach. Try it. >>> 2. needs explicitly creating a register-value struct i.e. >>> (register-set ?a (register-value-make ....)). >> I see that as a feature. > If register-value-make is not used, 'typecase polymorphism' has to be > used. If we were to eliminate 'typecase polymorphism', > register-value-make is required. `typecase polymorphism' is what we have, and after the addition I suggest we can remove it little by little. > It just has selectors and three public function register-make, > register-find, register-map. The rest of code can just build on top of > them. With the alist representation, register-find and register-map aren't even needed. Stefan From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 23 04:11:58 2011 Received: (at submit) by debbugs.gnu.org; 23 Jun 2011 08:11:58 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QZf14-0000C9-DB for submit@debbugs.gnu.org; Thu, 23 Jun 2011 04:11:58 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QZf12-0000Bx-CI for submit@debbugs.gnu.org; Thu, 23 Jun 2011 04:11:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QZf0v-0001SD-LN for submit@debbugs.gnu.org; Thu, 23 Jun 2011 04:11:50 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:58273) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QZf0v-0001S7-CV for submit@debbugs.gnu.org; Thu, 23 Jun 2011 04:11:49 -0400 Received: from eggs.gnu.org ([140.186.70.92]:38935) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QZf0t-00079Y-Mp for bug-gnu-emacs@gnu.org; Thu, 23 Jun 2011 04:11:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QZf0r-0001Rd-5L for bug-gnu-emacs@gnu.org; Thu, 23 Jun 2011 04:11:47 -0400 Received: from mail-iw0-f169.google.com ([209.85.214.169]:37501) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QZf0q-0001RR-Pn for bug-gnu-emacs@gnu.org; Thu, 23 Jun 2011 04:11:45 -0400 Received: by iwn8 with SMTP id 8so1803810iwn.0 for ; Thu, 23 Jun 2011 01:11:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=2cO7yN4yaNhR8IsBEdmeEzi9vXuQM10WI9gppXn+pSE=; b=bX7wyyEvlymgw2pgvXdOtWEfhQ3RPWSASbsa2r5H1hDWdmQtKF6Ch7NYhP9tzzgh8c YEVreBBvLJKq9LVyUano4Dm5uO/ld9l+FTiCUaS2FpsXxHvNhst5S3d9Jeur6wBKu5dM iPsbd/uILWQkaYgeOClXjphbzC4DyRmeHQ/C4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=hsSS4oEQp4QzFVkzfCsHSrUTOJvBBTfROtzWcXyXDwer1RBWR6nvs6alMTsAjqthQb yIlGAqIdQFnvFV0+ep1+Ls7ZDMopQXGd+foXWS/jx9ZV4eVaDMr7MH5XJjOTS0/6GR8b d9amI0PRFL3QVoHBihcqKuIDKUaZVBTEuaWeg= Received: by 10.42.168.2 with SMTP id u2mr1836282icy.317.1308816703699; Thu, 23 Jun 2011 01:11:43 -0700 (PDT) Received: from localhost ([114.247.10.75]) by mx.google.com with ESMTPS id vn4sm1403942icb.7.2011.06.23.01.11.36 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 23 Jun 2011 01:11:42 -0700 (PDT) From: Leo To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Thu, 23 Jun 2011 16:11:27 +0800 In-Reply-To: (Stefan Monnier's message of "Fri, 08 Apr 2011 22:25:02 -0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -5.9 (-----) X-Debbugs-Envelope-To: submit Cc: bug-gnu-emacs@gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -5.9 (-----) --=-=-= Content-Type: text/plain Hello Stefan, Is this patch OK? --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=reg.diff Content-Description: reg.diff === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-23 03:35:05 +0000 +++ lisp/ChangeLog 2011-06-23 07:46:05 +0000 @@ -1,3 +1,11 @@ +2011-06-23 Leo Liu + + * register.el (registerv): New struct. + (registerv-make): New function. + (jump-to-register, describe-register-1, insert-register): Support + the jump-func, print-func and insert-func slot of a registerv + struct. + 2011-06-22 Leo Liu * minibuffer.el (completing-read-function) === modified file 'lisp/register.el' --- lisp/register.el 2011-04-19 13:44:55 +0000 +++ lisp/register.el 2011-06-23 05:07:49 +0000 @@ -28,6 +28,8 @@ ;; pieces of buffer state to named variables. The entry points are ;; documented in the Emacs user's manual. +(eval-when-compile (require 'cl)) + (declare-function semantic-insert-foreign-tag "semantic/tag" (foreign-tag)) (declare-function semantic-tag-buffer "semantic/tag" (tag)) (declare-function semantic-tag-start "semantic/tag" (tag)) @@ -50,9 +52,36 @@ ;;; Code: +(defstruct + (registerv (:constructor nil) + (:constructor registerv--make (&optional data print-func + jump-func insert-func)) + (:copier nil) + (:type list) + :named) + (data nil :read-only t) + (print-func nil :read-only t) + (jump-func nil :read-only t) + (insert-func nil :read-only t)) + +(defun* registerv-make (data &key print-func jump-func insert-func) + "Create a register value object. + +DATA can be any value. +PRINT-FUNC if provided controls how `list-registers' and +`view-register' print the register. It should be a function +recieving one argument DATA and print text that completes +this sentence: + Register X contains [TEXT PRINTED BY PRINT-FUNC] +JUMP-FUNC if provided, controls how `jump-to-register' jumps to the register. +INSERT-FUNC if provided, controls how `insert-register' insert the register. +They both receive DATA as argument." + (registerv--make data print-func jump-func insert-func)) + (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 is a string, number, marker, list +or a struct returned by `registerv-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 @@ -118,8 +147,10 @@ delete any existing frames that the frame configuration doesn't mention. \(Otherwise, these frames are iconified.)" (interactive "cJump to register: \nP") - (let ((val (get-register register))) + (let* ((val (get-register register)) + (jump-func (and (registerv-p val) (registerv-jump-func val)))) (cond + (jump-func (funcall jump-func (registerv-data val))) ((and (consp val) (frame-configuration-p (car val))) (set-frame-configuration (car val) (not delete)) (goto-char (cadr val))) @@ -207,8 +238,11 @@ (princ "Register ") (princ (single-key-description register)) (princ " contains ") - (let ((val (get-register register))) + (let* ((val (get-register register)) + (print-func (and (registerv-p val) (registerv-print-func val)))) (cond + (print-func (funcall print-func (registerv-data val))) + ((numberp val) (princ val)) @@ -283,8 +317,10 @@ Interactively, second arg is non-nil if prefix arg is supplied." (interactive "*cInsert register: \nP") (push-mark) - (let ((val (get-register register))) + (let* ((val (get-register register)) + (insert-func (and (registerv-p val) (registerv-insert-func val)))) (cond + (insert-func (funcall insert-func (registerv-data val))) ((consp val) (insert-rectangle val)) ((stringp val) --=-=-= Content-Type: text/plain Leo --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Jun 25 09:20:07 2011 Received: (at submit) by debbugs.gnu.org; 25 Jun 2011 13:20:07 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QaSmM-0001nO-9k for submit@debbugs.gnu.org; Sat, 25 Jun 2011 09:20:06 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QaSmK-0001ms-JB for submit@debbugs.gnu.org; Sat, 25 Jun 2011 09:20:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QaSmE-0004bT-En for submit@debbugs.gnu.org; Sat, 25 Jun 2011 09:19:59 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:50073) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaSmE-0004bP-DP for submit@debbugs.gnu.org; Sat, 25 Jun 2011 09:19:58 -0400 Received: from eggs.gnu.org ([140.186.70.92]:50957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaSmD-0006NG-8D for bug-gnu-emacs@gnu.org; Sat, 25 Jun 2011 09:19:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QaSmC-0004b3-9w for bug-gnu-emacs@gnu.org; Sat, 25 Jun 2011 09:19:57 -0400 Received: from ironport2-out.teksavvy.com ([206.248.154.183]:48911 helo=ironport2-out.pppoe.ca) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaSmC-0004ay-6L for bug-gnu-emacs@gnu.org; Sat, 25 Jun 2011 09:19:56 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAN3dBU5MCqDH/2dsb2JhbABTp0d4iHTBV4YwBJ4RhCk X-IronPort-AV: E=Sophos;i="4.65,424,1304308800"; d="scan'208";a="117113299" Received: from 76-10-160-199.dsl.teksavvy.com (HELO pastel.home) ([76.10.160.199]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 25 Jun 2011 09:19:51 -0400 Received: by pastel.home (Postfix, from userid 20848) id 0098958FD6; Sat, 25 Jun 2011 09:19:50 -0400 (EDT) From: Stefan Monnier To: Leo Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers Message-ID: References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Sat, 25 Jun 2011 09:19:50 -0400 In-Reply-To: (Leo's message of "Thu, 23 Jun 2011 16:11:27 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -4.1 (----) X-Debbugs-Envelope-To: submit Cc: bug-gnu-emacs@gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.1 (----) > Is this patch OK? Looks OK, yes. > + (jump-func (funcall jump-func (registerv-data val))) But I'd pass `val' directly, so the function can use extra fields in values that inherit from registerv. You could drop the `data' field as well, at that point. This just makes it more OO, and maybe experience would show that it actually makes things worse (just adds unused extra flexibility), so I'll let you judge. Either way is OK with me. Stefan From debbugs-submit-bounces@debbugs.gnu.org Sun Jun 26 02:42:40 2011 Received: (at 8415) by debbugs.gnu.org; 26 Jun 2011 06:42:41 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Qaj3I-0002Cu-2L for submit@debbugs.gnu.org; Sun, 26 Jun 2011 02:42:40 -0400 Received: from mail-iy0-f172.google.com ([209.85.210.172]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Qaj3G-0002Cj-0y for 8415@debbugs.gnu.org; Sun, 26 Jun 2011 02:42:38 -0400 Received: by iye7 with SMTP id 7so3590824iye.3 for <8415@debbugs.gnu.org>; Sat, 25 Jun 2011 23:42:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=rojUhkcdJyXFQQH2A+Qte5TkPuow8SsoY8mBK/a8eE8=; b=Qo7oVGml4rzJjCNhw+RUJ1BaD2RMZY3QToYORzeS0AYJvTXY4G0D5vj4alnRakj/Ua Ceseb0NFfWdiw+IzgndqDKwLL+lDwmHDe2oJs4f26bKVPmCd23ZMhhKBAIeMSqop9BWm SBowV7AdY9VA8sAv/fyIWdSNPfVMmTY26c48s= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=u7mgxcZGYbrrJE5gbPRWgX9CcbWtj8tc7RwPR/jZTBygodixVCBOLgsDHMv5rn34XK GQpayGlNhScuT+i0q3wPeq2nemwoLdwNoUOUZ8ZYRk7uKYrhv63dlA+pjkZZ3Zu4lwly Bw0w6rbq+fPrA7DUhpoHBLeJwWq+GfaNL3uuI= Received: by 10.231.115.146 with SMTP id i18mr1551474ibq.22.1309070552020; Sat, 25 Jun 2011 23:42:32 -0700 (PDT) Received: from localhost ([222.130.137.63]) by mx.google.com with ESMTPS id 4sm2380313ibc.42.2011.06.25.23.42.27 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 25 Jun 2011 23:42:30 -0700 (PDT) From: Leo To: Stefan Monnier Subject: Re: bug#8415: 23.3.50; Extensible Emacs Registers References: <4D9A45CD.4030808@gmail.com> <4D9A7537.5030005@gmail.com> Date: Sun, 26 Jun 2011 14:42:19 +0800 In-Reply-To: (Stefan Monnier's message of "Sat, 25 Jun 2011 09:19:50 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -3.6 (---) X-Debbugs-Envelope-To: 8415 Cc: 8415@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.6 (---) On 2011-06-25 21:19 +0800, Stefan Monnier wrote: > But I'd pass `val' directly, so the function can use extra fields in > values that inherit from registerv. You could drop the `data' field as > well, at that point. > > This just makes it more OO, and maybe experience would show that it > actually makes things worse (just adds unused extra flexibility), so > I'll let you judge. Either way is OK with me. Thanks for the comments. From my use cases, it seems most of the time only DATA is needed and in other times closure can be used. I have made the commit for wider testing. Leo From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 09 15:58:00 2011 Received: (at control) by debbugs.gnu.org; 9 Jul 2011 19:58:01 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Qfdf5-0004Hb-5w for submit@debbugs.gnu.org; Sat, 09 Jul 2011 15:57:59 -0400 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Qfdez-0004HN-UX for control@debbugs.gnu.org; Sat, 09 Jul 2011 15:57:56 -0400 Received: from rgm by fencepost.gnu.org with local (Exim 4.71) (envelope-from ) id 1Qfdeu-0001dl-Aa for control@debbugs.gnu.org; Sat, 09 Jul 2011 15:57:48 -0400 Date: Sat, 09 Jul 2011 15:57:48 -0400 Message-Id: Subject: control message for bug 8415 To: X-Mailer: mail (GNU Mailutils 2.1) From: Glenn Morris X-Spam-Score: -6.4 (------) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.4 (------) close 8415 24.1 From unknown Mon Jun 23 02:23:14 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sun, 07 Aug 2011 11:24:07 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator