;; -*- emacs-lisp -*- ;;; mst-arch.el --- functions for managing arch projects ;; Author: Mark Triggs ;; This file 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, or (at your option) ;; any later version. ;; This file 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; Nothing fancy. Just a few hacks to save me time. ;; I've started contributing to the Xtla project ;; (http://wiki.gnuarch.org/moin.cgi/xtla). If you're after something more ;; than a bunch of cobbled hacks, you might like to check this out. Xtla's ;; features are certainly a superset of what's here. ;;; Code: (defun arch-diff-buffer () (interactive) (let ((cmd (if current-prefix-arg "tla what-changed --diffs" (format "tla file-diffs %s" (buffer-file-name))))) (shell-command cmd "*arch diffs*" nil)) (switch-to-buffer "*arch diffs*") (view-mode) (diff-mode)) (defun arch-update () (interactive) (shell-command "tla update")) (defun arch-make-log () (interactive) (find-file (subseq (shell-command-to-string "tla make-log") 0 -1)) (let ((map (copy-keymap (current-local-map)))) (define-key map (kbd "C-c C-c") (lambda () (interactive) (save-buffer) (arch-commit) (kill-buffer nil))) (use-local-map map))) (defun arch-commit () (interactive) (with-frame-display (shell-command "tla commit" "*arch commit*"))) (defmacro with-working-directory (dir &rest body) (let ((old (gensym))) `(let ((,old default-directory)) (cd ,dir) (unwind-protect (progn ,@body) (cd ,old))))) (put 'with-working-directory 'lisp-indent-function 1) (defvar *arch-pending-setup* nil) (defun arch-import () (interactive) (let ((base (read-file-name "Directory containing files to import: " (if (buffer-file-name) (file-name-directory (buffer-file-name)) (getenv "HOME")))) (archive (completing-read "Archive?: " (mapcar #'(lambda (e) (cons e e)) (split-string (shell-command-to-string "tla archives -n"))))) (project (read-from-minibuffer "Project name (eg hello--dev--1.0): "))) (dired base "-laR") (message "Use 'm' and 'u' to mark/unmark files. Press C-c C-c to finish") (let ((map (copy-keymap (current-local-map)))) (define-key map (kbd "C-c C-c") `(lambda () (interactive) ;; Initialise the project tree (unless (zerop (with-working-directory ,base (shell-command (format "tla init-tree -A %s %s" ,archive ,project)))) (error "There was a problem initialising %s/%s" ,archive ,project)) ;; Add selected files (with-working-directory ,base (let ((files (dired-get-marked-files))) (mapc (lambda (file) (shell-command (format "tla add %s" file))) files) (kill-buffer (current-buffer)))) ;; Complete the import (setq *arch-pending-setup* ,base) (arch-do-import))) (use-local-map map)))) (defun arch-do-import () (interactive) (if *arch-pending-setup* (with-working-directory *arch-pending-setup* (cond ((zerop (shell-command "tla tree-lint" "*tree-lint*" "*tree-lint*")) (shell-command "tla import --setup") (setq *arch-pending-setup* nil)) (t (message (concat "Tree lint failed. Please correct and run" " M-x arch-do-import (see buffer " "*tree-lint*)"))))) (error "Nothing to do!"))) (defun arch-add-buffer-file () (interactive) (shell-command (format "tla add %s" (buffer-file-name)))) (defun arch-revdelta () (interactive) (let ((tla-out (let ((temp-buffer (get-buffer-create (generate-new-buffer-name " *temp*")))) (if (zerop (save-window-excursion (shell-command "tla revisions" temp-buffer))) (with-current-buffer temp-buffer (prog1 (buffer-string) (kill-buffer nil))) nil)))) (when tla-out (let* ((revisions (split-string tla-out "\n")) (rev1 (completing-read "Revision 1: " revisions)) (rev2 (completing-read "Revision 2: " revisions))) (save-window-excursion (shell-command (format "tla revdelta --diffs %s %s" rev1 rev2) "*arch diffs*")) (switch-to-buffer "*arch diffs*") (goto-char (point-min)) (delete-region (point-min) (search-forward "* changeset report" nil t)) (diff-mode) (view-mode 1))))) (provide 'mst-arch) ;;; mst-arch.el ends here