home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode:Emacs-Lisp -*-
- ;;; Copyright ⌐ 1991-1993 by Lucid, Inc. All Rights Reserved.
-
- (eval-when-compile
- (require 'etags))
-
- ;; true if current-buffer is an energize buffer that does not support
- ;; the real write-file and so has to do the special energize way of doing
- ;; write-file that loses the annotations.
- (defun energize-write-file-buffer-p ()
- ;; (and (energize-buffer-p (current-buffer)
- ;; (not (eq major-mode 'energize-project-mode)))
- (energize-buffer-p (current-buffer)))
-
-
- (defun energize-beginning-of-defun (&optional arg)
- "Move point to the beginning of the current top-level form.
- With a numeric argument, move back that many forms."
- (interactive "_p")
- (or arg (setq arg 1))
- (if (not (energize-buffer-p (current-buffer)))
- (error "Not an Energize buffer")
- (if (< arg 0)
- (energize-end-of-defun (- arg))
- (while (> arg 0)
- (or (bobp) (forward-char -1))
- (while (and (not (bobp)) (null (energize-extent-at (point))))
- (forward-char -1))
- (let ((pos (point)))
- (map-extents
- (function
- (lambda (extent dummy)
- (if (< (setq pos (extent-start-position extent)) (point))
- (goto-char pos))))
- (current-buffer) (point) (point) nil t))
- (setq arg (1- arg))))))
-
- (defun energize-end-of-defun (&optional arg)
- "Move point to the end of the current top-level form.
- With a numeric argument, move forward over that many forms."
- (interactive "_p")
- (or arg (setq arg 1))
- (if (not (energize-buffer-p (current-buffer)))
- (error "Not an Energize buffer")
- (if (< arg 0)
- (energize-beginning-of-defun (- arg))
- (while (> arg 0)
- (or (eobp) (forward-char 1))
- (while (and (not (eobp)) (null (energize-extent-at (point))))
- (forward-char 1))
- (let ((pos (point)))
- (map-extents
- (function
- (lambda (extent dummy)
- (if (> (setq pos (extent-end-position extent)) (point))
- (goto-char pos))))
- (current-buffer) (point) (point) nil t))
- (setq arg (1- arg))))))
-
-
- ;;; Patching Energize into file I/O via the standard hooks.
-
- (defun energize-write-data-hook (name)
- ;; for use as the last element of write-file-data-hooks
- ;; in energize buffers.
- (if (energize-buffer-p (current-buffer))
- (progn
- (message "saving %s to Energize..." name)
- (energize-execute-command "save")
- (energize-update-menubar)
- (message "saved %s to Energize." name)
- t)
- nil))
-
- (defun energize-revert-buffer-insert-file-contents-hook (file noconfirm)
- ;; for use as the value of revert-buffer-insert-file-contents-function
- ;; in energize buffers.
- (if (not (energize-buffer-p (current-buffer)))
- (error "energize-revert-buffer-hook called for a non-energize buffer"))
- (widen)
- (cond ((equal file buffer-file-name) ; reverting from energize
- ;; Do the default as in files.el
- (if (file-exists-p file)
- (progn
- ;; Bind buffer-file-name to nil
- ;; so that we don't try to lock the file.
- (let ((buffer-file-name nil))
- (unlock-buffer)
- (erase-buffer))
- (insert-file-contents file t)))
- ;; Then asks the extents from Energize
- (energize-execute-command "revert"))
- (t ; reverting from autosave
- (if (not (file-exists-p file))
- (error "File %s no longer exists!" file))
- (erase-buffer)
- (insert-file-contents file)))
- t)
-
-
- (defun energize-kill-buffer-hook ()
- ;; for use as the value of kill-buffer-hook in energize buffers.
- (if (energize-buffer-p (current-buffer))
- (energize-request-kill-buffer (current-buffer))
- (error "energize-kill-buffer-hook called on a non-energize buffer"))
- t)
-
-
- ;;;
-
- (defun energize-edit-definition-default ()
- (save-excursion
- (if (not (memq (char-syntax (preceding-char)) '(?w ?_)))
- (while (not (looking-at "\\sw\\|\\s_\\|\\'"))
- (forward-char 1)))
- (while (looking-at "\\sw\\|\\s_")
- (forward-char 1))
- (if (re-search-backward "\\sw\\|\\s_" nil t)
- (progn (forward-char 1)
- (buffer-substring (point)
- (progn (forward-sexp -1)
- (while (looking-at "\\s'")
- (forward-char 1))
- (point))))
- nil)))
-
- ;;; This prompts in the minibuffer, ##### with no completion.
- (defun energize-edit-definition (def)
- "If connected to Energize, the Energize database is used.
- Otherwise, `find-tag' is invoked.
- The X selection is used as a default, if it exists and contains no
- newlines. Otherwise, the preceeding token is used as a default.
- If invoked from a mouse command, prompting happens with a dialog box;
- otherwise, the minibuffer is used."
- (interactive
- (if (and (connected-to-energize-p)
- (or (menu-event-p last-command-event)
- (button-press-event-p last-command-event)
- (button-release-event-p last-command-event)))
- '(nil)
- (list
- (let (default
- def)
- (cond ((x-selection-owner-p)
- (setq default (x-get-selection))
- (while (string-match "\\`[ \t\n]+" default)
- (setq default (substring default (match-end 0))))
- (while (string-match "[ \t\n]+\\'" default)
- (setq default (substring default 0 (match-beginning 0))))
- (if (string-match "[ \t\n]" default)
- (setq default nil))))
- (or default (setq default (energize-edit-definition-default)))
- (setq def
- (if (connected-to-energize-p)
- (completing-read
- (if default
- (format "Edit definition [%s]: " default)
- "Edit definition: ")
- nil nil; 'energize-edit-def-predicate
- nil nil)
- (or (and (fboundp 'find-tag-tag) (fboundp 'find-tag-default))
- (require 'tags "etags"))
- (find-tag-tag "Edit definition: ")))
- (if (or (equal "" def)
- (equal '("") def))
- (setq def default))
- def))))
- (if (connected-to-energize-p)
- ;; FIXME - this should fall back on tags if it fails...we might be
- ;; searching for elisp or something...
- (energize-execute-command "editdef" () (if (consp def) (car def) def) t)
- (find-tag def)))
-
- (define-key global-map "\M-." 'energize-edit-definition)
- (define-key global-map "\M-B" 'energize-build-a-target) ; M-Sh-B
-
- (defun disconnect-from-energize-query ()
- "Disconnect this emacs from the Energize server, after confirming."
- (interactive)
- (or (y-or-n-p "Disconnect from Energize? ") (error "not confirmed"))
- (disconnect-from-energize))
-
-
- ;;; Functions to add commands to the project buffers
- (defun energize-insert-slots (got-to-top-p l)
- (if (not (eq major-mode 'energize-project-mode))
- (error "Command available only in project buffers"))
- ;; move to a suitable place
- (if got-to-top-p
- (beginning-of-buffer)
- (beginning-of-line))
- ;; go before "Associated Projects" and "Related Files"
- (if (or (search-backward "Related Projects:" () t)
- (search-backward "Associated Files:" () t)
- (looking-at "Related Projects:")
- (looking-at "Associated Files:"))
- (previous-line 2))
- ;; find empty space
- (while (and (not (looking-at "$"))
- (not (eq (point) (point-max))))
- (next-line 1))
- (newline)
- (save-excursion
- (mapcar '(lambda (i) (insert i) (newline)) l))
- ;; this is magic
- (forward-char 18))
-
- (defun energize-insert-rule ()
- (interactive)
- (energize-insert-slots
- t
- '(" Rules:"
- " <rule>: lcc -Xez -c -g -Xa -o $object $source")))
-
- (defun energize-insert-object-file-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" Object File: <object-file>"
- " Source File: <source-file>"
- " Build Rule: <rule>")))
-
- (defun energize-insert-executable-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" Executable: <executable>"
- " Build Command: lcc -Xf -Xez -o $object <object-file> ...")))
-
- (defun energize-insert-library-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" Library: <library>"
- " Build Command: energize_ar -Xez -remove -ranlib clq $object \\"
- " <object-file> ...")))
-
- (defun energize-insert-collection-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" Collection: <collection>"
- " Build Command: energize_collect -Xez -o $object <object-file> ...")))
-
- (defun energize-insert-file-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" File Target: <target>"
- " Dependencies: <target> ..."
- " Build Command: <shell-command>")))
-
- (defun energize-insert-target-target ()
- (interactive)
- (energize-insert-slots
- ()
- '(" Target: <target>"
- " Dependencies: <target> ..."
- " Build Command: <shell-command>")))
-
-
-
- ;;; Keymaps for Energize buffers.
-
- (defvar energize-map nil "*Parent keymap for all Energize buffers")
- (defvar energize-top-level-map nil "*Keymap for the Energize top-level buffer")
- (defvar energize-debugger-map nil "*Keymap for Energize debugger buffers")
- (defvar energize-breakpoint-map nil "*Keymap for Energize breakpoint-lists")
- (defvar energize-browser-map nil "*Keymap for Energize browser buffers")
- (defvar energize-project-map nil "*Keymap for Energize project buffers")
- (defvar energize-no-file-project-map nil
- "*Keymap for Energize project buffers not associated with a file")
- (defvar energize-source-map nil "*Keymap for Energize source buffers")
-
- (defvar energize-mode-hook nil
- "Hook called when each energize buffer is created.")
- (defvar energize-top-level-mode-hook nil
- "Hook called when the energize top-level buffer is created.")
- (defvar energize-project-mode-hook nil
- "Hook called when an Energize project buffer is created.")
- (defvar energize-no-file-project-mode-hook nil
- "Hook called when an Energize project buffer with no file is created.")
- (defvar energize-breakpoint-mode-hook nil
- "Hook called when an Energize breakpoint-list buffer is created.")
- (defvar energize-browser-mode-hook nil
- "Hook called when an Energize browser buffer is created.")
- (defvar energize-log-mode-hook nil
- "Hook called when an Energize log buffer is created.")
- (defvar energize-manual-mode-hook nil
- "Hook called when an Energize manual buffer is created.")
- (defvar energize-source-mode-hook nil
- "Hook called when any source buffer is placed in the Energize minor-mode.")
-
-
- (if energize-map
- nil
- (setq energize-map (make-sparse-keymap))
- (set-keymap-name energize-map 'energize-map)
- (define-key energize-map "\^C\^F" 'energize-find-project)
- (define-key energize-map "\^C\^B\^E" 'energize-browse-error)
- (define-key energize-map "\^C\^B\^L" 'energize-browse-language-elt)
- (define-key energize-map "\^C\^B\^T" 'energize-browse-tree)
- (define-key energize-map "\^C\^B\^C" 'energize-browse-class)
- ;; now in global-map
- ;; (define-key energize-map "\M-B" 'energize-build-a-target) ; M-Sh-B
- (define-key energize-map "\M-C" 'energize-default-compile-file) ; M-Sh-C
- (define-key energize-map 'button3 'energize-popup-menu)
- )
-
- (if energize-top-level-map
- nil
- (setq energize-top-level-map (make-sparse-keymap))
- (set-keymap-name energize-top-level-map 'energize-top-level-map)
- (set-keymap-parent energize-top-level-map energize-map)
- (suppress-keymap energize-top-level-map)
- (define-key energize-top-level-map "?" 'describe-mode)
- (define-key energize-top-level-map " " 'energize-top-next-project)
- (define-key energize-top-level-map "n" 'energize-top-next-project)
- (define-key energize-top-level-map "p" 'energize-top-prev-project)
- (define-key energize-top-level-map "N" 'energize-top-next-project)
- (define-key energize-top-level-map "P" 'energize-top-prev-project)
- (define-key energize-top-level-map "\t" 'energize-top-next-project)
- (define-key energize-top-level-map '(shift tab) 'energize-top-prev-project)
- (define-key energize-top-level-map '(control I) 'energize-top-prev-project)
-
- (define-key energize-top-level-map "Q" 'disconnect-from-energize-query)
-
- (define-key energize-top-level-map "d" 'energize-top-debug)
- (define-key energize-top-level-map "\^D" 'energize-top-delete-project)
- (define-key energize-top-level-map "e" 'energize-top-edit-project)
- )
-
- (if energize-project-map
- nil
- (setq energize-project-map (make-sparse-keymap))
- (set-keymap-name energize-project-map 'energize-project-map)
- (set-keymap-parent energize-project-map energize-map)
- ;;(suppress-keymap energize-project-map)
- ;;(define-key energize-project-map "\t" 'energize-project-next-field)
- ;;(define-key energize-project-map '(shift tab) 'energize-project-prev-field)
- ;;(define-key energize-project-map '(control I) 'energize-project-prev-field)
-
- (define-key energize-project-map "\^C\^I" 'energize-import-file)
- (define-key energize-project-map "\^C\^E" 'energize-project-edit-file)
- (define-key energize-project-map "\^C\^S\^A" 'energize-project-sort-alpha)
- (define-key energize-project-map "\^C\^S\^L" 'energize-project-sort-link)
- (define-key energize-project-map "\^C\^V\^N" 'energize-project-view-names)
- ; (define-key energize-project-map "\^C\^V\^L" 'energize-project-view-long)
- (define-key energize-project-map "\^C\^V\^C" 'energize-project-view-options)
- )
-
-
- (if energize-no-file-project-map
- nil
- (setq energize-no-file-project-map (make-sparse-keymap))
- (set-keymap-name energize-no-file-project-map 'energize-no-file-project-map)
- (set-keymap-parent energize-no-file-project-map energize-map))
-
- (if energize-breakpoint-map
- nil
- (setq energize-breakpoint-map (make-sparse-keymap))
- (set-keymap-name energize-breakpoint-map 'energize-breakpoint-map)
- (set-keymap-parent energize-breakpoint-map energize-map)
- )
-
- (if energize-browser-map
- nil
- (setq energize-browser-map (make-sparse-keymap))
- (set-keymap-name energize-browser-map 'energize-browser-map)
- (set-keymap-parent energize-browser-map energize-map)
- )
-
- (if energize-source-map
- nil
- (setq energize-source-map (make-sparse-keymap))
- (set-keymap-name energize-source-map 'energize-source-map)
- (set-keymap-parent energize-source-map energize-map)
- ;; There are too many problems with using extents to determine where the
- ;; top level forms are...
- ;; (define-key energize-source-map "\M-\C-a" 'energize-beginning-of-defun)
- ;; (define-key energize-source-map "\M-\C-e" 'energize-end-of-defun)
- )
-
- (defvar energize-menu-state nil
- "State of the energize menu items of the buffer.
- Automatically updated by the kernel when the state changes")
-
- (defvar energize-default-menu-state nil
- "State of the energize default menu items.
- Automatically updated by the kernel when the state changes")
-
- (defun energize-mode-internal ()
- ;; initialize stuff common to all energize buffers (hooks, etc).
- (make-local-variable 'write-file-data-hooks)
- (add-hook 'write-file-data-hooks 'energize-write-data-hook t)
- ;;
- (make-local-variable 'revert-buffer-insert-file-contents-function)
- (setq revert-buffer-insert-file-contents-function
- 'energize-revert-buffer-insert-file-contents-hook)
- ;;
- (make-local-variable 'kill-buffer-hook)
- (setq kill-buffer-hook 'energize-kill-buffer-hook)
- ;;
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- ;;
- (make-local-variable 'energize-menu-state)
- ;;
- (run-hooks 'energize-mode-hook))
-
- (defun energize-non-file-mode-internal ()
- ;; do magic associated with energize-modes for buffers which are not
- ;; and cannot be associated with files.
- ; (or (null buffer-file-name)
- ; (equal buffer-file-name mode-name)
- ; (error
- ; "This buffer is associated with a file, it can't be placed in %s mode"
- ; mode-name))
- ;; hack so that save-file doesn't prompt for a filename.
- (or buffer-file-name
- (setq buffer-file-name (buffer-name)))
- (set (make-local-variable 'version-control) 'never)
- nil)
-
- ;; don't create random new buffers in these modes
- (put 'energize-top-level-mode 'mode-class 'special)
- (put 'energize-project-mode 'mode-class 'special)
- (put 'energize-no-file-project-mode 'mode-class 'special)
- (put 'energize-breakpoint-mode 'mode-class 'special)
- (put 'energize-browser-mode 'mode-class 'special)
- (put 'energize-log-mode 'mode-class 'special)
-
- (defun energize-top-level-mode ()
- "Major mode for the Energize top-level buffer.
- In addition to normal cursor-motion commands, the following keys are bound:
- \\{energize-top-level-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-top-level-map)
- (setq major-mode 'energize-top-level-mode
- mode-name "Energize")
- (energize-non-file-mode-internal)
- ;; the default of "energize: Energize" is not very attractive.
- (if (equal frame-title-format "%S: %b")
- (set (make-local-variable 'frame-title-format) "%S: Top-Level"))
- (run-hooks 'energize-top-level-mode-hook))
-
-
- (defun energize-project-mode ()
- "Major mode for the Energize Project buffers.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-project-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-project-map)
- (setq major-mode 'energize-project-mode
- mode-name "Project")
- ;; in later revisions of the kernel the project is really a file.
- (if (< (cdr (energize-protocol-level)) 8)
- (energize-non-file-mode-internal))
- (run-hooks 'energize-project-mode-hook))
-
- (defun energize-no-file-project-mode ()
- "Major mode for the Energize Project buffers not associated with a file.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-no-file-project-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-no-file-project-map)
- (setq major-mode 'energize-no-file-project-mode
- mode-name "NoFileProject")
- (energize-non-file-mode-internal)
- (run-hooks 'energize-no-file-project-mode-hook))
-
- (defun energize-breakpoint-mode ()
- "Major mode for the Energize Breakpoint-list buffers.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-breakpoint-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-breakpoint-map)
- (setq major-mode 'energize-breakpoint-mode
- mode-name "Breakpoint")
- (energize-non-file-mode-internal)
- (run-hooks 'energize-breakpoint-mode-hook))
-
- (defun energize-browser-mode ()
- "Major mode for the Energize Browser buffers.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-browser-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-browser-map)
- (setq major-mode 'energize-browser-mode
- mode-name "Browser")
- (energize-non-file-mode-internal)
- (run-hooks 'energize-browser-mode-hook))
-
- (defun energize-log-mode ()
- "Major mode for the Energize Error Log and System Log buffers.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-map)
- (setq major-mode 'energize-log-mode
- mode-name "Energize-Log")
- (energize-non-file-mode-internal)
- (run-hooks 'energize-log-mode-hook))
-
- (defun energize-manual-mode ()
- "Major mode for the Energize UNIX Manual buffers.
- In addition to the normal editing commands, the following keys are bound:
- \\{energize-map}"
- (interactive)
- (energize-mode-internal)
- (use-local-map energize-map)
- (setq major-mode 'energize-manual-mode
- mode-name "Energize-Manual")
- (energize-non-file-mode-internal)
- (run-hooks 'energize-manual-mode-hook))
-
- (defvar energize-source-mode nil)
- ;;(put 'energize-source-mode 'permanent-local t) ; persists beyond mode-change
-
- ;;; Add energize-source-mode to minor-mode-alist so that it shows up in
- ;;; the modeline when true.
- ;;;
- (or (assq 'energize-source-mode minor-mode-alist)
- (setq minor-mode-alist
- (append minor-mode-alist
- '((energize-source-mode " Energize")))))
-
-
- (defun energize-source-minor-mode ()
- "Minor mode for adding additional keybindings to Energize source buffers.
- The following key bindings are added:
- \\{energize-source-map}
-
- Since this minor mode defines keys, once it gets turned on you can't really
- turn it off."
- (interactive)
- (energize-mode-internal)
- (make-local-variable 'energize-source-mode)
- (setq energize-source-mode t)
- (let ((source-map energize-source-map)
- (dest-map (make-sparse-keymap)))
- (set-keymap-parent dest-map (current-local-map))
- (set-keymap-name dest-map 'energize-minor-mode-map)
- (while source-map
- (let (mapper prefixes)
- (setq mapper (function (lambda (key val)
- (if (keymapp val)
- (let ((prefixes (append prefixes
- (cons key nil))))
- (map-keymap val mapper))
- (define-key dest-map
- (apply 'vector
- (append prefixes (cons key nil)))
- val)
- ))))
- (map-keymap source-map mapper))
- (setq source-map (keymap-parent source-map)))
- (use-local-map dest-map))
- (run-hooks 'energize-source-mode-hook))
-
-
- ;;; Commands in source buffers
-
- (defun recenter-definition ()
- "Position the beginning of the current definition at the top of the frame."
- (interactive)
- (end-of-line)
- (if (eq major-mode 'c++-mode)
- (c++-beginning-of-defun 1)
- (beginning-of-defun 1))
- (recenter 1))
-
- (define-key global-map "\M-\C-r" 'recenter-definition)
-
- (defun energize-hide-error-glyphs-in-form ()
- "Hides the error icons in the current toplevel form.
- You cannot get them back until you recompile the file."
- (interactive)
- (save-excursion
- (save-restriction
- (let ((start (progn (energize-beginning-of-defun) (point)))
- (end (progn (energize-end-of-defun) (point)))
- e)
- (narrow-to-region start end)
- (goto-char (point-min))
- (setq e (extent-at (point)))
- (while (and e
- (< (extent-end-position e) (point-max)))
- (if (extent-property e 'begin-glyph)
- (set-extent-begin-glyph e nil))
- (setq e (next-extent e)))))))
-
- ;;; Dired-like commands
-
- (defun energize-next-extent-for (command prev not-this-one)
- (let ((last-e (if not-this-one 'none nil))
- e result)
- (save-excursion
- (while (not (or result
- (if prev (bobp) (eobp))))
- (setq e (extent-at (point) (current-buffer)))
- (if (and (not (eq e last-e))
- (not (eq last-e 'none)))
- (setq result
- (energize-menu-item-for-name e command)))
- (forward-char (if prev -1 1))
- (setq last-e e)))
- (if result e)))
-
- (defun energize-next-extent-on-line-for (command not-this-one)
- (save-excursion
- (save-restriction
- (narrow-to-region (point) (progn (end-of-line) (point)))
- (goto-char (point-min))
- (energize-next-extent-for command nil not-this-one))))
-
-
- ;;; commands in the top-level buffer
-
- (defun energize-top-next-project ()
- "Position the cursor at the beginning of the following project."
- (interactive)
- (let ((p (point)))
- (let ((e (energize-next-extent-for "editproject" nil t)))
- (if (and e (= p (extent-start-position e)))
- (save-excursion
- (forward-char (extent-length e))
- (setq e (energize-next-extent-for "editproject" nil t))))
- (if e
- (goto-char (extent-start-position e))
- (error "no next project")))))
-
- (defun energize-top-prev-project ()
- "Position the cursor at the beginning of the preceeding project."
- (interactive)
- (let ((p (point)))
- (let ((e (energize-next-extent-for "editproject" t t)))
- (if (and e (= p (extent-start-position e)))
- (save-excursion
- (forward-char -1)
- (setq e (energize-next-extent-for "editproject" t t))))
- (if e
- (goto-char (extent-start-position e))
- (error "no previous project")))))
-
- (defun energize-top-execute-command (command)
- (let ((e (or (energize-next-extent-on-line-for command nil)
- (error
- (concat "no following field on this line that handles the `"
- command "' Energize command.")))))
- (energize-execute-command command e)))
-
- (defun energize-top-debug ()
- "Execute the `Debug' command on the project at or following point."
- (interactive)
- (energize-top-execute-command "debugprogram"))
-
- (defun energize-top-delete-project ()
- "Delete the project at or following point."
- (interactive)
- (energize-top-execute-command "deleteproject"))
-
- (defun energize-top-edit-project ()
- "Edit the project at or following point."
- (interactive)
- (energize-top-execute-command "editproject"))
-
- ;;; commands in the project buffer
-
- (defun energize-project-next-field (&optional prev)
- (interactive)
- (let ((e (extent-at (point) (current-buffer))))
- (if e
- (if prev
- (goto-char (1- (extent-start-position e)))
- (goto-char (1+ (extent-end-position e)))))
- (while (null (extent-at (point) (current-buffer)))
- (forward-char (if prev -1 1)))
- (while (extent-at (point) (current-buffer) 'write-protected)
- (forward-char (if prev -1 1)))
- (if prev
- (if (setq e (extent-at (point) (current-buffer)))
- (goto-char (extent-start-position e))
- (while (not (extent-at (point) (current-buffer)))
- (forward-char -1))))))
-
- (defun energize-project-prev-field () (interactive)
- (energize-project-next-field t))
-
- (defun energize-project-edit-file () (interactive)
- (energize-top-execute-command "editfile"))
-
-
- (defun energize-project-prune-unused-rules ()
- "Deletes all unused rules from the Rules: part of a Project buffer,
- and renumbers the remaining rules sequentally."
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (re-search-forward "^[ \t]+Rules:")
- (forward-line 1)
- (let ((rules-regexp "^[ \t]*\\(\\.[a-zA-Z]+\\(([0-9]+)\\)?\\):")
- (all-rules nil)
- eor)
- ;;
- ;; Gather the contents of the Rule section, and find its end.
- ;;
- (save-excursion
- (while (looking-at rules-regexp)
- (setq all-rules (cons (list (buffer-substring (match-beginning 1)
- (match-end 1))
- (point-marker))
- all-rules))
- (while (progn (end-of-line) (= (preceding-char) ?\\))
- (forward-line 1))
- (forward-line 1))
- (setq eor (point-marker)))
- (setq all-rules (nreverse all-rules))
- (let ((rest all-rules)
- rule)
- ;;
- ;; Walk through the buffer gathering references to the rules.
- ;;
- (while rest
- (setq rule (car rest))
- (goto-char eor)
- (let ((pattern (concat "^[ \t]+" (regexp-quote (car rule)) ":")))
- (while (re-search-forward pattern nil t)
- (setcdr (cdr rule)
- (cons (set-marker (make-marker) (match-beginning 0))
- (cdr (cdr rule))))))
- (setq rest (cdr rest)))
- ;;
- ;; Delete those rules that have no references.
- ;;
- (goto-char eor)
- (setq rest all-rules)
- (while rest
- (setq rule (car rest))
- (if (null (cdr (cdr rule)))
- (let ((p (nth 1 rule)))
- (goto-char p)
- (while (progn (end-of-line) (= (preceding-char) ?\\))
- (forward-line 1))
- (forward-line 1)
- (delete-region p (point))
- (set-marker p nil)
- (setq all-rules (delq rule all-rules))
- ))
- (setq rest (cdr rest)))
- ;;
- ;; Renumber the remaining rules sequentally.
- ;;
- (goto-char eor)
- (setq rest all-rules)
- (let ((i 1))
- (while rest
- (setq rule (car rest))
- (let ((referents (cdr rule))) ; including definition
- (while referents
- (goto-char (car referents))
- (or (and (looking-at
- (concat "^[ \t]+" (regexp-quote (car rule)) ":"))
- (looking-at "[^:(]+\\((\\([0-9]+\\))\\|\\):"))
- (error "internal error"))
- (if (null (match-beginning 2))
- (progn
- (goto-char (match-beginning 1))
- (insert "(" (int-to-string i) ")"))
- (goto-char (match-beginning 2))
- (delete-region (match-beginning 2) (match-end 2))
- (insert (int-to-string i)))
- (set-marker (car referents) nil)
- (setq referents (cdr referents))))
- (setq i (1+ i))
- (setq rest (cdr rest))))
- ;;
- ;; TODO:
- ;; - order the Rule Users list in the same order as the Rules list.
- ;; - or, order the Rule Users list by number of files, and then
- ;; order the Rules list the same as that (numbered sequentially.)
- ;; - or, order the Rules list by length-of-rule (= complicatedness.)
- )
- (set-marker eor nil))))
-