This is a first little piece of emacs-code, to achieve the task of writing log messages to
_MTN/log instead of
ChangeLog if appropriate. (Note that DVC already includes a similar feature, bound to
C-x V a by default.)
Look at the source for a way to use it. From now on use
mtn-add-change-log-entry instead of
mtn-add-change-log-entry will try do the right thing.
If a directory named
_MTN exists in the buffers
default-directory or in any parent directory, use
../_MTN/log or whatsoever.
./ChangeLog (or better
change-log-default-name as from customize) otherwise. All your customisations (
M-x customize-group RET change-log RET) work as expected.
I have a symbolic link named
current in my home directory, that always points the folder of the project I'm currently working on. If I
mtn-add-change-log-entry on a file in there, these functions still search up the real directory tree.
/home/sebastian/current points to
/home/sebastian/develop/gtkmm/application/src, and there are
mtn-add-changelog-entry will choose
add-change-log-entry interactively, you still can choose to write to use an other file.
;; File: sr-monotone.el ;; $Revision: 1.2 $ ;; Date: 2006-12-04 ;; Author: Sebastian Rose <email@example.com> ;; License: GPL ;; ;; Copyright (c) 2006 Sebastian Rose <firstname.lastname@example.org> ;; ;; ;; Provides to funktions: ;; * mtn-get-parent-directory (child) ;; returns the parent directory or nil, if there is no parent. ;; I wrote it, since I could not find a function like this. ;; * mtn-add-change-log-entry () ;; looks for _MTN directory and changes the behaviour of ;; add-change-log-entry to use /PATH/TO/_MTN as directory ;; and 'log' as the default filename for the logfile. ;; ;; ;; ;; Usage: ;; ;; THE ONE WAY ;; In your .emacs put this line: ;; (require 'sr-monotone) ;; ... and place this file somewhere in your load-path. ;; ;; ;; THE OTHER WAY ;; Copy the two functions here and paste them in your .emacs. ;; ;; ;; ;; Bind any key you like to mtn-add-change-log-entry. ;; (global-set-key [(f8)] 'mtn-add-change-log-entry) ;; ;; From now on only use mtn-add-change-log-entry. It detects automagically the ;; right way to call add-change-log-entry. (provide 'sr-monotone) (defun mtn-get-parent-directory (child) "Retruns the parent directory or nil, if there is no parent. Parent has always a trailing slash, or what ever is your systems file separtor. Improvements and suggestions to email@example.com." (if (file-regular-p child) (file-name-as-directory (file-name-directory child)) ; this is else: (let ((child (file-name-as-directory child))) (let ((dir (file-name-as-directory (expand-file-name child))) (parent (file-truename (file-name-as-directory (expand-file-name (concat child "..")))))) (if (string= dir parent) nil parent))))) (defun mtn-add-change-log-entry() "Searches in buffers default-directory and above for a directory named '_MTN'. If it exists, monotone-add-change-log-entry calls add-change-log-entry interactively with apropriate arguments. Otherwise interactively calls add-change-log-entry the normal way. So one can just bind this function to the keys, that call add-change-log-entry now, and it will work just fine. Improvements and suggestions to firstname.lastname@example.org." (interactive) (let ((filename buffer-file-name) (is-mtn-dir nil) (original-default-directory default-directory) (original-change-log-filename nil)) (if (boundp 'change-log-default-name) (setq original-change-log-filename change-log-default-name)) (unwind-protect (progn (if filename (progn (catch 'done (while (setq filename (mtn-get-parent-directory filename)) (if (file-directory-p (concat filename "_MTN")) (progn (setq change-log-default-name "log") (setq is-mtn-dir (concat filename "_MTN")) (throw 'done 'is-mtn-dir))))) (if is-mtn-dir (let ((default-directory is-mtn-dir)) (call-interactively 'add-change-log-entry)) (call-interactively 'add-change-log-entry)) ))) (setq default-directory original-default-directory) (setq change-log-default-name original-change-log-filename) ))) ;; 2006-16-12 ;; This function is the one you need, to make add-change-log-entry ;; print the path of the file you're writing the change log entry for ;; relative to the root of your project directory. ;; If change-log-default-name is "log", this function assumes the ;; file is part of a monotone project and return the files path ;; relative to "/_MTN/..", just like monotone commands would do. ;; Otherwise returns the path of the file relative to the directory, ;; where the log file lives in. ;; ;; No leading slash prepended. ;; ;; To use this function type ;; M-x customize-variable RET add-log-file-name-function RET ;; and make it point to mtn-add-log-file-name. ;; Unfortunately this function relies on log-file, which is an undocumented ;; variable in add-log.el, actually a local variabel in function ;; add-log-file-name (buffer-file log-file). ;; But I couldn't find an other way, to get the logfile, the user has ;; choosen at this point. ;; (defun mtn-add-log-file-name(original-name) "Return the filename printed in _MTN/log (or ChangeLog) relative to the projects root. That is the driectory the file ChangeLog lives in, if not a monotone project, _MTN/../ otherwise. Improvements and suggestions to email@example.com." (let ((directory (mtn-get-parent-directory log-file)) (file (file-truename original-name))) (if (string= change-log-default-name "log") ;; monotone (let ((directory (mtn-get-parent-directory directory))) (file-relative-name file directory)) ;; else no monotone: (file-relative-name file directory))))