diff options
| author | Masatake YAMATO | 2004-03-15 11:27:47 +0000 |
|---|---|---|
| committer | Masatake YAMATO | 2004-03-15 11:27:47 +0000 |
| commit | 11ece56b1ab84d0ce8add8a1241ba7062e840860 (patch) | |
| tree | 3b6035739c3019d396d5f94ba4f70fa01be262fd | |
| parent | 0eeebaf5d779e417c9582ccb1e7a1d20708f779d (diff) | |
| download | emacs-11ece56b1ab84d0ce8add8a1241ba7062e840860.tar.gz emacs-11ece56b1ab84d0ce8add8a1241ba7062e840860.zip | |
2004-03-15 Masatake YAMATO <jet@gyve.org>
Added context menu support in smerge mode.
Most of the part is written by Stefan Monnier.
* smerge-mode.el (smerge-context-menu-map, smerge-context-menu): New
keyman and menu.
(smerge-text-properties): New function.
(smerge-remove-props): New function.
(smerge-popup-context-menu): New function.
(smerge-resolve): Call `smerge-remove-props'.
(smerge-keep-base, smerge-keep-other, smerge-keep-mine):
Ditto.
(smerge-keep-current): Ditto.
(smerge-kill-current): New function.
(smerge-match-conflict): Detect the file as `a same-diff conflict'
if the filename is "ANCESTOR". Put text properties.
| -rw-r--r-- | lisp/ChangeLog | 18 | ||||
| -rw-r--r-- | lisp/smerge-mode.el | 110 |
2 files changed, 112 insertions, 16 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5a4799a913f..b9c938a089b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,21 @@ | |||
| 1 | 2004-03-15 Masatake YAMATO <jet@gyve.org> | ||
| 2 | |||
| 3 | Added context menu support in smerge mode. | ||
| 4 | Most of the part is written by Stefan Monnier. | ||
| 5 | |||
| 6 | * smerge-mode.el (smerge-context-menu-map, smerge-context-menu): New | ||
| 7 | keyman and menu. | ||
| 8 | (smerge-text-properties): New function. | ||
| 9 | (smerge-remove-props): New function. | ||
| 10 | (smerge-popup-context-menu): New function. | ||
| 11 | (smerge-resolve): Call `smerge-remove-props'. | ||
| 12 | (smerge-keep-base, smerge-keep-other, smerge-keep-mine): | ||
| 13 | Ditto. | ||
| 14 | (smerge-keep-current): Ditto. | ||
| 15 | (smerge-kill-current): New function. | ||
| 16 | (smerge-match-conflict): Detect the file as `a same-diff conflict' | ||
| 17 | if the filename is "ANCESTOR". Put text properties. | ||
| 18 | |||
| 1 | 2004-03-15 David Ponce <david@dponce.com> | 19 | 2004-03-15 David Ponce <david@dponce.com> |
| 2 | 20 | ||
| 3 | * ruler-mode.el: (ruler-mode-left-fringe-cols) | 21 | * ruler-mode.el: (ruler-mode-left-fringe-cols) |
diff --git a/lisp/smerge-mode.el b/lisp/smerge-mode.el index 711ceefedc0..742de9c2b96 100644 --- a/lisp/smerge-mode.el +++ b/lisp/smerge-mode.el | |||
| @@ -3,8 +3,7 @@ | |||
| 3 | ;; Copyright (C) 1999, 2000, 01, 03, 2004 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1999, 2000, 01, 03, 2004 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Stefan Monnier <monnier@cs.yale.edu> | 5 | ;; Author: Stefan Monnier <monnier@cs.yale.edu> |
| 6 | ;; Keywords: merge diff3 cvs conflict | 6 | ;; Keywords: revision-control merge diff3 cvs conflict |
| 7 | ;; Revision: $Id: smerge-mode.el,v 1.24 2003/10/06 16:34:59 fx Exp $ | ||
| 8 | 7 | ||
| 9 | ;; This file is part of GNU Emacs. | 8 | ;; This file is part of GNU Emacs. |
| 10 | 9 | ||
| @@ -187,6 +186,19 @@ Used in `smerge-diff-base-mine' and related functions." | |||
| 187 | :active (smerge-check 1)] | 186 | :active (smerge-check 1)] |
| 188 | )) | 187 | )) |
| 189 | 188 | ||
| 189 | (easy-mmode-defmap smerge-context-menu-map | ||
| 190 | `(([down-mouse-3] . smerge-activate-context-menu)) | ||
| 191 | "Keymap for context menu appeared on conflicts area.") | ||
| 192 | (easy-menu-define smerge-context-menu nil | ||
| 193 | "Context menu for mine area in `smerge-mode'." | ||
| 194 | '(nil | ||
| 195 | ["Keep Current" smerge-keep-current :help "Use current (at point) version"] | ||
| 196 | ["Kill Current" smerge-kill-current :help "Remove current (at point) version"] | ||
| 197 | ["Keep All" smerge-keep-all :help "Keep all three versions"] | ||
| 198 | "---" | ||
| 199 | ["More..." (popup-menu smerge-mode-menu) :help "Show full SMerge mode menu"] | ||
| 200 | )) | ||
| 201 | |||
| 190 | (defconst smerge-font-lock-keywords | 202 | (defconst smerge-font-lock-keywords |
| 191 | '((smerge-find-conflict | 203 | '((smerge-find-conflict |
| 192 | (1 smerge-mine-face prepend t) | 204 | (1 smerge-mine-face prepend t) |
| @@ -283,12 +295,53 @@ Convenient for the kind of conflicts that can arise in ChangeLog files." | |||
| 283 | The function is called with no argument and with the match data set | 295 | The function is called with no argument and with the match data set |
| 284 | according to `smerge-match-conflict'.") | 296 | according to `smerge-match-conflict'.") |
| 285 | 297 | ||
| 298 | (defvar smerge-text-properties | ||
| 299 | `(help-echo "merge conflict: mouse-3 shows a menu" | ||
| 300 | ;; mouse-face highlight | ||
| 301 | keymap (keymap (down-mouse-3 . smerge-popup-context-menu)))) | ||
| 302 | |||
| 303 | (defun smerge-remove-props (&optional beg end) | ||
| 304 | (remove-text-properties | ||
| 305 | (or beg (match-beginning 0)) | ||
| 306 | (or end (match-end 0)) | ||
| 307 | smerge-text-properties)) | ||
| 308 | |||
| 309 | (defun smerge-popup-context-menu (event) | ||
| 310 | "Pop up the Smerge mode context menu under mouse." | ||
| 311 | (interactive "e") | ||
| 312 | (if (and smerge-mode | ||
| 313 | (save-excursion (mouse-set-point event) (smerge-check 1))) | ||
| 314 | (progn | ||
| 315 | (mouse-set-point event) | ||
| 316 | (smerge-match-conflict) | ||
| 317 | (let ((i (smerge-get-current)) | ||
| 318 | o) | ||
| 319 | (if (<= i 0) | ||
| 320 | ;; Out of range | ||
| 321 | (popup-menu smerge-mode-menu) | ||
| 322 | ;; Install overlay. | ||
| 323 | (setq o (make-overlay (match-beginning i) (match-end i))) | ||
| 324 | (overlay-put o 'face 'highlight) | ||
| 325 | (sit-for 0) | ||
| 326 | (popup-menu (if (smerge-check 2) | ||
| 327 | smerge-mode-menu | ||
| 328 | smerge-context-menu)) | ||
| 329 | ;; Delete overlay. | ||
| 330 | (delete-overlay o)))) | ||
| 331 | ;; There's no conflict at point, the text-props are just obsolete. | ||
| 332 | (save-excursion | ||
| 333 | (let ((beg (re-search-backward smerge-end-re nil t)) | ||
| 334 | (end (re-search-forward smerge-begin-re nil t))) | ||
| 335 | (smerge-remove-props (or beg (point-min)) (or end (point-max))) | ||
| 336 | (push event unread-command-events))))) | ||
| 337 | |||
| 286 | (defun smerge-resolve () | 338 | (defun smerge-resolve () |
| 287 | "Resolve the conflict at point intelligently. | 339 | "Resolve the conflict at point intelligently. |
| 288 | This relies on mode-specific knowledge and thus only works in | 340 | This relies on mode-specific knowledge and thus only works in |
| 289 | some major modes. Uses `smerge-resolve-function' to do the actual work." | 341 | some major modes. Uses `smerge-resolve-function' to do the actual work." |
| 290 | (interactive) | 342 | (interactive) |
| 291 | (smerge-match-conflict) | 343 | (smerge-match-conflict) |
| 344 | (smerge-remove-props) | ||
| 292 | (funcall smerge-resolve-function) | 345 | (funcall smerge-resolve-function) |
| 293 | (smerge-auto-leave)) | 346 | (smerge-auto-leave)) |
| 294 | 347 | ||
| @@ -297,6 +350,7 @@ some major modes. Uses `smerge-resolve-function' to do the actual work." | |||
| 297 | (interactive) | 350 | (interactive) |
| 298 | (smerge-match-conflict) | 351 | (smerge-match-conflict) |
| 299 | (smerge-ensure-match 2) | 352 | (smerge-ensure-match 2) |
| 353 | (smerge-remove-props) | ||
| 300 | (replace-match (match-string 2) t t) | 354 | (replace-match (match-string 2) t t) |
| 301 | (smerge-auto-leave)) | 355 | (smerge-auto-leave)) |
| 302 | 356 | ||
| @@ -305,6 +359,7 @@ some major modes. Uses `smerge-resolve-function' to do the actual work." | |||
| 305 | (interactive) | 359 | (interactive) |
| 306 | (smerge-match-conflict) | 360 | (smerge-match-conflict) |
| 307 | ;;(smerge-ensure-match 3) | 361 | ;;(smerge-ensure-match 3) |
| 362 | (smerge-remove-props) | ||
| 308 | (replace-match (match-string 3) t t) | 363 | (replace-match (match-string 3) t t) |
| 309 | (smerge-auto-leave)) | 364 | (smerge-auto-leave)) |
| 310 | 365 | ||
| @@ -313,6 +368,7 @@ some major modes. Uses `smerge-resolve-function' to do the actual work." | |||
| 313 | (interactive) | 368 | (interactive) |
| 314 | (smerge-match-conflict) | 369 | (smerge-match-conflict) |
| 315 | ;;(smerge-ensure-match 1) | 370 | ;;(smerge-ensure-match 1) |
| 371 | (smerge-remove-props) | ||
| 316 | (replace-match (match-string 1) t t) | 372 | (replace-match (match-string 1) t t) |
| 317 | (smerge-auto-leave)) | 373 | (smerge-auto-leave)) |
| 318 | 374 | ||
| @@ -330,9 +386,23 @@ some major modes. Uses `smerge-resolve-function' to do the actual work." | |||
| 330 | (smerge-match-conflict) | 386 | (smerge-match-conflict) |
| 331 | (let ((i (smerge-get-current))) | 387 | (let ((i (smerge-get-current))) |
| 332 | (if (<= i 0) (error "Not inside a version") | 388 | (if (<= i 0) (error "Not inside a version") |
| 389 | (smerge-remove-props) | ||
| 333 | (replace-match (match-string i) t t) | 390 | (replace-match (match-string i) t t) |
| 334 | (smerge-auto-leave)))) | 391 | (smerge-auto-leave)))) |
| 335 | 392 | ||
| 393 | (defun smerge-kill-current () | ||
| 394 | "Remove the current (under the cursor) version." | ||
| 395 | (interactive) | ||
| 396 | (smerge-match-conflict) | ||
| 397 | (let ((i (smerge-get-current))) | ||
| 398 | (if (<= i 0) (error "Not inside a version") | ||
| 399 | (smerge-remove-props) | ||
| 400 | (replace-match (mapconcat | ||
| 401 | (lambda (j) | ||
| 402 | (match-string j)) | ||
| 403 | (remove i '(1 2 3)) "") t t) | ||
| 404 | (smerge-auto-leave)))) | ||
| 405 | |||
| 336 | (defun smerge-diff-base-mine () | 406 | (defun smerge-diff-base-mine () |
| 337 | "Diff 'base' and 'mine' version in current conflict region." | 407 | "Diff 'base' and 'mine' version in current conflict region." |
| 338 | (interactive) | 408 | (interactive) |
| @@ -389,20 +459,28 @@ An error is raised if not inside a conflict." | |||
| 389 | (setq mine-end (match-beginning 0)) | 459 | (setq mine-end (match-beginning 0)) |
| 390 | (setq base-start (match-end 0))) | 460 | (setq base-start (match-end 0))) |
| 391 | 461 | ||
| 392 | ((string= filename (file-name-nondirectory | 462 | ((string= filename (file-name-nondirectory |
| 393 | (or buffer-file-name ""))) | 463 | (or buffer-file-name ""))) |
| 394 | ;; a 2-parts conflict | 464 | ;; a 2-parts conflict |
| 395 | (set (make-local-variable 'smerge-conflict-style) 'diff3-E)) | 465 | (set (make-local-variable 'smerge-conflict-style) 'diff3-E)) |
| 396 | 466 | ||
| 397 | ((and (not base-start) | 467 | ((and (not base-start) |
| 398 | (or (eq smerge-conflict-style 'diff3-A) | 468 | (or (eq smerge-conflict-style 'diff3-A) |
| 399 | (string-match "^[.0-9]+\\'" filename))) | 469 | (equal filename "ANCESTOR") |
| 400 | ;; a same-diff conflict | 470 | (string-match "\\`[.0-9]+\\'" filename))) |
| 401 | (setq base-start mine-start) | 471 | ;; a same-diff conflict |
| 402 | (setq base-end mine-end) | 472 | (setq base-start mine-start) |
| 403 | (setq mine-start other-start) | 473 | (setq base-end mine-end) |
| 404 | (setq mine-end other-end))) | 474 | (setq mine-start other-start) |
| 405 | 475 | (setq mine-end other-end))) | |
| 476 | |||
| 477 | (let ((inhibit-read-only t) | ||
| 478 | (inhibit-modification-hooks t) | ||
| 479 | (m (buffer-modified-p))) | ||
| 480 | (unwind-protect | ||
| 481 | (add-text-properties start end smerge-text-properties) | ||
| 482 | (restore-buffer-modified-p m))) | ||
| 483 | |||
| 406 | (store-match-data (list start end | 484 | (store-match-data (list start end |
| 407 | mine-start mine-end | 485 | mine-start mine-end |
| 408 | base-start base-end | 486 | base-start base-end |