    Allow a macro to set the document's window title or title format

    This is done by allowing the document window to carry a custom version
    of the title format string. The new macro function,
    set_window_title_format(), is called as follows:
	    set_window_title_format(<I>string</I>)
	    set_window_title_format(<I>string</I>, "text")
	    set_window_title_format(<I>string</I>, "format")
    The string will be interpreted as a title format if the "format" keyword is
    supplied, or as a fixed title string otherwise. The format directives are
    those used in Preferences> Default Settings> Customize Window Title...
    dialog. If an empty string is used, the default format (from the
    Preferences) is applied.

diff -ur nedit_official nedit_mod
diff -ur nedit_official/doc/help.etx nedit_mod/doc/help.etx
--- nedit_official/doc/help.etx	2007-01-04 02:42:23.000000000 +0100
+++ nedit_mod/doc/help.etx	2007-01-15 17:53:33.203125000 +0100
@@ -3781,9 +3781,16 @@
   below).
 
 **Customize Window Title**
+.. ? help~
+  Opens a dialog where the information to be displayed in the window's title
+  field can be defined and tested. The Customize_Window_Title_Dialog_ contains
+  a Help button, providing further information about the options available.
+.. ~ help
+.. ! help~
   Opens a dialog where the information to be displayed in the window's title
   field can be defined and tested. The dialog contains a Help button, providing
   further information about the options available.
+.. ~ help
 
 **Searching**
   Options for controlling the behavior of Find and Replace commands:
diff -ur nedit_official/source/macro.c nedit_mod/source/macro.c
--- nedit_official/source/macro.c	2007-01-04 02:42:24.000000000 +0100
+++ nedit_mod/source/macro.c	2007-01-15 17:53:33.203125000 +0100
@@ -403,6 +403,8 @@
         DataValue *result, char **errMsg);
 static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
         DataValue* result, char** errMsg);
+static int setWindowTitleFormatMS(WindowInfo *window, DataValue *argList,
+        int nArgs, DataValue *result, char **errMsg);
 
 /* Built-in subroutines and variables for the macro language */
 static BuiltInSubr MacroSubrs[] = {lengthMS, getRangeMS, tPrintMS,
@@ -421,7 +423,8 @@
         rangesetSetColorMS, rangesetSetNameMS, rangesetSetModeMS,
         rangesetGetByNameMS,
         getPatternByNameMS, getPatternAtPosMS,
-        getStyleByNameMS, getStyleAtPosMS, filenameDialogMS
+        getStyleByNameMS, getStyleAtPosMS, filenameDialogMS,
+        setWindowTitleFormatMS,
     };
 #define N_MACRO_SUBRS (sizeof MacroSubrs/sizeof *MacroSubrs)
 static const char *MacroSubrNames[N_MACRO_SUBRS] = {"length", "get_range", "t_print",
@@ -440,7 +443,8 @@
         "rangeset_set_color", "rangeset_set_name", "rangeset_set_mode",
         "rangeset_get_by_name",
         "get_pattern_by_name", "get_pattern_at_pos",
-        "get_style_by_name", "get_style_at_pos", "filename_dialog"
+        "get_style_by_name", "get_style_at_pos", "filename_dialog",
+        "set_window_title_format",
     };
 static BuiltInSubr SpecialVars[] = {cursorMV, lineMV, columnMV,
         fileNameMV, filePathMV, lengthMV, selectionStartMV, selectionEndMV,
@@ -3471,6 +3475,80 @@
     return True;
 }
 
+/* 
+ * set_window_title_format(format[, ("text"|"format")])
+ */
+static int setWindowTitleFormatMS(WindowInfo *window, DataValue *argList,
+        int nArgs, DataValue *result, char **errMsg)
+{
+    char stringStorage[2][TYPE_INT_STR_SIZE(int)];
+    char *fmt = NULL;
+    char *type = NULL;
+    char *newFmt;
+    char *from, *to;
+    int isText = 1;
+    int perCents;
+
+    if (nArgs > 2) {
+        *errMsg = "subroutine %s called with too many arguments";
+        return False;
+    }
+    if (nArgs > 0 &&
+        !readStringArg(argList[0], &fmt, stringStorage[0], errMsg)) {
+        return False;
+    }
+    if (nArgs > 1 &&
+        !readStringArg(argList[1], &type, stringStorage[1], errMsg)) {
+        return False;
+    }
+    if (type) {
+        if (strcmp(type, "text") == 0)
+            isText = 1;
+        else if (strcmp(type, "format") == 0)
+            isText = 0;
+        else {
+            *errMsg = "subroutine %s type value must be \"text\" or \"format\"";
+            return False;
+        }
+    }
+
+    if (!fmt || !*fmt) {
+        /* empty string: return tu default behaviour */
+        XtFree(window->titleFormat);
+        window->titleFormat = NULL;
+        UpdateWindowTitle(window);
+        return True;
+    }
+
+    perCents = 0;
+    if (isText) {
+        /* measure extra space for '%' */
+        for (from = fmt; *from; from++)
+            if ('%' == *from)
+                ++perCents;
+    }
+
+    newFmt = XtMalloc(strlen(fmt) + perCents + 1);
+    if (!newFmt) {
+        *errMsg = "subroutine %s failed to allocate format value";
+        return False;
+    }
+    if (isText) {
+        /* double up any % signs */
+        for (from = fmt, to = newFmt; *from; *to++ = *from++)
+            if ('%' == *from)
+                *to++ = '%';
+        *to = '\0';
+    }
+    else
+        strcpy(newFmt, fmt);
+
+    XtFree(window->titleFormat);
+    window->titleFormat = newFmt;
+    UpdateWindowTitle(window);
+    return True;
+}
+
 /* T Balinski */
 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
       DataValue *result, char **errMsg)
diff -ur nedit_official/source/nedit.h nedit_mod/source/nedit.h
--- nedit_official/source/nedit.h	2006-11-22 14:45:52.000000000 +0100
+++ nedit_mod/source/nedit.h	2007-01-15 17:53:33.218750000 +0100
@@ -454,6 +454,7 @@
 #endif
     char	filename[MAXPATHLEN];	/* name component of file being edited*/
     char	path[MAXPATHLEN];	/* path component of file being edited*/
+    char        *titleFormat;           /* custom title format string */
     unsigned	fileMode;		/* permissions of file being edited */
     uid_t	fileUid; 		/* last recorded user id of the file */
     gid_t	fileGid;		/* last recorded group id of the file */
diff -ur nedit_official/source/window.c nedit_mod/source/window.c
--- nedit_official/source/window.c	2006-12-02 11:27:06.000000000 +0100
+++ nedit_mod/source/window.c	2007-01-15 17:53:33.218750000 +0100
@@ -248,6 +248,7 @@
     window->writableWindows = NULL;
     window->nWritableWindows = 0;
     window->fileChanged = FALSE;
+    window->titleFormat = NULL;
     window->fileMode = 0;
     window->fileUid = 0;
     window->fileGid = 0;
@@ -943,7 +944,13 @@
     /* Kill shell sub-process and free related memory */
     AbortShellCommand(window);
 #endif /*VMS*/
-    
+
+    /* drop any custom title */
+    if (window->titleFormat) {
+        XtFree(window->titleFormat);
+        window->titleFormat = NULL;
+    }
+
     /* Unload the default tips files for this language mode if necessary */
     UnloadLanguageModeTipsFile(window);
 
@@ -2020,28 +2027,33 @@
 */
 void UpdateWindowTitle(const WindowInfo *window)
 {
-    char *iconTitle, *title;
+    char *iconTitle, *title, *format, *filename;
     
     if (!IsTopDocument(window))
     	return;
 
+    format = window->titleFormat ? window->titleFormat : GetPrefTitleFormat();
+    filename = window->filename;
     title = FormatWindowTitle(window->filename,
-                                    window->path,
+                              window->path,
 #ifdef VMS
-                                    NULL,
+                              NULL,
 #else
-                                    GetClearCaseViewTag(),
+                              GetClearCaseViewTag(),
 #endif /* VMS */
-                                    GetPrefServerName(),
-                                    IsServer,
-                                    window->filenameSet,
-                                    window->lockReasons,
-                                    window->fileChanged,
-                                    GetPrefTitleFormat());
-                   
-    iconTitle = XtMalloc(strlen(window->filename) + 2); /* strlen("*")+1 */
+                              GetPrefServerName(),
+                              IsServer,
+                              window->filenameSet,
+                              window->lockReasons,
+                              window->fileChanged,
+                              format);
+
+    if (strcmp(title, format) == 0)
+        filename = title;
+
+    iconTitle = XtMalloc(strlen(filename) + 2); /* strlen("*")+1 */
 
-    strcpy(iconTitle, window->filename);
+    strcpy(iconTitle, filename);
     if (window->fileChanged)
         strcat(iconTitle, "*");
     XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, iconTitle, NULL);
@@ -3285,6 +3297,7 @@
     window->nWritableWindows = 0;
     window->fileChanged = FALSE;
     window->fileMissing = True;
+    window->titleFormat = NULL;
     window->fileMode = 0;
     window->fileUid = 0;
     window->fileGid = 0;
