<none>
rv at fore.comrv
rv at fore.comrv
Tue Jun 9 07:10:35 PDT 1998
>From rv at fore.com Tue Jun 9 10: 06:45 1998
Return-Path: <rv at fore.com>
Received: from mailman.fore.com (mailman.fore.com. [169.144.2.12])
by sol.eng.fore.com (8.8.8/8.8.8) with ESMTP id KAA26712
for <rv at eng.fore.com>; Tue, 9 Jun 1998 10:06:44 -0400 (EDT)
Received: from sol.eng.fore.com (sol [169.144.155.73])
by mailman.fore.com (8.8.6/8.8.6) with ESMTP id KAA19014
for <rv at fore.com>; Tue, 9 Jun 1998 10:09:24 -0400 (EDT)
Received: from agastya.fore.com (tejas [169.144.86.36])
by sol.eng.fore.com (8.8.8/8.8.8) with SMTP id KAA26708
for <rv at fore.com>; Tue, 9 Jun 1998 10:06:43 -0400 (EDT)
Received: from fore.com by agastya.fore.com (SMI-8.6/SMI-SVR4)
id KAA05959; Tue, 9 Jun 1998 10:08:06 -0400
Sender: rv at fore.com
Message-ID: <357D41C4.FC3E5380 at fore.com>
Date: Tue, 09 Jun 1998 10:08:04 -0400
From: Rajesh V <rv at fore.com>
Organization: FORE Systems, Inc.
X-Mailer: Mozilla 4.04 [en] (X11; I; SunOS 5.6 sun4u)
MIME-Version: 1.0
Newsgroups: gnu.emacs.sources
To: rv at fore.com
Subject: Re: p4.el (Perforce library v2.2) :: 2.3 Released
References: <357C6EFA.CE712C63 at fore.com>
Content-Type: multipart/mixed; boundary="------------984CD27706DB6D6382F49DAC"
Resent-To: perforce-user at perforce.com
Resent-Date: Tue, 09 Jun 1998 10:10:35 -0400
Resent-From: Rajesh Vaidheeswarran <rv at eng.fore.com>
This is a multi-part message in MIME format.
- --------------984CD27706DB6D6382F49DAC
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Folks:
After the release of 2.2, I had some more feedback and hence I decided
to release another minor release, 2.3. Thanks to all of you who passed
on your valuable feedback.
These are the changes:
New in 2.3 Release
- ------------------
1. Change all references to "GNU Emacs" and "XEmacs" to "Emacs" and
"XEmacs" respectively, since the former may mistakenly portray XEmacs as
a program that has nothing to do with GNU (It did originate from a GNU
program), which is neither fair nor accurate. The only place where the
explicit check is done for "GNU Emacs" is in the string-match.
2. Rename p4-running-gnuemacs to p4-running-emacs per the above
sentiment.
3. Add p4-set-p4-port and p4-get-p4-port to set and get the current P4
server/port that we are attached to.
Thanks
rv
- --------------984CD27706DB6D6382F49DAC
Content-Type: text/plain; charset=us-ascii; name="p4.el"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="p4.el"
;; Simple Emacs <-> Perforce Integration
;;
;; $Id: //depot/user/rv/lisp/20.2/lisp/fore/p4.el#11$
;; Applied the GNU G.P.L. to this file - rv 3/27/1997
;; Programs for Emacs <-> Perforce Integration.
;; Copyright (C) 1996, 1997 Eric Promislow
;; Copyright (C) 1997, 1998 Rajesh Vaidheeswarran
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;; If you have any problems to report, or suggestions, please send them
;; to rv at fore.com
;;
;; WARNING:
;; --------
;;
;; % p4 edit foo.c
;; ... make changes to foo.c in emacs
;; % p4 submit
;; ... keep the writable copy of foo.c in emacs. Start making changes
;; to it. Discover that you can't save it. If you do M-x:p4-edit,
;; you'll lose your changes. You need to do a 'p4 edit' at the
;; command-line.
;;
;; Original Functions: (Contributed by Eric Promislow)
;; p4-exec-p4 (not exported)
;; p4-buffer-action (not exported)
;; p4-edit
;; p4-revert
;; p4-diff
;; Modified Original Functions
;; p4-buffer-action - modified to support optional args to be passed
;; p4-edit - added help
;; p4-revert - added help
;; p4-diff - added help
;; Added Functions:
;; p4-add
;; p4-delete
;; p4-diff2
;; p4-filelog
;; p4-files
;; p4-refresh
;; p4-noinput-exec-p4 (not exported)
;; p4-noinput-buffer-action (not exported)
;; p4-get
;; p4-have
;; p4-help
;; p4-info
;; p4-integ
;; p4-opened
;; p4-users
;; p4-where
;; p4-async-commands (not exported)
;; p4-change
;; p4-client
;; p4-submit
;; p4-user
;; p4-get-client-name
;; p4-set-client-name
;; p4-find-file-hook (not exported)
;; p4-is-vc (not exported)
;; p4-check-mode (not exported)
;; p4-menu-add
;; NOTES:
;; ------
;;
;; It is best if you take this file and byte compile it. To do that, you
;; need to do the following:
;;
;; % emacs -batch -f batch-byte-compile /full/path/to/file/p4.el
;;
;; This creates a binary file p4.elc in the path. Add the path to your
;; load-path variable in .emacs like this:
;;
;; (setq load-path (cons "/full/path/to/file" load-path))
;;
;; Then add the library like this:
;;
;; (load-library "p4")
;;
;; NEW Additions in the 1.2 Release:
;;
;; Functions:
;; -----------
;; p4-set-notify-list
;; p4-get-notify-list
;; p4-notify
;; p4-emacs-version
;;
;; Modifications:
;; --------------
;; The following functions now accept prefix argument (C-u) to specify
;; optional argument like -n or ..., etc.
;;
;; p4-files, p4-refresh, p4-get, p4-have, p4-integ, p4-opened, p4-users,
;; p4-where.
;;
;; Now supports RCS/CVS type vc revision level display on mode line, and
;; menu bar support.
;;
;; NEW Additions in the 1.3 Release:
;; ---------------------------------
;; 1. "/dev/null" replaced with grep-null-device for NT compatibility
;;
;; 2. p4-is-vc now returns the version number if p4 owns the file
;;
;; 3. added p4-ediff which uses ediff to allow more interactive diffing
;;
;; 4. removed p4-noinput-exec-p4 because it was the same as p4-exec-p4.
;; p4-noinput-buffer-action and p4-buffer-action should probably be one
;; routine but I left them alone for now.
;;
;; 5. changed kill-region to delete-region to avoid kill ring clutter
;;
;; 6. replaced 'nil with nil and 't with t
;;
;; 7. removed unused p4-output-buffer
;;
;; New in 1.4 Release
;; ------------------
;; Split p4.el for Emacs and XEmacs
;;
;; New in 1.5 Release
;; ------------------
;; 1. Make p4.el work with both Emacs and XEmacs. The problem is that
;; this might cause some compilation warnings since some functions are
;; mutually exclusive and don't exist on both. But, testing has proved no
;; conflicts or problems that arise due to this.
;;
;; Functions added:
;; ----------------
;; p4-set-p4-executable p4-set-gnu-client p4-set-notifier
;; p4-emacs-server-start p4-mode-menu (For XEmacs)
;;
;; 2. Cleanup comments and a document some more functions.
;; New in 2.0 Release
;; ------------------
;; Technically, since 1.5 supports Emacs and XEmacs in the same
;; file, it should have been a major release, but all the cleanup
;; occurred only after I saw tested that thoroughly.. Hence, I'm calling
;; this 2.0
;; 1. Remove dependency on grep-null-device and use the system-type variable
;; to check this instead.
;; 2. BUGFIX: Make sure to use p4-running-gnuemacs instead of
;; running-gnuemacs and p4-running-xemacs instead of running-xemacs
;; 3. Added p4-force-mode-line-update to wrap the modeline updation
;; for different flavors of Emacs.
;; 4. Quash all compiler warnings that are independant of Emacs flavor.
;;
;; The only warnings that exist are:
;; Emacs (20.2)
;; ================
;; While compiling p4-add:
;; ** assignment to free variable p4-mode
;; While compiling p4-emacs-server-start:
;; ** reference to free variable server-process
;; While compiling p4-check-mode:
;; ** assignment to free variable p4-mode
;; While compiling the end of the data:
;; ** The following functions are not known to be defined: gnuserv-start,
;; gnuserv-running-p, p4-menu-add, redraw-modeline, easy-menu-add,
;; p4-mode-menu
;;
;; XEmacs (20.4)
;; =============
;; While compiling p4-emacs-server-start:
;; ** reference to free variable server-process
;; While compiling the end of the data:
;; ** the function server-start is not known to be defined.
;; New in 2.1 Release
;; ------------------
;; 1. Added p4-toggle-vc-mode to administratively enable/disable the VC
;; check (mainly for offline working, ro when a P4 server is
;; unavailable).
;; 2. Emacs Menu works now.
;; 3. Standardized the Menus in XEmacs and Emacs.
;; 4. Add a lot of documentation to the variables, and cleanup indentation
;; in function documentation.
;; New in 2.2 Release
;; ------------------
;; 1. p4-add now takes prefix argument to specify optional parameters.
;; 2. p4-check-mode modified to accept optional argument so that it can
;; update menu of a buffer whose file has been added to p4.
;; 3. Add p4-get-client-name and p4-set-client-name to the menu.
;; New in 2.3 Release
;; ------------------
;; 1. Change all references to "GNU Emacs" and "XEmacs" to "Emacs" and
;; "XEmacs" respectively, since the former may mistakenly portray XEmacs
;; as a program that has nothing to do with GNU (It did originate from a
;; GNU program), which is neither fair nor accurate. The only place where
;; the explicit check is done for "GNU Emacs" is in the string-match.
;; 2. Rename p4-running-gnuemacs to p4-running-emacs per the above
;; sentiment.
;; 3. Add p4-set-p4-port and p4-get-p4-port to set and get the current P4
;; server/port that we are attached to.
;; Find out what type of emacs we are running in. We will be using this
;; quite a few times in this program.
(defvar p4-running-emacs
(string-match "GNU Emacs" (emacs-version))
"If the current Emacs is not XEmacs, then, this is non-nil")
(defvar p4-running-xemacs
(string-match "XEmacs\\|Lucid" (emacs-version))
"If the current Emacs is XEmacs/Lucid, then, this is non-nil")
;; This can be set to wherever 'p4' lies using p4-set-p4-executable
(defvar p4-executable
"/usr/swlocal/bin/p4"
" This is the p4 executable. To set this, use the function
`p4-set-p4-executable'")
(cond (p4-running-xemacs
;; This can be set to wherever the appropriate client lies using
;; p4-set-gnu-client
(defvar p4-gnuclient
"/usr/swlocal/bin/gnuclient"
"This is the GNU Client to use with the server. To set this
variable, use `p4-set-gnu-client'")
;; Start the server ...
(gnuserv-start))
(p4-running-emacs
;; This can be set to wherever the appropriate client lies using
;; p4-set-gnu-client
(defvar p4-gnuclient
"/usr/swlocal/bin/emacsclient"
"This is the Emacs Client to use with the server. To set this
variable, use `p4-set-gnu-client'")
(server-start)))
;; Set the null device
(if (memq system-type '(ms-dos windows-nt))
;; Set the null device for Windows and DOS
(defvar p4-null-device "NUL" "Null Device for MS-DOS/Windows")
(defvar p4-null-device "/dev/null" "Null Device for UNIX"))
(defvar p4-output-buffer-name "*P4 Output*" "P4 Output Buffer")
(defvar p4-oldclt (getenv "P4CLIENT") "The P4 Client in use.")
(defvar p4-old-p4-port (getenv "P4PORT") "The P4 Server/Port in use.")
(if (eq p4-old-p4-port nil)
(progn
(setq p4-old-p4-port "p4:1666") ;; Default P4 port.
(setenv "P4PORT" p4-old-p4-port)))
(defvar p4-value 'no)
(defvar p4-old-notify-list (getenv "P4NOTIFY") "The P4 Notify List")
(defvar p4-notify-list (getenv "P4NOTIFY") "The P4 Notify List")
;; This can be set with p4-set-notifier
(defvar p4-notifier "/usr/swlocal/bin/mailch"
"The P4 notification Program. To set this use `p4-set-notifier'")
(defvar p4-notify nil)
(defvar p4-emacs-version "2.3" "The Current P4-Emacs Integration Revision")
;; This can be set with p4-toggle-vc-mode
(defvar p4-do-find-file t
"If non-nil, the p4-find-file-hook will run when opening files")
;; Now add a hook to find-file-hooks
(add-hook 'find-file-hooks 'p4-find-file-hook)
;; Tell Emacs about this new kind of minor mode
(make-variable-buffer-local 'p4-mode)
(put 'p4-mode 'permanent-local t)
(if (not (assoc 'p4-mode minor-mode-alist))
(setq minor-mode-alist (cons '(p4-mode p4-mode)
minor-mode-alist)))
;; A generic function that we use to execute p4 commands
(defun p4-exec-p4 (output-buffer
args
&optional clear-output-buffer)
(if clear-output-buffer
(progn
(set-buffer output-buffer)
(delete-region (point-min) (point-max))))
(apply 'call-process
(append
(list p4-executable
p4-null-device
output-buffer
nil) ; update display?
args)))
;; A generic function to take action of a buffer for interactive p4 commands
(defun p4-buffer-action (cmd do-revert
show-output
&optional argument
&optional argument1)
(save-excursion
(if (not (stringp cmd))
(error "p4-buffer-action: Command not a string."))
(save-excursion
(if (and argument argument1)
(p4-exec-p4 (get-buffer-create p4-output-buffer-name)
(list cmd argument argument1) t)
(p4-exec-p4 (get-buffer-create p4-output-buffer-name)
(list cmd (buffer-file-name)) t)))
(if do-revert (revert-buffer t t))
(if show-output
(progn
(delete-other-windows)
(display-buffer p4-output-buffer-name t)))))
;; We use the noinput version for commands like p4 opened, p4 get etc.
;; which don't take any input file name.
(defun p4-noinput-buffer-action (cmd
do-revert
show-output
&optional argument)
(save-excursion
(if (not (stringp cmd))
(error "p4-noinput-buffer-action: Command not a string."))
(save-excursion
(if argument
(p4-exec-p4 (get-buffer-create p4-output-buffer-name)
(append (list cmd) argument) t)
(p4-exec-p4 (get-buffer-create p4-output-buffer-name)
(list cmd) t)))
(if do-revert (revert-buffer t t))
(if show-output
(progn
(delete-other-windows)
(display-buffer p4-output-buffer-name t)))))
;; The p4 edit command
(defun p4-edit (show-output)
" To open the current depot file for edit, type M-x `p4-edit'
Open or re-open an existing file for edit.
If file is already open for edit or delete then it is reopened
for edit and moved into the specified change number (or 'default'
change if no change number is given.)
If -t type is given the file is explicitly opened as the specified
file type, which may be text, ltext, xtext, binary, xbinary, ktext
kxtext, symlink, or resource. Not all types are supported on all
operating systems. See the Users' Guide for a description of file
types. If no type is specified, the type is determined automatically
by examination of the file's contents and execution permission bits."
(interactive "P")
(p4-buffer-action "edit" t show-output)
(p4-check-mode))
;; The p4 revert command
(defun p4-revert (show-output)
"Revert the changes in the current file"
(interactive "P")
(if (yes-or-no-p "Really revert changes? ")
(p4-buffer-action "revert" t show-output))
(p4-check-mode))
;; The p4 diff command
(defun p4-diff ()
" To diff the current file and topmost depot version, type M-x `p4-diff'
Run diff (on the client) of a client file against the corresponding
revision in the depot. The file is only compared if the file is
opened for edit or the revision provided with the file argument is
not the same as the revision had by the client.
If no file argument is given, diff all open files.
This can be used to view pending changes.
The -f flag forces a diff for every file, regardless of whether
they are opened or if the client has the named revision.
This can be used to verify the client contents.
The -s flag outputs reduces the output of diff to the names of files
satisfying the following criteria:
-sa Opened files that are different than the revision
in the depot, or missing.
-sd Unopened files that are missing on the client.
-se Unopened files that are different than the revision
in the depot.
-sr Opened files that are the same as the revision in the
depot."
(interactive)
(p4-buffer-action "diff" nil t))
;; The p4 diff2 command
(defun p4-diff2 (version1 version2 )
" diff2 -- Display diff of two depot files.
When visiting a depot file, type M-x `p4-diff2' and
enter the versions.
Example: (find-file \"/us/rv/tag/main/Construct\")
M-x p4-diff2 <RET>
First Version to diff: 113
Second Version to diff: 100
Will produce the diff between the two versions in the
output buffer *P4 Output*
Run diff (on the server) of two files in the depot. Both files
may optionally include a revision specification; the default is
to compare the head revision. Wildcards may be used, but they
must match between file1 and file2 and they must be escaped from
the user's shell by quoting or with backslashes (\).
The -d flag allows you to pass flags to the underlying diff
program.
-dc passes the -c (context diff) flag. -dn passes the the -n
(rcs diff) flag. Other diff flags are not supported."
(interactive "sFirst Version to diff: \nsSecond Version to diff: ")
(make-variable-buffer-local 'p4-diff-version1)
(make-variable-buffer-local 'p4-diff-version2)
(defvar p4-diff-version1 nil)
(defvar p4-diff-version2 nil)
(setq p4-diff-version1 (concat (buffer-file-name) "#" version1))
(setq p4-diff-version2 (concat (buffer-file-name) "#" version2))
(p4-buffer-action "diff2" nil t p4-diff-version1 p4-diff-version2))
;; p4-ediff for all those who diff using ediff
(defun p4-ediff ()
"Use ediff to compare file with its original client version"
(interactive)
(require 'ediff)
(p4-noinput-buffer-action "print" nil nil
(list "-q"
(concat (buffer-file-name) "#have")))
(let ((local (current-buffer))
(depot (get-buffer-create p4-output-buffer-name)))
(ediff-buffers local
depot
`((lambda ()
(make-local-variable 'ediff-cleanup-hook)
(setq ediff-cleanup-hook
(cons (lambda ()
(kill-buffer ,depot))
ediff-cleanup-hook)))))))
;; The p4 add command
(defun p4-add ()
" To add the current file to the depot, type M-x `p4-add'
Prefix Argument (C-u) can be specified to give parameters.
Example: To add a file with the type specified as ktext,
C-u M-x p4-add<Enter>
Optional Arguments: -tktext<Enter>
Open a new file for adding to the depot. If the file exists
on the client it is read to determine if it is text or binary.
If it does not exist it is assumed to be text. The file must
either not exist in the depot, or it must be deleted at the
current head revision. Files may be deleted and re-added arbitrarily.
If the -c flag is given the open files are associated with the
specified pending change number; otherwise the open files are
associated with the current 'default' change.
If file is already open it is moved into the specified pending
change. It is not permissible to reopen a file for add unless
it was already open for add.
If -t type is given the file is explicitly opened as the specified
file type, which may be text, ltext, xtext, binary, xbinary, ktext
kxtext, symlink, or resource. Not all types are supported on all
operating systems. See the Users' Guide for a description of file
types. If no type is specified, the type is determined automatically
by examination of the file's contents and execution permission bits."
(interactive)
(if (not (p4-is-vc))
(progn
(if current-prefix-arg
(let ((args ""))
(progn
(setq args (read-string "Optional Args: "))
(p4-buffer-action "add" nil t args buffer-file-name)))
(p4-buffer-action "add" nil t))
(p4-check-mode "Add"))
(message "%s already in depot client %s!" buffer-file-name
(getenv "P4CLIENT"))))
;; The p4 delete command
(defun p4-delete ()
" To delete the current file from the depot, type M-x `p4-delete'
Opens a file that currently exists in the depot for deletion.
If the file is present on the client it is removed. If a pending
change number is given with the -c flag the opened file is associated
with that change, otherwise it is associated with the 'default'
pending change.
If file is already open it is reopened for delete and moved into
the specified pending change (or 'default' change if no change
number is given.)
Files that are deleted generally do not appear on the have list."
(interactive)
(if (yes-or-no-p "Really delete from depot? ")
(if (p4-is-vc)
(p4-buffer-action "delete" nil t))
(p4-check-mode)))
;; The p4 filelog command
(defun p4-filelog ()
" To view a history of the changes made to the current file, type
M-x `p4-filelog'
List the revision history of the files named, working backwards
from the latest revision to the most recent revision 'added'.
If file is given as a client file, the depot file last gotten is
listed. The -l flag produces long output with the full text of the
change descriptions."
(interactive)
(p4-buffer-action "filelog" nil t))
;; The p4 files command
(defun p4-files ()
" files -- List files in the depot
To pass optional args [file ...]
use the prefix argument (i.e.) C-u M-x `p4-files'
List files named or matching wild card specification. Display
shows depot file name, revision, file type, change action and change
number of the current head revision. If client file names are given
as arguments the view mapping is used to list the corresponding depot
files."
(interactive)
(if current-prefix-arg
(let ((args 'nil))
(progn
(setq args (list (read-string "Optional Args: ")))
(p4-noinput-buffer-action "files" nil t args)))
(p4-buffer-action "files" nil t)))
;; The p4 refresh command
(defun p4-refresh ()
" refresh -- Refresh the contents of an unopened file
To pass optional args [file ...]
use the prefix argument (i.e.) C-u M-x `p4-refresh'
Refresh replaces the files with their contents from the depot.
Refresh only refreshes unopened files; opened files must be
reverted. This command requires naming files explicitly."
(interactive)
(if current-prefix-arg
(let ((args 'nil))
(progn
(setq args (list (read-string "Optional Args: ")))
(p4-noinput-buffer-action "refresh" nil t args)))
(p4-buffer-action "refresh" nil t)))
;; The p4 get/sync command
(defun p4-get ()
" To synchronise the local view with the depot, type M-x `p4-get'
To pass optional args [-n] [file ...]
use the prefix argument (i.e.) C-u M-x `p4-get'
Synchronize a client with its view for the files named, or
for the entire client if no files named. Get handles the case
where files have been updated in the depot and need to be brought
up-to-date on the client as well as the case when the view itself
has changed.
Depot files in the clients view not currently gotten on
the client will be added. Client files that were gotten
from the depot but that are no longer in the clients view
(or have been deleted in the depot) will be deleted from
the client. Client files that are still in the client view
but which have been updated in the depot are replaced by
the needed revision from the depot.
If file gives a revision specifier, then retrieve the
revision so indicated.
The client view is used to map client file names to depot file
names and vice versa.
If -n is given show what revisions would need to be gotten to
synchronize the client with the view, but do not actually get
the files. If no files are named show the result for the
entire client view."
(interactive)
(let ((args 'nil))
(if current-prefix-arg
(setq args (list (read-string "Optional Args: ")))
(setq args (list "")))
(p4-noinput-buffer-action "get" nil t args)))
;; The p4 have command
(defun p4-have ()
" To list revisions last gotten, type M-x `p4-have'
To pass optional args [file ...]
use the prefix argument (i.e.) C-u M-x `p4-have'
List revisions of named files that were last gotten from the depot.
If no file name is given list all files gotten on this client."
(interactive)
(let ((args 'nil))
(if current-prefix-arg
(setq args (list (read-string "Optional Args: ")))
(setq args (list "")))
(p4-noinput-buffer-action "have" nil t args)))
;; The p4 help command
(defun p4-help (arg)
" To print help message , type M-x `p4-help'
Print a help message about command. If no command name is given
print a general help message about Perforce and give a list
of available client commands."
(interactive "sHelp on which command: ")
(if (string< "" arg)
(p4-noinput-buffer-action "help" nil t (list arg))
(p4-noinput-buffer-action "help" nil t)))
;; The p4 info command
(defun p4-info ()
" To print out client/server information, type M-x `p4-info'
Info dumps out what the server knows about the client (the user
name, the client name, and the client directory) and some server
information (the server's address, version, and license data)."
(interactive)
(p4-noinput-buffer-action "info" nil t))
;; The p4 integrate command
(defun p4-integ (branch)
" To schedule integrations between branches, type M-x `p4-integ'
To pass optional args [-n -r] [-c change#] [file ...]
use the prefix argument (i.e.) C-u M-x `p4-integ'
Integ determines what integrations are necessary between
related files, according to the branch named and its view.
These integrations, represented by a list of revisions of branch
source files which need to be merged into the related branch target
file, are scheduled for later action. The actual merge and any
necessary conflict resolution is performed using the resolve
command. The -n flag displays what integrations would be
necessary but does not schedule them. A branch name is required.
If the -r flag is present, the mappings in the branch view are
reversed, with the target files and source files exchanging place.
If no file names are given then the entire branch view is examined
for needed integrations. Files that are not mapped in the client's
view are ignored. Files scheduled for integration are opened for the
appropriate action in the default change. If -c change# is given
the files are opened in the numbered pending change."
(interactive "sP4 Branch Name: ")
(let ((args 'nil))
(if current-prefix-arg
(setq args (list "-b" branch (read-string "Optional Args: ")))
(setq args (list "-b" branch)))
(p4-noinput-buffer-action "integ" nil t args)))
;; The p4 opened command
(defun p4-opened ()
" To display list of files opened for pending change, type
M-x `p4-opened'
To pass optional args [-a] [file ...]
use the prefix argument (i.e.) C-u M-x `p4-opened'
Shows files currently opened for pending changes or indicates for the
specified individual files whether they are currently opened.
If no file names are given, all files open on the current client
are listed. The -a flag lists opened files in all clients."
(interactive)
(p4-noinput-buffer-action "opened" nil t))
;; The p4 users command
(defun p4-users ()
" To display list of known users, type M-x `p4-users'
To pass optional args [user ...]
use the prefix argument (i.e.) C-u M-x `p4-users'
Reports the list of all users, or those users matching the argument,
currently known to the system. The report includes the last time
each user accessed the system."
(interactive)
(let ((args 'nil))
(if current-prefix-arg
(setq args (list (read-string "Optional Args: ")))
(setq args (list "")))
(p4-noinput-buffer-action "users" nil t args)))
;; The p4 where command
(defun p4-where ()
"To show how local file names map into depot names, type M-x `p4-where'
To pass optional args [file ...]
use the prefix argument (i.e.) C-u M-x `p4-where'
Where shows how the named files map through the client map
into the depot. If no file is given, the mapping for '...'
(all files in the current directory and below) is shown."
(interactive)
(let ((args 'nil))
(if current-prefix-arg
(setq args (list (read-string "Optional Args: ")))
(setq args (list "")))
(p4-noinput-buffer-action "where" nil t args)))
;; A generic function to do asynchronous p4 commands. All commands that use
;; this would use the emacsclient or gnuclient as their editor using the
;; server running inside emacs.
(defun p4-async-commands (value &optional clear-output-buffer)
(setenv "EDITOR" p4-gnuclient)
(if clear-output-buffer
(progn
(set-buffer (get-buffer-create p4-output-buffer-name))
(delete-region (point-min) (point-max))))
(save-excursion
(p4-emacs-server-start)
(start-process value
p4-output-buffer-name
p4-executable value)
(display-buffer p4-output-buffer-name t)))
;; The p4 change command
(defun p4-change ()
" To edit the change specification, type M-x `p4-change'
To pass optional args [-d | -o] [ change# ]
use the prefix argument (i.e.) C-u M-x `p4-change'
Creates a new change description with no argument or edit the
text description of an existing change if a change number is
given. To associate or remove files from a pending change use
the open commands (edit, add, delete) or revert.
The -d flag discards a pending change, but only if it has no
opened files and no pending fixes associated with it. Use 'opened -a'
to report on opened files and 'reopen' to move them to another
change. Use 'fixes -c change#' to report on pending fixes and
'fix -d -c change# jobs...' to delete pending fixes. The change
can only be deleted by the user and client who created it.
The -o flag causes the change specification to be written
to the standard output. The user's editor is not invoked.
The -i flag causes a change specification to be read from the
standard input. The user's editor is not invoked."
(interactive)
(p4-async-commands "change"))
;; The p4 client command
(defun p4-client ()
" To edit a client specification , type M-x `p4-client'
With no argument client creates a new client view specification or
edits an existing client specification. The client name is taken
from the environment variable $P4CLIENT if set, or else from
the current host name. The specification form is put into a
temporary file and the editor (given by the environment variable
$EDITOR) is invoked. If a name is given, the specification of
the named client is displayed read-only.
The specification form contains the following fields:
Client: The client name (read only.)
Date: The date specification was last modified (read only.)
Description: A short description of the client (optional).
Root: The root directory of the client file workspace
(given in local file system syntax), under which all
client files will be placed. If you change this, you
must physically relocate any files as well.
View: What files you want to see from the depot and how
they map to locations on the client. The left hand
side specifies a depot path, which must begin with
//depot/. The right hand side gives the corresponding
client path, given in canonical Perforce file syntax.
On expansion to an actual local client file name the
initial //client/ is replaced by the Root value, given
above. You may use wildcards:
... matches any characters including
* matches any character except /
%1 to %9 like *, used to associate wild cards
Wildcarding must be congruent in both the client and
depot paths. You may have any number of view entries.
A new view takes effect on the next 'get'.
Normally, new clients are created with a default view that maps
all depot files onto the client. The -t flag uses the view from
the named template client as a default instead.
The -d flag causes the named client to be deleted.
The -o flag causes the named client specification to be written
to the standard output. The user's editor is not invoked.
The -i flag causes a client specification to be read from the
standard input. The user's editor is not invoked."
(interactive)
(p4-async-commands "client"))
;; The p4 submit command
(defun p4-submit ()
" To submit a pending change to the depot, type M-x `p4-submit'
Submit commits a pending change with its associated files to the depot.
With no argument submit sends the 'default' change. With the -c flag
the designated pending change is sent. Before committing the change
submit locks all associated files not already locked. If any file
cannot be locked the change is aborted. If submit is sending the
default change it first provides the user with a dialog similar to
'p4 change' so the user can compose a change description. In this
dialog the user is presented with the list of open files in change
'default'. Files may be deleted from this list but they cannot be
added. (Use an open command (open, edit, add, delete) to add
additional files to a change or to move files between changes.)
If the submit fails for any reason the files are left open in
a newly created pending change.
Submit is guaranteed to be atomic. Either all files will be
updated in the depot as a unit or none will be.
The -i flag causes a change specification to be read from the
standard input. The user's editor is not invoked."
(interactive)
(p4-async-commands "submit" t))
;; The p4 user command
(defun p4-user ()
" To create or edit a user specification, type M-x `p4-user'
Create a new user specification or edit an existing user
specification. The specification form is put into a temporary
file and the editor (given by the environment variable $EDITOR)
is invoked.
Normally, a user specification is created automatically the
first time the user invokes any client command that can update
the depot. The 'user' command is generally used to edit the
user's reviewing subscription list for change review.
The user specification form contains the following fields:
User: The user name (read only).
Email: The user's email address (user at client default).
Update: The date the specification was last modified (read only).
Access: The date the user last issued a client command.
FullName: The user's real name.
Reviews: The subscription list for change review. You may
use wildcards:
... matches any characters including
* matches any character except /
There may be any number of review lines.
The -d flag deletes the named user, but only if the user is not
the owner of any branches, clients, jobs, labels, or opened files.
The -o flag causes the named user specification to be written
to the standard output. The user's editor is not invoked.
The -i flag causes a user specification to be read from the
standard input. The user's editor is not invoked."
(interactive)
(p4-async-commands "user"))
;; A function to get the current P4 client name
(defun p4-get-client-name ()
" To get the current value of the environment variable P4CLIENT,
type M-x `p4-get-client-name'
This will be the current client that is in use for access through
Emacs P4."
(interactive)
(message "P4CLIENT is %s" (getenv "P4CLIENT")))
;; A function to set the current P4 client name
(defun p4-set-client-name (p4-new-client-name)
" To set the current value of P4CLIENT, type M-x `p4-set-client-name'
This will change the current client from the previous client to the new
given value.
Setting this value to `nil' would disable P4 Version Checking."
(interactive (list (let
((symbol (read-string "Change Client to: "
p4-oldclt)))
(if (equal symbol "")
p4-oldclt
symbol))))
(if (equal p4-new-client-name "nil")
(progn
(setenv "P4CLIENT" nil)
(message
"P4 Version check disabled. Set a valid client name to enable."))
(progn
(setenv "P4CLIENT" p4-new-client-name)
(setq p4-oldclt p4-new-client-name)
(message "P4CLIENT changed to %s" p4-new-client-name))))
;; A function to get the current P4PORT
(defun p4-get-p4-port ()
" To get the current value of the environment variable P4PORT,
type M-x `p4-get-p4-port'
This will be the current server/port that is in use for access through
Emacs P4."
(interactive)
(message "P4PORT is %s" (getenv "P4PORT")))
;; A function to set the current P4PORT
(defun p4-set-p4-port (p4-new-p4-port)
" To set the current value of P4PORT, type M-x `p4-set-p4-port'
This will change the current server from the previous server to the new
given value."
(interactive (list (let
((symbol (read-string "Change server:port to: "
p4-old-p4-port)))
(if (equal symbol "")
p4-old-p4-port
symbol))))
(if (equal p4-new-p4-port "nil")
(progn
(setenv "P4PORT" nil)
(message
"P4 Version check disabled. Set a valid client name to enable."))
(progn
(setenv "P4PORT" p4-new-p4-port)
(setq p4-old-p4-port p4-new-p4-port)
(message "P4PORT changed to %s" p4-new-p4-port))))
;; The find-file hook for p4.
(defun p4-find-file-hook ()
"To check while loading the file, if it is a P4 version controlled file."
(if (getenv "P4CLIENT")
(p4-check-mode)))
;; A function to check if the file being opened is version controlled by p4.
(defun p4-is-vc ()
"If a file is controlled by P4 then return version else return nil"
(save-excursion
(get-buffer-create p4-output-buffer-name)
(set-buffer p4-output-buffer-name)
(delete-region (point-min) (point-max)))
(if (zerop (call-process
p4-executable
nil
p4-output-buffer-name
nil
"files" buffer-file-name))
(progn
(save-excursion
(set-buffer p4-output-buffer-name)
(goto-char (point-min))
(if (re-search-forward "#[0-9]+" (point-max) t)
(substring (match-string 0) 1)
nil)))
nil))
;; set keymap. We use the C-x P Keymap for all perforce commands
(defvar p4-prefix-map (lookup-key global-map "\C-xP")
"The Prefix for P4 Library Commands")
(if (not (keymapp p4-prefix-map))
(progn
(setq p4-prefix-map (make-sparse-keymap))
(define-key global-map "\C-xP" p4-prefix-map)
(define-key p4-prefix-map "a" 'p4-add)
(define-key p4-prefix-map "c" 'p4-client)
(define-key p4-prefix-map "d" 'p4-diff2)
(define-key p4-prefix-map "e" 'p4-edit)
(define-key p4-prefix-map "f" 'p4-filelog)
(define-key p4-prefix-map "g" 'p4-get-client-name)
(define-key p4-prefix-map "G" 'p4-get)
(define-key p4-prefix-map "h" 'p4-help)
(define-key p4-prefix-map "i" 'p4-info)
(define-key p4-prefix-map "n" 'p4-notify)
(define-key p4-prefix-map "o" 'p4-opened)
(define-key p4-prefix-map "P" 'p4-set-p4-port)
(define-key p4-prefix-map "r" 'p4-revert)
(define-key p4-prefix-map "R" 'p4-refresh)
(define-key p4-prefix-map "s" 'p4-set-client-name)
(define-key p4-prefix-map "S" 'p4-submit)
(define-key p4-prefix-map "t" 'p4-toggle-vc-mode)
(define-key p4-prefix-map "u" 'p4-user)
(define-key p4-prefix-map "v" 'p4-emacs-version)
(define-key p4-prefix-map "x" 'p4-delete)
(define-key p4-prefix-map "=" 'p4-diff)
(define-key p4-prefix-map "-" 'p4-ediff)))
;; For users interested in notifying a change, a notification list can be
;; set up using this function.
(defun p4-set-notify-list (p4-new-notify-list)
" To set the current value of P4NOTIFY, type M-x `p4-set-notify-list'
This will change the current notify list from the existing list to
the new given value.
Enter `nil' to disable notification."
(interactive (list (let
((symbol (read-string
"Change Notification List to: "
p4-notify-list)))
(if (equal symbol "")
p4-notify-list
symbol))))
(setq p4-old-notify-list p4-notify-list)
(if (equal p4-new-notify-list "nil")
(progn
(setenv "P4NOTIFY" nil)
(setq p4-notify-list nil)
(setq p4-notify nil))
(progn
(setenv "P4NOTIFY" p4-new-notify-list)
(setq p4-notify-list p4-new-notify-list)
(setq p4-notify t)))
(message "Notification list changed from '%s' to '%s'"
p4-old-notify-list p4-notify-list))
;; To get the current notification list.
(defun p4-get-notify-list ()
" To get the current value of the environment variable P4NOTIFY,
type M-x `p4-get-notify-list'
This will be the current notification list that is in use for mailing
change notifications through Emacs P4."
(interactive)
(message "P4NOTIFY is %s" p4-notify-list))
;; Function to actually notify the users. Unfortunately, there are
;; limitations to this. It uses an external program to make the
;; notification, and since Emacs is not threaded, we can't really do
;; autonotification without going through pains, since p4-submit calls an
;; async process. The closest thing would be a diligent user who notifies
;; voluntarily after submitting a change.
(defun p4-notify (users)
" To notify a list of users of a change submission.
Since Emacs is not threaded, there is no good way to make this
happen intelligently. So, `p4-notify' is supposed to be used only
after you submit `p4-submit' or `C-x P S' a change _from_ Emacs using
the Emacs-P4 Interface. `p4-notify' will look for a submitted change
returned from the submit command. Any external program can be used to
actually mail the change description, and the default is a perl-based
program `mailch' - mail change description."
(interactive (list (let
((symbol (read-string "Notify whom? "
p4-notify-list)))
(if (equal symbol "")
p4-notify-list
symbol))))
(set-buffer (get-buffer-create p4-output-buffer-name))
(goto-char (point-min))
(if (re-search-forward "[0-9]+.*submitted" (point-max) t)
(progn
(p4-set-notify-list users)
(let ((p4-matched-change 'nil))
(setq p4-matched-change (substring (match-string 0) 0 -9))
(start-process p4-matched-change
nil
p4-notifier (concat p4-matched-change " "
users))))
(message "No Changes Submitted." users)))
;; Function to return the current version.
(defun p4-emacs-version ()
"Return the current Emacs-P4 Integration version."
(interactive)
(cond (p4-running-xemacs
(message "XEmacs-P4 Integration v%s" p4-emacs-version))
(p4-running-emacs
(message "Emacs-P4 Integration v%s" p4-emacs-version))))
;; To set the path to the p4 executable
(defun p4-set-p4-executable (p4-exe-name)
" Set the path to the correct P4 Executable.
To set this as a part of the .emacs, add the following to your .emacs:
(load-library \"p4\")
(p4-set-p4-executable \"/my/path/to/p4\")"
(interactive "fFull path to your P4 executable: " )
(setq p4-executable p4-exe-name))
;; To set the path to the emacsclient/gnuclient.
(defun p4-set-gnu-client (p4-gnu-client)
" Set the path to the correct Emacs client.
This would be 'emacsclient' for Emacs and
'gnuclient' for XEmacs
To set this as a part of the .emacs, add the following to your .emacs:
(load-library \"p4\")
(p4-set-gnu-client \"/my/path/to/client\")"
(interactive "fFull path to your GNU client: " )
(setq p4-gnuclient p4-gnu-client))
;; To set the path to the mailch notification program (if it exists).
(defun p4-set-notifier (p4-notify-name)
" Set the path to the correct mailch.
To set this as a part of the .emacs, add the following to your .emacs:
(load-library \"p4\")
(p4-set-notifier \"/my/path/to/mailch\")"
(interactive "fFull path to your P4 Notifier (mailch): " )
(setq p4-notifier p4-notify-name))
;; To start the correct emacs server depending on the type of emacs.
(defun p4-emacs-server-start ()
"To Start the correct server depending on type of Emacs"
(cond (p4-running-xemacs
(if (not (gnuserv-running-p)) (gnuserv-start)))
(p4-running-emacs
(if (and (boundp 'server-process)
(not server-process)) (server-start)))))
;; To check if the current buffer's modeline and menu need to be altered
(defun p4-check-mode (&optional args)
"Check to see whether we should export the menu map to this buffer."
(if p4-do-find-file
(let ((p4-vc-check 'nil))
(if args
(setq p4-vc-check args)
(setq p4-vc-check (p4-is-vc)))
(if p4-vc-check
(progn
(cond (p4-running-xemacs
(p4-menu-add)))
(setq p4-mode (concat " P4:" p4-vc-check)))
(setq p4-mode nil)))
(p4-force-mode-line-update)))
;; Force mode line updation for different Emacs versions
(defun p4-force-mode-line-update ()
"To Force the mode line update for different flavors of Emacs"
(cond (p4-running-xemacs
(redraw-modeline))
(p4-running-emacs
(force-mode-line-update))))
;; In case, the P4 server is not available, or when operating off-line, the
;; p4-find-file-hook becomes a pain... this functions toggles the use of the
;; hook when opening files.
(defun p4-toggle-vc-mode ()
" In case, the P4 server is not available, or when working off-line,
this function toggles the VC check on/off when opening files."
(interactive)
(setq p4-do-find-file (not p4-do-find-file))
(if p4-do-find-file
(message "P4 mode check enabled.")
(message "P4 mode check disabled.")))
;; I separated the menu support for Emacs and XEmacs since they seemed
;; to differ considerably.
(cond (p4-running-xemacs
;; Menu Support for XEmacs
(require 'easymenu)
(defun p4-mode-menu (modestr)
(let ((m
'(["Add Current to P4" p4-add
(and buffer-file-name (not p4-mode))]
["Check out/Edit" p4-edit (and buffer-file-name
(and buffer-read-only p4-mode))]
["------------------" nil nil]
["Revert File" p4-revert (and buffer-file-name
(and (not buffer-read-only)
p4-mode))]
["Filelog" p4-filelog (and buffer-file-name p4-mode)]
["------------------" nil nil]
["Diff 2 Versions" p4-diff2 (and buffer-file-name
p4-mode)]
["Diff Current" p4-diff (and buffer-file-name
(and (not buffer-read-only)
p4-mode))]
["Diff Current with Ediff" p4-ediff
(and buffer-file-name (and (not buffer-read-only)
p4-mode))]
["------------------" nil nil]
["Delete File from Depot" p4-delete
(and buffer-file-name
(and buffer-read-only p4-mode))]
["------------------" nil nil]
["Submit Changes" p4-submit (and
buffer-file-name
p4-mode)]
["------------------" nil nil]
["Show Version" p4-emacs-version (and
buffer-file-name
p4-mode)]
["Disable P4 VC Check" p4-toggle-vc-mode
p4-do-find-file]
["Enable P4 VC Check" p4-toggle-vc-mode
(not p4-do-find-file)]
["------------------" nil nil]
["Set P4 Client" p4-set-client-name p4-do-find-file]
["Get Current P4 Client" p4-get-client-name
p4-do-find-file]
["------------------" nil nil]
["Set P4 Server/Port" p4-set-p4-port p4-do-find-file]
["Get Current P4 Server/Port" p4-get-p4-port
p4-do-find-file]
)))
(cons modestr m)))
(defun p4-menu-add ()
"To add the P4 menu bar button for files that are already not in
the P4 depot or in the current client view.."
(interactive)
(easy-menu-add (p4-mode-menu "P4"))))
(p4-running-emacs
;; Menu support for Emacs
(or (lookup-key global-map [menu-bar])
(define-key global-map [menu-bar] (make-sparse-keymap "menu-bar")))
(defvar menu-bar-p4-menu (make-sparse-keymap "P4"))
(setq menu-bar-final-items (cons 'p4-menu menu-bar-final-items))
(define-key global-map [menu-bar p4-menu]
(cons "P4" menu-bar-p4-menu))
(define-key menu-bar-p4-menu [p4-get-p4-port]
'("Get Current P4 Server/Port" . p4-get-p4-port))
(define-key menu-bar-p4-menu [p4-set-p4-port]
'("Set P4 Server/Port" . p4-set-p4-port))
(define-key menu-bar-p4-menu [separator-server-name]
'("--"))
(define-key menu-bar-p4-menu [p4-get-client-name]
'("Get Current P4 Client" . p4-get-client-name))
(define-key menu-bar-p4-menu [p4-set-client-name]
'("Set P4 Client" . p4-set-client-name))
(define-key menu-bar-p4-menu [separator-client-name]
'("--"))
(define-key menu-bar-p4-menu [p4-toggle-vc-mode]
'("Toggle P4 VC Check" . p4-toggle-vc-mode))
(define-key menu-bar-p4-menu [p4-emacs-version]
'("Show Version" . p4-emacs-version))
(define-key menu-bar-p4-menu [separator-vc-check]
'("--"))
(define-key menu-bar-p4-menu [p4-submit]
'("Submit Changes" . p4-submit))
(define-key menu-bar-p4-menu [separator-submit]
'("--"))
(define-key menu-bar-p4-menu [p4-delete]
'("Delete File from Depot" . p4-delete))
(define-key menu-bar-p4-menu [separator-delete]
'("--"))
(define-key menu-bar-p4-menu [p4-ediff]
'("Diff Current with Ediff" . p4-ediff))
(define-key menu-bar-p4-menu [p4-diff]
'("Diff Current" . p4-diff))
(define-key menu-bar-p4-menu [p4-diff2]
'("Diff 2 Versions" . p4-diff2))
(define-key menu-bar-p4-menu [separator-diff]
'("--"))
(define-key menu-bar-p4-menu [p4-filelog]
'("Filelog" . p4-filelog))
(define-key menu-bar-p4-menu [p4-revert]
'("Revert File" . p4-revert))
(define-key menu-bar-p4-menu [separator-revert]
'("--"))
(define-key menu-bar-p4-menu [p4-edit]
'("Checkout/Edit" . p4-edit))
(define-key menu-bar-p4-menu [p4-add]
'("Add Current to P4" . p4-add))
(put 'p4-add 'menu-enable '(and buffer-file-name (not p4-mode)))
(put 'p4-edit 'menu-enable '(and buffer-file-name
(and p4-mode buffer-read-only)))
(put 'p4-delete 'menu-enable '(and buffer-file-name
(and p4-mode buffer-read-only)))
(put 'p4-revert 'menu-enable '(and buffer-file-name
(and p4-mode
(not buffer-read-only))))
(put 'p4-ediff 'menu-enable '(and buffer-file-name
(and p4-mode
(not buffer-read-only))))
(put 'p4-diff 'menu-enable '(and buffer-file-name
(and p4-mode
(not buffer-read-only))))
(put 'p4-diff2 'menu-enable '(and buffer-file-name p4-mode))
(put 'p4-filelog 'menu-enable '(and buffer-file-name p4-mode))
(put 'p4-get-client-name 'menu-enable '(and t p4-do-find-file))
(put 'p4-set-client-name 'menu-enable '(and t p4-do-find-file))
(put 'p4-get-p4-port 'menu-enable '(and t p4-do-find-file))
(put 'p4-set-p4-port 'menu-enable '(and t p4-do-find-file))
))
- --------------984CD27706DB6D6382F49DAC--
More information about the perforce-user
mailing list