1 From: Thorsten Haude <yoo@vranx.de>
2 Subject: transient documents
4 Transient documents ignore the modified flag.
8 doc/help.etx | 18 +++++++++++
9 source/file.c | 74 +++++++++++++++++++++++++++++++++----------------
11 source/highlightData.c | 4 +-
12 source/macro.c | 14 +++++++++
13 source/menu.c | 51 +++++++++++++++++++++++++++++----
16 source/server.c | 5 +--
18 source/window.c | 18 ++++++++---
19 source/windowTitle.c | 51 ++++++++++++++++++++++++++-------
20 source/windowTitle.h | 1
21 13 files changed, 192 insertions(+), 55 deletions(-)
23 diff --quilt old/doc/help.etx new/doc/help.etx
26 @@ -3241,11 +3241,11 @@ Action Routines
27 3>Menu Action Routine Arguments
29 Arguments are text strings enclosed in quotes. Below are the menu action
30 routines which take arguments. Optional arguments are enclosed in [].
32 - **new**( ["tab" | "window" | "prefs" | "opposite"] )
33 + **new**( ["tab" | "window" | "prefs" | "opposite"] [, "transient"] )
35 **close**( ["prompt" | "save" | "nosave"] )
37 **execute_command**( shell-command )
39 @@ -3308,10 +3308,19 @@ Action Routines
41 "opposite": Opposite of user's tab/window
43 Default behaviour is "prefs".
45 + "transient" [EXPERIMENTAL]: Open the new
46 + document in transient mode. This disables the
47 + warning NEdit usually gives when you try to
48 + close a file which is not saved.
50 + WARNING: This is an experimental feature.
51 + Make sure to use this setting only for
52 + documents which can easily be recreated.
54 ~filename~ Path names are relative to the directory from
55 which NEdit was started. Shell interpreted
56 wildcards and `~' are not expanded.
58 ~keep-dialog~ Either "keep" or "nokeep".
59 @@ -3942,10 +3951,17 @@ Preferences
61 Lock the file against accidental modification. This temporarily prevents the
62 file from being modified in this NEdit session. Note that this is different
63 from setting the file protection.
65 +**Transient [EXPERIMENTAL]**
66 + Flags the document as transient. This disables the warning NEdit usually
67 + gives when you try to close a file which is not saved.
69 + WARNING: This is an experimental feature. Make sure to use this setting
70 + only for documents which can easily be recreated.
72 3>Preferences -> Default Settings Menu
74 Options in the Preferences -> Default Settings menu have the same meaning as
75 those in the top-level Preferences menu, except that they apply to future
76 NEdit windows and future NEdit sessions if saved with the Save Defaults
77 diff --quilt old/source/file.h new/source/file.h
81 #define PROMPT_SBC_DIALOG_RESPONSE 0
82 #define YES_SBC_DIALOG_RESPONSE 1
83 #define NO_SBC_DIALOG_RESPONSE 2
85 WindowInfo *EditNewFile(WindowInfo *inWindow, char *geometry, int iconic,
86 - const char *languageMode, const char *defaultPath);
87 + const char *languageMode, const char *defaultPath, Boolean transient);
88 WindowInfo *EditExistingFile(WindowInfo *inWindow, const char *name,
89 const char *path, int flags, char *geometry, int iconic,
90 const char *languageMode, int tabbed, int bgOpen);
91 void RevertToSaved(WindowInfo *window);
92 int SaveWindow(WindowInfo *window);
93 @@ -58,9 +58,9 @@ int IncludeFile(WindowInfo *window, cons
94 int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname);
95 int PromptForNewFile(WindowInfo *window, char *prompt, char *fullname,
96 int *fileFormat, int *addWrap);
97 int CheckReadOnly(WindowInfo *window);
98 void RemoveBackupFile(WindowInfo *window);
99 -void UniqueUntitledName(char *name);
100 +void UniqueUntitledName(char *name, Boolean transient);
101 void CheckForChangesToFile(WindowInfo *window);
103 #endif /* NEDIT_FILE_H_INCLUDED */
104 diff --quilt old/source/file.c new/source/file.c
105 --- old/source/file.c
106 +++ new/source/file.c
107 @@ -108,21 +108,21 @@ static void forceShowLineNumbers(WindowI
109 void removeVersionNumber(char *fileName);
112 WindowInfo *EditNewFile(WindowInfo *inWindow, char *geometry, int iconic,
113 - const char *languageMode, const char *defaultPath)
114 + const char *languageMode, const char *defaultPath, Boolean transient)
116 char name[MAXPATHLEN];
121 /*... test for creatability? */
123 /* Find a (relatively) unique name for the new file */
124 - UniqueUntitledName(name);
125 + UniqueUntitledName(name, transient);
127 /* create new window/document */
129 window = CreateDocument(inWindow, name);
131 @@ -167,10 +167,18 @@ WindowInfo *EditNewFile(WindowInfo *inWi
132 if (iconic && IsIconic(window))
133 RaiseDocument(window);
135 RaiseDocumentWindow(window);
138 + /* Set the window to transient mode. */
139 + String apParams[1];
142 + XtCallActionProc(window->lastFocus, "set_transient", NULL, apParams, 1);
150 @@ -730,21 +738,26 @@ int CloseFileAndWindow(WindowInfo *windo
152 /* Make sure that the window is not in iconified state */
153 if (window->fileChanged)
154 RaiseDocumentWindow(window);
156 - /* If the window is a normal & unmodified file or an empty new file,
157 - or if the user wants to ignore external modifications then
158 - just close it. Otherwise ask for confirmation first. */
159 - if (!window->fileChanged &&
160 + /* If the document is transient, belongs to a normal & unmodified file
161 + or is empty and unchanged, or if the user wants to ignore external
162 + modifications then just close it. Otherwise ask for confirmation
166 + window->transient ||
167 + (!window->fileChanged &&
169 ((!window->fileMissing && window->lastModTime > 0) ||
171 (window->fileMissing && window->lastModTime == 0) ||
172 /* File deleted/modified externally, ignored by user. */
173 - !GetPrefWarnFileMods()))
174 + !GetPrefWarnFileMods())))
176 + RemoveBackupFile(window);
178 /* up-to-date windows don't have outstanding backup files to close */
181 if (preResponse == PROMPT_SBC_DIALOG_RESPONSE)
182 @@ -1082,10 +1095,20 @@ static int doSave(WindowInfo *window)
183 window->fileMissing = TRUE;
188 + /* If the window was previously transient and the user saves it, than he
189 + obviously don't want the window to be transient anymore */
190 + if (window->transient) {
191 + /* Unset the window to transient mode. */
192 + String apParams[1];
195 + XtCallActionProc(window->lastFocus, "set_transient", NULL, apParams, 1);
198 /* call "post_save_hook" */
199 MacroApplyHook(window, "post_save_hook", 0, NULL, NULL);
203 @@ -1180,14 +1203,10 @@ int WriteBackupFile(WindowInfo *window)
205 void RemoveBackupFile(WindowInfo *window)
207 char name[MAXPATHLEN];
209 - /* Don't delete backup files when backups aren't activated. */
210 - if (window->autoSave == FALSE)
213 backupFileName(window, name, sizeof(name));
218 @@ -1612,28 +1631,35 @@ int PromptForNewFile(WindowInfo *window,
222 ** Find a name for an untitled file, unique in the name space of in the opened
223 ** files in this session, i.e. Untitled or Untitled_nn, and write it into
224 -** the string "name".
225 +** the string "name" (at least MAXPATHLEN).
227 -void UniqueUntitledName(char *name)
228 +void UniqueUntitledName(char *name, Boolean transient)
232 + const char *base = transient ? "Transient" : "Untitled";
234 + size_t baseLen = strlen(base);
235 + size_t totalSpace = MAXPATHLEN;
237 + snprintf(name, MAXPATHLEN, "%s", base);
238 + tail = name + baseLen;
239 + totalSpace -= baseLen;
243 + for (w = WindowList; w != NULL; w = w->next)
244 + if (!strcmp(w->filename, name))
249 - for (i=0; i<INT_MAX; i++) {
251 - sprintf(name, "Untitled");
253 - sprintf(name, "Untitled_%d", i);
254 - for (w=WindowList; w!=NULL; w=w->next)
255 - if (!strcmp(w->filename, name))
260 + snprintf(tail, totalSpace, "_%d", ++i);
261 + } while (i < INT_MAX);
265 ** Callback that guards us from trying to access a window after it has
266 ** been destroyed while a modal dialog is up.
267 diff --quilt old/source/highlightData.c new/source/highlightData.c
268 --- old/source/highlightData.c
269 +++ new/source/highlightData.c
270 @@ -546,14 +546,14 @@ static char *DefaultPatternSets[] = {
271 Wrong logical ops:\"&&|\\|\\|\":::Plain::\n\
272 Logical operators:\"~|&|\\|\":::Text Arg2::}",
274 README:\"NEdit Macro syntax highlighting patterns, version 2.6, maintainer Thorsten Haude, nedit at thorstenhau.de\":::Flag::D\n\
275 Comment:\"#\":\"$\"::Comment::\n\
276 - Built-in Misc Vars:\"(?<!\\Y)\\$(?:active_pane|args|calltip_ID|column|cursor|display_width|empty_array|file_name|file_path|language_mode|line|locked|max_font_width|min_font_width|modified|n_display_lines|n_panes|rangeset_list|read_only|selection_(?:start|end|left|right)|server_name|text_length|top_line|VERSION|NEDIT_HOME)>\":::Identifier::\n\
277 + Built-in Misc Vars:\"(?<!\\Y)\\$(?:active_pane|args|calltip_ID|column|cursor|display_width|empty_array|file_name|file_path|language_mode|line|locked|max_font_width|min_font_width|modified|n_display_lines|n_panes|rangeset_list|read_only|selection_(?:start|end|left|right)|server_name|text_length|top_line|transient|VERSION|NEDIT_HOME)>\":::Identifier::\n\
278 Built-in Pref Vars:\"(?<!\\Y)\\$(?:auto_indent|em_tab_dist|file_format|font_name|font_name_bold|font_name_bold_italic|font_name_italic|highlight_syntax|incremental_backup|incremental_search_line|make_backup_copy|match_syntax_based|overtype_mode|show_line_numbers|show_matching|statistics_line|tab_dist|use_tabs|wrap_margin|wrap_text)>\":::Identifier2::\n\
279 Built-in Special Vars:\"(?<!\\Y)\\$(?:[1-9]|list_dialog_button|n_args|read_status|search_end|shell_cmd_status|string_dialog_button|sub_sep)>\":::String1::\n\
280 - Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|dialog|filename_dialog|focus_window|get_character|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
281 + Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|dialog|filename_dialog|focus_window|get_character|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|set_transient|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
282 Menu Actions:\"<(?:new(?:_tab|_opposite)?|open|open-dialog|open_dialog|open-selected|open_selected|close|save|save-as|save_as|save-as-dialog|save_as_dialog|revert-to-saved|revert_to_saved|revert_to_saved_dialog|include-file|include_file|include-file-dialog|include_file_dialog|load-macro-file|load_macro_file|load-macro-file-dialog|load_macro_file_dialog|load-tags-file|load_tags_file|load-tags-file-dialog|load_tags_file_dialog|unload_tags_file|load_tips_file|load_tips_file_dialog|unload_tips_file|print|print-selection|print_selection|exit|undo|redo|delete|select-all|select_all|shift-left|shift_left|shift-left-by-tab|shift_left_by_tab|shift-right|shift_right|shift-right-by-tab|shift_right_by_tab|find|find-dialog|find_dialog|find-again|find_again|find-selection|find_selection|find_incremental|start_incremental_find|replace|replace-dialog|replace_dialog|replace-all|replace_all|replace-in-selection|replace_in_selection|replace-again|replace_again|replace_find|replace_find_same|replace_find_again|goto-line-number|goto_line_number|goto-line-number-dialog|goto_line_number_dialog|goto-selected|goto_selected|mark|mark-dialog|mark_dialog|goto-mark|goto_mark|goto-mark-dialog|goto_mark_dialog|match|select_to_matching|goto_matching|find-definition|find_definition|show_tip|split-pane|split_pane|close-pane|close_pane|detach_document(?:_dialog)?|move_document_dialog|(?:next|previous|last)_document|uppercase|lowercase|fill-paragraph|fill_paragraph|control-code-dialog|control_code_dialog|filter-selection-dialog|filter_selection_dialog|filter-selection|filter_selection|execute-command|execute_command|execute-command-dialog|execute_command_dialog|execute-command-line|execute_command_line|shell-menu-command|shell_menu_command|macro-menu-command|macro_menu_command|bg_menu_command|post_window_bg_menu|post_tab_context_menu|beginning-of-selection|beginning_of_selection|end-of-selection|end_of_selection|repeat_macro|repeat_dialog|raise_window|focus_pane|set_statistics_line|set_incremental_search_line|set_show_line_numbers|set_auto_indent|set_wrap_text|set_wrap_margin|set_highlight_syntax|set_make_backup_copy|set_incremental_backup|set_show_matching|set_match_syntax_based|set_overtype_mode|set_locked|set_tab_dist|set_em_tab_dist|set_use_tabs|set_fonts|set_language_mode)(?=\\s*\\()\":::Subroutine::\n\
283 Text Actions:\"<(?:self-insert|self_insert|grab-focus|grab_focus|extend-adjust|extend_adjust|extend-start|extend_start|extend-end|extend_end|secondary-adjust|secondary_adjust|secondary-or-drag-adjust|secondary_or_drag_adjust|secondary-start|secondary_start|secondary-or-drag-start|secondary_or_drag_start|process-bdrag|process_bdrag|move-destination|move_destination|move-to|move_to|move-to-or-end-drag|move_to_or_end_drag|end_drag|copy-to|copy_to|copy-to-or-end-drag|copy_to_or_end_drag|exchange|process-cancel|process_cancel|paste-clipboard|paste_clipboard|copy-clipboard|copy_clipboard|cut-clipboard|cut_clipboard|copy-primary|copy_primary|cut-primary|cut_primary|newline|newline-and-indent|newline_and_indent|newline-no-indent|newline_no_indent|delete-selection|delete_selection|delete-previous-character|delete_previous_character|delete-next-character|delete_next_character|delete-previous-word|delete_previous_word|delete-next-word|delete_next_word|delete-to-start-of-line|delete_to_start_of_line|delete-to-end-of-line|delete_to_end_of_line|forward-character|forward_character|backward-character|backward_character|key-select|key_select|process-up|process_up|process-down|process_down|process-shift-up|process_shift_up|process-shift-down|process_shift_down|process-home|process_home|forward-word|forward_word|backward-word|backward_word|forward-paragraph|forward_paragraph|backward-paragraph|backward_paragraph|beginning-of-line|beginning_of_line|end-of-line|end_of_line|beginning-of-file|beginning_of_file|end-of-file|end_of_file|next-page|next_page|previous-page|previous_page|page-left|page_left|page-right|page_right|toggle-overstrike|toggle_overstrike|scroll-up|scroll_up|scroll-down|scroll_down|scroll_left|scroll_right|scroll-to-line|scroll_to_line|select-all|select_all|deselect-all|deselect_all|focusIn|focusOut|process-return|process_return|process-tab|process_tab|insert-string|insert_string|mouse_pan)(?=\\s*\\()\":::Subroutine::\n\
284 Macro Hooks:\"<(?:(?:pre|post)_(?:open|save)|cursor_moved|modified|(?:losing_)?focus)_hook(?=\\s*\\()\":::Subroutine1::\n\
285 Keyword:\"<(?:break|continue|define|delete|else|for|if|in|return|while)>\":::Keyword::\n\
286 Braces:\"[{}\\[\\]]\":::Keyword::\n\
287 diff --quilt old/source/windowTitle.c new/source/windowTitle.c
288 --- old/source/windowTitle.c
289 +++ new/source/windowTitle.c
290 @@ -99,10 +99,11 @@ static struct {
295 Widget oFileChangedW;
296 + Widget oTransientW;
298 Widget oFileReadOnlyW;
299 Widget oServerEqualViewW;
301 char filename[MAXPATHLEN];
302 @@ -111,15 +112,16 @@ static struct {
303 char serverName[MAXPATHLEN];
310 int suppressFormatUpdate;
311 } etDialog = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
312 - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
313 - NULL,NULL,"","","","",0,0,0,0,0};
314 + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
315 + NULL,NULL,"","","","",0,0,0,0,0,0};
319 static char* removeSequence(char* sourcePtr, char c)
321 @@ -257,10 +259,11 @@ char *FormatWindowTitle(const char* file
322 const char* serverName,
328 const char* titleFormat)
330 static char title[WINDOWTITLE_MAX_LEN];
331 char *titlePtr = title;
332 char* titleEnd = title + WINDOWTITLE_MAX_LEN - 1;
333 @@ -359,18 +362,20 @@ char *FormatWindowTitle(const char* file
334 titlePtr = safeStrCpy(titlePtr, titleEnd, GetNameOfHost());
337 case 'S': /* file status */
338 fileStatusPresent = True;
339 - if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged)
340 + if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged && !transient)
341 titlePtr = safeStrCpy(titlePtr, titleEnd, "read only, modified");
342 else if (IS_ANY_LOCKED_IGNORING_USER(lockReasons))
343 titlePtr = safeStrCpy(titlePtr, titleEnd, "read only");
344 - else if (IS_USER_LOCKED(lockReasons) && fileChanged)
345 + else if (IS_USER_LOCKED(lockReasons) && fileChanged && !transient)
346 titlePtr = safeStrCpy(titlePtr, titleEnd, "locked, modified");
347 else if (IS_USER_LOCKED(lockReasons))
348 titlePtr = safeStrCpy(titlePtr, titleEnd, "locked");
349 + else if (transient)
350 + titlePtr = safeStrCpy(titlePtr, titleEnd, "transient");
351 else if (fileChanged)
352 titlePtr = safeStrCpy(titlePtr, titleEnd, "modified");
355 case 'u': /* user name */
356 @@ -386,18 +391,20 @@ char *FormatWindowTitle(const char* file
357 fileStatusPresent = True;
358 if (*titleFormat && *titleFormat == 'S')
362 - if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged)
363 + if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged && !transient)
364 titlePtr = safeStrCpy(titlePtr, titleEnd, "RO*");
365 else if (IS_ANY_LOCKED_IGNORING_USER(lockReasons))
366 titlePtr = safeStrCpy(titlePtr, titleEnd, "RO");
367 - else if (IS_USER_LOCKED(lockReasons) && fileChanged)
368 + else if (IS_USER_LOCKED(lockReasons) && fileChanged && !transient)
369 titlePtr = safeStrCpy(titlePtr, titleEnd, "LO*");
370 else if (IS_USER_LOCKED(lockReasons))
371 titlePtr = safeStrCpy(titlePtr, titleEnd, "LO");
372 + else if (transient)
373 + titlePtr = safeStrCpy(titlePtr, titleEnd, "TR");
374 else if (fileChanged)
375 titlePtr = safeStrCpy(titlePtr, titleEnd, "*");
379 @@ -462,10 +469,11 @@ char *FormatWindowTitle(const char* file
383 /* Enable/disable test buttons, depending on presence of codes */
384 XtSetSensitive(etDialog.oFileChangedW, fileStatusPresent);
385 + XtSetSensitive(etDialog.oTransientW, fileStatusPresent);
386 XtSetSensitive(etDialog.oFileReadOnlyW, fileStatusPresent);
387 XtSetSensitive(etDialog.oFileLockedW, fileStatusPresent &&
388 !IS_PERM_LOCKED(etDialog.lockReasons));
390 XtSetSensitive(etDialog.oServerNameW, serverNamePresent);
391 @@ -491,10 +499,12 @@ static void setToggleButtons(void)
393 XmToggleButtonSetState(etDialog.oDirW,
394 etDialog.filenameSet == True, False);
395 XmToggleButtonSetState(etDialog.oFileChangedW,
396 etDialog.fileChanged == True, False);
397 + XmToggleButtonSetState(etDialog.oTransientW,
398 + etDialog.transient == True, False);
399 XmToggleButtonSetState(etDialog.oFileReadOnlyW,
400 IS_PERM_LOCKED(etDialog.lockReasons), False);
401 XmToggleButtonSetState(etDialog.oFileLockedW,
402 IS_USER_LOCKED(etDialog.lockReasons), False);
403 /* Read-only takes precedence on locked */
404 @@ -557,10 +567,11 @@ static void formatChangedCB(Widget w, Xt
408 etDialog.lockReasons,
409 XmToggleButtonGetState(etDialog.oFileChangedW),
410 + XmToggleButtonGetState(etDialog.oTransientW),
413 XmTextFieldSetString(etDialog.previewW, title);
416 @@ -587,10 +598,16 @@ static void fileChangedCB(Widget w, XtPo
418 etDialog.fileChanged = XmToggleButtonGetState(w);
419 formatChangedCB(w, clientData, callData);
422 +static void transientCB(Widget w, XtPointer clientData, XtPointer callData)
424 + etDialog.transient = XmToggleButtonGetState(w);
425 + formatChangedCB(w, clientData, callData);
428 static void fileLockedCB(Widget w, XtPointer clientData, XtPointer callData)
430 SET_USER_LOCKED(etDialog.lockReasons, XmToggleButtonGetState(w));
431 formatChangedCB(w, clientData, callData);
433 @@ -1274,39 +1291,50 @@ static void createEditTitleDialog(Widget
434 XmNtopWidget, testLbl,
435 XmNlabelString, s1=XmStringCreateSimple("File modified"),
436 XmNmnemonic, 'o', NULL);
437 XtAddCallback(etDialog.oFileChangedW, XmNvalueChangedCallback, fileChangedCB, NULL);
440 - etDialog.oFileReadOnlyW = XtVaCreateManagedWidget("fileReadOnly",
441 - xmToggleButtonWidgetClass, previewBox,
443 + etDialog.oTransientW = XtVaCreateManagedWidget("transient",
444 + xmToggleButtonWidgetClass, previewBox,
445 XmNleftAttachment, XmATTACH_WIDGET,
446 XmNleftWidget, etDialog.oFileChangedW,
447 XmNtopAttachment, XmATTACH_WIDGET,
448 XmNtopWidget, testLbl,
449 + XmNlabelString, s1=XmStringCreateSimple("File transient"),
450 + XmNmnemonic, 't', NULL);
451 + XtAddCallback(etDialog.oTransientW, XmNvalueChangedCallback, transientCB, NULL);
454 + etDialog.oFileReadOnlyW = XtVaCreateManagedWidget("fileReadOnly",
455 + xmToggleButtonWidgetClass, previewBox,
456 + XmNleftAttachment, XmATTACH_POSITION,
457 + XmNleftPosition, RADIO_INDENT,
458 + XmNtopAttachment, XmATTACH_WIDGET,
459 + XmNtopWidget, etDialog.oFileChangedW,
460 XmNlabelString, s1=XmStringCreateSimple("File read only"),
461 XmNmnemonic, 'n', NULL);
462 XtAddCallback(etDialog.oFileReadOnlyW, XmNvalueChangedCallback, fileReadOnlyCB, NULL);
465 etDialog.oFileLockedW = XtVaCreateManagedWidget("fileLocked",
466 xmToggleButtonWidgetClass, previewBox,
467 XmNleftAttachment, XmATTACH_WIDGET,
468 XmNleftWidget, etDialog.oFileReadOnlyW,
469 XmNtopAttachment, XmATTACH_WIDGET,
470 - XmNtopWidget, testLbl,
471 + XmNtopWidget, etDialog.oFileChangedW,
472 XmNlabelString, s1=XmStringCreateSimple("File locked"),
473 XmNmnemonic, 'l', NULL);
474 XtAddCallback(etDialog.oFileLockedW, XmNvalueChangedCallback, fileLockedCB, NULL);
477 etDialog.oServerNameW = XtVaCreateManagedWidget("servernameSet",
478 xmToggleButtonWidgetClass, previewBox,
479 XmNleftAttachment, XmATTACH_POSITION,
480 XmNleftPosition, RADIO_INDENT,
481 XmNtopAttachment, XmATTACH_WIDGET,
482 - XmNtopWidget, etDialog.oFileChangedW,
483 + XmNtopWidget, etDialog.oFileReadOnlyW,
484 XmNlabelString, s1=XmStringCreateSimple("Server name present"),
485 XmNmnemonic, 'v', NULL);
486 XtAddCallback(etDialog.oServerNameW, XmNvalueChangedCallback, serverNameCB, NULL);
489 @@ -1455,10 +1483,11 @@ void EditCustomTitleFormat(WindowInfo *w
491 etDialog.isServer = IsServer;
492 etDialog.filenameSet = window->filenameSet;
493 etDialog.lockReasons = window->lockReasons;
494 etDialog.fileChanged = window->fileChanged;
495 + etDialog.transient = window->transient;
497 if (etDialog.window != window && etDialog.form)
499 /* Destroy the dialog owned by the other window.
500 Note: don't rely on the destroy event handler to reset the
501 diff --quilt old/source/windowTitle.h new/source/windowTitle.h
502 --- old/source/windowTitle.h
503 +++ new/source/windowTitle.h
504 @@ -40,10 +40,11 @@ char *FormatWindowTitle(const char* file
505 const char* serverName,
511 const char* titleFormat);
513 void EditCustomTitleFormat(WindowInfo *window);
515 #endif /* NEDIT_WINDOWTITLE_H_INCLUDED */
516 diff --quilt old/source/macro.c new/source/macro.c
517 --- old/source/macro.c
518 +++ new/source/macro.c
519 @@ -376,10 +376,12 @@ static int rangesetListMV(WindowInfo *wi
520 int nArgs, DataValue *result, char **errMsg);
521 static int versionMV(WindowInfo* window, DataValue* argList, int nArgs,
522 DataValue* result, char** errMsg);
523 static int neditHomeMV(WindowInfo *window, DataValue *argList, int nArgs,
524 DataValue *result, char **errMsg);
525 +static int transientMV(WindowInfo *window, DataValue *argList, int nArgs,
526 + DataValue *result, char **errMsg);
527 static int rangesetCreateMS(WindowInfo *window, DataValue *argList, int nArgs,
528 DataValue *result, char **errMsg);
529 static int rangesetDestroyMS(WindowInfo *window, DataValue *argList, int nArgs,
530 DataValue *result, char **errMsg);
531 static int rangesetGetByNameMS(WindowInfo *window, DataValue *argList, int nArgs,
532 @@ -536,10 +538,11 @@ static const BuiltInSubrName SpecialVars
533 { "$backlight_string", backlightStringMV },
535 { "$rangeset_list", rangesetListMV },
536 { "$VERSION", versionMV },
537 { "$NEDIT_HOME", neditHomeMV },
538 + { "$transient", transientMV },
539 { NULL, NULL } /* sentinel */
542 /* Global symbols for "returning" secondary values from built-in functions */
543 static int STRING_DIALOG_BUTTON, SEARCH_END, READ_STATUS,
544 @@ -4768,10 +4771,21 @@ static int neditHomeMV(WindowInfo *windo
550 +** Returns the transient status of the current window
552 +static int transientMV(WindowInfo *window, DataValue *argList, int nArgs,
553 + DataValue *result, char **errMsg)
555 + result->tag = INT_TAG;
556 + result->val.n = !!window->transient;
561 ** Built-in macro subroutine to create a new rangeset or rangesets.
562 ** If called with one argument: $1 is the number of rangesets required and
563 ** return value is an array indexed 0 to n, with the rangeset labels as values;
564 ** (or an empty array if the requested number of rangesets are not available).
565 ** If called with no arguments, returns a single rangeset label (not an array),
566 diff --quilt old/source/menu.c new/source/menu.c
567 --- old/source/menu.c
568 +++ new/source/menu.c
569 @@ -413,10 +413,12 @@ static void setMatchSyntaxBasedAP(Widget
571 static void setOvertypeModeAP(Widget w, XEvent *event, String *args,
573 static void setLockedAP(Widget w, XEvent *event, String *args,
575 +static void setTransientAP(Widget text, XEvent *event, String *args,
577 static void setUseTabsAP(Widget w, XEvent *event, String *args,
579 static void setEmTabDistAP(Widget w, XEvent *event, String *args,
581 static void setTabDistAP(Widget w, XEvent *event, String *args,
582 @@ -583,10 +585,11 @@ static XtActionsRec Actions[] = {
583 {"set_incremental_backup", setIncrementalBackupAP},
584 {"set_show_matching", setShowMatchingAP},
585 {"set_match_syntax_based", setMatchSyntaxBasedAP},
586 {"set_overtype_mode", setOvertypeModeAP},
587 {"set_locked", setLockedAP},
588 + {"set_transient", setTransientAP},
589 {"set_tab_dist", setTabDistAP},
590 {"set_em_tab_dist", setEmTabDistAP},
591 {"set_use_tabs", setUseTabsAP},
592 {"set_fonts", setFontsAP},
593 {"set_language_mode", setLanguageModeAP}
594 @@ -768,10 +771,12 @@ Widget CreateMenuBar(Widget parent, Wind
595 createMenuSeparator(menuPane, "sep4", SHORT);
596 window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O',
597 doActionCB, "set_overtype_mode", False, SHORT);
598 window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only",
599 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL);
600 + window->transientItem = createMenuToggle(menuPane, "transient", "Transient",
601 + 'r', doActionCB, "set_transient", window->transient, FULL);
605 ** "Search" pull down menu.
607 @@ -1158,10 +1163,12 @@ Widget CreateMenuBar(Widget parent, Wind
608 createMenuSeparator(menuPane, "sep2", SHORT);
609 window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O',
610 doActionCB, "set_overtype_mode", False, SHORT);
611 window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only",
612 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL);
613 + window->transientItem = createMenuToggle(menuPane, "transient", "Transient",
614 + 'r', doActionCB, "set_transient", window->transient, FULL);
619 ** Create the Shell menu
620 @@ -2780,10 +2787,11 @@ static void unloadTipsFileMenuCB(Widget
622 static void newAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
624 WindowInfo *window = WidgetToWindow(w);
625 int openInTab = GetPrefOpenInTab();
626 + Boolean transient = False;
629 if (strcmp(args[0], "prefs") == 0) {
630 /* accept default */;
632 @@ -2794,16 +2802,25 @@ static void newAP(Widget w, XEvent *even
635 else if (strcmp(args[0], "opposite") == 0) {
636 openInTab = !openInTab;
638 + else if (strcmp(args[0], "transient") == 0) {
642 fprintf(stderr, "nedit: Unknown argument to action procedure \"new\": %s\n", args[0]);
646 - EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path);
647 + /* Catch transient if it comes after a window type argument. */
648 + if (2 == *nArgs && strcmp(args[1], "transient") == 0) {
652 + EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path,
658 ** These are just here because our techniques make it hard to bind a menu item
659 @@ -2813,18 +2830,18 @@ static void newAP(Widget w, XEvent *even
660 static void newOppositeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
662 WindowInfo *window = WidgetToWindow(w);
664 EditNewFile(GetPrefOpenInTab()? NULL : window, NULL, False, NULL,
666 + window->path, False);
669 static void newTabAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
671 WindowInfo *window = WidgetToWindow(w);
673 - EditNewFile(window, NULL, False, NULL, window->path);
674 + EditNewFile(window, NULL, False, NULL, window->path, False);
678 static void openDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
680 @@ -2956,11 +2973,11 @@ static void revertDialogAP(Widget w, XEv
682 WindowInfo *window = WidgetToWindow(w);
685 /* re-reading file is irreversible, prompt the user first */
686 - if (window->fileChanged)
687 + if (window->fileChanged && !window->transient)
689 b = DialogF(DF_QUES, window->shell, 2, "Discard Changes",
690 "Discard changes to\n%s%s?", "OK", "Cancel", window->path,
693 @@ -3184,11 +3201,12 @@ static void exitAP(Widget w, XEvent *eve
694 user really wants to exit */
697 strcpy(ptr, "Editing: "); ptr += 9; lineLen += 9;
698 for (win=WindowList; win!=NULL; win=win->next) {
699 - sprintf(filename, "%s%s", win->filename, win->fileChanged? "*": "");
700 + sprintf(filename, "%s%s", win->filename,
701 + (win->fileChanged && !win->transient) ? "*": "");
703 titleLen = strlen(title);
704 if (ptr - exitMsg + titleLen + 30 >= DF_MAX_MSG_LENGTH) {
705 strcpy(ptr, "..."); ptr += 3;
707 @@ -4312,10 +4330,31 @@ static void setLockedAP(Widget w, XEvent
708 XmToggleButtonSetState(window->readOnlyItem, IS_ANY_LOCKED(window->lockReasons), False);
709 UpdateWindowTitle(window);
710 UpdateWindowReadOnly(window);
714 +** Action procedure for setting or toggling the transient flag.
716 +static void setTransientAP(Widget text, XEvent *event, String *args,
719 + WindowInfo *window = WidgetToWindow(text);
722 + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args,
723 + window->transient, "set_transient");
725 + window->transient = newState;
726 + if (IsTopDocument(window)) {
727 + XmToggleButtonSetState(window->transientItem, window->transient, False);
730 + UpdateWindowTitle(window);
731 + RefreshTabState(window);
734 static void setTabDistAP(Widget w, XEvent *event, String *args,
737 WindowInfo *window = WidgetToWindow(w);
739 @@ -4697,11 +4736,11 @@ void AddToPrevOpenMenu(const char *filen
740 static char* getWindowsMenuEntry(const WindowInfo* window)
742 static char fullTitle[MAXPATHLEN * 2 + 3+ 1];
744 sprintf(fullTitle, "%s%s", window->filename,
745 - window->fileChanged? "*" : "");
746 + (window->fileChanged && !window->transient) ? "*" : "");
748 if (GetPrefShowPathInWindowsMenu() && window->filenameSet)
750 strcat(fullTitle, " - ");
751 strcat(fullTitle, window->path);
752 diff --quilt old/source/nedit.h new/source/nedit.h
753 --- old/source/nedit.h
754 +++ new/source/nedit.h
755 @@ -330,10 +330,11 @@ typedef struct _WindowInfo {
756 Widget replaceMultiFileList;
757 Widget replaceMultiFilePathBtn;
758 Widget fontDialog; /* NULL, unless font dialog is up */
759 Widget colorDialog; /* NULL, unless color dialog is up */
760 Widget readOnlyItem; /* menu bar settable widgets... */
761 + Widget transientItem;
765 Widget newOppositeItem;
767 @@ -497,10 +498,11 @@ typedef struct _WindowInfo {
768 of selection related menu items */
769 Boolean filenameSet; /* is the window still "Untitled"? */
770 Boolean fileChanged; /* has window been modified? */
771 Boolean fileMissing; /* is the window's file gone? */
772 int lockReasons; /* all ways a file can be locked */
773 + Boolean transient; /* buffer is transient */
774 Boolean autoSave; /* is autosave turned on? */
775 Boolean saveOldVersion; /* keep old version in filename.bck */
776 char indentStyle; /* whether/how to auto indent */
777 char wrapMode; /* line wrap style: NO_WRAP,
778 NEWLINE_WRAP or CONTINUOUS_WRAP */
779 diff --quilt old/source/window.c new/source/window.c
780 --- old/source/window.c
781 +++ new/source/window.c
782 @@ -267,10 +267,11 @@ WindowInfo *CreateWindow(const char *nam
783 window->autoSaveCharCount = 0;
784 window->autoSaveOpCount = 0;
785 window->undoOpCount = 0;
786 window->undoMemUsed = 0;
787 CLEAR_ALL_LOCKS(window->lockReasons);
788 + window->transient = False;
789 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
790 window->autoSave = GetPrefAutoSave();
791 window->saveOldVersion = GetPrefSaveOldVersion();
792 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
793 window->showWrapMargin = GetPrefShowWrapMargin();
794 @@ -995,12 +996,13 @@ void CloseWindow(WindowInfo *window)
796 /* if this is the last window, or must be kept alive temporarily because
797 it's running the macro calling us, don't close it, make it Untitled */
798 if (keepWindow || (WindowList == window && window->next == NULL)) {
799 window->filename[0] = '\0';
800 - UniqueUntitledName(name);
801 + UniqueUntitledName(name, False);
802 CLEAR_ALL_LOCKS(window->lockReasons);
803 + window->transient = False;
804 window->fileMode = 0;
807 strcpy(window->filename, name);
808 strcpy(window->path, "");
809 @@ -2109,16 +2111,17 @@ void UpdateWindowTitle(const WindowInfo
816 GetPrefTitleFormat());
818 iconTitle = XtMalloc(strlen(window->filename) + 2); /* strlen("*")+1 */
820 strcpy(iconTitle, window->filename);
821 - if (window->fileChanged)
822 + if (window->fileChanged && !window->transient)
823 strcat(iconTitle, "*");
824 XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, iconTitle, NULL);
826 /* If there's a find or replace dialog up in "Keep Up" mode, with a
827 file name in the title, update it too */
828 @@ -2443,11 +2446,12 @@ static void modifiedCB(int pos, int nIns
829 SaveUndoInformation(window, pos, nInserted, nDeleted, deletedText);
831 /* Trigger automatic backup if operation or character limits reached */
832 if (window->autoSave &&
833 (window->autoSaveCharCount > AUTOSAVE_CHAR_LIMIT ||
834 - window->autoSaveOpCount > AUTOSAVE_OP_LIMIT)) {
835 + window->autoSaveOpCount > AUTOSAVE_OP_LIMIT)
836 + && !window->transient) {
837 WriteBackupFile(window);
838 window->autoSaveCharCount = 0;
839 window->autoSaveOpCount = 0;
842 @@ -3439,10 +3443,11 @@ WindowInfo* CreateDocument(WindowInfo* s
843 window->autoSaveCharCount = 0;
844 window->autoSaveOpCount = 0;
845 window->undoOpCount = 0;
846 window->undoMemUsed = 0;
847 CLEAR_ALL_LOCKS(window->lockReasons);
848 + window->transient = False;
849 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
850 window->autoSave = GetPrefAutoSave();
851 window->saveOldVersion = GetPrefSaveOldVersion();
852 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
853 window->showWrapMargin = GetPrefShowWrapMargin();
854 @@ -3728,22 +3733,23 @@ void RefreshTabState(WindowInfo *win)
856 XmString s1, tipString;
857 char labelString[MAXPATHLEN];
858 char *tag = XmFONTLIST_DEFAULT_TAG;
859 unsigned char alignment;
860 + const char *star = (win->fileChanged && !win->transient) ? "*" : "";
862 /* Set tab label to document's filename. Position of
863 "*" (modified) will change per label alignment setting */
864 XtVaGetValues(win->tab, XmNalignment, &alignment, NULL);
865 if (alignment != XmALIGNMENT_END) {
866 sprintf(labelString, "%s%s",
867 - win->fileChanged? "*" : "",
871 sprintf(labelString, "%s%s",
873 - win->fileChanged? "*" : "");
877 /* Make the top document stand out a little more */
878 if (IsTopDocument(win))
880 @@ -3879,10 +3885,11 @@ void RefreshMenuToggleStates(WindowInfo
882 XmToggleButtonSetState(window->autoSaveItem, window->autoSave, False);
883 XmToggleButtonSetState(window->overtypeModeItem, window->overstrike, False);
884 XmToggleButtonSetState(window->matchSyntaxBasedItem, window->matchSyntaxBased, False);
885 XmToggleButtonSetState(window->readOnlyItem, IS_USER_LOCKED(window->lockReasons), False);
886 + XmToggleButtonSetState(window->transientItem, window->transient, False);
888 XtSetSensitive(window->smartIndentItem,
889 SmartIndentMacrosAvailable(LanguageModeName(window->languageMode)));
891 SetAutoIndent(window, window->indentStyle);
892 @@ -4447,10 +4454,11 @@ static void cloneDocument(WindowInfo *wi
893 window->fileFormat = orgWin->fileFormat;
894 window->lastModTime = orgWin->lastModTime;
895 window->fileChanged = orgWin->fileChanged;
896 window->fileMissing = orgWin->fileMissing;
897 window->lockReasons = orgWin->lockReasons;
898 + window->transient = orgWin->transient;
899 window->autoSaveCharCount = orgWin->autoSaveCharCount;
900 window->autoSaveOpCount = orgWin->autoSaveOpCount;
901 window->undoOpCount = orgWin->undoOpCount;
902 window->undoMemUsed = orgWin->undoMemUsed;
903 window->lockReasons = orgWin->lockReasons;
904 diff --quilt old/source/nedit.c new/source/nedit.c
905 --- old/source/nedit.c
906 +++ new/source/nedit.c
907 @@ -565,11 +565,11 @@ int main(int argc, char **argv)
909 if (strcmp(GetPrefServerName(), "") != 0) {
913 - EditNewFile(NULL, geometry, iconic, langMode, NULL);
914 + EditNewFile(NULL, geometry, iconic, langMode, NULL, False);
915 ReadMacroInitFile(WindowList);
918 /* Process any command line arguments (-tags, -do, -read, -create,
919 +<line_number>, -line, -server, and files to edit) not already
920 diff --quilt old/source/server.c new/source/server.c
921 --- old/source/server.c
922 +++ new/source/server.c
923 @@ -354,11 +354,11 @@ static void processServerCommandString(c
924 if (!window->filenameSet && !window->fileChanged &&
925 isLocatedOnDesktop(window, currentDesktop))
927 if (window == NULL) {
928 EditNewFile(findWindowOnDesktop(tabbed, currentDesktop), NULL,
929 - False, NULL, NULL);
930 + False, NULL, NULL, False);
934 RaiseDocument(window);
935 XMapRaised(TheDisplay, XtWindow(window->shell));
936 @@ -418,11 +418,12 @@ static void processServerCommandString(c
939 if (*doCommand == '\0') {
940 if (window == NULL) {
941 EditNewFile(findWindowOnDesktop(tabbed, currentDesktop),
942 - NULL, iconicFlag, lmLen==0?NULL:langMode, NULL);
943 + NULL, iconicFlag, lmLen==0?NULL:langMode, NULL,
947 RaiseDocument(window);
949 RaiseDocumentWindow(window);
950 diff --quilt old/source/shell.c new/source/shell.c
951 --- old/source/shell.c
952 +++ new/source/shell.c
953 @@ -387,11 +387,12 @@ void DoShellMenuCmd(WindowInfo *window,
954 if (output == TO_DIALOG) {
956 flags |= OUTPUT_TO_DIALOG;
958 } else if (output == TO_NEW_WINDOW) {
959 - EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL, window->path);
960 + EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL,
961 + window->path, False);
962 outWidget = WindowList->textArea;
963 inWindow = WindowList;
966 } else { /* TO_SAME_WINDOW */