From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: joaotavora@gmail.com (=?iso-8859-1?Q?Jo=E3o_T=E1vora?=) Newsgroups: gmane.emacs.devel Subject: Re: PATCH: make linum.el play nicely with other margin-setting extensions Date: Fri, 13 Nov 2015 11:11:49 +0000 Message-ID: References: <5645B4F6.7000306@gmx.at> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1447413127 8527 80.91.229.3 (13 Nov 2015 11:12:07 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 13 Nov 2015 11:12:07 +0000 (UTC) Cc: markus.triska@gmx.at, emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Nov 13 12:12:02 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZxCGt-0008FI-Tc for ged-emacs-devel@m.gmane.org; Fri, 13 Nov 2015 12:12:00 +0100 Original-Received: from localhost ([::1]:52246 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxCGt-0003fm-Cg for ged-emacs-devel@m.gmane.org; Fri, 13 Nov 2015 06:11:59 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42604) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxCGp-0003d9-H6 for emacs-devel@gnu.org; Fri, 13 Nov 2015 06:11:56 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZxCGm-0000jw-AC for emacs-devel@gnu.org; Fri, 13 Nov 2015 06:11:55 -0500 Original-Received: from mail-wm0-x22b.google.com ([2a00:1450:400c:c09::22b]:38583) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxCGm-0000js-0n for emacs-devel@gnu.org; Fri, 13 Nov 2015 06:11:52 -0500 Original-Received: by wmec201 with SMTP id c201so25749594wme.1 for ; Fri, 13 Nov 2015 03:11:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type:content-transfer-encoding; bh=Y0MnE0wlq/ivtlHPmRiZvGW5QzzuSUrrf8RmN3abOEw=; b=p5K/UW5UKif9LlNZ4O4BM605+wg7vb4V55GboGhgZT8wIsE5tJurerbN28VOiMuGnf YCisvNO5dsvDTpDKx6TqWmP3AIs73WmIJVq9pHUzlW+oqHRpi9oCw1+6SeaeJkt78rPy y+7RKk47y/1iZp8b3KzPVAZrD8WPAcd7Xl3Etwf534u39hMrH7eu2JA5JSVDZI+AbWAL W/XG46PLt2RkZDo//t+6Nv2i9Uc7igqm0fVnt0HiX5VG9NoU8wh0s4r/n4MRqUAnK8Sc brqE6yjGDMxp0mi3TYZlDDeWYjn2EJjrRylqOziJS1DlFscJ+KEN2vJufQEz571rySTr g+sg== X-Received: by 10.194.184.81 with SMTP id es17mr21274433wjc.10.1447413111237; Fri, 13 Nov 2015 03:11:51 -0800 (PST) Original-Received: from GONDOMAR.yourcompany.com (mail3.siscog.pt. [195.23.29.18]) by smtp.gmail.com with ESMTPSA id y77sm3430909wme.15.2015.11.13.03.11.50 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Nov 2015 03:11:50 -0800 (PST) In-Reply-To: <5645B4F6.7000306@gmx.at> (martin rudalics's message of "Fri, 13 Nov 2015 11:01:26 +0100") User-Agent: Gnus/5, (Gnus v5.13) Emacs/25.0.50 (windows-nt) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c09::22b X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:194346 Archived-At: martin rudalics writes: >> (mapc #'delete-overlay linum-overlays) >> (setq linum-overlays nil) >> (dolist (w (get-buffer-window-list (current-buffer) nil t)) >> - (set-window-margins w 0 (cdr (window-margins w))))) >> + ;; restore margins if needed >> + (let ((set-margins (window-parameter w 'linum--set-margins)) >> + (current-margins (window-margins w))) >> + (when (and set-margins >> + (equal set-margins current-margins)) > > I suppose this will reset the left margin to zero when the "other mode" > was started after =91linum-mode=92 and incidentally used the same margin > width as =91linum-mode=92. Maybe nothing reasonable can be done about th= at. Absolutely. That's what I meant earlier by=20 >> It seems robust enough for now, but ideally linum-mode would know that >> "his" margins have been overriden interactively or by some other >> extension, and decide in accordance. Though if we come up with `left-margin-min-width' we'll probably have to come up with some `max-width' version some time in the future, no? And so on for every other window-related property. And so on for every frame-related property while we're at it. Woundn't it be nicer that a package/mode, when it so sees fit, could mark a particular window|frame|buffer setting as being "owned" by it and then query arbitrarily later if it still owns it? Clearly if *all* extensions played by these rules we would be out of the woods: the test would become (if (eq (get-setting-owner 'set-window-margins w) 'linum) ;; reset the margins to whatever was there before ;; else do nothing ) The only difficulty here is that we can't magically make all extensions abide by this rule. But we can advise 'set-window-margins to reset the owner unconditionally. What do you think of this? (defvar *setting-owners* (make-hash-table :test #'equal)) =20=20=20=20=20 (cl-defgeneric get-setting-owner (setting-setter object) "Return the proclaimed owner of SETTING-SETTER in OBJECT.") =20=20=20=20=20 (cl-defgeneric set-setting-owner (setting-setter object owner) "Return the proclaimed owner of SETTING-SETTER in OBJECT.") =20=20=20=20=20 (defmacro define-owned-setting (setting-setter) "Make the function SETTING-SETTER reset the owner when called " `(progn (advice-add ',setting-setter :after (lambda (object &rest _ignored) (set-setting-owner ',setting-setter object nil))) (cl-defmethod get-setting-owner ((setting-setter (eql ,setting-set= ter)) o) (gethash (list setting-setter o) *setting-owners*)) (cl-defmethod set-setting-owner ((setting-setter (eql ,setting-set= ter)) o owner) (if owner (puthash (list setting-setter o) owner *setting-owners*) (remhash (list setting-setter o) *setting-owners*))))) =20=20=20=20=20 (define-owned-setting set-window-margins) With this in place, my patch to linum.el becomes smaller, more robust, and more readable. Patching other extensions that compete for other window|frame|buffer|whatever resources also becomes easier. The smaller, correct patch to linum.el follows after the sign-off. Jo=E3o diff --git a/lisp/linum.el b/lisp/linum.el index 23e5605..4346d81 100644 --- a/lisp/linum.el +++ b/lisp/linum.el @@ -120,7 +120,10 @@ Linum mode is a buffer-local minor mode." (mapc #'delete-overlay linum-overlays) (setq linum-overlays nil) (dolist (w (get-buffer-window-list (current-buffer) nil t)) - (set-window-margins w 0 (cdr (window-margins w))))) + ;; restore margins if we still own that setting + ;;=20 + (if (eq (get-setting-owner 'set-window-margins w) 'linum) + (set-window-margins w 0 (cdr (window-margins w)))))) =20 (defun linum-update-current () "Update line numbers for the current buffer." @@ -178,7 +181,12 @@ Linum mode is a buffer-local minor mode." (let ((inhibit-point-motion-hooks t)) (forward-line)) (setq line (1+ line))) - (set-window-margins win width (cdr (window-margins win))))) + ;; open up space in the left margin, if needed + ;;=20 + (let ((existing-margins (window-margins win))) + (when (> width (or (car existing-margins) 0)) + (set-window-margins win width (cdr existing-margins)) + (set-setting-owner 'set-window-margins win 'linum))))) =20 (defun linum-after-change (beg end _len) ;; update overlays on deletions, and after newlines are inserted