;;; p4-merge.el --- Glue code to interface emerge/ediff with perforce ;; Author: Paul Du Bois ;; Maintainer: dubois@infinite-machine.com ;; $Id: //depot/tools/lisp/p4-merge.el#2 $ ;;; Commentary: ;; Install the gnuserv package ;; (autoload 'p4-merge-mode "p4-merge" nil t) ;; set MERGE=emacs-merge.pl ;; ;; optional: (setq p4-merge-style 'ediff) ;;; Code: (defvar p4-merge-style 'emerge "* Package to use for merging. Possible values are 'emerge and 'ediff") (defvar p4-merge-mode-hook nil "Run near the end of p4-merge-mode, but before it processes any key bindings.") (defvar p4-merge-help-string "Commands available in this buffer: \\[p4-merge-start] to start merging \\[p4-merge-end] to end the merge (only necessary if you're using ediff) \\[p4-merge-abort] to abort (kill this buffer) You can also set p4-merge-style to 'ediff or 'emerge. ") (defvar p4-merge-started nil "Buffer-local variable that disables p4-merge-start") (defvar p4-merge-base nil) (defvar p4-merge-theirs nil) (defvar p4-merge-yours nil) (defvar p4-merge-output nil) (defvar p4-merge-mode-map nil) (if p4-merge-mode-map nil (let ((map (make-sparse-keymap))) (suppress-keymap map) (define-key map "s" 'p4-merge-start) (define-key map "e" 'p4-merge-end) (define-key map "a" 'p4-merge-abort) (setq p4-merge-mode-map map))) (defun p4-merge-mode () (interactive) (make-variable-buffer-local 'p4-merge-started) (use-local-map p4-merge-mode-map) (rename-buffer "p4-merge" t) (search-forward "Files") (forward-line 1) (mapcar (lambda (sym) (set (make-local-variable sym) (buffer-substring (point) (progn (end-of-line) (point)))) (forward-line 1)) '(p4-merge-base p4-merge-theirs p4-merge-yours p4-merge-output)) (run-hooks 'p4-merge-mode-hook) (goto-char (point-min)) (forward-line 1) (insert "\nKill this buffer to abort merge prematurely\n\n") (insert (substitute-command-keys p4-merge-help-string)) (set-buffer-modified-p nil) (setq major-mode 'p4-merge-mode mode-name "P4-Merge" buffer-read-only t)) ;; This is a separate function to get around some annoying ;; chicken-and-egg issues with emerge and ediff. (defun p4-merge-start () (interactive) (if p4-merge-started (error "Merge already started") (setq p4-merge-started t)) (cond ;; emerge ;; ((eq p4-merge-style 'emerge) (let ((quit-hook `(lambda () (kill-buffer ,(current-buffer))))) (save-excursion (emerge-files-with-ancestor nil p4-merge-yours p4-merge-theirs p4-merge-base p4-merge-output nil quit-hook)))) ;; ediff ;; Not easy to tell ediff to spit output in a certain file. ;; So make the user do it ;; ((eq p4-merge-style 'ediff) (goto-char (point-min)) (forward-line 1) (save-excursion (ediff-merge-files-with-ancestor p4-merge-yours p4-merge-theirs p4-merge-base))) (t (message "Warning: Unknown merge style")))) (defun p4-merge-end () (interactive) (if (not p4-merge-started) (error "Start merge first")) (cond ((eq p4-merge-style 'emerge) nil) ((eq p4-merge-style 'ediff) (let ((output p4-merge-output) (buf (get-buffer "*ediff-merge*"))) (if (not buf) (error "Can't find ediff merge buffer")) (save-excursion (set-buffer buf) (write-file output) (message "Finished merge.")) (kill-buffer (current-buffer)))) (t (message "Warning: Unknown merge style")))) (defun p4-merge-abort () (interactive) (kill-buffer (current-buffer))) ;;;; end of file p4-merge.el