From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Masatake YAMATO Newsgroups: gmane.emacs.devel Subject: Re: popup menu support for smerge-mode Date: Fri, 26 Sep 2003 16:58:08 +0900 (JST) Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <20030926.165808.260114910.jet@gyve.org> References: <20030919.182502.242160171.jet@gyve.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1064563258 10763 80.91.224.253 (26 Sep 2003 08:00:58 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 26 Sep 2003 08:00:58 +0000 (UTC) Cc: monnier+gnu/emacs@rum.cs.yale.edu, monnier+gnu/emacs@cs.yale.edu, emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Fri Sep 26 10:00:55 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1A2nX5-0000ZU-00 for ; Fri, 26 Sep 2003 10:00:55 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1A2nec-0005Uw-00 for ; Fri, 26 Sep 2003 10:08:42 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.22) id 1A2nW5-0001hZ-NJ for emacs-devel@quimby.gnus.org; Fri, 26 Sep 2003 03:59:53 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.22) id 1A2nVK-0001RZ-0U for emacs-devel@gnu.org; Fri, 26 Sep 2003 03:59:06 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.22) id 1A2nVF-0001MH-8j for emacs-devel@gnu.org; Fri, 26 Sep 2003 03:59:03 -0400 Original-Received: from [210.130.136.40] (helo=r-maa.spacetown.ne.jp) by monty-python.gnu.org with esmtp (Exim 4.22) id 1A2nUd-0000wD-L7 for emacs-devel@gnu.org; Fri, 26 Sep 2003 03:58:23 -0400 Original-Received: from localhost (mx.jp.redhat.com [219.96.218.186]) by r-maa.spacetown.ne.jp (8.11.6) with ESMTP id h8Q7w9O04705; Fri, 26 Sep 2003 16:58:12 +0900 (JST) Original-To: monnier@IRO.UMontreal.CA In-Reply-To: X-Mailer: Mew version 3.1.52 on Emacs 21.3 / Mule 5.0 (SAKAKI) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:16664 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:16664 > >>>> It's simpler to just place a single overlay over > >>>> the whole conflict (including markers). > >> > >>> I have not done as you wrote. > >>> I expect "Keep Current" works on the region which is highlighted. > >> > >> The highlight does not have to apply to the same region as the > >> `keymap' overlay. > > > I think applying highlight and keymap to the same region is not so > > complex....probably I have not understood the intent of your > > suggestions. > > You justified using 2 or 3 overlays over each alternative rather than > a single one over the whole conflict by saying that "keep current" > should work on the region which is highlighted. > > What I meant to reply is that you could place a single overlay over the > whole conflict with a `keymap' property and then when mouse-3 is pressed > and you add the highlight, you can create a new overlay that covers only > the relevant alternative and place the highlight there: the highlight > and the keymap do not have to apply to the same region. > > If you place the overlay over the whole conflict, then the "current" > alternative can be empty without any problem (other than the fact > that the highlighting will not aplly to any character) so you > don't need smerge-delete-current. > > BTW, I don't understand this `smerge-delete-current'. It seems to take > a conflict with a non-empty current alternative and replaces it with > a conflict with an empty current alternative, is that right ? What I said > I need is to take a conflict where the current alternative is empty and > select that alternative (i.e. just delete the whole conflict). I see. Now overlays for highlighting and a overlays for keymap are used. Each overlays for highlighting have a property named owner. Owner property could take a value; whole, mine, other, base... The popup menu is switched by the property value. mine and other uses special menus. I added "Keep alternative" to the menus. Other including whole uses the smerge menu appeared on the menu bar. smerge-delete-current is gone. > > I've removed smerge-reset-all-overlays. Instead I use evaporate property > > of overlays. When an overlay is created, I put t to evaporate property of > > the overlay. The overlay will be deleted when its region becomes empty. > > I was thinking of suggesting that but wasn't sure whether it'd work. > Does it ? If it does, it's probably the simplest alternative, indeed. `evaporate' doesn't work I expect. So I introduced suboverlays property to manage overlay deletion. Masatake YAMATO Index: lisp/smerge-mode.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/smerge-mode.el,v retrieving revision 1.22 diff -u -r1.22 smerge-mode.el --- lisp/smerge-mode.el 1 Sep 2003 15:45:14 -0000 1.22 +++ lisp/smerge-mode.el 26 Sep 2003 07:45:14 -0000 @@ -159,6 +159,31 @@ :help "Use Ediff to resolve the conflicts"] )) +(defvar smerge-overlays nil "Overlays managed by smerge-mode") +(easy-mmode-defmap smerge-popup-menu-map + `(([down-mouse-3] . smerge-activate-popup-menu)) + "Keymap for popup menu appeared on conflicts area.") +(easy-menu-define smerge-mode-mine-popup-menu nil + "Popup menu for mine area in `smerge-mode'." + '(nil + ["Keep This" smerge-keep-current :help "Use current (at point) version"] + ;; mine <-> other + ["Keep Alternative" smerge-keep-other :help "Use alternative version"] + ["Keep All" smerge-keep-all :help "Keep all three versions"] + "---" + ["More..." (popup-menu smerge-mode-menu) :help "Show full SMerge mode menu"] + )) +(easy-menu-define smerge-mode-other-popup-menu nil + "Popup menu for other area in `smerge-mode'." + '(nil + ["Keep This" smerge-keep-current :help "Use current (at point) version"] + ;; other <-> mine + ["Keep Alternative" smerge-keep-mine :help "Use alternative version"] + ["Keep All" smerge-keep-all :help "Keep all three versions"] + "---" + ["More..." (popup-menu smerge-mode-menu) :help "Show full SMerge mode menu"] + )) + (defconst smerge-font-lock-keywords '((smerge-find-conflict (1 smerge-mine-face prepend t) @@ -199,11 +224,13 @@ (error (format "No `%s'" (aref smerge-match-names n))))) (defun smerge-auto-leave () + "If no conflict left, turn off Smerge mode. +Return non-nil if the mode was indeed turned off." (when (and smerge-auto-leave (save-excursion (goto-char (point-min)) (not (re-search-forward smerge-begin-re nil t)))) - (smerge-mode -1))) - + (smerge-mode -1) + t)) (defun smerge-keep-all () "Keep all three versions. @@ -316,6 +343,92 @@ (interactive) (smerge-diff 1 3)) +(defun smerge-put-overlays (match-data) + "Put overlays of smerge-mode on the place specified by MATCH-DATA." + (let ((m (cddr match-data)) + (owners '(mine base other base-start other-start)) + (b-whole (car match-data)) + (e-whole (cadr match-data)) + b e o os) + (while m + (setq b (car m) + e (cadr m) + m (cddr m) + o (car owners) + owners (cdr owners)) + (when (and b e (not (= b e))) + (push (smerge-put-highlight-overlay b e o) + os))) + ;; highlight overlays are managed by keymap overlay. + ;; When keymap overlay is shrinked or removed, + ;; highlight overlays are removed. + (smerge-put-keymap-overlay b-whole e-whole os))) + +(defun smerge-put-highlight-overlay (start end owner) + "Put overlay of smerge-mode between START and END. +The overlay is highlight when it is pressed. +OWNER is stored to `owner' property of the new overlay." + (let ((overlay (make-overlay start end))) + (overlay-put overlay 'evaporate t) + (overlay-put overlay 'owner owner) + (push overlay smerge-overlays) + overlay)) + +(defun smerge-put-keymap-overlay (start end suboverlays) + "Put overlay of smerge-mode between START and END. +The overlay has its own keymap to show popup menu. +SUBOVERLAYS are overlays managed by this overlay." + (let ((overlay (make-overlay start end))) + (overlay-put overlay 'evaporate t) + (overlay-put overlay 'help-echo "down-mouse-3: Show popup menu") + (overlay-put overlay 'local-map smerge-popup-menu-map) + (overlay-put overlay 'owner 'whole) + (overlay-put overlay 'suboverlays suboverlays) + (push overlay smerge-overlays) + overlay)) + +(defun smerge-activate-popup-menu (event) + "Show a popup menu for smerge-mode." + (interactive "e") + (with-current-buffer (window-buffer + (posn-window (event-end event))) + (save-excursion + (goto-char (posn-point (event-end event))) + (let* ((os-at (overlays-at (point))) + (o-whole (car os-at)) + (region-whole (- (overlay-end o-whole) (overlay-start o-whole))) + (os-sub (overlay-get o-whole 'suboverlays)) + (o (if (= 1 (length os-at)) o-whole (cadr os-at))) + (owner (overlay-get o 'owner)) + (face 'highlight) + (menu smerge-mode-menu)) + ;; Set face and menu + (cond + ((eq 'mine owner) + (setq menu smerge-mode-mine-popup-menu + face 'region)) + ((eq 'other owner) + (setq menu smerge-mode-other-popup-menu + face 'region))) + ;; Highlight and show popup menu + (unwind-protect + (progn + (overlay-put o 'face face) + (sit-for 0) ;; redisplay + (popup-menu menu)) + (overlay-put o 'face nil)) + ;; Delete overlays + (when (or + (not (overlay-buffer o-whole)) ;; dead + (< (- (overlay-end o-whole) (overlay-start o-whole)) + region-whole)) ;; shrinked up + (mapc 'delete-overlay (cons o-whole os-sub))))))) + +(defun smerge-delete-overlays () + "Delete all overlays made by `smerge-put-overlay'." + (mapc 'delete-overlay smerge-overlays) + (setq smerge-overlays nil)) + (defun smerge-match-conflict () "Get info about the conflict. Puts the info in the `match-data'. The submatches contain: @@ -522,6 +635,12 @@ "Minor mode to simplify editing output from the diff3 program. \\{smerge-mode-map}" nil " SMerge" nil + ;; overlays management + (if smerge-mode + ;; entering smerge-mode + (make-variable-buffer-local 'smerge-overlays) + ;; leaving smerge-mode + (smerge-delete-overlays)) (when (and (boundp 'font-lock-mode) font-lock-mode) (set (make-local-variable 'font-lock-multiline) t) (save-excursion @@ -531,8 +650,8 @@ (goto-char (point-min)) (while (smerge-find-conflict) (save-excursion - (font-lock-fontify-region (match-beginning 0) (match-end 0) nil)))))) - + (font-lock-fontify-region (match-beginning 0) (match-end 0) nil) + (smerge-put-overlays (match-data))))))) (provide 'smerge-mode)