2 doc/help.etx | 109 +++++
3 source/Makefile.common | 1
4 source/Makefile.dependencies | 3
5 source/calltips.c | 334 ++++++++++++----
7 source/file.c | 337 ++++++-----------
10 source/highlightData.c | 4
11 source/interpret.c | 27 +
12 source/macro.c | 271 +++++++++++--
14 source/menu.c | 254 +++++++++++-
17 source/preferences.c | 279 ++++++++++++--
18 source/preferences.h | 8
19 source/search.c | 159 +++++---
21 source/selection.c | 49 +-
24 source/text.c | 72 ++-
26 source/textDisp.c | 461 ++++++++++++++++++++---
27 source/textDisp.h | 53 +-
29 source/window.c | 179 +++++++--
32 util/getfiles.c | 847 ++++++++++++++++++++++++++++++++++++-------
33 util/getfiles.h | 47 ++
34 util/prefFile.c | 31 -
36 35 files changed, 2951 insertions(+), 779 deletions(-)
38 diff --quilt old/ReleaseNotes new/ReleaseNotes
41 @@ -13,11 +13,43 @@ If you are upgrading NEdit from a versio
42 the README file which came with the (source or executable) distribution kit,
43 about updating macros and font settings in your .nedit file.
45 New Features in $NEXT_VERSION
47 - - The macro variable $VERSION returns NEdit's version number.
48 + - Hidden files (dotfiles) can now be excluded from the file and directory
49 + lists in the file selection box (SF patch #502840).
51 + - A 'Smart Case' toggles the regex search caseness depending on the occur-
52 + rence of upper case letters in the search expression (SF patch #685618).
54 + - The help window got some small changes to increase usability.
56 + - The resource nedit.prevOpenFilesMask can be set to a regex to exclude
57 + certain files from the Open Previous menu.
59 + - Changes to the macro language:
60 + - The function highlight_calltip_line() can highlight single lines in
61 + a macro-created calltip.
63 + - If the macro routine file_open_hook() exists, it is called when an existing
66 + - A hairline can be displayed at the wrap column (SF patch #701337).
68 + - The current line is now optionally displayed with a colored background
71 + - Documents can now be flagged 'transient'. This disables the warning
72 + NEdit usually gives when you try to close a document which is not saved.
74 - The new macro function filename_dialog() can be used to query a file
75 name from the user by using the usual file selection dialog.
78 diff --quilt old/doc/help.etx new/doc/help.etx
81 @@ -127,10 +127,13 @@ Getting Started
82 If you already have an empty (Untitled) window displayed, just begin typing
83 in the window. To create a new Untitled window, choose New Window or New Tab
84 from the File menu. To give the file a name and save its contents to the
85 disk, choose Save or Save As... from the File menu.
87 + In both Open and Save File Dialogs you can choose whether hidden files and
88 + directories are shown in the lists. Just check/uncheck the toggle button.
92 NEdit maintains periodic backups of the file you are editing so that you can
93 recover the file in the event of a problem such as a system crash, network
94 failure, or X server crash. These files are saved under the name `~filename`
95 @@ -260,10 +263,15 @@ Finding and Replacing Text
96 button with an icon resembling "|<". Clicking on it empties the search text widget
97 without disturbing selections. A middle click on the clear button copies the
98 content of any existing selection into the search text widget and triggers a new
101 + All searches will default to the search mode selected in the preference menu.
102 + (Default Setting -> Searching -> Default Search Style). You can choose a smart
103 + case sensitivity here; this let all searches start insensitive, but changes to
104 + case sensitive as soon as you enter an upper-case letter.
106 3>Searching Backwards
108 Holding down the shift key while choosing any of the search or replace
109 commands from the menu (or using the keyboard shortcut), will search in the
110 reverse direction. Users who have set the search direction using the buttons
111 @@ -1939,13 +1947,13 @@ Macro Language
116 An NEdit macro language program consists of a list of statements, each
117 - terminated by a newline. Groups of statements which are executed together
118 - conditionally, such as the body of a loop, are surrounded by curly braces
120 + terminated by a newline or a semicolon (;). Groups of statements which
121 + are executed together conditionally, such as the body of a loop, are
122 + surrounded by curly braces "{}".
124 Blank lines and comments are also allowed. Comments begin with a "#" and end
125 with a newline, and can appear either on a line by themselves, or at the end
128 @@ -2660,11 +2674,11 @@ Macro Subroutines
129 **filename_dialog( [title[, mode[, defaultPath[, filter[, defaultName]]]]] )**
130 Presents a file selection dialog with the given title to the user that
131 prompts for a new or existing file.
133 Options are: ~title~ will be the title of the dialog, defaults to "Choose
134 - file". If ~mode~ is set to "exist" (default), the "New File Name"TextField
135 + file". If ~mode~ is set to "exist" (default), the "New File Name" TextField
136 of the FSB will be unmanaged. If "new", the TextField will be managed.
137 ~defaultPath~ is the default path to use. Default (or "") will use the
138 active document's directory. ~filter~ is the file glob which determines
139 which files to display. Is set to "*" if filter is "" and by default.
140 ~defaultName~ is the default filename that is filled in automatically.
141 @@ -2682,12 +2696,12 @@ Macro Subroutines
142 focused window (the first window being the one returned from calling
143 focus_window("last"). Returns the name of the newly-focused window, or an
144 empty string if the requested window was not found.
146 **get_character( position )**
147 - Returns the single character at the position
148 - indicated by the first argument to the routine from the current window.
149 + Returns the single character at the position indicated by the first argument
150 + to the routine from the current window.
152 **get_range( start, end )**
153 Returns the text between a starting and ending position from the current
156 @@ -2697,10 +2711,14 @@ Macro Subroutines
157 the screen (keyword "any").
160 Gets the value of an environment variable.
162 +**highlight_calltip_line(calltip_ID, line)**
163 + Highlights a single line in the given calltip. Set line to 0 to remove
164 + any existing highlighting.
166 **kill_calltip( [calltip_ID] )**
167 Kills any calltip that is being displayed in the window in which the macro is
168 running. If there is no displayed calltip this does nothing. If a calltip
169 ID is supplied then the calltip is killed only if its ID is calltip_ID.
171 @@ -2853,10 +2871,19 @@ Macro Subroutines
172 Return an all lower-case version of string.
174 **toupper( string )**
175 Return an all upper-case version of string.
178 + Returns a string indicating the type of a macro value. The value can be
179 + any NEdit macro language value except for the return value of functions
180 + without a return value. Examples:
181 + typeof(2) # -> "INTEGER"
182 + typeof($empty_array) # -> "ARRAY"
183 + typeof(get_range(10, 20)) # -> "STRING"
184 + typeof(myArray["doesnotexist"]) # -> "UNDEFINED"
186 **valid_number( string )**
187 Returns 1 if the string can be converted to a number without error
188 following the same rules that the implicit conversion would. Otherwise 0.
190 **write_file( string, filename )**
191 @@ -3226,11 +3253,11 @@ Action Routines
192 3>Menu Action Routine Arguments
194 Arguments are text strings enclosed in quotes. Below are the menu action
195 routines which take arguments. Optional arguments are enclosed in [].
197 - **new**( ["tab" | "window" | "prefs" | "opposite"] )
198 + **new**( ["tab" | "window" | "prefs" | "opposite"] [, "transient"] )
200 **close**( ["prompt" | "save" | "nosave"] )
202 **execute_command**( shell-command )
204 @@ -3293,10 +3320,19 @@ Action Routines
206 "opposite": Opposite of user's tab/window
208 Default behaviour is "prefs".
210 + "transient" [EXPERIMENTAL]: Open the new
211 + document in transient mode. This disables the
212 + warning NEdit usually gives when you try to
213 + close a file which is not saved.
215 + WARNING: This is an experimental feature.
216 + Make sure to use this setting only for
217 + documents which can easily be recreated.
219 ~filename~ Path names are relative to the directory from
220 which NEdit was started. Shell interpreted
221 wildcards and `~' are not expanded.
223 ~keep-dialog~ Either "keep" or "nokeep".
224 @@ -3730,10 +3766,35 @@ Action Routines
227 To be attached to a key-press event, inserts the character
228 equivalent of the key pressed.
234 + Hooks are macro routines which are called at specific points in NEdit's
235 + execution. You can use hooks to tie in user-defined functionality at these
238 + No hooks are provided. To use a hook, simply define a macro function with
239 + the name of the hook. The next time the hook will catch, the macro function
242 + You don't have to provide any hook. If a certain hook does not exist, it is
245 +**file_open_hook()**
246 + Called when an existing file is opened.
248 +..**file_name_hook(filename)**
249 +.. Called before NEdit opens a file using a certain name. The parameter is
250 +.. the filename NEdit intends to open.
252 +.. Return a string to use instead of the original filename. Return 0 to tell
253 +.. NEdit to use the original filename.
255 ----------------------------------------------------------------------
260 @@ -3830,10 +3891,18 @@ Preferences
262 Set margin for Auto Newline Wrap, Continuous Wrap, and Fill Paragraph. Lines
263 may, be wrapped at the right margin of the window, or the margin can be set
264 at a specific column.
266 +**Show Wrap Margin**
267 + Visually indicate which column is set as the wrap margin by drawing a vertical
268 + line. Choose between never, always and when wrap is enabled. "Never" turns
269 + this feature off. "Always" will show the wrap margin irrespecitive of the
270 + wrapping style. "When Wrap is Enabled" will show the wrap margin only if
271 + continuous or auto-newline wrap styles are choosen and does not show the wrap
272 + margin if wrapping is turned off.
275 Set the tab distance (number of characters between tab stops) for tab
276 characters, and control tab emulation and use of tab characters in padding
279 @@ -3873,10 +3942,17 @@ Preferences
281 Lock the file against accidental modification. This temporarily prevents the
282 file from being modified in this NEdit session. Note that this is different
283 from setting the file protection.
285 +**Transient [EXPERIMENTAL]**
286 + Flags the document as transient. This disables the warning NEdit usually
287 + gives when you try to close a file which is not saved.
289 + WARNING: This is an experimental feature. Make sure to use this setting
290 + only for documents which can easily be recreated.
292 3>Preferences -> Default Settings Menu
294 Options in the Preferences -> Default Settings menu have the same meaning as
295 those in the top-level Preferences menu, except that they apply to future
296 NEdit windows and future NEdit sessions if saved with the Save Defaults
297 @@ -3974,10 +4050,16 @@ Preferences
299 **Terminate with Line Break on Save**
300 Some UNIX tools expect that files end with a line feed. If this option is
301 activated, NEdit will append one if required.
303 +**Show Hidden Files**
304 + Show hidden files by default in file selection boxes.
306 **Sort Open Prev. Menu**
307 Option to order the File -> Open Previous menu alphabetically, versus in
308 order of last access.
310 **Popups Under Pointer**
311 @@ -4310,10 +4392,16 @@ X Resources
313 Number of files listed in the Open Previous sub-menu of the File menu.
314 Setting this to zero disables the Open Previous menu item and maintenance of
315 the NEdit file history file.
317 +**nedit.prevOpenFilesMask**: (not defined)
319 + Files not to be listed in the Open Previous sub-menu of the File menu.
320 + Setting this to a regular expression causes files matching the expression to
321 + be omitted from the Open Previous menu item and the .neditdb file.
323 **nedit.printCommand**: (system specific)
325 Command used by the print dialog to print a file, such as, lp, lpr, etc..
326 The command must be capable of accepting input via stdin (standard input).
328 @@ -4349,10 +4437,16 @@ X Resources
329 **nedit.printDefaultHost**: (system specific)
331 The node name of the default print host. Used only to display in the print
332 dialog, and has no effect on printing.
334 +**nedit.showScrolltip**: True
336 + If this resource is set to True, NEdit will show a tooltip displaying the
337 + line number if the user grabs and moves the scroll handle. Set to False to
340 **nedit.visualID**: Best
342 If your screen supports multiple visuals (color mapping models), this
343 resource allows you to manually choose among them. The default value of
344 "Best" chooses the deepest (most colors) visual available. Since NEdit does
345 @@ -5993,10 +6087,11 @@ Problems/Defects
346 .. Menu: Macro Language # macro_lang
347 .. Menu: M_a_cro Subroutines # macro_subrs
348 .. Menu: Rangesets # rangeset
349 .. Menu: Highlighting Information # hiliteInfo
350 .. Menu: Action Routines # actions
351 +.. Menu: H_o_oks # hooks
353 .. Menu: Customizing # customizing
354 .. Menu: Customizing NEdit # customize
355 .. Menu: Preferences # preferences
356 .. Menu: X Resources # resources
357 diff --quilt old/source/Makefile.common new/source/Makefile.common
358 --- old/source/Makefile.common
359 +++ new/source/Makefile.common
361 OBJS = nedit.o file.o menu.o window.o selection.o search.o undo.o shift.o \
362 help.o preferences.o tags.o userCmds.o shell.o regularExp.o macro.o \
363 text.o textSel.o textDisp.o textBuf.o textDrag.o server.o highlight.o \
364 highlightData.o interpret.o parse.o smartIndent.o regexConvert.o \
365 rbTree.o windowTitle.o calltips.o server_common.o rangeset.o
368 XLTLIB = ../Xlt/libXlt.a
369 XMLLIB = ../Microline/XmL/libXmL.a
372 diff --quilt old/source/Makefile.dependencies new/source/Makefile.dependencies
373 --- old/source/Makefile.dependencies
374 +++ new/source/Makefile.dependencies
376 # $Id: Makefile.dependencies,v 1.21 2003/05/02 18:18:41 edg Exp $
377 +backup.o: backup.c backup.h
378 calltips.o: calltips.c text.h textBuf.h textP.h textDisp.h calltips.h \
379 nedit.h ../util/misc.h
380 file.o: file.c file.h nedit.h textBuf.h text.h window.h preferences.h \
381 undo.h menu.h tags.h server.h ../util/misc.h ../util/DialogF.h \
382 ../util/fileUtils.h ../util/getfiles.h ../util/printUtils.h \
384 + ../util/utils.h macro.h
385 help.o: help.c help.h help_topic.h textBuf.h text.h textP.h textDisp.h \
386 textSel.h nedit.h search.h window.h preferences.h help_data.h file.h \
387 highlight.h ../util/misc.h ../util/DialogF.h ../util/system.h
388 highlight.o: highlight.c highlight.h nedit.h textBuf.h textDisp.h text.h \
389 textP.h regularExp.h highlightData.h preferences.h window.h \
390 diff --quilt old/source/calltips.c new/source/calltips.c
391 --- old/source/calltips.c
392 +++ new/source/calltips.c
394 /*******************************************************************************
396 * calltips.c -- Calltip UI functions (calltip *file* functions are in tags.c) *
398 -* Copyright (C) 2002 Nathaniel Gray *
399 +* Copyright (C) 2002, 2004, 2005 The NEdit Developers *
401 * This is free software; you can redistribute it and/or modify it under the *
402 * terms of the GNU General Public License as published by the Free Software *
403 * Foundation; either version 2 of the License, or (at your option) any later *
404 -* version. In addition, you may distribute version of this program linked to *
405 +* version. In addition, you may distribute versions of this program linked to *
406 * Motif or Open Motif. See README for details. *
408 * This software is distributed in the hope that it will be useful, but WITHOUT *
409 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
410 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
414 #include "../config.h"
417 +#include "calltips.h"
419 +#include "regularExp.h"
422 -#include "calltips.h"
423 #include "../util/misc.h"
431 -#include <Xm/Label.h>
432 #include <X11/Shell.h>
433 +#include <Xm/Text.h>
436 #include "../debug.h"
439 -static char *expandAllTabs( char *text, int tab_width );
440 +static char* expandAllTabs(const char *text, const int tab_width);
441 +Boolean getRangeOfLine(const char* textString, const unsigned line,
442 + unsigned* begin, unsigned* end);
443 +Widget createTip(const Widget parent, const Pixel foreground,
444 + const Pixel background, const unsigned char alignment);
447 ** Pop-down a calltip if one exists, else do nothing
449 void KillCalltip(WindowInfo *window, int calltipID) {
450 @@ -60,31 +66,23 @@ void KillCalltip(WindowInfo *window, int
452 void TextDKillCalltip(textDisp *textD, int calltipID) {
453 if( textD->calltip.ID == 0 )
455 if( calltipID == 0 || calltipID == textD->calltip.ID ) {
456 - XtPopdown( textD->calltipShell );
457 + XtPopdown(XtParent(textD->calltip.widget));
458 textD->calltip.ID = 0;
463 -** Is a calltip displayed? Returns the calltip ID of the currently displayed
464 -** calltip, or 0 if there is no calltip displayed. If called with
465 -** calltipID != 0, returns 0 unless there is a calltip being
466 -** displayed with that calltipID.
467 +** Returns the calltip ID of the currently displayed calltip, or 0 if
468 +** there is no calltip displayed.
470 -int GetCalltipID(WindowInfo *window, int calltipID) {
471 +int GetCalltipID(const WindowInfo *window) {
472 textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
473 - if( calltipID == 0 )
474 - return textD->calltip.ID;
476 - if( calltipID == textD->calltip.ID)
482 + return textD->calltip.ID;
485 #define CALLTIP_EDGE_GUARD 5
486 static Boolean offscreenV(XWindowAttributes *screenAttr, int top, int height) {
487 return (top < CALLTIP_EDGE_GUARD ||
488 @@ -129,12 +127,15 @@ void TextDRedrawCalltip(textDisp *textD,
491 rel_x = textD->calltip.pos;
494 - XtVaGetValues(textD->calltipShell, XmNwidth, &tipWidth, XmNheight,
495 - &tipHeight, XmNborderWidth, &borderWidth, NULL);
496 + XtVaGetValues(XtParent(textD->calltip.widget),
497 + XmNwidth, &tipWidth,
498 + XmNheight, &tipHeight,
499 + XmNborderWidth, &borderWidth,
501 rel_x += borderWidth;
502 rel_y += lineHeight/2 + borderWidth;
504 /* Adjust rel_x for horizontal alignment modes */
505 if (textD->calltip.hAlign == TIP_CENTER)
506 @@ -175,119 +176,110 @@ void TextDRedrawCalltip(textDisp *textD,
507 abs_y = screenAttr.height - tipHeight - CALLTIP_EDGE_GUARD;
508 /* If no case applied, just go with the default placement. */
512 - XtVaSetValues( textD->calltipShell, XmNx, abs_x, XmNy, abs_y, NULL );
513 + XtVaSetValues(XtParent(textD->calltip.widget), XmNx, abs_x, XmNy, abs_y, NULL);
517 ** Returns a new string with each \t replaced with tab_width spaces or
518 ** a pointer to text if there were no tabs. Returns NULL on malloc failure.
519 ** Note that this is dumb replacement, not smart tab-like behavior! The goal
520 ** is to prevent tabs from turning into squares in calltips, not to get the
521 ** formatting just right.
523 -static char *expandAllTabs( char *text, int tab_width ) {
525 +static char* expandAllTabs(const char* text, const int tab_width)
529 - char *c, *cCpy, *textCpy;
531 + char *cCpy, *textCpy;
533 /* First count 'em */
534 - for( c = text; *c; ++c )
536 + for (c = (char*) text; *c; ++c) {
543 + return strdup(text);
546 /* Allocate the new string */
547 - len = strlen( text ) + ( tab_width - 1 )*nTabs;
548 - textCpy = (char*)malloc( len + 1 );
551 - "nedit: Out of heap memory in expandAllTabs!\n");
552 + len = strlen(text) + (tab_width - 1) * nTabs;
553 + textCpy = (char*) malloc(len + 1);
555 + fprintf(stderr, "nedit: Out of heap memory in expandAllTabs!\n");
559 /* Now replace 'em */
560 - for( c = text, cCpy = textCpy; *c; ++c, ++cCpy) {
562 - for( i = 0; i < tab_width; ++i, ++cCpy )
563 + for (c = text, cCpy = textCpy; *c; ++c, ++cCpy) {
565 + for (i = 0; i < tab_width; ++i, ++cCpy) {
568 --cCpy; /* Will be incremented in outer for loop */
579 -** Pop-up a calltip.
580 -** If a calltip is already being displayed it is destroyed and replaced with
581 -** the new calltip. Returns the ID of the calltip or 0 on failure.
582 +** Pop-up a calltip.
584 +** If a calltip is already being displayed it is destroyed and replaced
585 +** with the new calltip.
587 +** Returns the ID of the calltip or 0 on failure.
589 -int ShowCalltip(WindowInfo *window, char *text, Boolean anchored,
590 - int pos, int hAlign, int vAlign, int alignMode) {
591 - static int StaticCalltipID = 1;
592 +int ShowCalltip(const WindowInfo *window, const char *text,
593 + const Boolean anchored, const int pos, const int hAlign,
594 + const int vAlign, const int alignMode)
596 + static unsigned StaticCalltipID = 1;
597 textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
599 - Position txtX, txtY;
604 /* Destroy any previous calltip */
605 - TextDKillCalltip( textD, 0 );
606 + TextDKillCalltip(textD, 0);
608 /* Make sure the text isn't NULL */
609 if (text == NULL) return 0;
611 - /* Expand any tabs in the calltip and make it an XmString */
612 - textCpy = expandAllTabs( text, BufGetTabDistance(textD->buffer) );
613 - if( textCpy == NULL )
614 + /* Expand any tabs in the calltip */
615 + tablessText = expandAllTabs(text, BufGetTabDistance(textD->buffer));
616 + if (NULL == tablessText) {
617 return 0; /* Out of memory */
618 - str = XmStringCreateLtoR(textCpy, XmFONTLIST_DEFAULT_TAG);
619 - if( textCpy != text )
622 - /* Get the location/dimensions of the text area */
623 - XtVaGetValues(textD->w,
630 /* Create the calltip widget on first request */
631 - if (textD->calltipW == NULL) {
634 - XtSetArg(args[argcnt], XmNsaveUnder, True); argcnt++;
635 - XtSetArg(args[argcnt], XmNallowShellResize, True); argcnt++;
637 - textD->calltipShell = CreatePopupShellWithBestVis("calltipshell",
638 - overrideShellWidgetClass, textD->w, args, argcnt);
640 - /* Might want to make this a read-only XmText eventually so that
641 - users can copy from it */
642 - textD->calltipW = XtVaCreateManagedWidget(
643 - "calltip", xmLabelWidgetClass, textD->calltipShell,
644 - XmNborderWidth, 1, /* Thin borders */
645 - XmNhighlightThickness, 0,
646 - XmNalignment, XmALIGNMENT_BEGINNING,
647 - XmNforeground, textD->calltipFGPixel,
648 - XmNbackground, textD->calltipBGPixel,
652 - /* Set the text on the label */
653 - XtVaSetValues( textD->calltipW, XmNlabelString, str, NULL );
654 - XmStringFree( str );
655 + if (NULL == textD->calltip.widget) {
656 + textD->calltip.widget = createTip(textD->w, textD->calltipFGPixel,
657 + textD->calltipBGPixel, XmALIGNMENT_BEGINNING);
660 + /* The text widget will keep the size of the largest text it contained
661 + over its lifetime unless we do something about it. So we set it to
662 + minimum size and let the resize functionality do its work to get it
663 + back up again matching the current text. */
664 + XtVaSetValues(textD->calltip.widget,
668 + XmTextSetString(textD->calltip.widget, tablessText);
671 /* Figure out where to put the tip */
673 /* Put it at the specified position */
674 /* If position is not displayed, return 0 */
675 - if (pos < textD->firstChar || pos > textD->lastChar ) {
676 + if (pos < textD->firstChar || pos > textD->lastChar) {
677 XBell(TheDisplay, 0);
680 textD->calltip.pos = pos;
682 @@ -311,15 +303,179 @@ int ShowCalltip(WindowInfo *window, char
683 textD->calltip.vAlign = vAlign;
684 textD->calltip.alignMode = alignMode;
686 /* Increment the static calltip ID. Macro variables can only be int,
687 not unsigned, so have to work to keep it > 0 on overflow */
688 - if(++StaticCalltipID <= 0)
689 + /* Macro variables can only be int, that's why you have to keep the ID
690 + in the unsigned range? */
691 + if (++StaticCalltipID <= 0) {
695 /* Realize the calltip's shell so that its width & height are known */
696 - XtRealizeWidget( textD->calltipShell );
697 + XtRealizeWidget(XtParent(textD->calltip.widget));
699 /* Move the calltip and pop it up */
700 TextDRedrawCalltip(textD, 0);
701 - XtPopup( textD->calltipShell, XtGrabNone );
702 + XtPopup(XtParent(textD->calltip.widget), XtGrabNone);
704 return textD->calltip.ID;
708 +** Highlight a single line in a given calltip, erasing all other highlights.
710 +** Return values for this one need to be a bit more expressive. Some errors
711 +** might just be the result of sloppy parameters, and the caller should
712 +** decide whether to fail hard or not. The following results are possible:
714 +** - The calltip ID given is invalid (CT_INVALID_ID).
715 +** - The user requested to remove all highlightings (CT_OK).
716 +** - The requested line is highlighted (CT_OK).
717 +** - The requested line is not in the provided text (CT_NOLINE).
719 +int HighlightCalltipLine(const WindowInfo* window, const int calltipID,
720 + const unsigned line)
722 + textDisp* textD = ((TextWidget) window->lastFocus)->text.textD;
723 + Boolean result = False;
725 + if (calltipID == textD->calltip.ID) {
726 + Widget textWidget = textD->calltip.widget;
727 + char* textString = XmTextGetString(textWidget);
728 + XmTextPosition textLength = XmTextGetLastPosition(textWidget);
729 + unsigned begin = 0, end = 0;
730 + Boolean lineIsValid = False;
732 + /* First remove all existing highlights. */
733 + XmTextSetHighlight(textWidget, 0, textLength + 1, XmHIGHLIGHT_NORMAL);
736 + /* Just return without highlighting anything. */
739 + lineIsValid = getRangeOfLine(textString, line, &begin, &end);
741 + XmTextSetHighlight(textWidget, (XmTextPosition) begin,
742 + (XmTextPosition) end, XmHIGHLIGHT_SELECTED);
746 + /* The requested line is not in the provided text. */
747 + result = CT_NOLINE;
751 + XtFree(textString);
753 + result = CT_INVALID_ID;
760 +** Sets the parameters to beginning and end of the line. Returns False if
761 +** the line is not in the text, True otherwise.
763 +Boolean getRangeOfLine(const char* textString, const unsigned line,
764 + unsigned* begin, unsigned* end)
767 + size_t position = 0;
769 + for (i = 0; i < line; i++)
771 + *end = strcspn(textString + position, "\n") + position;
773 + position = *end + 1;
775 + if (*begin == *end)
777 + /* Break if last line is found. */
782 + return (*begin != *end);
786 +** Pop up a scroll calltip.
788 +Boolean ShowScrolltip(textDisp* textD, const char* text, const int x,
791 + if (NULL == textD->scrolltip) {
792 + textD->scrolltip = createTip(textD->w, textD->calltipFGPixel,
793 + textD->calltipBGPixel, XmALIGNMENT_CENTER);
796 + /* Set the text on the tip's label. */
797 + XmTextSetString(textD->scrolltip, (char*) text);
799 + /* Realize the calltip's shell so that its width and height are known */
800 + XtRealizeWidget(XtParent(textD->scrolltip));
802 + /* Move the tip where it belongs and pop it up. */
803 + XtVaSetValues(XtParent(textD->scrolltip), XmNx, x, XmNy, y, NULL);
804 + XtPopup(XtParent(textD->scrolltip), XtGrabNone);
810 +** Pop down scrolltip if it exists
812 +void KillScrolltip(textDisp* textD)
814 + if (NULL != textD->scrolltip && NULL != XtParent(textD->scrolltip)) {
815 + XtPopdown(XtParent(textD->scrolltip));
820 +** This creates a calltip of class XmText and its parent, a shell of class
821 +** OverrideShell (which in turn will be the child of the grandfather
822 +** parameter). The tip will have minimum size but will resize to match
823 +** the text entered (see XmNallowShellResize).
825 +** Color is picked by the two parameters foreground and background.
827 +** The alignment is on of XmALIGNMENT_BEGINNING, XmALIGNMENT_CENTER or
828 +** XmALIGNMENT_END, taken from the XmLabel class.
830 +** TODO: Some helper functions are still desirable to make this function
831 +** available from other parts of the code. At the moment the caller must
832 +** use calls to Motif/Intrinsics functions to handle it.
835 +Widget createTip(const Widget grandfather, const Pixel foreground,
836 + const Pixel background, const unsigned char alignment)
839 + Widget shell = NULL;
843 + XtSetArg(args[argc], XmNsaveUnder, True); argc++;
844 + XtSetArg(args[argc], XmNallowShellResize, True); argc++;
846 + shell = CreatePopupShellWithBestVis("tipshell", overrideShellWidgetClass,
847 + grandfather, args, argc);
849 + tip = XtVaCreateManagedWidget("tip",
850 + xmTextWidgetClass, shell,
851 + XmNhighlightThickness, 0,
852 + XmNalignment, alignment,
853 + XmNeditable, False,
854 + XmNeditMode, XmMULTI_LINE_EDIT,
855 + XmNcursorPositionVisible, False,
856 + XmNresizeHeight, True,
857 + XmNresizeWidth, True,
858 + XmNforeground, foreground,
859 + XmNbackground, background,
860 + XmNheight, 10, /* will be resized automatically */
861 + XmNwidth, 10, /* will be resized automatically */
865 diff --quilt old/source/calltips.h new/source/calltips.h
866 --- old/source/calltips.h
867 +++ new/source/calltips.h
871 enum TipHAlignMode {TIP_LEFT, TIP_CENTER, TIP_RIGHT};
872 enum TipVAlignMode {TIP_ABOVE, TIP_BELOW};
873 enum TipAlignStrict {TIP_SLOPPY, TIP_STRICT};
874 +enum TipHighlightError {CT_OK, CT_INVALID_ID, CT_NOLINE};
876 -int ShowCalltip(WindowInfo *window, char *text, Boolean anchored,
877 - int pos, int hAlign, int vAlign, int alignMode);
878 +int ShowCalltip(const WindowInfo *window, const char *text,
879 + const Boolean anchored, const int pos, const int hAlign,
880 + const int vAlign, const int alignMode);
881 void KillCalltip(WindowInfo *window, int calltipID);
882 +Boolean ShowScrolltip(textDisp* textD, const char* text, const int x,
884 +void KillScrolltip(textDisp* textD);
885 void TextDKillCalltip(textDisp *textD, int calltipID);
886 -int GetCalltipID(WindowInfo *window, int calltipID);
887 +int GetCalltipID(const WindowInfo *window);
888 void TextDRedrawCalltip(textDisp *textD, int calltipID);
889 +int HighlightCalltipLine(const WindowInfo* window, const int calltipID,
890 + const unsigned line);
892 #endif /* ifndef NEDIT_CALLTIPS_H_INCLUDED */
893 diff --quilt old/source/file.c new/source/file.c
894 --- old/source/file.c
895 +++ new/source/file.c
896 @@ -30,19 +30,22 @@ static const char CVSID[] = "$Id: file.c
898 #include "../config.h"
907 #include "preferences.h"
912 #include "interpret.h"
914 #include "../util/misc.h"
915 #include "../util/DialogF.h"
916 #include "../util/fileUtils.h"
917 #include "../util/getfiles.h"
918 #include "../util/printUtils.h"
919 @@ -73,10 +76,15 @@ static const char CVSID[] = "$Id: file.c
920 #include <Xm/ToggleB.h>
921 #include <Xm/FileSB.h>
922 #include <Xm/RowColumn.h>
924 #include <Xm/Label.h>
925 +#include <Xm/PushB.h>
927 +/* What kinds of backup files to make -- see
928 + table `version_control_values' in backup.c. */
929 +static enum backup_mode version_control;
932 #include "../debug.h"
935 @@ -84,22 +92,22 @@ static const char CVSID[] = "$Id: file.c
936 The periodic check is only performed on buffer modification, and the check
937 interval is only to prevent checking on every keystroke in case of a file
938 system which is slow to process stat requests (which I'm not sure exists) */
939 #define MOD_CHECK_INTERVAL 3000
941 +#define MAX_X_ARGS 20 /* Maximum number of X arguments */
943 static int doSave(WindowInfo *window);
944 static void safeClose(WindowInfo *window);
945 static int doOpen(WindowInfo *window, const char *name, const char *path,
947 static void backupFileName(WindowInfo *window, char *name, size_t len);
948 static int writeBckVersion(WindowInfo *window);
949 static int bckError(WindowInfo *window, const char *errString, const char *file);
950 static int fileWasModifiedExternally(WindowInfo *window);
951 static const char *errorString(void);
952 static void addWrapNewlines(WindowInfo *window);
953 -static void setFormatCB(Widget w, XtPointer clientData, XtPointer callData);
954 -static void addWrapCB(Widget w, XtPointer clientData, XtPointer callData);
955 static int cmpWinAgainstFile(WindowInfo *window, const char *fileName);
956 static int min(int i1, int i2);
957 static void modifiedWindowDestroyedCB(Widget w, XtPointer clientData,
959 static void forceShowLineNumbers(WindowInfo *window);
960 @@ -107,11 +115,11 @@ static void forceShowLineNumbers(WindowI
962 void removeVersionNumber(char *fileName);
965 WindowInfo *EditNewFile(WindowInfo *inWindow, char *geometry, int iconic,
966 - const char *languageMode, const char *defaultPath)
967 + const char* languageMode, const char* defaultPath, Boolean transient)
969 char name[MAXPATHLEN];
972 /*... test for creatability? */
973 @@ -143,11 +151,19 @@ WindowInfo *EditNewFile(WindowInfo *inWi
975 if (iconic && IsIconic(window))
976 RaiseDocument(window);
978 RaiseDocumentWindow(window);
982 + /* Set the window to transient mode. */
983 + String apParams[1];
986 + XtCallActionProc(window->lastFocus, "set_transient", NULL, apParams, 1);
994 @@ -173,11 +189,11 @@ WindowInfo *EditExistingFile(WindowInfo
995 const char *path, int flags, char *geometry, int iconic,
996 const char *languageMode, int tabbed, int bgOpen)
999 char fullname[MAXPATHLEN];
1002 /* first look to see if file is already displayed in a window */
1003 window = FindWindowWithFile(name, path);
1004 if (window != NULL) {
1007 @@ -248,10 +264,13 @@ WindowInfo *EditExistingFile(WindowInfo
1008 strcat(fullname, name);
1009 if(GetPrefAlwaysCheckRelTagsSpecs())
1010 AddRelTagsFile(GetPrefTagFile(), path, TAG);
1011 AddToPrevOpenMenu(fullname);
1013 + /* file_open_hook() */
1014 + MacroApplyHook(window, "file_open_hook", 0, NULL, NULL);
1019 void RevertToSaved(WindowInfo *window)
1021 @@ -337,11 +356,11 @@ static int doOpen(WindowInfo *window, co
1022 int fileLen, readLen;
1023 char *fileString, *c;
1029 /* initialize lock reasons */
1030 CLEAR_ALL_LOCKS(window->lockReasons);
1032 /* Update the window data structure */
1033 strcpy(window->filename, name);
1034 @@ -536,10 +555,14 @@ static int doOpen(WindowInfo *window, co
1037 SET_TMBD_LOCKED(window->lockReasons, TRUE);
1038 for (c = fileString; c < &fileString[readLen]; c++) {
1040 + /* Looks like every NUL character is replaced with:
1041 + ISO 8859-1: LATIN SMALL LETTER THORN
1042 + ISO 8859-7: GREEK SMALL LETTER OMEGA WITH TONOS
1043 + UTF-8: <unused> */
1047 window->buffer->nullSubsChar = (char) 0xfe;
1049 @@ -705,20 +728,21 @@ int CloseFileAndWindow(WindowInfo *windo
1051 /* Make sure that the window is not in iconified state */
1052 if (window->fileChanged)
1053 RaiseDocumentWindow(window);
1055 - /* If the window is a normal & unmodified file or an empty new file,
1056 - or if the user wants to ignore external modifications then
1057 - just close it. Otherwise ask for confirmation first. */
1058 - if (!window->fileChanged &&
1060 - ((!window->fileMissing && window->lastModTime > 0) ||
1062 - (window->fileMissing && window->lastModTime == 0) ||
1063 - /* File deleted/modified externally, ignored by user. */
1064 - !GetPrefWarnFileMods()))
1065 + /* If the document is transient, belongs to a normal & unmodified file
1066 + or is empty and unchanged, or if the user wants to ignore external
1067 + modifications then just close it. Otherwise ask for confirmation first. */
1068 + if (window->transient
1069 + || (!window->fileChanged
1070 + /* Normal document, already saved */
1071 + && ((!window->fileMissing && window->lastModTime > 0)
1072 + /* New document, unchanged yet */
1073 + || (window->fileMissing && window->lastModTime == 0)
1074 + /* File deleted/modified externally, ignored by user. */
1075 + || !GetPrefWarnFileMods())))
1077 CloseWindow(window);
1078 /* up-to-date windows don't have outstanding backup files to close */
1081 @@ -908,10 +932,11 @@ static int doSave(WindowInfo *window)
1082 char *fileString = NULL;
1083 char fullname[MAXPATHLEN];
1084 struct stat statbuf;
1086 int fileLen, result;
1087 + DataValue* fileNameArg = (DataValue*) XtMalloc(sizeof(DataValue));
1089 /* Get the full name of the file */
1090 strcpy(fullname, window->path);
1091 strcat(fullname, window->filename);
1093 @@ -1045,10 +1070,14 @@ static int doSave(WindowInfo *window)
1094 window->fileMissing = TRUE;
1099 + fileNameArg->tag = STRING_TAG;
1100 + AllocNStringNCpy(&fileNameArg->val.str, fullname, MAXPATHLEN);
1101 + MacroApplyHook(window, "post_save_hook", 1, fileNameArg, NULL);
1107 ** Create a backup file for the current window. The name for the backup file
1108 @@ -1182,38 +1211,52 @@ static void backupFileName(WindowInfo *w
1110 static int writeBckVersion(WindowInfo *window)
1113 char fullname[MAXPATHLEN], bckname[MAXPATHLEN];
1115 struct stat statbuf;
1119 #define IO_BUFFER_SIZE ((size_t)(1024*1024))
1121 /* Do only if version backups are turned on */
1122 if (!window->saveOldVersion) {
1126 + /* First fime numbered backup files are used. */
1127 + if (unset == version_control) {
1128 + initialize_backups();
1131 /* Get the full name of the file */
1132 strcpy(fullname, window->path);
1133 strcat(fullname, window->filename);
1135 + backname = generate_backup_filename(version_control, fullname);
1136 + if ((fileLen = strlen(backname)) < MAXPATHLEN) {
1137 + strncpy(bckname, backname, sizeof(bckname));
1141 /* Generate name for old version */
1142 - if ((strlen(fullname) + 5) > (size_t) MAXPATHLEN) {
1143 + if (fileLen >= (size_t) MAXPATHLEN) {
1144 return bckError(window, "file name too long", window->filename);
1146 - sprintf(bckname, "%s.bck", fullname);
1148 /* Delete the old backup file */
1149 /* Errors are ignored; we'll notice them later. */
1152 /* open the file being edited. If there are problems with the
1153 old file, don't bother the user, just skip the backup */
1154 in_fd = open(fullname, O_RDONLY);
1156 + /* This is rather surprising behavior. Let's see more about the error. */
1157 + perror("nedit: Error reading edited file");
1161 /* Get permissions of the file.
1162 We preserve the normal permissions but not ownership, extended
1163 @@ -1415,162 +1458,98 @@ void PrintString(const char *string, int
1169 -** Wrapper for GetExistingFilename which uses the current window's path
1170 -** (if set) as the default directory.
1171 +** Wrapper for GetFilenameByDialog()
1173 +** TODO: I stopped the refactoring here for now, but these two could
1174 +** be combined into some sort of PromptFor.*File().
1176 int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname)
1178 - char *savedDefaultDir;
1181 - /* Temporarily set default directory to window->path, prompt for file,
1182 - then, if the call was unsuccessful, restore the original default
1184 - savedDefaultDir = GetFileDialogDefaultDirectory();
1185 - if (*window->path != '\0')
1186 - SetFileDialogDefaultDirectory(window->path);
1187 - retVal = GetExistingFilename(window->shell, prompt, fullname);
1188 - if (retVal != GFN_OK)
1189 - SetFileDialogDefaultDirectory(savedDefaultDir);
1191 - XtFree(savedDefaultDir);
1192 + gfbdParams params;
1193 + gfbdValue* gfbdrc;
1194 + int rc = GFN_ERROR;
1196 + params.dialogTitle = prompt;
1197 + params.parentShell = window->shell;
1198 + params.fileExists = True;
1199 + params.textfieldLabel = (GetPrefStdOpenDialog() ? "File Name" : NULL);
1200 + params.defaultName = NULL;
1201 + params.haveFormatButtons = False;
1202 + /* ...so no file format for wrap info necessary. */
1203 + params.showHidden = GetPrefShowHiddenFiles();
1205 + gfbdrc = GetFilenameByDialog(params);
1207 + switch(gfbdrc->status) {
1209 + strncpy(fullname, gfbdrc->payload, MAXPATHLEN);
1216 + fprintf(stderr, "nedit: Error while calling GetFilenameByDialog(): %s\n", gfbdrc->payload);
1221 + fprintf(stderr, "nedit: Unexpected error in GetFilenameByDialog().\n");
1231 -** Wrapper for HandleCustomNewFileSB which uses the current window's path
1232 -** (if set) as the default directory, and asks about embedding newlines
1233 -** to make wrapping permanent.
1234 +** Wrapper for GetFilenameByDialog()
1236 int PromptForNewFile(WindowInfo *window, char *prompt, char *fullname,
1237 int *fileFormat, int *addWrap)
1242 - Widget fileSB, wrapToggle;
1243 - Widget formatForm, formatBtns, unixFormat, dosFormat, macFormat;
1244 - char *savedDefaultDir;
1246 - *fileFormat = window->fileFormat;
1248 - /* Temporarily set default directory to window->path, prompt for file,
1249 - then, if the call was unsuccessful, restore the original default
1251 - savedDefaultDir = GetFileDialogDefaultDirectory();
1252 - if (*window->path != '\0')
1253 - SetFileDialogDefaultDirectory(window->path);
1255 - /* Present a file selection dialog with an added field for requesting
1256 - long line wrapping to become permanent via inserted newlines */
1259 - XmNselectionLabelString,
1260 - s1 = XmStringCreateLocalized("New File Name:")); n++;
1261 - XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
1264 - s2 = XmStringCreateSimple(prompt)); n++;
1265 - fileSB = CreateFileSelectionDialog(window->shell,"FileSelect",args,n);
1268 - formatForm = XtVaCreateManagedWidget("formatForm", xmFormWidgetClass,
1270 - formatBtns = XtVaCreateManagedWidget("formatBtns",
1271 - xmRowColumnWidgetClass, formatForm,
1272 - XmNradioBehavior, XmONE_OF_MANY,
1273 - XmNorientation, XmHORIZONTAL,
1274 - XmNpacking, XmPACK_TIGHT,
1275 - XmNtopAttachment, XmATTACH_FORM,
1276 - XmNleftAttachment, XmATTACH_FORM,
1278 - XtVaCreateManagedWidget("formatBtns", xmLabelWidgetClass, formatBtns,
1279 - XmNlabelString, s1=XmStringCreateSimple("Format:"), NULL);
1281 - unixFormat = XtVaCreateManagedWidget("unixFormat",
1282 - xmToggleButtonWidgetClass, formatBtns,
1283 - XmNlabelString, s1 = XmStringCreateSimple("Unix"),
1284 - XmNset, *fileFormat == UNIX_FILE_FORMAT,
1285 - XmNuserData, (XtPointer)UNIX_FILE_FORMAT,
1286 - XmNmarginHeight, 0,
1287 - XmNalignment, XmALIGNMENT_BEGINNING,
1291 - XtAddCallback(unixFormat, XmNvalueChangedCallback, setFormatCB,
1293 - dosFormat = XtVaCreateManagedWidget("dosFormat",
1294 - xmToggleButtonWidgetClass, formatBtns,
1295 - XmNlabelString, s1 = XmStringCreateSimple("DOS"),
1296 - XmNset, *fileFormat == DOS_FILE_FORMAT,
1297 - XmNuserData, (XtPointer)DOS_FILE_FORMAT,
1298 - XmNmarginHeight, 0,
1299 - XmNalignment, XmALIGNMENT_BEGINNING,
1303 - XtAddCallback(dosFormat, XmNvalueChangedCallback, setFormatCB,
1305 - macFormat = XtVaCreateManagedWidget("macFormat",
1306 - xmToggleButtonWidgetClass, formatBtns,
1307 - XmNlabelString, s1 = XmStringCreateSimple("Macintosh"),
1308 - XmNset, *fileFormat == MAC_FILE_FORMAT,
1309 - XmNuserData, (XtPointer)MAC_FILE_FORMAT,
1310 - XmNmarginHeight, 0,
1311 - XmNalignment, XmALIGNMENT_BEGINNING,
1315 - XtAddCallback(macFormat, XmNvalueChangedCallback, setFormatCB,
1317 - if (window->wrapMode == CONTINUOUS_WRAP) {
1318 - wrapToggle = XtVaCreateManagedWidget("addWrap",
1319 - xmToggleButtonWidgetClass, formatForm,
1320 - XmNlabelString, s1 = XmStringCreateSimple("Add line breaks where wrapped"),
1321 - XmNalignment, XmALIGNMENT_BEGINNING,
1323 - XmNtopAttachment, XmATTACH_WIDGET,
1324 - XmNtopWidget, formatBtns,
1325 - XmNleftAttachment, XmATTACH_FORM,
1327 - XtAddCallback(wrapToggle, XmNvalueChangedCallback, addWrapCB,
1332 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_LABEL),
1334 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_TEXT),
1336 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST_LABEL),
1338 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST),
1340 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST_LABEL),
1342 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST),
1344 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_SELECTION_LABEL),
1345 - XmNmnemonic, prompt[strspn(prompt, "lFD")],
1346 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_TEXT),
1348 - AddDialogMnemonicHandler(fileSB, FALSE);
1349 - RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_TEXT));
1350 - RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_TEXT));
1351 - retVal = HandleCustomNewFileSB(fileSB, fullname,
1352 - window->filenameSet ? window->filename : NULL);
1353 + gfbdParams params;
1354 + gfbdValue* gfbdrc;
1355 + int rc = GFN_ERROR;
1357 + params.dialogTitle = prompt;
1358 + params.parentShell = window->shell;
1359 + params.fileExists = False;
1360 + params.textfieldLabel = "New File Name";
1361 + params.defaultName = window->filenameSet ? window->filename : NULL;
1362 + params.haveFormatButtons = True;
1363 + params.fileFormat = window->fileFormat;
1364 + params.isContWrapped = (CONTINUOUS_WRAP == window->wrapMode);
1365 + params.showHidden = GetPrefShowHiddenFiles();
1367 - if (retVal != GFN_OK)
1368 - SetFileDialogDefaultDirectory(savedDefaultDir);
1369 + gfbdrc = GetFilenameByDialog(params);
1372 - XtFree(savedDefaultDir);
1373 + switch(gfbdrc->status) {
1375 + strncpy(fullname, gfbdrc->payload, MAXPATHLEN);
1376 + *addWrap = gfbdrc->addWrap;
1383 + fprintf(stderr, "nedit: Error while calling GetFilenameByDialog(): %s\n", gfbdrc->payload);
1388 + fprintf(stderr, "nedit: Unexpected error in GetFilenameByDialog().\n");
1398 ** Find a name for an untitled file, unique in the name space of in the opened
1399 ** files in this session, i.e. Untitled or Untitled_nn, and write it into
1400 @@ -1882,56 +1861,10 @@ void removeVersionNumber(char *fileName)
1401 *versionStart = '\0';
1406 -** Callback procedure for File Format toggle buttons. Format is stored
1407 -** in userData field of widget button
1409 -static void setFormatCB(Widget w, XtPointer clientData, XtPointer callData)
1411 - if (XmToggleButtonGetState(w)) {
1412 - XtPointer userData;
1413 - XtVaGetValues(w, XmNuserData, &userData, NULL);
1414 - *(int*) clientData = (int) userData;
1419 -** Callback procedure for toggle button requesting newlines to be inserted
1420 -** to emulate continuous wrapping.
1422 -static void addWrapCB(Widget w, XtPointer clientData, XtPointer callData)
1425 - int *addWrap = (int *)clientData;
1427 - if (XmToggleButtonGetState(w))
1429 - resp = DialogF(DF_WARN, w, 2, "Add Wrap",
1430 - "This operation adds permanent line breaks to\n"
1431 - "match the automatic wrapping done by the\n"
1432 - "Continuous Wrap mode Preferences Option.\n\n"
1433 - "*** This Option is Irreversable ***\n\n"
1434 - "Once newlines are inserted, continuous wrapping\n"
1435 - "will no longer work automatically on these lines", "OK",
1439 - XmToggleButtonSetState(w, False, False);
1452 ** Change a window created in NEdit's continuous wrap mode to the more
1453 ** conventional Unix format of embedded newlines. Indicate to the user
1454 ** by turning off Continuous Wrap mode.
1456 static void addWrapNewlines(WindowInfo *window)
1457 diff --quilt old/source/file.h new/source/file.h
1458 --- old/source/file.h
1459 +++ new/source/file.h
1461 /* flags for EditExistingFile */
1463 #define SUPPRESS_CREATE_WARN 2
1464 #define PREF_READ_ONLY 4
1466 +/* These were once set in util/getfiles.h and used throughout NEdit; they
1467 + were moved here to lower coupling between util/getfiles.c and the rest
1469 +enum gfnResult {GFN_OK, GFN_CANCEL, GFN_ERROR};
1471 #define PROMPT_SBC_DIALOG_RESPONSE 0
1472 #define YES_SBC_DIALOG_RESPONSE 1
1473 #define NO_SBC_DIALOG_RESPONSE 2
1475 WindowInfo *EditNewFile(WindowInfo *inWindow, char *geometry, int iconic,
1476 - const char *languageMode, const char *defaultPath);
1477 + const char *languageMode, const char *defaultPath, Boolean transient);
1478 WindowInfo *EditExistingFile(WindowInfo *inWindow, const char *name,
1479 const char *path, int flags, char *geometry, int iconic,
1480 const char *languageMode, int tabbed, int bgOpen);
1481 void RevertToSaved(WindowInfo *window);
1482 int SaveWindow(WindowInfo *window);
1483 diff --quilt old/source/help.c new/source/help.c
1484 --- old/source/help.c
1485 +++ new/source/help.c
1486 @@ -6,11 +6,11 @@ static const char CVSID[] = "$Id: help.c
1487 * Copyright (C) 1999 Mark Edel *
1489 * This is free software; you can redistribute it and/or modify it under the *
1490 * terms of the GNU General Public License as published by the Free Software *
1491 * Foundation; either version 2 of the License, or (at your option) any later *
1492 -* version. In addition, you may distribute version of this program linked to *
1493 +* version. In addition, you may distribute versions of this program linked to *
1494 * Motif or Open Motif. See README for details. *
1496 * This software is distributed in the hope that it will be useful, but WITHOUT *
1497 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
1498 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
1499 @@ -598,42 +598,48 @@ static Widget createHelpPanel(enum HelpT
1500 form = XtVaCreateManagedWidget("helpForm", xmFormWidgetClass, appShell,
1502 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
1504 /* Create the bottom row of buttons */
1505 - btn = XtVaCreateManagedWidget("find", xmPushButtonWidgetClass, form,
1506 + btn = XtVaCreateManagedWidget("find",
1507 + xmPushButtonWidgetClass, form,
1508 XmNlabelString, st1=XmStringCreateSimple("Find..."),
1510 XmNbottomAttachment, XmATTACH_FORM,
1511 XmNleftAttachment, XmATTACH_POSITION,
1513 XmNrightAttachment, XmATTACH_POSITION,
1514 XmNrightPosition, 25,
1515 + XmNtraversalOn, False,
1517 XtAddCallback(btn, XmNactivateCallback, searchHelpCB, appShell);
1520 - btn = XtVaCreateManagedWidget("findAgain", xmPushButtonWidgetClass, form,
1521 + btn = XtVaCreateManagedWidget("findAgain",
1522 + xmPushButtonWidgetClass, form,
1523 XmNlabelString, st1=XmStringCreateSimple("Find Again"),
1525 XmNbottomAttachment, XmATTACH_FORM,
1526 XmNleftAttachment, XmATTACH_POSITION,
1527 XmNleftPosition, 27,
1528 XmNrightAttachment, XmATTACH_POSITION,
1529 XmNrightPosition, 49,
1530 + XmNtraversalOn, False,
1532 XtAddCallback(btn, XmNactivateCallback, searchHelpAgainCB, appShell);
1535 - btn = XtVaCreateManagedWidget("print", xmPushButtonWidgetClass, form,
1536 + btn = XtVaCreateManagedWidget("print",
1537 + xmPushButtonWidgetClass, form,
1538 XmNlabelString, st1=XmStringCreateSimple("Print..."),
1540 XmNbottomAttachment, XmATTACH_FORM,
1541 XmNleftAttachment, XmATTACH_POSITION,
1542 XmNleftPosition, 51,
1543 XmNrightAttachment, XmATTACH_POSITION,
1544 XmNrightPosition, 73,
1545 + XmNtraversalOn, False,
1547 XtAddCallback(btn, XmNactivateCallback, printCB, appShell);
1550 closeBtn = XtVaCreateManagedWidget("close",
1551 @@ -642,79 +648,89 @@ static Widget createHelpPanel(enum HelpT
1552 XmNbottomAttachment, XmATTACH_FORM,
1553 XmNleftAttachment, XmATTACH_POSITION,
1554 XmNleftPosition, 75,
1555 XmNrightAttachment, XmATTACH_POSITION,
1556 XmNrightPosition, 97,
1557 + XmNtraversalOn, False,
1559 XtAddCallback(closeBtn, XmNactivateCallback, closeCB, appShell);
1562 /* Create the next row of buttons (for navigation) */
1563 - btn = XtVaCreateManagedWidget("prevTopic", xmPushButtonWidgetClass, form,
1564 + btn = XtVaCreateManagedWidget("prevTopic",
1565 + xmPushButtonWidgetClass, form,
1566 XmNlabelString, st1=XmStringCreateSimple("<< Browse"),
1568 XmNbottomAttachment, XmATTACH_WIDGET,
1569 XmNbottomWidget, closeBtn,
1570 XmNleftAttachment, XmATTACH_POSITION,
1571 XmNleftPosition, 51,
1572 XmNrightAttachment, XmATTACH_POSITION,
1573 XmNrightPosition, 73,
1574 + XmNtraversalOn, False,
1576 XtAddCallback(btn, XmNactivateCallback, prevTopicCB, appShell);
1579 - btn = XtVaCreateManagedWidget("nextTopic", xmPushButtonWidgetClass, form,
1580 + btn = XtVaCreateManagedWidget("nextTopic",
1581 + xmPushButtonWidgetClass, form,
1582 XmNlabelString, st1=XmStringCreateSimple("Browse >>"),
1584 XmNbottomAttachment, XmATTACH_WIDGET,
1585 XmNbottomWidget, closeBtn,
1586 XmNleftAttachment, XmATTACH_POSITION,
1587 XmNleftPosition, 75,
1588 XmNrightAttachment, XmATTACH_POSITION,
1589 XmNrightPosition, 97,
1590 + XmNtraversalOn, False,
1592 XtAddCallback(btn, XmNactivateCallback, nextTopicCB, appShell);
1595 - btn = XtVaCreateManagedWidget("histBack", xmPushButtonWidgetClass, form,
1596 + btn = XtVaCreateManagedWidget("histBack",
1597 + xmPushButtonWidgetClass, form,
1598 XmNlabelString, st1=XmStringCreateSimple("Back"),
1600 XmNbottomAttachment, XmATTACH_WIDGET,
1601 XmNbottomWidget, closeBtn,
1602 XmNleftAttachment, XmATTACH_POSITION,
1604 XmNrightAttachment, XmATTACH_POSITION,
1605 XmNrightPosition, 25,
1606 + XmNtraversalOn, False,
1608 XtAddCallback(btn, XmNactivateCallback, bwHistoryCB, appShell);
1611 - btnFW = XtVaCreateManagedWidget("histForw", xmPushButtonWidgetClass, form,
1612 + btnFW = XtVaCreateManagedWidget("histForw",
1613 + xmPushButtonWidgetClass, form,
1614 XmNlabelString, st1=XmStringCreateSimple("Forward"),
1616 XmNbottomAttachment, XmATTACH_WIDGET,
1617 XmNbottomWidget, closeBtn,
1618 XmNleftAttachment, XmATTACH_POSITION,
1619 XmNleftPosition, 27,
1620 XmNrightAttachment, XmATTACH_POSITION,
1621 XmNrightPosition, 49,
1622 + XmNtraversalOn, False,
1624 XtAddCallback(btnFW, XmNactivateCallback, fwHistoryCB, appShell);
1627 /* Create a text widget inside of a scrolled window widget */
1628 - sw = XtVaCreateManagedWidget("sw", xmScrolledWindowWidgetClass, form,
1629 + sw = XtVaCreateManagedWidget("sw",
1630 + xmScrolledWindowWidgetClass, form,
1631 XmNshadowThickness, 2,
1632 XmNtopAttachment, XmATTACH_FORM,
1633 XmNleftAttachment, XmATTACH_FORM,
1634 XmNrightAttachment, XmATTACH_FORM,
1635 XmNbottomAttachment, XmATTACH_WIDGET,
1636 XmNbottomWidget, btnFW,
1638 hScrollBar = XtVaCreateManagedWidget("hScrollBar",
1639 xmScrollBarWidgetClass, sw,
1640 - XmNorientation, XmHORIZONTAL,
1641 + XmNorientation, XmHORIZONTAL,
1644 vScrollBar = XtVaCreateManagedWidget("vScrollBar",
1645 xmScrollBarWidgetClass, sw,
1646 XmNorientation, XmVERTICAL,
1647 @@ -733,15 +749,16 @@ static Widget createHelpPanel(enum HelpT
1648 textNvScrollBar, vScrollBar,
1649 textNreadOnly, True,
1650 textNcontinuousWrap, True,
1651 textNautoShowInsertPos, True,
1653 - XtVaSetValues(sw, XmNworkWindow, HelpTextPanes[topic],
1655 + XmNworkWindow, HelpTextPanes[topic],
1656 XmNhorizontalScrollBar, hScrollBar,
1657 XmNverticalScrollBar, vScrollBar,
1661 /* Initialize help style information, if it hasn't already been init'd */
1662 initHelpStyles (HelpTextPanes[topic]);
1664 /* Put together the text to display and separate it into parallel text
1665 and style data for display by the widget */
1666 @@ -802,11 +819,10 @@ static void changeTopicOrRaise(int exist
1668 RaiseShellWindow(HelpWindows[newTopic], True);
1669 adaptNavigationButtons(existingTopic);
1670 adaptNavigationButtons(newTopic);
1676 ** Callbacks for window controls
1678 @@ -900,12 +916,22 @@ static void searchHelpCB(Widget w, XtPoi
1679 static void searchHelpAgainCB(Widget w, XtPointer clientData,
1684 - if ((topic = findTopicFromShellWidget((Widget)clientData)) == -1)
1685 - return; /* shouldn't happen */
1686 + if ((topic = findTopicFromShellWidget((Widget)clientData)) == -1) {
1687 + /* shouldn't happen */
1688 + fprintf(stderr, "nedit: Unexpected location found in help.c\n");
1692 + if (0 == strcmp(LastSearchString, "")) {
1693 + /* no previous search */
1694 + XBell(TheDisplay, 0);
1698 searchHelpText(HelpWindows[topic], topic, LastSearchString,
1699 LastSearchWasAllTopics, LastSearchPos, LastSearchTopic);
1702 static void printCB(Widget w, XtPointer clientData, XtPointer callData)
1703 @@ -1005,16 +1031,10 @@ static void followHyperlink(int topic, i
1704 adaptNavigationButtons(topic);
1709 -static void helpFocusButtonsAP(Widget w, XEvent *event, String *args,
1712 - XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP);
1716 * handler for help-button-action(<button-name>)
1717 * Calls the activate callback for the named button widget of the help text win.
1719 static void helpButtonActionAP(Widget w, XEvent *event, String *args,
1720 @@ -1148,11 +1168,10 @@ static void helpHyperlinkAP(Widget w, XE
1721 void InstallHelpLinkActions(XtAppContext context)
1723 static XtActionsRec Actions[] =
1725 {"help-hyperlink", helpHyperlinkAP},
1726 - {"help-focus-buttons", helpFocusButtonsAP},
1727 {"help-button-action", helpButtonActionAP}
1730 XtAppAddActions(context, Actions, XtNumber(Actions));
1732 diff --quilt old/source/highlightData.c new/source/highlightData.c
1733 --- old/source/highlightData.c
1734 +++ new/source/highlightData.c
1735 @@ -546,14 +546,14 @@ static char *DefaultPatternSets[] = {
1736 Wrong logical ops:\"&&|\\|\\|\":::Plain::\n\
1737 Logical operators:\"~|&|\\|\":::Text Arg2::}",
1738 "NEdit Macro:2:0{\n\
1739 README:\"NEdit Macro syntax highlighting patterns, version 2.6, maintainer Thorsten Haude, nedit at thorstenhau.de\":::Flag::D\n\
1740 Comment:\"#\":\"$\"::Comment::\n\
1741 - 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)>\":::Identifier::\n\
1742 + 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\
1743 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\
1744 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\
1745 - 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|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\
1746 + 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|typeof|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
1747 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\
1748 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\
1749 Keyword:\"<(?:break|continue|define|delete|else|for|if|in|return|while)>\":::Keyword::\n\
1750 Braces:\"[{}\\[\\]]\":::Keyword::\n\
1751 Global Variable:\"\\$[A-Za-z0-9_]+\":::Identifier1::\n\
1752 diff --quilt old/source/interpret.c new/source/interpret.c
1753 --- old/source/interpret.c
1754 +++ new/source/interpret.c
1755 @@ -199,11 +199,11 @@ static SparseArrayEntryWrapper *Allocate
1757 /* Message strings used in macros (so they don't get repeated every time
1758 the macros are used */
1759 static const char *StackOverflowMsg = "macro stack overflow";
1760 static const char *StackUnderflowMsg = "macro stack underflow";
1761 -static const char *StringToNumberMsg = "string could not be converted to number";
1762 +static const char* StringToNumberMsg = "string '%s' could not be converted to number";
1764 /* Temporary global data for use while accumulating programs */
1765 static Symbol *LocalSymList = NULL; /* symbols local to the program */
1766 static Inst Prog[PROGRAM_SIZE]; /* the program */
1767 static Inst *ProgP; /* next free spot for code gen. */
1768 @@ -597,10 +597,13 @@ int ContinueMacro(RestartData *continuat
1772 /* Execute an instruction */
1774 +// fprintf(stderr, "inst->sym->name: %s\n", inst->sym->name);
1775 +// fprintf(stderr, "inst->sym->type: %d\n", inst->sym->type);
1776 +// fprintf(stderr, "inst->sym->value.tag: %d\n", inst->sym->value.tag);
1777 status = (inst->func)();
1779 /* If error return was not STAT_OK, return to caller */
1780 if (status != STAT_OK) {
1781 if (status == STAT_PREEMPT) {
1782 @@ -1198,12 +1201,13 @@ static void freeSymbolTable(Symbol *symT
1783 #define POP_INT(number) \
1784 if (StackP == TheStack) \
1785 return execError(StackUnderflowMsg, ""); \
1787 if (StackP->tag == STRING_TAG) { \
1788 - if (!StringToNum(StackP->val.str.rep, &number)) \
1789 - return execError(StringToNumberMsg, ""); \
1790 + if (!StringToNum(StackP->val.str.rep, &number)) {\
1791 + return execError(StringToNumberMsg, StackP->val.str.rep); \
1793 } else if (StackP->tag == INT_TAG) \
1794 number = StackP->val.n; \
1796 return(execError("can't convert array to integer", NULL));
1798 @@ -1316,13 +1320,17 @@ static int pushSymVal(void)
1799 return execError(errMsg, s->name);
1803 return execError("reading non-variable: %s", s->name);
1806 if (StackP->tag == NO_TAG) {
1807 - return execError("variable not set: %s", s->name);
1808 + return execError("variable not set: %s", s->name);
1813 if (StackP >= &TheStack[STACK_SIZE]) {
1814 return execError(StackOverflowMsg, "");
1817 @@ -1423,13 +1431,15 @@ static int pushArraySymVal(void)
1818 if (initEmpty && dataPtr->tag == NO_TAG) {
1819 dataPtr->tag = ARRAY_TAG;
1820 dataPtr->val.arrayPtr = ArrayNew();
1824 if (dataPtr->tag == NO_TAG) {
1825 return execError("variable not set: %s", sym->name);
1832 if (StackP >= &TheStack[STACK_SIZE]) {
1833 @@ -3081,17 +3091,21 @@ static int arrayRef(void)
1837 if (srcArray.tag == ARRAY_TAG) {
1838 if (!ArrayGet(&srcArray, keyString, &valueItem)) {
1839 - return(execError("referenced array value not in array: %s", keyString));
1840 +/*typeof() return(execError("referenced array value not in array: %s", keyString));*/
1841 + valueItem.tag = NO_TAG;
1847 - return(execError("operator [] on non-array", NULL));
1848 +/*typeof() return(execError("operator [] on non-array", NULL));*/
1849 + valueItem.tag = NO_TAG;
1856 if (srcArray.tag == ARRAY_TAG) {
1857 @@ -3494,10 +3508,11 @@ static int execError(const char *s1, con
1858 static char msg[MAX_ERR_MSG_LEN];
1859 static char *err = NULL;
1860 static int errlen = 0;
1862 sprintf(msg, s1, s2);
1863 + msg[MAX_ERR_MSG_LEN - 1] = '\0';
1864 ErrMsg = stackDumpStr(FrameP, msg, &err, &errlen);
1868 int StringToNum(const char *string, int *number)
1869 diff --quilt old/source/macro.c new/source/macro.c
1870 --- old/source/macro.c
1871 +++ new/source/macro.c
1872 @@ -30,35 +30,35 @@ static const char CVSID[] = "$Id: macro.
1874 #ifdef HAVE_CONFIG_H
1875 #include "../config.h"
1878 +#include "calltips.h"
1879 +#include "highlightData.h"
1880 +#include "highlight.h"
1881 +#include "interpret.h"
1883 -#include "textBuf.h"
1886 -#include "window.h"
1887 -#include "preferences.h"
1888 -#include "interpret.h"
1890 +#include "preferences.h"
1891 +#include "rangeset.h"
1892 +#include "rbTree.h"
1894 +#include "selection.h"
1897 #include "smartIndent.h"
1898 -#include "userCmds.h"
1899 -#include "selection.h"
1900 -#include "rbTree.h"
1902 -#include "calltips.h"
1903 +#include "textBuf.h"
1905 +#include "userCmds.h"
1906 +#include "window.h"
1907 #include "../util/DialogF.h"
1908 -#include "../util/misc.h"
1909 #include "../util/fileUtils.h"
1910 -#include "../util/utils.h"
1911 #include "../util/getfiles.h"
1912 -#include "highlight.h"
1913 -#include "highlightData.h"
1914 -#include "rangeset.h"
1915 +#include "../util/misc.h"
1916 +#include "../util/utils.h"
1922 @@ -75,26 +75,27 @@ static const char CVSID[] = "$Id: macro.
1924 #include <sys/param.h>
1928 +#include <stdarg.h>
1930 #include <X11/Intrinsic.h>
1931 #include <X11/keysym.h>
1933 #include <Xm/CutPaste.h>
1934 +#include <Xm/DialogS.h>
1935 #include <Xm/Form.h>
1936 -#include <Xm/RowColumn.h>
1937 #include <Xm/LabelG.h>
1938 #include <Xm/List.h>
1939 -#include <Xm/ToggleB.h>
1940 -#include <Xm/DialogS.h>
1941 #include <Xm/MessageB.h>
1942 -#include <Xm/SelectioB.h>
1943 #include <Xm/PushB.h>
1944 -#include <Xm/Text.h>
1945 +#include <Xm/RowColumn.h>
1946 +#include <Xm/SelectioB.h>
1947 #include <Xm/Separator.h>
1948 +#include <Xm/Text.h>
1949 +#include <Xm/ToggleB.h>
1952 #include "../debug.h"
1955 @@ -233,10 +234,12 @@ static void stringDialogCloseCB(Widget w
1956 static void stringDialogEscCB(Widget w, XtPointer clientData, XEvent *event,
1958 #endif /* LESSTIF_VERSION */
1959 static int calltipMS(WindowInfo *window, DataValue *argList, int nArgs,
1960 DataValue *result, char **errMsg);
1961 +static int highlightCTLineMS(WindowInfo* window, DataValue* argList, int nArgs,
1962 + DataValue* result, char** errMsg);
1963 static int killCalltipMS(WindowInfo *window, DataValue *argList, int nArgs,
1964 DataValue *result, char **errMsg);
1966 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
1967 DataValue *result, char **errMsg);
1968 @@ -350,19 +353,21 @@ static int calltipIDMV(WindowInfo *windo
1969 static int readSearchArgs(DataValue *argList, int nArgs, int*searchDirection,
1970 int *searchType, int *wrap, char **errMsg);
1971 static int wrongNArgsErr(char **errMsg);
1972 static int tooFewArgsErr(char **errMsg);
1973 static int strCaseCmp(char *str1, char *str2);
1974 -static int readIntArg(DataValue dv, int *result, char **errMsg);
1975 +static Boolean readIntArg(DataValue dv, int *result, char **errMsg);
1976 static int readStringArg(DataValue dv, char **result, char *stringStorage,
1979 static int backlightStringMV(WindowInfo *window, DataValue *argList,
1980 int nArgs, DataValue *result, char **errMsg);
1982 static int rangesetListMV(WindowInfo *window, DataValue *argList,
1983 int nArgs, DataValue *result, char **errMsg);
1984 static int versionMV(WindowInfo* window, DataValue* argList, int nArgs,
1985 DataValue* result, char** errMsg);
1986 static int rangesetCreateMS(WindowInfo *window, DataValue *argList, int nArgs,
1987 DataValue *result, char **errMsg);
1988 static int rangesetDestroyMS(WindowInfo *window, DataValue *argList, int nArgs,
1989 @@ -405,10 +410,12 @@ static int getStyleAtPosMS(WindowInfo *w
1990 DataValue *result, char **errMsg);
1991 static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
1992 DataValue* result, char** errMsg);
1993 static int callMS(WindowInfo *window, DataValue *argList,
1994 int nArgs, DataValue *result, char **errMsg);
1995 +static int typeofMS(WindowInfo* window, DataValue* argList, int nArgs,
1996 + DataValue* result, char** errMsg);
1998 /* Built-in subroutines and variables for the macro language */
1999 static const BuiltInSubrName MacroSubrs[] = {
2000 { "length", lengthMS },
2001 { "get_range", getRangeMS },
2002 @@ -444,10 +451,11 @@ static const BuiltInSubrName MacroSubrs[
2003 { "getenv", getenvMS },
2004 { "string_compare", stringCompareMS },
2005 { "split", splitMS },
2006 { "calltip", calltipMS },
2007 { "kill_calltip", killCalltipMS },
2008 + { "highlight_calltip_line", highlightCTLineMS },
2010 { "set_backlight_string", setBacklightStringMS },
2012 { "rangeset_create", rangesetCreateMS },
2013 { "rangeset_destroy", rangesetDestroyMS },
2014 @@ -465,10 +473,11 @@ static const BuiltInSubrName MacroSubrs[
2015 { "get_pattern_at_pos", getPatternAtPosMS },
2016 { "get_style_by_name", getStyleByNameMS },
2017 { "get_style_at_pos", getStyleAtPosMS },
2018 { "filename_dialog", filenameDialogMS },
2020 + { "typeof", typeofMS },
2021 { NULL, NULL } /* sentinel */
2024 static const BuiltInSubrName SpecialVars[] = {
2025 { "$cursor", cursorMV },
2026 @@ -3420,10 +3430,61 @@ bad_arg:
2027 *errMsg = "unrecognized argument to %s";
2032 +** highlight_calltip_line(ctID, line)
2034 +static int highlightCTLineMS(WindowInfo* window, DataValue* argList, int nArgs,
2035 + DataValue* result, char** errMsg)
2037 + int calltipID = 0;
2039 + int highlightResult;
2042 + *errMsg = "%s() called with wrong number of arguments";
2046 + if (!readIntArg(argList[0], &calltipID, errMsg)) {
2047 + *errMsg = "%s(): Could not read calltip ID from argument 1";
2051 + /* The macro function calltip() uses 0 to report an error. Catch sloppy
2052 + programmers who just feed this value into this function. */
2053 + if (0 == calltipID) {
2054 + *errMsg = "%s(): Invalid calltip ID 0";
2058 + if (!readIntArg(argList[1], &line, errMsg) || line < 0) {
2059 + *errMsg = "%s(): Could not read line number from argument 2";
2063 + result->tag = NO_TAG;
2065 + highlightResult = HighlightCalltipLine(window, calltipID, (unsigned) line);
2067 + if (CT_INVALID_ID == highlightResult) {
2068 + /* Fail only if the calltip ID given is invalid. */
2069 + *errMsg = "%s(): Invalid calltip ID";
2073 + /* In case NEdit ever gets a warning (!= error) mechanism:
2074 + if (CT_NOLINE == highlightResult) {
2075 + *warnMsg = "%s(): Calltip line out of range";
2083 ** A subroutine to kill the current calltip
2085 static int killCalltipMS(WindowInfo *window, DataValue *argList, int nArgs,
2086 DataValue *result, char **errMsg)
2088 @@ -3449,11 +3510,11 @@ static int killCalltipMS(WindowInfo *win
2090 static int calltipIDMV(WindowInfo *window, DataValue *argList,
2091 int nArgs, DataValue *result, char **errMsg)
2093 result->tag = INT_TAG;
2094 - result->val.n = GetCalltipID(window, 0);
2095 + result->val.n = GetCalltipID(window);
2100 ** filename_dialog([title[, mode[, defaultPath[, filter[, defaultName]]]]])
2101 @@ -3478,19 +3539,20 @@ static int calltipIDMV(WindowInfo *windo
2103 static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
2104 DataValue* result, char** errMsg)
2106 char stringStorage[5][TYPE_INT_STR_SIZE(int)];
2107 - char filename[MAXPATHLEN + 1];
2108 char* title = "Choose Filename";
2109 char* mode = "exist";
2110 char* defaultPath = "";
2112 char* defaultName = "";
2113 char* orgDefaultPath;
2116 + gfbdParams params;
2117 + gfbdValue* gfbdrc;
2120 /* Ignore the focused window passed as the function argument and put
2121 the dialog up over the window which is executing the macro */
2122 window = MacroRunWindow();
2124 @@ -3545,37 +3607,56 @@ static int filenameDialogMS(WindowInfo*
2125 orgFilter = GetFileDialogDefaultPattern();
2126 if ('\0' != filter[0]) {
2127 SetFileDialogDefaultPattern(filter);
2130 - /* Fork to one of the worker methods from util/getfiles.c.
2131 - (This should obviously be refactored.) */
2132 - if (0 == strcmp(mode, "exist")) {
2133 - gfnResult = GetExistingFilename(window->shell, title, filename);
2135 - gfnResult = GetNewFilename(window->shell, title, filename, defaultName);
2136 - } /* Invalid values are weeded out above. */
2137 + params.dialogTitle = title;
2138 + params.parentShell = window->shell;
2139 + params.fileExists = (0 == strcmp(mode, "exist")) ? True : False;
2140 + params.textfieldLabel = "New File Name";
2141 + params.defaultName = (0 == strcmp("", defaultName)) ? NULL : defaultName;
2142 + params.haveFormatButtons = False;
2143 + /* ...so no file format for wrap info necessary. */
2144 + params.showHidden = GetPrefShowHiddenFiles();
2146 + gfbdrc = GetFilenameByDialog(params);
2148 /* Reset original values and free temps */
2149 SetFileDialogDefaultDirectory(orgDefaultPath);
2150 SetFileDialogDefaultPattern(orgFilter);
2151 XtFree(orgDefaultPath);
2154 result->tag = STRING_TAG;
2155 - if (GFN_OK == gfnResult) {
2156 - /* Got a string, copy it to the result */
2157 - if (!AllocNStringNCpy(&result->val.str, filename, MAXPATHLEN)) {
2158 - M_FAILURE("failed to allocate return value: %s");
2161 - /* User cancelled. Return "" */
2162 - result->val.str.rep = PERM_ALLOC_STR("");
2163 - result->val.str.len = 0;
2164 + switch(gfbdrc->status) {
2166 + /* Got a filename, copy it to the result */
2167 + if (!AllocNStringNCpy(&result->val.str, gfbdrc->payload, MAXPATHLEN)) {
2168 + M_FAILURE("failed to allocate return value: %s");
2173 + /* User cancelled. Return "" */
2174 + result->val.str.rep = PERM_ALLOC_STR("");
2175 + result->val.str.len = 0;
2179 + fprintf(stderr, "nedit: Error while calling GetFilenameByDialog(): %s\n", gfbdrc->payload);
2180 + *errMsg = "Error while calling GetFilenameByDialog() in %s";
2185 + fprintf(stderr, "nedit: Unexpected error in GetFilenameByDialog().\n");
2186 + *errMsg = "Unexpected error in GetFilenameByDialog() in %s";
2196 * call(fnname, arg, ...)
2198 @@ -5854,10 +5956,56 @@ static int getPatternAtPosMS(WindowInfo
2199 return fillPatternResult(result, errMsg, window,
2200 HighlightNameOfCode(window, patCode), False, True,
2201 HighlightStyleOfCode(window, patCode), bufferPos);
2205 +** Returns a string containing a flag indicating the arguments type:
2206 +** ARRAY - Argument is an array
2207 +** INTEGER - Argument is an integer or a string that can be cleanly
2208 +** transformed into an integer.
2209 +** STRING - Argument is a string that cannot be cleanly transformed
2210 +** into an integer.
2211 +** UNDEFINED - Argument is undefined. No support for void functions though.
2213 +static int typeofMS(WindowInfo* window, DataValue* argList, int nArgs,
2214 + DataValue* result, char** errMsg)
2218 + /* Validate number of arguments. */
2220 + return wrongNArgsErr(errMsg);
2223 + /* Prepare result. */
2224 + result->tag = STRING_TAG;
2226 + switch (argList[0].tag) {
2228 + if (readIntArg(argList[0], &buffer, errMsg)) {
2229 + AllocNStringCpy(&result->val.str, "INTEGER");
2231 + AllocNStringCpy(&result->val.str, "STRING");
2235 + AllocNStringCpy(&result->val.str, "INTEGER");
2238 + AllocNStringCpy(&result->val.str, "ARRAY");
2241 + AllocNStringCpy(&result->val.str, "UNDEFINED");
2244 + fprintf(stderr, "nedit: Internal error: Invalid type in typeofMS().\n");
2250 static int wrongNArgsErr(char **errMsg)
2252 *errMsg = "Wrong number of arguments to function %s";
2255 @@ -5901,11 +6049,11 @@ static int strCaseCmp(char *str1, char *
2257 ** Get an integer value from a tagged DataValue structure. Return True
2258 ** if conversion succeeded, and store result in *result, otherwise
2259 ** return False with an error message in *errMsg.
2261 -static int readIntArg(DataValue dv, int *result, char **errMsg)
2262 +static Boolean readIntArg(DataValue dv, int *result, char **errMsg)
2266 if (dv.tag == INT_TAG) {
2268 @@ -5944,5 +6092,46 @@ static int readStringArg(DataValue dv, c
2271 *errMsg = "%s called with unknown object";
2276 +void MacroApplyHook(const WindowInfo* document, const char* hook, int argc,
2277 + DataValue* argv, DataValue* resultDV)
2279 + Symbol* hookSymbol;
2281 + hookSymbol = LookupSymbol(hook);
2282 + if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
2283 + Program* hookProg = hookSymbol->value.val.prog;
2284 + RestartData* restartData;
2285 + DataValue dummyResultDV; /* Passed to ExecuteMacro() if no result requested */
2288 +// char statusT[1024];
2291 + status = ExecuteMacro((WindowInfo*) document, hookProg, argc, argv,
2292 + (NULL == resultDV) ? &dummyResultDV : resultDV, &restartData,
2296 +// case 0: strncpy(statusT, "MACRO_TIME_LIMIT", 1024); break;
2297 +// case 1: strncpy(statusT, "MACRO_PREEMPT", 1024); break;
2298 +// case 2: strncpy(statusT, "MACRO_DONE", 1024); break;
2299 +// case 3: strncpy(statusT, "MACRO_ERROR", 1024); break;
2300 +// default: strncpy(statusT, "UNKNOWN_ERROR", 1024);
2302 +// fprintf(stderr, "\tstatus: %s\n", statusT);
2303 + while (MACRO_TIME_LIMIT == status) {
2304 + status = ContinueMacro(restartData,
2305 + (NULL == resultDV) ? &dummyResultDV : resultDV, &errMsg);
2308 + if (MACRO_PREEMPT == status || MACRO_ERROR == status) {
2309 + fprintf(stderr, "nedit: \"%s\" error: %s\n", hook, (MACRO_ERROR == status) ? errMsg : "No dialogs");
2311 + /* Macro is done here */
2315 diff --quilt old/source/macro.h new/source/macro.h
2316 --- old/source/macro.h
2317 +++ new/source/macro.h
2318 @@ -71,7 +71,10 @@ int ReadMacroString(WindowInfo *window,
2319 int CheckMacroString(Widget dialogParent, char *string, const char *errIn,
2321 char *GetReplayMacro(void);
2322 void ReadMacroInitFile(WindowInfo *window);
2323 void ReturnShellCommandOutput(WindowInfo *window, const char *outText, int status);
2324 +struct DataValueTag;
2325 +void MacroApplyHook(const WindowInfo* document, const char *hook, int argc,
2326 + struct DataValueTag* argv, struct DataValueTag* resultDV);
2328 #endif /* NEDIT_MACRO_H_INCLUDED */
2329 diff --quilt old/source/menu.c new/source/menu.c
2330 --- old/source/menu.c
2331 +++ new/source/menu.c
2332 @@ -50,10 +50,11 @@ static const char CVSID[] = "$Id: menu.c
2333 #include "highlight.h"
2334 #include "highlightData.h"
2335 #include "interpret.h"
2336 #include "smartIndent.h"
2337 #include "windowTitle.h"
2338 +#include "regularExp.h"
2339 #include "../util/getfiles.h"
2340 #include "../util/DialogF.h"
2341 #include "../util/misc.h"
2342 #include "../util/fileUtils.h"
2343 #include "../util/utils.h"
2344 @@ -177,10 +178,13 @@ static void bgMenuDefCB(Widget w, Window
2345 static void searchDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
2346 static void beepOnSearchWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
2347 static void keepSearchDlogsDefCB(Widget w, WindowInfo *window,
2349 static void searchWrapsDefCB(Widget w, WindowInfo *window, caddr_t callData);
2350 +static void showHiddenFilesCB(Widget w, WindowInfo* window, caddr_t callData);
2351 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData);
2352 static void sortOpenPrevDefCB(Widget w, WindowInfo *window, caddr_t callData);
2353 static void reposDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
2354 static void autoScrollDefCB(Widget w, WindowInfo *window, caddr_t callData);
2355 static void modWarnDefCB(Widget w, WindowInfo *window, caddr_t callData);
2356 @@ -189,10 +193,12 @@ static void exitWarnDefCB(Widget w, Wind
2357 static void searchLiteralCB(Widget w, WindowInfo *window, caddr_t callData);
2358 static void searchCaseSenseCB(Widget w, WindowInfo *window, caddr_t callData);
2359 static void searchLiteralWordCB(Widget w, WindowInfo *window, caddr_t callData);
2360 static void searchCaseSenseWordCB(Widget w, WindowInfo *window, caddr_t callData);
2361 static void searchRegexNoCaseCB(Widget w, WindowInfo *window, caddr_t callData);
2362 +static void searchRegexSmartCaseCB(Widget toggleButton, WindowInfo* windowInfo,
2363 + caddr_t callData);
2364 static void searchRegexCB(Widget w, WindowInfo *window, caddr_t callData);
2365 #ifdef REPLACE_SCOPE
2366 static void replaceScopeWindowCB(Widget w, WindowInfo *window, caddr_t callData);
2367 static void replaceScopeSelectionCB(Widget w, WindowInfo *window, caddr_t callData);
2368 static void replaceScopeSmartCB(Widget w, WindowInfo *window, caddr_t callData);
2369 @@ -392,10 +398,12 @@ static void setAutoIndentAP(Widget w, XE
2371 static void setWrapTextAP(Widget w, XEvent *event, String *args,
2373 static void setWrapMarginAP(Widget w, XEvent *event, String *args,
2375 +static void setShowWrapMarginAP(Widget w, XEvent *event, String *args,
2377 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
2379 static void setMakeBackupCopyAP(Widget w, XEvent *event, String *args,
2381 static void setIncrementalBackupAP(Widget w, XEvent *event, String *args,
2382 @@ -406,10 +414,12 @@ static void setMatchSyntaxBasedAP(Widget
2384 static void setOvertypeModeAP(Widget w, XEvent *event, String *args,
2386 static void setLockedAP(Widget w, XEvent *event, String *args,
2388 +static void setTransientAP(Widget text, XEvent* event, String* args,
2390 static void setUseTabsAP(Widget w, XEvent *event, String *args,
2392 static void setEmTabDistAP(Widget w, XEvent *event, String *args,
2394 static void setTabDistAP(Widget w, XEvent *event, String *args,
2395 @@ -566,19 +576,21 @@ static XtActionsRec Actions[] = {
2396 {"set_incremental_search_line", setIncrementalSearchLineAP},
2397 {"set_show_line_numbers", setShowLineNumbersAP},
2398 {"set_auto_indent", setAutoIndentAP},
2399 {"set_wrap_text", setWrapTextAP},
2400 {"set_wrap_margin", setWrapMarginAP},
2401 + {"set_show_wrap_margin", setShowWrapMarginAP},
2402 {"set_highlight_syntax", setHighlightSyntaxAP},
2404 {"set_make_backup_copy", setMakeBackupCopyAP},
2406 {"set_incremental_backup", setIncrementalBackupAP},
2407 {"set_show_matching", setShowMatchingAP},
2408 {"set_match_syntax_based", setMatchSyntaxBasedAP},
2409 {"set_overtype_mode", setOvertypeModeAP},
2410 {"set_locked", setLockedAP},
2411 + {"set_transient", setTransientAP},
2412 {"set_tab_dist", setTabDistAP},
2413 {"set_em_tab_dist", setEmTabDistAP},
2414 {"set_use_tabs", setUseTabsAP},
2415 {"set_fonts", setFontsAP},
2416 {"set_language_mode", setLanguageModeAP}
2417 @@ -813,10 +825,13 @@ Widget CreateMenuBar(Widget parent, Wind
2418 XtSetSensitive(window->showTipItem, (TagsFileList != NULL ||
2419 TipsFileList != NULL) );
2422 ** Preferences menu, Default Settings sub menu
2424 + ** Mnemonics: L, A, W, C, T, F, u, d, g, H, S, i, N, e, B, M, o, P, r, z
2425 + ** A, B, C, d, e, F, g, H, i, L, M, N, o, P, r, S, T, u, W, z
2427 menuPane = createMenu(menuBar, "preferencesMenu", "Preferences", 0, NULL,
2429 subPane = createMenu(menuPane, "defaultSettings", "Default Settings", 'D',
2431 @@ -926,12 +941,17 @@ Widget CreateMenuBar(Widget parent, Wind
2432 GetPrefSearch() == SEARCH_CASE_SENSE_WORD, FULL);
2433 window->searchRegexDefItem = createMenuToggle(subSubSubPane,
2434 "regularExpression", "Regular Expression", 'R', searchRegexCB,
2435 window, GetPrefSearch() == SEARCH_REGEX, FULL);
2436 window->searchRegexNoCaseDefItem = createMenuToggle(subSubSubPane,
2437 - "regularExpressionNoCase", "Regular Expression, Case Insensitive", 'I', searchRegexNoCaseCB, window,
2438 - GetPrefSearch() == SEARCH_REGEX_NOCASE, FULL);
2439 + "regularExpressionNoCase", "Regular Expression, Case Insensitive",
2440 + 'I', searchRegexNoCaseCB, window,
2441 + GetPrefSearch() == SEARCH_REGEX_NOCASE, FULL);
2442 + window->searchRegexSmartCaseDefItem = createMenuToggle(subSubSubPane,
2443 + "regularExpressionSmartCase", "Regular Expression, Smart Case",
2444 + 'S', searchRegexSmartCaseCB, window,
2445 + GetPrefSearch() == SEARCH_REGEX_SMARTCASE, FULL);
2446 #ifdef REPLACE_SCOPE
2447 subSubSubPane = createMenu(subSubPane, "defaultReplaceScope",
2448 "Default Replace Scope", 'R', NULL, FULL);
2449 XtVaSetValues(subSubSubPane, XmNradioBehavior, True, NULL);
2450 window->replScopeWinDefItem = createMenuToggle(subSubSubPane, "window",
2451 @@ -1015,10 +1035,20 @@ Widget CreateMenuBar(Widget parent, Wind
2452 createMenuSeparator(subSubPane, "sep", SHORT);
2453 window->matchSyntaxBasedDefItem = createMenuToggle(subSubPane,
2454 "matchSyntax", "Syntax Based", 'S', matchSyntaxBasedDefCB, window,
2455 GetPrefMatchSyntaxBased(), SHORT);
2457 + /* Show Hidden Files */
2458 + window->showHiddenFilesItem = createMenuToggle(subPane,
2459 + "showHiddenFilesItem", "Show hidden Files", 'y', showHiddenFilesCB,
2460 + NULL, GetPrefShowHiddenFiles(), FULL);
2462 /* Append LF at end of files on save */
2463 window->appendLFItem = createMenuToggle(subPane, "appendLFItem",
2464 "Terminate with Line Break on Save", 'v', appendLFCB, NULL,
2465 GetPrefAppendLF(), FULL);
2467 @@ -1141,10 +1171,12 @@ Widget CreateMenuBar(Widget parent, Wind
2468 createMenuSeparator(menuPane, "sep2", SHORT);
2469 window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O',
2470 doActionCB, "set_overtype_mode", False, SHORT);
2471 window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only",
2472 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL);
2473 + window->transientItem = createMenuToggle(menuPane, "transient", "Transient",
2474 + 'r', doActionCB, "set_transient", window->transient, FULL);
2479 ** Create the Shell menu
2480 @@ -2175,10 +2208,41 @@ static void searchWrapsDefCB(Widget w, W
2481 if (IsTopDocument(win))
2482 XmToggleButtonSetState(win->searchWrapsDefItem, state, False);
2486 +static void showHiddenFilesCB(Widget widget, WindowInfo* unused,
2489 + WindowInfo *window;
2490 + Boolean state = XmToggleButtonGetState(widget);
2492 + SetPrefShowHiddenFiles(state);
2493 + for (window = WindowList; window != NULL; window = window->next) {
2494 + XmToggleButtonSetState(window->showHiddenFilesItem, state, False);
2498 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData)
2501 int state = XmToggleButtonGetState(w);
2503 @@ -2537,10 +2601,39 @@ static void searchRegexNoCaseCB(Widget w
2504 XmToggleButtonSetState(win->searchRegexNoCaseDefItem, True, False);
2509 +static void searchRegexSmartCaseCB(Widget toggleButton, WindowInfo* window,
2512 + WindowInfo* windowInfo;
2514 + /* Set the preference and make the other windows' menus agree */
2515 + if (XmToggleButtonGetState(toggleButton)) {
2516 + SetPrefSearch(SEARCH_REGEX_SMARTCASE);
2517 + for (windowInfo = WindowList;
2518 + windowInfo != NULL;
2519 + windowInfo = windowInfo->next) {
2520 + XmToggleButtonSetState(windowInfo->searchLiteralDefItem,
2522 + XmToggleButtonSetState(windowInfo->searchCaseSenseDefItem,
2524 + XmToggleButtonSetState(windowInfo->searchLiteralWordDefItem,
2526 + XmToggleButtonSetState(windowInfo->searchCaseSenseWordDefItem,
2528 + XmToggleButtonSetState(windowInfo->searchRegexDefItem,
2530 + XmToggleButtonSetState(windowInfo->searchRegexNoCaseDefItem,
2532 + XmToggleButtonSetState(windowInfo->searchRegexSmartCaseDefItem,
2538 #ifdef REPLACE_SCOPE
2539 static void replaceScopeWindowCB(Widget w, WindowInfo *window, caddr_t callData)
2543 @@ -2714,51 +2807,59 @@ static void unloadTipsFileMenuCB(Widget
2545 static void newAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2547 WindowInfo *window = WidgetToWindow(w);
2548 int openInTab = GetPrefOpenInTab();
2549 + Boolean transient = False;
2551 + /* Look for arguments managing the type of window requested and whether
2552 + or not the user wants to have a transient window. */
2554 - if (strcmp(args[0], "prefs") == 0) {
2555 + if (0 == strcmp(args[0], "prefs")) {
2556 /* accept default */;
2558 - else if (strcmp(args[0], "tab") == 0) {
2559 + } else if (0 == strcmp(args[0], "tab")) {
2562 - else if (strcmp(args[0], "window") == 0) {
2563 + } else if (0 == strcmp(args[0], "window")) {
2566 - else if (strcmp(args[0], "opposite") == 0) {
2567 + } else if (0 == strcmp(args[0], "opposite")) {
2568 openInTab = !openInTab;
2571 + } else if (0 == strcmp(args[0], "transient")) {
2574 fprintf(stderr, "nedit: Unknown argument to action procedure \"new\": %s\n", args[0]);
2578 - EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path);
2580 + /* Catch transient if it comes after a window type argument */
2581 + if (2 == *nArgs && (0 == strcmp(args[1], "transient"))) {
2585 + EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path,
2591 -** These are just here because our techniques make it hard to bind a menu item
2592 -** to an action procedure that takes arguments. The user doesn't need to know
2593 -** about them -- they can use new( "opposite" ) or new( "tab" ).
2594 +** newOppositeAP() and newTabAP() are just here because our techniques make
2595 +** it hard to bind a menu item to an action procedure that takes arguments.
2596 +** The user doesn't need to know about them -- they can use new("opposite")
2599 static void newOppositeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2601 WindowInfo *window = WidgetToWindow(w);
2603 EditNewFile(GetPrefOpenInTab()? NULL : window, NULL, False, NULL,
2605 + window->path, False);
2608 static void newTabAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2610 WindowInfo *window = WidgetToWindow(w);
2612 - EditNewFile(window, NULL, False, NULL, window->path);
2613 + EditNewFile(window, NULL, False, NULL, window->path, False);
2617 static void openDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2619 @@ -2781,21 +2882,31 @@ static void openDialogAP(Widget w, XEven
2621 static void openAP(Widget w, XEvent *event, String *args, Cardinal *nArgs)
2623 WindowInfo *window = WidgetToWindow(w);
2624 char filename[MAXPATHLEN], pathname[MAXPATHLEN];
2625 + DataValue* fileNameArg = (DataValue*) XtMalloc(sizeof(DataValue));
2626 + DataValue* resultDV = (DataValue*) XtMalloc(sizeof(DataValue));
2629 fprintf(stderr, "nedit: open action requires file argument\n");
2632 - if (0 != ParseFilename(args[0], filename, pathname)
2634 + fileNameArg->tag = STRING_TAG;
2635 + AllocNStringNCpy(&fileNameArg->val.str, args[0], MAXPATHLEN);
2636 + MacroApplyHook(window, "file_name_hook", 1, fileNameArg, resultDV);
2637 + XtFree((char*) fileNameArg);
2639 + if (0 != ParseFilename(resultDV->val.str.rep, filename, pathname)
2640 || strlen(filename) + strlen(pathname) > MAXPATHLEN - 1) {
2641 fprintf(stderr, "nedit: invalid file name for open action: %s\n",
2645 + XtFree((char*) resultDV);
2647 EditExistingFile(window, filename, pathname, 0, NULL, False,
2648 NULL, GetPrefOpenInTab(), False);
2652 @@ -4085,10 +4196,23 @@ static void setWrapMarginAP(Widget w, XE
2654 fprintf(stderr, "nedit: set_wrap_margin requires argument\n");
2658 +static void setShowWrapMarginAP(Widget w, XEvent *event, String *args,
2661 + WindowInfo *window = WidgetToWindow(w);
2662 + int showWrapMargin = 0;
2665 + if (sscanf(args[0], "%d", &showWrapMargin) == 1) {
2666 + SetShowWrapMargin(window, showWrapMargin);
2671 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
2674 WindowInfo *window = WidgetToWindow(w);
2676 @@ -4209,10 +4333,28 @@ static void setLockedAP(Widget w, XEvent
2677 XmToggleButtonSetState(window->readOnlyItem, IS_ANY_LOCKED(window->lockReasons), False);
2678 UpdateWindowTitle(window);
2679 UpdateWindowReadOnly(window);
2683 +** Action procedure for setting or toggling the transient flag.
2685 +static void setTransientAP(Widget text, XEvent* event, String* args,
2688 + WindowInfo* window = WidgetToWindow(text);
2691 + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args,
2692 + window->transient, "set_transient");
2694 + window->transient = newState;
2695 + if (IsTopDocument(window)) {
2696 + XmToggleButtonSetState(window->transientItem, window->transient, False);
2700 static void setTabDistAP(Widget w, XEvent *event, String *args,
2703 WindowInfo *window = WidgetToWindow(w);
2705 @@ -4511,17 +4653,40 @@ static void invalidatePrevOpenMenus(void
2707 void AddToPrevOpenMenu(const char *filename)
2711 + char *fileMask, *compileMsg;
2712 + regexp *compiledRE;
2715 /* If the Open Previous command is disabled, just return */
2716 if (GetPrefMaxPrevOpenFiles() < 1) {
2720 + /* If the name is to be omitted, return */
2721 + if ((fileMask = GetPrevOpenFilesMask()) && *fileMask)
2723 + compiledRE = CompileRE(fileMask, &compileMsg, REDFLT_STANDARD);
2724 + if (compiledRE == NULL)
2726 + fprintf(stderr, "nedit: %s\n", compileMsg);
2729 + if (ExecRE(compiledRE, filename, NULL, FALSE, '\0', '\0', NULL,
2732 + free((char *)compiledRE);
2736 + free((char *)compiledRE);
2741 /* Refresh list of previously opened files to avoid Big Race Condition,
2742 where two sessions overwrite each other's changes in NEdit's
2744 Of course there is still Little Race Condition, which occurs if a
2745 Session A reads the list, then Session B reads the list and writes
2746 @@ -4864,10 +5029,12 @@ static int cmpStrPtr(const void *strA, c
2747 void WriteNEditDB(void)
2749 const char* fullName = GetRCFileName(NEDIT_HISTORY);
2752 + char *fileMask, *compileMsg;
2753 + regexp *compiledRE=NULL;
2754 static char fileHeader[] =
2755 "# File name database for NEdit Open Previous command\n";
2757 if (fullName == NULL) {
2758 /* GetRCFileName() might return NULL if an error occurs during
2759 @@ -4900,23 +5067,48 @@ void WriteNEditDB(void)
2765 + /* set up removal of any files matching prevOpenFilesMask */
2766 + if ((fileMask = GetPrevOpenFilesMask()) && *fileMask)
2768 + compiledRE = CompileRE(fileMask, &compileMsg, REDFLT_STANDARD);
2769 + if (compiledRE == NULL)
2771 + fprintf(stderr, "%s\n", compileMsg);
2775 /* write the file header text to the file */
2776 fprintf(fp, "%s", fileHeader);
2778 /* Write the list of file names */
2779 - for (i = 0; i < NPrevOpen; ++i) {
2780 - size_t lineLen = strlen(PrevOpen[i]);
2781 + for (i = 0; i < NPrevOpen; i++)
2783 + /* omitting any files matching prevOpenFilesMask */
2784 + if (NULL == compiledRE
2785 + || 0 == ExecRE(compiledRE, PrevOpen[i], NULL, FALSE, '\0', '\0',
2786 + NULL, NULL, NULL))
2788 + size_t lineLen = strlen(PrevOpen[i]);
2790 - if (lineLen > 0 && PrevOpen[i][0] != '#' &&
2791 - strcspn(PrevOpen[i], neditDBBadFilenameChars) == lineLen) {
2792 - fprintf(fp, "%s\n", PrevOpen[i]);
2793 + /* omitting any files with invalid filenames */
2794 + if (lineLen > 0 && '#' != PrevOpen[i][0]
2795 + && strcspn(PrevOpen[i], neditDBBadFilenameChars) == lineLen)
2797 + fprintf(fp, "%s\n", PrevOpen[i]);
2803 + if (compiledRE != NULL) {
2804 + free((char *)compiledRE);
2807 + /* Close the file */
2812 ** Read database of file names for 'Open Previous' submenu.
2813 diff --quilt old/source/nedit.c new/source/nedit.c
2814 --- old/source/nedit.c
2815 +++ new/source/nedit.c
2816 @@ -352,15 +352,21 @@ static char *fallbackResources[] = {
2817 "*windowsMenu.splitPane.acceleratorText: Ctrl+2",
2818 "*windowsMenu.closePane.accelerator: Ctrl<Key>1",
2819 "*windowsMenu.closePane.acceleratorText: Ctrl+1",
2820 "*helpMenu.mnemonic: H",
2821 "nedit.help.helpForm.sw.helpText*baseTranslations: #override\
2822 -<Key>Tab:help-focus-buttons()\\n\
2823 +<Key>space: scroll_down(1, \"pages\")\\n\
2824 +~Alt~Shift~Ctrl~Meta<KeyPress>osfUp: scroll_up(1)\\n\
2825 +~Alt~Shift~Ctrl~Meta<KeyPress>osfDown: scroll_down(1)\\n\
2826 +~Alt ~Shift ~Ctrl ~Meta<KeyPress>osfPageUp: scroll_up(1, \"pages\")\\n\
2827 +~Alt ~Shift ~Ctrl ~Meta<KeyPress>osfPageDown: scroll_down(1, \"pages\")\\n\
2828 +~Alt~Shift~Ctrl~Meta<KeyPress>osfLeft: help-button-action(\"prevTopic\")\\n\
2829 +~Alt~Shift~Ctrl~Meta<KeyPress>osfRight: help-button-action(\"nextTopic\")\\n\
2830 <Key>Return:help-button-action(\"close\")\\n\
2831 -Ctrl<Key>F:help-button-action(\"find\")\\n\
2832 -Ctrl<Key>G:help-button-action(\"findAgain\")\\n\
2833 <KeyPress>osfCancel:help-button-action(\"close\")\\n\
2834 +Ctrl<Key>f:help-button-action(\"find\")\\n\
2835 +Ctrl<Key>g:help-button-action(\"findAgain\")\\n\
2836 ~Meta~Ctrl~Shift<Btn1Down>:\
2837 grab-focus() help-hyperlink()\\n\
2838 ~Meta~Ctrl~Shift<Btn1Up>:\
2839 help-hyperlink(\"current\", \"process-cancel\", \"extend-end\")\\n\
2840 ~Meta~Ctrl~Shift<Btn2Down>:\
2841 @@ -489,11 +495,11 @@ int main(int argc, char **argv)
2843 /* Initialize global symbols and subroutines used in the macro language */
2845 RegisterMacroSubroutines();
2847 - /* Store preferences from the command line and .nedit file,
2848 + /* Store preferences from the command line and the nedit.rc file,
2849 and set the appropriate preferences */
2850 RestoreNEditPrefs(prefDB, XtDatabase(TheDisplay));
2852 /* Intercept syntactically invalid virtual key bindings BEFORE we
2853 create any shells. */
2854 @@ -775,11 +781,11 @@ int main(int argc, char **argv)
2858 /* If no file to edit was specified, open a window to edit "Untitled" */
2859 if (!fileSpecified) {
2860 - EditNewFile(NULL, geometry, iconic, langMode, NULL);
2861 + EditNewFile(NULL, geometry, iconic, langMode, NULL, False);
2862 ReadMacroInitFile(WindowList);
2864 if (toDoCommand != NULL)
2865 DoMacro(WindowList, toDoCommand, "-do macro");
2867 diff --quilt old/source/nedit.h new/source/nedit.h
2868 --- old/source/nedit.h
2869 +++ new/source/nedit.h
2871 #define NEDIT_DEFAULT_SEL_BG "rgb:cc/cc/cc"
2872 #define NEDIT_DEFAULT_HI_FG "white" /* These are colors for flashing */
2873 #define NEDIT_DEFAULT_HI_BG "red" /* matching parens. */
2874 #define NEDIT_DEFAULT_LINENO_FG "black"
2875 #define NEDIT_DEFAULT_CURSOR_FG "black"
2876 +#define NEDIT_DEFAULT_WRAPMARGIN_FG "black"
2877 #define NEDIT_DEFAULT_HELP_FG "black"
2878 #define NEDIT_DEFAULT_HELP_BG "rgb:cc/cc/cc"
2880 /* Tuning parameters */
2881 #define SEARCHMAX 5119 /* Maximum length of search/replace strings */
2882 #define MAX_SEARCH_HISTORY 100 /* Maximum length of search string history */
2883 #define MAX_PANES 6 /* Max # of ADDITIONAL text editing panes
2884 @@ -103,10 +104,12 @@
2885 enum indentStyle {NO_AUTO_INDENT, AUTO_INDENT, SMART_INDENT};
2886 enum wrapStyle {NO_WRAP, NEWLINE_WRAP, CONTINUOUS_WRAP};
2887 enum showMatchingStyle {NO_FLASH, FLASH_DELIMIT, FLASH_RANGE};
2888 enum virtKeyOverride { VIRT_KEY_OVERRIDE_NEVER, VIRT_KEY_OVERRIDE_AUTO,
2889 VIRT_KEY_OVERRIDE_ALWAYS };
2890 +enum showWrapMarginEnums {SHOW_WRAP_MARGIN_NEVER, SHOW_WRAP_MARGIN_ALWAYS,
2891 + SHOW_WRAP_MARGIN_ON_WRAP};
2893 /* This enum must be kept in parallel to the array TruncSubstitutionModes[]
2895 enum truncSubstitution {TRUNCSUBST_SILENT, TRUNCSUBST_FAIL, TRUNCSUBST_WARN, TRUNCSUBST_IGNORE};
2897 @@ -191,10 +194,12 @@ enum colorTypes {
2903 + WRAPMARGIN_FG_COLOR,
2907 /* cache user menus: manage mode of user menu list element */
2909 @@ -325,10 +330,11 @@ typedef struct _WindowInfo {
2910 Widget replaceMultiFileList;
2911 Widget replaceMultiFilePathBtn;
2912 Widget fontDialog; /* NULL, unless font dialog is up */
2913 Widget colorDialog; /* NULL, unless color dialog is up */
2914 Widget readOnlyItem; /* menu bar settable widgets... */
2915 + Widget transientItem;
2916 Widget autoSaveItem;
2917 Widget saveLastItem;
2919 Widget newOppositeItem;
2921 @@ -393,10 +399,12 @@ typedef struct _WindowInfo {
2922 Widget backlightCharsDefItem;
2923 Widget searchDlogsDefItem;
2924 Widget beepOnSearchWrapDefItem;
2925 Widget keepSearchDlogsDefItem;
2926 Widget searchWrapsDefItem;
2927 + Widget showHiddenFilesItem;
2928 Widget appendLFItem;
2929 Widget sortOpenPrevDefItem;
2930 Widget allTagsDefItem;
2931 Widget smartTagsDefItem;
2932 Widget reposDlogsDefItem;
2933 @@ -417,10 +425,11 @@ typedef struct _WindowInfo {
2934 Widget searchLiteralDefItem;
2935 Widget searchCaseSenseDefItem;
2936 Widget searchLiteralWordDefItem;
2937 Widget searchCaseSenseWordDefItem;
2938 Widget searchRegexNoCaseDefItem;
2939 + Widget searchRegexSmartCaseDefItem;
2940 Widget searchRegexDefItem;
2941 #ifdef REPLACE_SCOPE
2942 Widget replScopeWinDefItem;
2943 Widget replScopeSelDefItem;
2944 Widget replScopeSmartDefItem;
2945 @@ -495,10 +504,12 @@ typedef struct _WindowInfo {
2946 Boolean autoSave; /* is autosave turned on? */
2947 Boolean saveOldVersion; /* keep old version in filename.bck */
2948 char indentStyle; /* whether/how to auto indent */
2949 char wrapMode; /* line wrap style: NO_WRAP,
2950 NEWLINE_WRAP or CONTINUOUS_WRAP */
2951 + int showWrapMargin; /* show wrap margin style: NEVER,
2952 + ALWAYS, ON-WRAP as enums */
2953 Boolean overstrike; /* is overstrike mode turned on ? */
2954 char showMatchingStyle; /* How to show matching parens:
2955 NO_FLASH, FLASH_DELIMIT, or
2957 char matchSyntaxBased; /* Use syntax info to show matching */
2958 @@ -555,10 +566,11 @@ typedef struct _WindowInfo {
2960 UserMenuCache *userMenuCache; /* cache user menus: */
2961 UserBGMenuCache userBGMenuCache; /* shell & macro menu are shared over all
2962 "tabbed" documents, while each document
2963 has its own background menu. */
2964 + Boolean transient;
2967 extern WindowInfo *WindowList;
2968 extern Display *TheDisplay;
2969 extern Widget TheAppShell;
2970 diff --quilt old/source/preferences.c new/source/preferences.c
2971 --- old/source/preferences.c
2972 +++ new/source/preferences.c
2973 @@ -115,13 +115,13 @@ enum fontStatus {GOOD_FONT, BAD_PRIMARY,
2974 ** The order of the elements in this array must be exactly the same
2975 ** as the order of the corresponding integers of the enum SearchType
2976 ** defined in search.h (!!)
2978 static char *SearchMethodStrings[] = {
2979 - "Literal", "CaseSense", "RegExp",
2980 - "LiteralWord", "CaseSenseWord", "RegExpNoCase",
2982 + "Literal", "CaseSense", "RegExp",
2983 + "LiteralWord", "CaseSenseWord", "RegExpNoCase", "RegExSmartCase",
2987 #ifdef REPLACE_SCOPE
2988 /* enumerated default scope for replace dialog if a selection exists when
2989 ** the dialog is popped up.
2990 @@ -138,10 +138,13 @@ static char *AutoWrapTypes[N_WRAP_STYLES
2991 static char *AutoIndentTypes[N_INDENT_STYLES+3] = {"None", "Auto",
2992 "Smart", "True", "False", NULL};
2993 #define N_VIRTKEY_OVERRIDE_MODES 3
2994 static char *VirtKeyOverrideModes[N_VIRTKEY_OVERRIDE_MODES+1] = { "Never",
2995 "Auto", "Always", NULL};
2996 +#define N_SHOW_WRAP_MARGIN_STYLES 3
2997 +static char *ShowWrapMarginStrings[N_SHOW_WRAP_MARGIN_STYLES+1] = { "Never",
2998 + "Always", "When Wrap is Enabled", NULL};
3000 #define N_SHOW_MATCHING_STYLES 3
3001 /* For backward compatibility, "False" and "True" are still accepted.
3002 They are internally converted to "Off" and "Delimiter" respectively.
3003 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
3004 @@ -233,18 +236,23 @@ typedef struct {
3005 Widget hiliteBgErrW;
3007 Widget lineNoFgErrW;
3009 Widget cursorFgErrW;
3010 + Widget wrapMarginFgW;
3011 + Widget wrapMarginFgErrW;
3015 /* Repository for simple preferences settings */
3016 static struct prefData {
3017 int openInTab; /* open files in new tabs */
3018 int wrapStyle; /* what kind of wrapping to do */
3019 int wrapMargin; /* 0=wrap at window width, other=wrap margin */
3020 + int showWrapMargin; /* whether to draw line at wrap margin */
3021 int autoIndent; /* style for auto-indent */
3022 int autoSave; /* whether automatic backup feature is on */
3023 int saveOldVersion; /* whether to preserve a copy of last version */
3024 int searchDlogs; /* whether to show explanatory search dialogs */
3025 int searchWrapBeep; /* 1=beep when search restarts at begin/end */
3026 @@ -293,14 +301,17 @@ static struct prefData {
3027 int sortTabs; /* sort tabs alphabetically */
3028 int repositionDialogs; /* w. to reposition dialogs under the pointer */
3029 int autoScroll; /* w. to autoscroll near top/bottom of screen */
3030 int autoScrollVPadding; /* how close to get before autoscrolling */
3031 int sortOpenPrevMenu; /* whether to sort the "Open Previous" menu */
3032 + int showHiddenFiles; /* whether to show hidden files in the FSBs */
3033 int appendLF; /* Whether to append LF at the end of each file */
3034 int mapDelete; /* whether to map delete to backspace */
3035 int stdOpenDialog; /* w. to retain redundant text field in Open */
3036 char tagFile[MAXPATHLEN]; /* name of tags file to look for at startup */
3037 + char prevOpenFilesMask[MAXPATHLEN]; /* regex to omit from Open Previous menu */
3038 int maxPrevOpenFiles; /* limit to size of Open Previous menu */
3039 int typingHidesPointer; /* hide mouse pointer when typing */
3040 char delimiters[MAX_WORD_DELIMITERS]; /* punctuation characters */
3041 char shell[MAXPATHLEN + 1]; /* shell to use for executing commands */
3042 char geometry[MAX_GEOM_STRING_LEN]; /* per-application geometry string,
3043 @@ -319,10 +330,11 @@ static struct prefData {
3044 char helpLinkColor[MAX_COLOR_LEN]; /* Color for hyperlinks in the help system */
3045 char colorNames[NUM_COLORS][MAX_COLOR_LEN];
3046 char tooltipBgColor[MAX_COLOR_LEN];
3047 int undoModifiesSelection;
3049 + Boolean showScrolltip;
3050 Boolean honorSymlinks;
3051 int truncSubstitution;
3052 Boolean forceOSConversion;
3055 @@ -845,10 +857,12 @@ static PrefDescripRec PrefDescrip[] = {
3056 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
3057 {"autoWrap", "AutoWrap", PREF_ENUM, "Continuous",
3058 &PrefData.wrapStyle, AutoWrapTypes, True},
3059 {"wrapMargin", "WrapMargin", PREF_INT, "0",
3060 &PrefData.wrapMargin, NULL, True},
3061 + {"showWrapMargin", "ShowWrapMargin", PREF_ENUM, "Never",
3062 + &PrefData.showWrapMargin, ShowWrapMarginStrings, True},
3063 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
3064 &PrefData.autoIndent, AutoIndentTypes, True},
3065 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
3066 &PrefData.autoSave, NULL, True},
3067 {"openInTab", "OpenInTab", PREF_BOOLEAN, "True",
3068 @@ -882,10 +896,12 @@ static PrefDescripRec PrefDescrip[] = {
3069 &PrefData.repositionDialogs, NULL, True},
3071 {"repositionDialogs", "RepositionDialogs", PREF_BOOLEAN, "True",
3072 &PrefData.repositionDialogs, NULL, True},
3074 + {"showHiddenFiles", "ShowHiddenFiles", PREF_BOOLEAN, "True",
3075 + &PrefData.showHiddenFiles, NULL, True},
3076 {"autoScroll", "AutoScroll", PREF_BOOLEAN, "False",
3077 &PrefData.autoScroll, NULL, True},
3078 {"autoScrollVPadding", "AutoScrollVPadding", PREF_INT, "4",
3079 &PrefData.autoScrollVPadding, NULL, False},
3080 {"appendLF", "AppendLF", PREF_BOOLEAN, "True",
3081 @@ -1020,13 +1036,20 @@ static PrefDescripRec PrefDescrip[] = {
3082 PrefData.colorNames[LINENO_FG_COLOR],
3083 (void *)sizeof(PrefData.colorNames[LINENO_FG_COLOR]), True},
3084 {"cursorFgColor", "CursorFgColor", PREF_STRING, NEDIT_DEFAULT_CURSOR_FG,
3085 PrefData.colorNames[CURSOR_FG_COLOR],
3086 (void *)sizeof(PrefData.colorNames[CURSOR_FG_COLOR]), True},
3087 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
3088 PrefData.tooltipBgColor,
3089 (void *)sizeof(PrefData.tooltipBgColor), False},
3090 + {"wrapMarginForeground", "wrapMarginForeground", PREF_STRING,
3091 + NEDIT_DEFAULT_LINENO_FG, PrefData.colorNames[WRAPMARGIN_FG_COLOR],
3092 + (void *)sizeof(PrefData.colorNames[WRAPMARGIN_FG_COLOR]), True},
3093 {"shell", "Shell", PREF_STRING, "DEFAULT", PrefData.shell,
3094 (void*) sizeof(PrefData.shell), True},
3095 {"geometry", "Geometry", PREF_STRING, "",
3096 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
3097 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
3098 @@ -1038,10 +1061,13 @@ static PrefDescripRec PrefDescrip[] = {
3099 {"wordDelimiters", "WordDelimiters", PREF_STRING,
3100 ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?",
3101 PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False},
3102 {"serverName", "ServerName", PREF_STRING, "", PrefData.serverName,
3103 (void *)sizeof(PrefData.serverName), False},
3104 + {"prevOpenFilesMask", "PrevOpenFilesMask", PREF_STRING, "",
3105 + PrefData.prevOpenFilesMask,
3106 + (void*) sizeof(PrefData.prevOpenFilesMask), False},
3107 {"maxPrevOpenFiles", "MaxPrevOpenFiles", PREF_INT, "30",
3108 &PrefData.maxPrevOpenFiles, NULL, False},
3109 {"bgMenuButton", "BGMenuButton" , PREF_STRING,
3110 "~Shift~Ctrl~Meta~Alt<Btn3Down>", PrefData.bgMenuBtn,
3111 (void *)sizeof(PrefData.bgMenuBtn), False},
3112 @@ -1069,10 +1095,14 @@ static PrefDescripRec PrefDescrip[] = {
3113 "False", &PrefData.focusOnRaise, NULL, False},
3114 {"forceOSConversion", "ForceOSConversion", PREF_BOOLEAN, "True",
3115 &PrefData.forceOSConversion, NULL, False},
3116 {"truncSubstitution", "TruncSubstitution", PREF_ENUM, "Fail",
3117 &PrefData.truncSubstitution, TruncSubstitutionModes, False},
3118 + {"showScrolltip", "ShowScrolltip", PREF_BOOLEAN, "True",
3119 + &PrefData.showScrolltip, NULL, False},
3120 {"honorSymlinks", "HonorSymlinks", PREF_BOOLEAN, "True",
3121 &PrefData.honorSymlinks, NULL, False}
3124 static XrmOptionDescRec OpTable[] = {
3125 @@ -1124,11 +1154,13 @@ static WindowInfo *TabsDialogForWindow;
3126 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
3128 /* Module-global variables for Wrap Margin dialog */
3129 static int DoneWithWrapDialog;
3130 static WindowInfo *WrapDialogForWindow;
3131 -static Widget WrapText, WrapTextLabel, WrapWindowToggle;
3132 +static Widget WrapText, WrapTextLabel, WrapWindowToggle, ShowWrapMarginPulldown,
3133 + ShowWrapMarginPulldownItems[N_SHOW_WRAP_MARGIN_STYLES],
3134 + ShowWrapMarginOptMenu, ShowWrapMarginLabel;
3136 /* Module-global variables for shell selection dialog */
3137 static int DoneWithShellSelDialog = False;
3139 static void translatePrefFormats(int convertOld, int fileVer);
3140 @@ -1234,22 +1266,22 @@ static void updatePatternsTo5dot6(void);
3141 static void updateMacroCmdsTo5dot6(void);
3142 static void migrateColorResources(XrmDatabase prefDB, XrmDatabase appDB);
3143 static void spliceString(char **intoString, const char *insertString, const char *atExpr);
3144 static int regexFind(const char *inString, const char *expr);
3145 static int regexReplace(char **inString, const char *expr,
3146 - const char *replaceWith);
3147 + const char *replaceWith);
3148 +static void initPrefDefaultsFromResources(XrmDatabase prefDB, XrmDatabase appDB);
3149 static int caseFind(const char *inString, const char *expr);
3150 static int caseReplace(char **inString, const char *expr,
3151 const char *replaceWith, int replaceLen);
3152 static int stringReplace(char **inString, const char *expr,
3153 const char *replaceWith, int searchType,
3155 static int replaceMacroIfUnchanged(const char* oldText, const char* newStart,
3156 const char* newEnd);
3157 static const char* getDefaultShell(void);
3161 static int shortPrefToDefault(Widget parent, const char *settingName, int *setDefault);
3164 XrmDatabase CreateNEditPrefDB(int *argcInOut, char **argvInOut)
3165 @@ -1264,10 +1296,14 @@ void RestoreNEditPrefs(XrmDatabase prefD
3166 int major; /* The integral part of version number */
3167 int minor; /* fractional part of version number */
3168 int fileVer = 0; /* Both combined into an integer */
3171 + /* Default values of certain preferences are derived from Motif resources,
3172 + if these resources are set. */
3173 + initPrefDefaultsFromResources(prefDB, appDB);
3175 /* Load preferences */
3176 RestorePreferences(prefDB, appDB, APP_NAME,
3177 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
3179 /* If the preferences file was written by an older version of NEdit,
3180 @@ -1559,10 +1595,20 @@ void SetPrefWrapMargin(int margin)
3181 int GetPrefWrapMargin(void)
3183 return PrefData.wrapMargin;
3186 +void SetPrefShowWrapMargin(int state)
3188 + setIntPref(&PrefData.showWrapMargin, state);
3191 +int GetPrefShowWrapMargin(void)
3193 + return PrefData.showWrapMargin;
3196 void SetPrefSearch(int searchType)
3198 setIntPref(&PrefData.searchMethod, searchType);
3201 @@ -1930,10 +1976,20 @@ void SetPrefRepositionDialogs(int state)
3202 int GetPrefRepositionDialogs(void)
3204 return PrefData.repositionDialogs;
3207 +void SetPrefShowHiddenFiles(int state)
3209 + setIntPref(&PrefData.showHiddenFiles, state);
3212 +int GetPrefShowHiddenFiles(void)
3214 + return PrefData.showHiddenFiles;
3217 void SetPrefAutoScroll(int state)
3219 WindowInfo *w = WindowList;
3220 int margin = state ? PrefData.autoScrollVPadding : 0;
3222 @@ -2118,10 +2174,15 @@ char *GetPrefServerName(void)
3223 char *GetPrefBGMenuBtn(void)
3225 return PrefData.bgMenuBtn;
3228 +char *GetPrevOpenFilesMask(void)
3230 + return PrefData.prevOpenFilesMask;
3233 int GetPrefMaxPrevOpenFiles(void)
3235 return PrefData.maxPrevOpenFiles;
3238 @@ -2186,10 +2247,25 @@ int GetPrefOverrideVirtKeyBindings(void)
3239 int GetPrefTruncSubstitution(void)
3241 return PrefData.truncSubstitution;
3244 +Boolean GetPrefShowScrolltip(void)
3246 + return (Boolean) PrefData.showScrolltip;
3250 ** If preferences don't get saved, ask the user on exit whether to save
3252 void MarkPrefsChanged(void)
3254 @@ -2678,10 +2754,13 @@ void WrapMarginDialog(Widget parent, Win
3256 Widget form, selBox;
3260 + int showWrapMargin;
3264 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
3265 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
3266 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
3267 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
3268 @@ -2720,20 +2799,74 @@ void WrapMarginDialog(Widget parent, Win
3269 XmNrightWidget, WrapText,
3270 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
3271 XmNbottomWidget, WrapText, NULL);
3274 + ShowWrapMarginPulldown = CreatePulldownMenu(form, "ShowWrapMarginPulldown",
3276 + for(i=0; i<N_SHOW_WRAP_MARGIN_STYLES; i++) {
3277 + s1 = XmStringCreateSimple(ShowWrapMarginStrings[i]);
3278 + ShowWrapMarginPulldownItems[i] = XtVaCreateManagedWidget(
3279 + "ShowWrapMarginPulldown",
3280 + xmPushButtonWidgetClass, ShowWrapMarginPulldown,
3281 + XmNlabelString, s1,
3282 + XmNmarginHeight, 0,
3288 + XtSetArg(args[n], XmNspacing, 0); n++;
3289 + XtSetArg(args[n], XmNmarginWidth, 0); n++;
3290 + XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
3291 + XtSetArg(args[n], XmNtopWidget, WrapText); n++;
3292 + XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
3293 + XtSetArg(args[n], XmNsubMenuId, ShowWrapMarginPulldown); n++;
3294 + ShowWrapMarginOptMenu = XmCreateOptionMenu(form,
3295 + "ShowWrapMarginOptMenu", args, n);
3296 + XtManageChild(ShowWrapMarginOptMenu);
3298 + ShowWrapMarginLabel = XtVaCreateManagedWidget("ShowWrapMarginLabel",
3299 + xmLabelGadgetClass, form,
3300 + XmNlabelString, s1=XmStringCreateSimple("Show Wrap Margin"),
3302 + XmNuserData, XtParent(ShowWrapMarginOptMenu),
3303 + XmNalignment, XmALIGNMENT_END,
3304 + XmNtopAttachment, XmATTACH_WIDGET,
3305 + XmNtopWidget, WrapText,
3306 + XmNleftAttachment, XmATTACH_FORM,
3307 + XmNrightAttachment, XmATTACH_WIDGET,
3308 + XmNrightWidget, ShowWrapMarginOptMenu,
3309 + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
3310 + XmNbottomWidget, ShowWrapMarginOptMenu,
3314 /* Set default value */
3315 - if (forWindow == NULL)
3316 + if (forWindow == NULL) {
3317 margin = GetPrefWrapMargin();
3319 + showWrapMargin = GetPrefShowWrapMargin();
3321 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
3322 + showWrapMargin = forWindow->showWrapMargin;
3325 + if (showWrapMargin > N_SHOW_WRAP_MARGIN_STYLES || showWrapMargin < 0)
3327 + fprintf(stderr, "nedit: internal error: illegal value for showWrapMargin: %d\n", showWrapMargin);
3328 + showWrapMargin = SHOW_WRAP_MARGIN_NEVER;
3331 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
3332 + XtVaSetValues(ShowWrapMarginOptMenu, XmNmenuHistory,
3333 + ShowWrapMarginPulldownItems[showWrapMargin], NULL);
3335 SetIntText(WrapText, margin);
3336 XtSetSensitive(WrapText, margin!=0);
3337 XtSetSensitive(WrapTextLabel, margin!=0);
3338 + XtSetSensitive(ShowWrapMarginOptMenu, margin!=0);
3339 + XtSetSensitive(ShowWrapMarginLabel, margin!=0);
3341 /* Handle mnemonic selection of buttons and focus to dialog */
3342 AddDialogMnemonicHandler(form, FALSE);
3344 /* put up dialog and wait for user to press ok or cancel */
3345 @@ -2752,10 +2885,12 @@ void WrapMarginDialog(Widget parent, Win
3347 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
3349 int wrapAtWindow, margin, stat;
3350 WindowInfo *window = WrapDialogForWindow;
3351 + int showWrapMargin;
3352 + Widget showWrapMarginSelectedItem;
3354 /* get the values that the user entered and make sure they're ok */
3355 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
3358 @@ -2771,10 +2906,17 @@ static void wrapOKCB(Widget w, XtPointer
3364 + XtVaGetValues(ShowWrapMarginOptMenu, XmNmenuHistory,
3365 + &showWrapMarginSelectedItem, NULL);
3366 + XtVaGetValues(showWrapMarginSelectedItem, XmNuserData, &showWrapMargin, NULL);
3367 + if (showWrapMargin > N_SHOW_WRAP_MARGIN_STYLES || showWrapMargin < 0) {
3368 + showWrapMargin = SHOW_WRAP_MARGIN_NEVER;
3372 /* Ask the user about saving as a default preference */
3373 if (WrapDialogForWindow != NULL) {
3375 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
3376 @@ -2782,24 +2924,29 @@ static void wrapOKCB(Widget w, XtPointer
3377 DoneWithWrapDialog = True;
3381 SetPrefWrapMargin(margin);
3382 + SetPrefShowWrapMargin(showWrapMargin);
3383 SaveNEditPrefs(window->shell, GetPrefShortMenus());
3388 /* Set the value in either the requested window or default preferences */
3389 - if (WrapDialogForWindow == NULL)
3390 + if (WrapDialogForWindow == NULL) {
3391 SetPrefWrapMargin(margin);
3393 + SetPrefShowWrapMargin(showWrapMargin);
3397 sprintf(marginStr, "%d", margin);
3398 params[0] = marginStr;
3399 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
3400 + sprintf(marginStr, "%d", showWrapMargin);
3401 + params[0] = marginStr;
3402 + XtCallActionProc(window->textArea, "set_show_wrap_margin", NULL, params, 1);
3404 DoneWithWrapDialog = True;
3407 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
3408 @@ -2811,10 +2958,12 @@ static void wrapWindowCB(Widget w, XtPoi
3410 int wrapAtWindow = XmToggleButtonGetState(w);
3412 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
3413 XtSetSensitive(WrapText, !wrapAtWindow);
3414 + XtSetSensitive(ShowWrapMarginOptMenu, !wrapAtWindow);
3415 + XtSetSensitive(ShowWrapMarginLabel, !wrapAtWindow);
3419 ** Create and show a dialog for selecting the shell
3421 @@ -6135,10 +6285,24 @@ static void cursorFgModifiedCB(Widget w,
3423 colorDialog *cd = (colorDialog *)clientData;
3424 showColorStatus(cd, cd->cursorFgW, cd->cursorFgErrW);
3427 +static void wrapMarginFgModifiedCB(Widget w, XtPointer clientData,
3428 + XtPointer callData)
3430 + colorDialog *cd = (colorDialog *)clientData;
3431 + showColorStatus(cd, cd->wrapMarginFgW, cd->wrapMarginFgErrW);
3436 * Helper functions for validating colors
3438 static int verifyAllColors(colorDialog *cd)
3439 @@ -6188,35 +6353,41 @@ static void updateColors(colorDialog *cd
3440 *selectFg = XmTextGetString(cd->selectFgW),
3441 *selectBg = XmTextGetString(cd->selectBgW),
3442 *hiliteFg = XmTextGetString(cd->hiliteFgW),
3443 *hiliteBg = XmTextGetString(cd->hiliteBgW),
3444 *lineNoFg = XmTextGetString(cd->lineNoFgW),
3445 - *cursorFg = XmTextGetString(cd->cursorFgW);
3446 + *cursorFg = XmTextGetString(cd->cursorFgW),
3447 + *wrapMarginFg = XmTextGetString(cd->wrapMarginFgW);
3449 for (window = WindowList; window != NULL; window = window->next)
3451 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
3452 - hiliteBg, lineNoFg, cursorFg);
3453 + hiliteBg, lineNoFg, cursorFg, wrapMarginFg);
3456 SetPrefColorName(TEXT_FG_COLOR , textFg );
3457 SetPrefColorName(TEXT_BG_COLOR , textBg );
3458 SetPrefColorName(SELECT_FG_COLOR, selectFg);
3459 SetPrefColorName(SELECT_BG_COLOR, selectBg);
3460 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
3461 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
3462 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
3463 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
3464 + SetPrefColorName(WRAPMARGIN_FG_COLOR, wrapMarginFg);
3474 + XtFree(wrapMarginFg);
3479 * Dialog button callbacks
3480 @@ -6382,10 +6553,27 @@ void ChooseColors(WindowInfo *window)
3486 + /* The right column (backgrounds) */
3487 + tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
3488 + &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
3489 + textBgModifiedCB, cd );
3490 + tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
3491 + &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
3492 + selectBgModifiedCB, cd );
3493 + tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
3494 + &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
3495 + hiliteBgModifiedCB, cd );
3496 + tmpW = addColorGroup( form, "wrapMarginFg", 'w', "Wrap Margin Color",
3497 + &(cd->wrapMarginFgW), &(cd->wrapMarginFgErrW), tmpW, 51, 99,
3498 + wrapMarginFgModifiedCB, cd );
3500 /* The left column (foregrounds) of color entry groups */
3501 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
3502 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
3503 textFgModifiedCB, cd );
3504 tmpW = addColorGroup( form, "selectFg", 'S', "Selection Foreground",
3505 @@ -6395,23 +6583,12 @@ void ChooseColors(WindowInfo *window)
3506 &(cd->hiliteFgW), &(cd->hiliteFgErrW), tmpW, 1, 49,
3507 hiliteFgModifiedCB, cd );
3508 tmpW = addColorGroup( form, "lineNoFg", 'L', "Line Numbers",
3509 &(cd->lineNoFgW), &(cd->lineNoFgErrW), tmpW, 1, 49,
3510 lineNoFgModifiedCB, cd );
3512 - /* The right column (backgrounds) */
3513 - tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
3514 - &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
3515 - textBgModifiedCB, cd );
3516 - tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
3517 - &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
3518 - selectBgModifiedCB, cd );
3519 - tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
3520 - &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
3521 - hiliteBgModifiedCB, cd );
3522 tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
3523 - &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 51, 99,
3524 + &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 1, 49,
3525 cursorFgModifiedCB, cd );
3527 tmpW = XtVaCreateManagedWidget("infoLbl",
3528 xmLabelGadgetClass, form,
3529 XmNtopAttachment, XmATTACH_WIDGET,
3530 @@ -6490,18 +6667,70 @@ void ChooseColors(WindowInfo *window)
3531 XmTextSetString(cd->selectBgW, GetPrefColorName(SELECT_BG_COLOR));
3532 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
3533 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
3534 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
3535 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
3536 + XmTextSetString(cd->wrapMarginFgW, GetPrefColorName(WRAPMARGIN_FG_COLOR));
3538 /* Handle mnemonic selection of buttons and focus to dialog */
3539 AddDialogMnemonicHandler(form, FALSE);
3542 ManageDialogCenteredOnPointer(form);
3545 +/* Overrides the defaults for certain preferences with values obtained from
3546 + obsoleted resources. */
3547 +static void initPrefDefaultsFromResources(XrmDatabase prefDB, XrmDatabase appDB)
3549 + char *type, *valueString;
3550 + XrmValue rsrcValue;
3552 + /* XmFileSelectionBox.fileFilterStyle is now obsolete since it is
3553 + overridden by nedit.showHiddenFiles, but this code tries to make
3554 + the transition painless by translating the resource value, if set,
3555 + to a matching default for the preferences */
3556 + const char* showHiddenResName =
3557 + APP_NAME "*XmFileSelectionBox.fileFilterStyle";
3558 + const char* showHiddenClassName =
3559 + APP_CLASS "*XmFileSelectionBox.FileFilterStyle";
3561 + /* Retrieve the value of the resource from the DB */
3562 + if (XrmGetResource(prefDB, showHiddenResName, showHiddenClassName, &type,
3564 + if (strcmp(type, XmRString)) {
3565 + fprintf(stderr, "nedit: Internal Error: Unexpected resource type, %s\n",
3569 + valueString = rsrcValue.addr;
3570 + } else if (XrmGetResource(appDB, showHiddenResName, showHiddenClassName,
3571 + &type, &rsrcValue)) {
3572 + if (strcmp(type, XmRString)) {
3573 + fprintf(stderr, "nedit: Internal Error: Unexpected resource type, %s\n",
3577 + valueString = rsrcValue.addr;
3579 + /* No resources set */
3583 + /* An X resource is set. If it's non-default, update the prefs default. */
3584 + if (0 == strcmp(valueString, "XmFILTER_HIDDEN_FILES")) {
3586 + for (i = 0; i < XtNumber(PrefDescrip); ++i) {
3587 + if (0 == strcmp(PrefDescrip[i].name, "showHiddenFiles")) {
3588 + PrefDescrip[i].defaultString = "False";
3596 ** This function passes up a pointer to the static name of the default
3597 ** shell, currently defined as the user's login shell.
3598 ** In case of errors, the fallback of "sh" will be returned.
3600 diff --quilt old/source/preferences.h new/source/preferences.h
3601 --- old/source/preferences.h
3602 +++ new/source/preferences.h
3603 @@ -57,10 +57,12 @@ void MarkPrefsChanged(void);
3604 int CheckPrefsChangesSaved(Widget dialogParent);
3605 void SetPrefWrap(int state);
3606 int GetPrefWrap(int langMode);
3607 void SetPrefWrapMargin(int margin);
3608 int GetPrefWrapMargin(void);
3609 +void SetPrefShowWrapMargin(int state);
3610 +int GetPrefShowWrapMargin(void);
3611 void SetPrefSearchDlogs(int state);
3612 int GetPrefSearchDlogs(void);
3613 void SetPrefKeepSearchDlogs(int state);
3614 int GetPrefKeepSearchDlogs(void);
3615 void SetPrefSearchWraps(int state);
3616 @@ -117,10 +119,12 @@ void SetPrefBacklightChars(int state);
3617 int GetPrefBacklightChars(void);
3618 void SetPrefBacklightCharTypes(char *types);
3619 char *GetPrefBacklightCharTypes(void);
3620 void SetPrefRepositionDialogs(int state);
3621 int GetPrefRepositionDialogs(void);
3622 +void SetPrefShowHiddenFiles(int state);
3623 +int GetPrefShowHiddenFiles(void);
3624 void SetPrefAutoScroll(int state);
3625 int GetPrefAutoScroll(void);
3626 int GetVerticalAutoScroll(void);
3627 void SetPrefAppendLF(int state);
3628 int GetPrefAppendLF(void);
3629 @@ -156,10 +160,11 @@ void RowColumnPrefDialog(Widget parent);
3630 void TabsPrefDialog(Widget parent, WindowInfo *forWindow);
3631 void WrapMarginDialog(Widget parent, WindowInfo *forWindow);
3632 int GetPrefMapDelete(void);
3633 int GetPrefStdOpenDialog(void);
3634 char *GetPrefDelimiters(void);
3635 +char *GetPrevOpenFilesMask(void);
3636 int GetPrefMaxPrevOpenFiles(void);
3637 int GetPrefTypingHidesPointer(void);
3639 void SetPrefShortMenus(int state);
3640 int GetPrefShortMenus(void);
3641 @@ -209,7 +214,10 @@ void SetPrefOpenInTab(int state);
3642 Boolean GetPrefUndoModifiesSelection(void);
3643 Boolean GetPrefFocusOnRaise(void);
3644 Boolean GetPrefHonorSymlinks(void);
3645 Boolean GetPrefForceOSConversion(void);
3646 void SetPrefFocusOnRaise(Boolean);
3647 +Boolean GetPrefShowScrolltip(void);
3649 #endif /* NEDIT_PREFERENCES_H_INCLUDED */
3650 diff --quilt old/source/search.c new/source/search.c
3651 --- old/source/search.c
3652 +++ new/source/search.c
3653 @@ -241,10 +241,11 @@ static void iSearchCaseToggleCB(Widget w
3654 XtPointer callData);
3655 static void iSearchTryBeepOnWrap(WindowInfo *window, int direction,
3656 int beginPos, int startPos);
3657 static void iSearchRecordLastBeginPos(WindowInfo *window, int direction,
3659 +static void smartCaseToggle(const char* searchString, Widget toggleButton);
3660 static Boolean prefOrUserCancelsSubst(const Widget parent,
3661 const Display* display);
3663 typedef struct _charMatchTable {
3665 @@ -279,10 +280,11 @@ static char *searchTypeStrings[] = {
3666 "case", /* SEARCH_CASE_SENSE */
3667 "regex", /* SEARCH_REGEX */
3668 "word", /* SEARCH_LITERAL_WORD */
3669 "caseWord", /* SEARCH_CASE_SENSE_WORD */
3670 "regexNoCase", /* SEARCH_REGEX_NOCASE */
3671 + "regexSmartCase", /* SEARCH_REGEX_SMARTCASE */
3676 ** Window for which a search dialog callback is currently active. That window
3677 @@ -317,70 +319,77 @@ static void initToggleButtons(int search
3678 Bool* lastRegexCase)
3680 /* Set the initial search type and remember the corresponding case
3681 sensitivity states in case sticky case sensitivity is required. */
3682 switch (searchType) {
3683 - case SEARCH_LITERAL:
3684 + case SEARCH_LITERAL:
3685 *lastLiteralCase = False;
3686 *lastRegexCase = True;
3687 XmToggleButtonSetState(regexToggle, False, False);
3688 XmToggleButtonSetState(caseToggle, False, False);
3690 XmToggleButtonSetState(*wordToggle, False, False);
3691 XtSetSensitive(*wordToggle, True);
3694 - case SEARCH_CASE_SENSE:
3697 + case SEARCH_CASE_SENSE:
3698 *lastLiteralCase = True;
3699 *lastRegexCase = True;
3700 XmToggleButtonSetState(regexToggle, False, False);
3701 XmToggleButtonSetState(caseToggle, True, False);
3703 XmToggleButtonSetState(*wordToggle, False, False);
3704 XtSetSensitive(*wordToggle, True);
3707 - case SEARCH_LITERAL_WORD:
3710 + case SEARCH_LITERAL_WORD:
3711 *lastLiteralCase = False;
3712 *lastRegexCase = True;
3713 XmToggleButtonSetState(regexToggle, False, False);
3714 XmToggleButtonSetState(caseToggle, False, False);
3716 XmToggleButtonSetState(*wordToggle, True, False);
3717 XtSetSensitive(*wordToggle, True);
3720 - case SEARCH_CASE_SENSE_WORD:
3723 + case SEARCH_CASE_SENSE_WORD:
3724 *lastLiteralCase = True;
3725 *lastRegexCase = True;
3726 XmToggleButtonSetState(regexToggle, False, False);
3727 XmToggleButtonSetState(caseToggle, True, False);
3729 XmToggleButtonSetState(*wordToggle, True, False);
3730 XtSetSensitive(*wordToggle, True);
3733 - case SEARCH_REGEX:
3736 + case SEARCH_REGEX:
3737 *lastLiteralCase = False;
3738 *lastRegexCase = True;
3739 XmToggleButtonSetState(regexToggle, True, False);
3740 XmToggleButtonSetState(caseToggle, True, False);
3742 XmToggleButtonSetState(*wordToggle, False, False);
3743 XtSetSensitive(*wordToggle, False);
3746 - case SEARCH_REGEX_NOCASE:
3747 - *lastLiteralCase = False;
3748 - *lastRegexCase = False;
3749 - XmToggleButtonSetState(regexToggle, True, False);
3750 - XmToggleButtonSetState(caseToggle, False, False);
3752 - XmToggleButtonSetState(*wordToggle, False, False);
3753 - XtSetSensitive(*wordToggle, False);
3758 + case SEARCH_REGEX_NOCASE:
3759 + case SEARCH_REGEX_SMARTCASE:
3760 + /* Smart case is no case for default setting */
3761 + *lastLiteralCase = False;
3762 + *lastRegexCase = False;
3763 + XmToggleButtonSetState(regexToggle, True, False);
3764 + XmToggleButtonSetState(caseToggle, False, False);
3766 + XmToggleButtonSetState(*wordToggle, False, False);
3767 + XtSetSensitive(*wordToggle, False);
3773 #ifdef REPLACE_SCOPE
3775 @@ -2404,14 +2413,23 @@ static int textFieldNonEmpty(Widget w)
3776 int nonEmpty = (str[0] != '\0');
3781 -static void rFindTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event)
3782 +static void rFindTextValueChangedCB(Widget textWidget, WindowInfo* window,
3785 - window = WidgetToWindow(w);
3786 + char* searchString = XmTextGetString(textWidget);
3788 + window = WidgetToWindow(textWidget);
3789 UpdateReplaceActionButtons(window);
3791 + /* Switch to case-sensitive as soon as the user enters an upper-case
3792 + letter. We have check the whole string each time to catch clipboard
3793 + or selection inserts. */
3794 + smartCaseToggle(searchString, window->replaceCaseToggle);
3795 + XtFree(searchString);
3798 static void rFindArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event)
3800 KeySym keysym = XLookupKeysym(event, 0);
3801 @@ -2499,14 +2517,23 @@ static void fUpdateActionButtons(WindowI
3803 int buttonState = textFieldNonEmpty(window->findText);
3804 XtSetSensitive(window->findBtn, buttonState);
3807 -static void findTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event)
3808 +static void findTextValueChangedCB(Widget textWidget, WindowInfo* window,
3811 - window = WidgetToWindow(w);
3812 + char* searchString = XmTextGetString(textWidget);
3814 + window = WidgetToWindow(textWidget);
3815 fUpdateActionButtons(window);
3817 + /* Switch to case-sensitive as soon as the user enters an upper-case
3818 + letter. We have check the whole string each time to catch clipboard
3819 + or selection inserts. */
3820 + smartCaseToggle(searchString, window->findCaseToggle);
3821 + XtFree(searchString);
3824 static void findArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event)
3826 KeySym keysym = XLookupKeysym(event, 0);
3827 @@ -2527,11 +2554,10 @@ static void findArrowKeyCB(Widget w, Win
3828 /* if the index is out of range, beep and return */
3829 if (index != 0 && historyIndex(index) == -1) {
3830 XBell(TheDisplay, 0);
3835 /* determine the strings and button settings to use */
3838 searchType = GetPrefSearch();
3839 @@ -2874,36 +2900,45 @@ static void selectedSearchCB(Widget w, X
3842 /* Use the passed method for searching, unless it is regex, since this
3843 kind of search is by definition a literal search */
3844 searchType = callDataItems->searchType;
3845 - if (searchType == SEARCH_REGEX )
3846 - searchType = SEARCH_CASE_SENSE;
3847 - else if (searchType == SEARCH_REGEX_NOCASE)
3848 - searchType = SEARCH_LITERAL;
3849 + if (searchType == SEARCH_REGEX || searchType == SEARCH_REGEX_SMARTCASE) {
3850 + /* Here smart case must be sensitive, because the user
3851 + cannot modify the string to search for. */
3852 + searchType = SEARCH_CASE_SENSE;
3853 + } else if (searchType == SEARCH_REGEX_NOCASE) {
3854 + searchType = SEARCH_LITERAL;
3857 /* search for it in the window */
3858 SearchAndSelect(window, callDataItems->direction, searchString,
3859 searchType, callDataItems->searchWrap);
3864 ** Pop up and clear the incremental search line and prepare to search.
3866 -void BeginISearch(WindowInfo *window, int direction)
3867 +void BeginISearch(WindowInfo* window, int direction)
3869 window->iSearchStartPos = -1;
3870 XmTextSetString(window->iSearchText, "");
3871 XmToggleButtonSetState(window->iSearchRevToggle,
3872 - direction == SEARCH_BACKWARD, FALSE);
3873 + direction == SEARCH_BACKWARD, FALSE);
3875 /* Note: in contrast to the replace and find dialogs, the regex and
3876 case toggles are not reset to their default state when the incremental
3877 search bar is redisplayed. I'm not sure whether this is the best
3878 choice. If not, an initToggleButtons() call should be inserted
3879 here. But in that case, it might be appropriate to have different
3880 default search modes for i-search and replace/find. */
3882 + /* The 'Case' toggle button must be deactivated for smart cases. */
3883 + if (GetPrefSearch() == SEARCH_REGEX_SMARTCASE) {
3884 + XmToggleButtonSetState(window->iSearchCaseToggle, False, False);
3886 TempShowISearch(window, TRUE);
3887 XmProcessTraversal(window->iSearchText, XmTRAVERSE_CURRENT);
3891 @@ -3181,32 +3216,40 @@ static void iSearchTextActivateCB(Widget
3894 ** Called when user types in the incremental search line. Redoes the
3895 ** search for the new search string.
3897 -static void iSearchTextValueChangedCB(Widget w, WindowInfo *window,
3898 - XmAnyCallbackStruct *callData)
3899 +static void iSearchTextValueChangedCB(Widget widget, WindowInfo *window,
3900 + XmAnyCallbackStruct *callData)
3904 int searchType, direction, nParams;
3906 - window = WidgetToWindow(w);
3909 + window = WidgetToWindow(widget);
3911 /* Fetch the string, search type and direction from the incremental
3912 search bar widgets at the top of the window */
3913 searchString = XmTextGetString(window->iSearchText);
3915 + /* Switch to case-sensitive as soon as the user enters an upper-case
3916 + letter. We have check the whole string each time to catch clipboard
3917 + or selection inserts. */
3918 + smartCaseToggle(searchString, window->iSearchCaseToggle);
3920 if(XmToggleButtonGetState(window->iSearchCaseToggle)) {
3921 - if(XmToggleButtonGetState(window->iSearchRegexToggle))
3922 - searchType = SEARCH_REGEX;
3924 - searchType = SEARCH_CASE_SENSE;
3925 + if(XmToggleButtonGetState(window->iSearchRegexToggle)) {
3926 + searchType = SEARCH_REGEX;
3928 + searchType = SEARCH_CASE_SENSE;
3931 - if(XmToggleButtonGetState(window->iSearchRegexToggle))
3932 - searchType = SEARCH_REGEX_NOCASE;
3934 - searchType = SEARCH_LITERAL;
3935 + if(XmToggleButtonGetState(window->iSearchRegexToggle)) {
3936 + searchType = SEARCH_REGEX_NOCASE;
3938 + searchType = SEARCH_LITERAL;
3941 direction = XmToggleButtonGetState(window->iSearchRevToggle) ?
3942 SEARCH_BACKWARD : SEARCH_FORWARD;
3944 /* If the search type is a regular expression, test compile it. If it
3945 @@ -4872,11 +4915,13 @@ static char *directionArg(int direction)
3947 ** Checks whether a search mode in one of the regular expression modes.
3949 static int isRegexType(int searchType)
3951 - return searchType == SEARCH_REGEX || searchType == SEARCH_REGEX_NOCASE;
3952 + return searchType == SEARCH_REGEX
3953 + || searchType == SEARCH_REGEX_NOCASE
3954 + || searchType == SEARCH_REGEX_SMARTCASE;
3958 ** Returns the default flags for regular expression matching, given a
3959 ** regular expression search mode.
3960 @@ -5003,17 +5048,35 @@ static void replaceCaseToggleCB(Widget w
3961 window->replaceLastRegexCase = searchCaseSense;
3963 window->replaceLastLiteralCase = searchCaseSense;
3966 -static void iSearchCaseToggleCB(Widget w, XtPointer clientData, XtPointer callData)
3967 +static void iSearchCaseToggleCB(Widget toggleButton, XtPointer clientData,
3968 + XtPointer callData)
3970 - WindowInfo * window = WidgetToWindow(w);
3971 - int searchCaseSense = XmToggleButtonGetState(w);
3972 + WindowInfo * window = WidgetToWindow(toggleButton);
3973 + int searchCaseSense = XmToggleButtonGetState(toggleButton);
3975 /* Save the state of the Case Sensitive button
3976 depending on the state of the Regex button*/
3977 if(XmToggleButtonGetState(window->iSearchRegexToggle))
3978 window->iSearchLastRegexCase = searchCaseSense;
3980 window->iSearchLastLiteralCase = searchCaseSense;
3984 +** Will search a string for uppercase characters. If there is one,
3985 +** The toggleButton will be set to True.
3987 +static void smartCaseToggle(const char* searchString, Widget toggleButton)
3989 + if (GetPrefSearch() == SEARCH_REGEX_SMARTCASE) {
3991 + for (i = 0; i < strlen(searchString); i++) {
3992 + if (isupper(*(searchString + i))) {
3993 + XmToggleButtonSetState(toggleButton, True, False);
3999 diff --quilt old/source/search.h new/source/search.h
4000 --- old/source/search.h
4001 +++ new/source/search.h
4002 @@ -85,14 +85,16 @@ Boolean WindowCanBeClosed(WindowInfo *wi
4003 ** The order of the integers in this enumeration must be exactly
4004 ** the same as the order of the coressponding strings of the
4005 ** array SearchMethodStrings defined in preferences.c (!!)
4009 - SEARCH_LITERAL, SEARCH_CASE_SENSE, SEARCH_REGEX,
4010 - SEARCH_LITERAL_WORD, SEARCH_CASE_SENSE_WORD, SEARCH_REGEX_NOCASE,
4011 - N_SEARCH_TYPES /* must be last in enum SearchType */ };
4014 + SEARCH_LITERAL, SEARCH_CASE_SENSE, SEARCH_REGEX, SEARCH_LITERAL_WORD,
4015 + SEARCH_CASE_SENSE_WORD, SEARCH_REGEX_NOCASE, SEARCH_REGEX_SMARTCASE,
4016 + N_SEARCH_TYPES /* must be last in enum SearchType */
4019 #ifdef REPLACE_SCOPE
4020 /* Scope on which the replace operations apply */
4021 enum ReplaceScope { REPL_SCOPE_WIN, REPL_SCOPE_SEL, REPL_SCOPE_MULTI };
4023 diff --quilt old/source/selection.c new/source/selection.c
4024 --- old/source/selection.c
4025 +++ new/source/selection.c
4026 @@ -27,21 +27,23 @@ static const char CVSID[] = "$Id: select
4028 #ifdef HAVE_CONFIG_H
4029 #include "../config.h"
4032 -#include "selection.h"
4033 -#include "textBuf.h"
4037 -#include "window.h"
4038 +#include "interpret.h"
4042 #include "preferences.h"
4043 +#include "selection.h"
4045 +#include "textBuf.h"
4047 #include "../util/DialogF.h"
4048 #include "../util/fileUtils.h"
4049 +#include "window.h"
4055 @@ -349,23 +351,34 @@ static void fileCB(Widget widget, Window
4056 XtFree(nameList[i]);
4058 XtFree((char *)nameList);
4064 - glob(nameText, GLOB_NOCHECK, NULL, &globbuf);
4065 - for (i=0; i<(int)globbuf.gl_pathc; i++) {
4066 - if (ParseFilename(globbuf.gl_pathv[i], filename, pathname) != 0)
4067 - XBell(TheDisplay, 0);
4069 - EditExistingFile(GetPrefOpenInTab()? window : NULL,
4070 - filename, pathname, 0, NULL, False, NULL,
4071 - GetPrefOpenInTab(), False);
4073 - globfree(&globbuf);
4078 + glob(nameText, GLOB_NOCHECK, NULL, &globbuf);
4079 + for (i = 0; i < (int) globbuf.gl_pathc; i++) {
4080 + DataValue* fileNameArg = (DataValue*) XtMalloc(sizeof(DataValue));
4081 + DataValue* resultDV = (DataValue*) XtMalloc(sizeof(DataValue));
4083 + fileNameArg->tag = STRING_TAG;
4084 + AllocNStringNCpy(&fileNameArg->val.str, globbuf.gl_pathv[i], MAXPATHLEN);
4085 + MacroApplyHook(window, "file_name_hook", 1, fileNameArg, resultDV);
4086 + XtFree((char*) fileNameArg);
4088 + if (ParseFilename(resultDV->val.str.rep, filename, pathname) != 0) {
4089 + XBell(TheDisplay, 0);
4091 + EditExistingFile(GetPrefOpenInTab() ? window : NULL, filename,
4092 + pathname, 0, NULL, False, NULL, GetPrefOpenInTab(),
4095 + XtFree((char*) resultDV);
4097 + globfree(&globbuf);
4103 diff --quilt old/source/server.c new/source/server.c
4104 --- old/source/server.c
4105 +++ new/source/server.c
4106 @@ -242,12 +242,10 @@ static void deleteFileOpenProperty2(cons
4108 Atom atom = findFileOpenProperty(filename, pathname);
4109 deleteProperty(&atom);
4114 /* Try to find existing 'FileClosed' property atom for path. */
4115 static Atom findFileClosedProperty(const char* filename,
4116 const char* pathname)
4118 char path[MAXPATHLEN];
4119 @@ -354,11 +352,11 @@ static void processServerCommandString(c
4120 if (!window->filenameSet && !window->fileChanged &&
4121 isLocatedOnDesktop(window, currentDesktop))
4123 if (window == NULL) {
4124 EditNewFile(findWindowOnDesktop(tabbed, currentDesktop), NULL,
4125 - False, NULL, NULL);
4126 + False, NULL, NULL, False);
4130 RaiseDocument(window);
4131 XMapRaised(TheDisplay, XtWindow(window->shell));
4132 @@ -417,12 +415,13 @@ static void processServerCommandString(c
4133 isLocatedOnDesktop(window, currentDesktop))
4136 if (*doCommand == '\0') {
4137 if (window == NULL) {
4138 - EditNewFile(findWindowOnDesktop(tabbed, currentDesktop),
4139 - NULL, iconicFlag, lmLen==0?NULL:langMode, NULL);
4140 + EditNewFile(findWindowOnDesktop(tabbed, currentDesktop),
4141 + NULL, iconicFlag, lmLen==0?NULL:langMode, NULL,
4145 RaiseDocument(window);
4147 RaiseDocumentWindow(window);
4148 diff --quilt old/source/shell.c new/source/shell.c
4149 --- old/source/shell.c
4150 +++ new/source/shell.c
4151 @@ -387,11 +387,12 @@ void DoShellMenuCmd(WindowInfo *window,
4152 if (output == TO_DIALOG) {
4154 flags |= OUTPUT_TO_DIALOG;
4156 } else if (output == TO_NEW_WINDOW) {
4157 - EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL, window->path);
4158 + EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL,
4159 + window->path, False);
4160 outWidget = WindowList->textArea;
4161 inWindow = WindowList;
4164 } else { /* TO_SAME_WINDOW */
4165 @@ -478,11 +479,11 @@ void AbortShellCommand(WindowInfo *windo
4167 static void issueCommand(WindowInfo *window, const char *command, char *input,
4168 int inputLen, int flags, Widget textW, int replaceLeft,
4169 int replaceRight, int fromMacro)
4171 - int stdinFD, stdoutFD, stderrFD = 0;
4172 + int stdinFD = 0, stdoutFD = 0, stderrFD = 0;
4173 XtAppContext context = XtWidgetToApplicationContext(window->shell);
4174 shellCmdInfo *cmdData;
4177 /* verify consistency of input parameters */
4178 diff --quilt old/source/text.c new/source/text.c
4179 --- old/source/text.c
4180 +++ new/source/text.c
4181 @@ -629,10 +629,17 @@ static XtResource resources[] = {
4182 XtOffset(TextWidget, text.highlightFGPixel), XmRString,
4183 NEDIT_DEFAULT_HI_FG},
4184 {textNhighlightBackground, textCHighlightBackground, XmRPixel,sizeof(Pixel),
4185 XtOffset(TextWidget, text.highlightBGPixel), XmRString,
4186 NEDIT_DEFAULT_HI_BG},
4187 + {textNshowScrolltip, textCshowScrolltip, XmRBoolean, sizeof(Boolean),
4188 + XtOffset(TextWidget, text.showScrolltip), XmRString, "False"},
4189 {textNlineNumForeground, textCLineNumForeground, XmRPixel,sizeof(Pixel),
4190 XtOffset(TextWidget, text.lineNumFGPixel), XmRString,
4191 NEDIT_DEFAULT_LINENO_FG},
4192 {textNcursorForeground, textCCursorForeground, XmRPixel,sizeof(Pixel),
4193 XtOffset(TextWidget, text.cursorFGPixel), XmRString,
4194 @@ -641,10 +648,13 @@ static XtResource resources[] = {
4195 XtOffset(TextWidget, text.calltipFGPixel), XmRString,
4196 NEDIT_DEFAULT_CALLTIP_FG},
4197 {textNcalltipBackground, textCcalltipBackground, XmRPixel,sizeof(Pixel),
4198 XtOffset(TextWidget, text.calltipBGPixel), XmRString,
4199 NEDIT_DEFAULT_CALLTIP_BG},
4200 + {textNwrapMarginForeground, textCWrapMarginForeground, XmRPixel,sizeof(Pixel),
4201 + XtOffset(TextWidget, text.wrapMarginFGPixel), XmRString,
4202 + NEDIT_DEFAULT_WRAPMARGIN_FG},
4203 {textNbacklightCharTypes,textCBacklightCharTypes,XmRString,sizeof(XmString),
4204 XtOffset(TextWidget, text.backlightCharTypes), XmRString, NULL},
4205 {textNrows, textCRows, XmRInt,sizeof(int),
4206 XtOffset(TextWidget, text.rows), XmRString, "24"},
4207 {textNcolumns, textCColumns, XmRInt, sizeof(int),
4208 @@ -671,10 +681,12 @@ static XtResource resources[] = {
4209 XtOffset(TextWidget, text.readOnly), XmRString, "False"},
4210 {textNhidePointer, textCHidePointer, XmRBoolean, sizeof(Boolean),
4211 XtOffset(TextWidget, text.hidePointer), XmRString, "False"},
4212 {textNwrapMargin, textCWrapMargin, XmRInt, sizeof(int),
4213 XtOffset(TextWidget, text.wrapMargin), XmRString, "0"},
4214 + {textNshowWrapMargin, textCShowWrapMargin, XmRBoolean, sizeof(Boolean),
4215 + XtOffset(TextWidget, text.showWrapMargin), XmRString, "True"},
4216 {textNhScrollBar, textCHScrollBar, XmRWidget, sizeof(Widget),
4217 XtOffset(TextWidget, text.hScrollBar), XmRString, ""},
4218 {textNvScrollBar, textCVScrollBar, XmRWidget, sizeof(Widget),
4219 XtOffset(TextWidget, text.vScrollBar), XmRString, ""},
4220 {textNlineNumCols, textCLineNumCols, XmRInt, sizeof(int),
4221 @@ -810,24 +822,34 @@ static void initialize(TextWidget reques
4224 /* Create and initialize the text-display part of the widget */
4225 textLeft = new->text.marginWidth +
4226 (lineNumCols == 0 ? 0 : marginWidth + charWidth * lineNumCols);
4227 - new->text.textD = TextDCreate((Widget)new, new->text.hScrollBar,
4228 - new->text.vScrollBar, textLeft, new->text.marginHeight,
4229 - new->core.width - marginWidth - textLeft,
4230 - new->core.height - new->text.marginHeight * 2,
4231 - lineNumCols == 0 ? 0 : marginWidth,
4232 - lineNumCols == 0 ? 0 : lineNumCols * charWidth,
4233 - buf, new->text.fontStruct, new->core.background_pixel,
4234 - new->primitive.foreground, new->text.selectFGPixel,
4235 - new->text.selectBGPixel, new->text.highlightFGPixel,
4236 - new->text.highlightBGPixel, new->text.cursorFGPixel,
4237 - new->text.lineNumFGPixel,
4238 - new->text.continuousWrap, new->text.wrapMargin,
4239 - new->text.backlightCharTypes, new->text.calltipFGPixel,
4240 - new->text.calltipBGPixel);
4241 + new->text.textD = TextDCreate(
4243 + (Widget)new, new->text.hScrollBar, new->text.vScrollBar,
4245 + textLeft, new->text.marginHeight,
4246 + new->core.width - marginWidth - textLeft,
4247 + new->core.height - new->text.marginHeight * 2,
4248 + lineNumCols == 0 ? 0 : marginWidth,
4249 + lineNumCols == 0 ? 0 : lineNumCols * charWidth,
4253 + new->text.fontStruct,
4255 + new->core.background_pixel, new->primitive.foreground,
4256 + new->text.selectFGPixel, new->text.selectBGPixel,
4257 + new->text.highlightFGPixel, new->text.highlightBGPixel,
4258 + new->text.cursorFGPixel, new->text.lineNumFGPixel,
4259 + new->text.wrapMarginFGPixel, new->text.calltipFGPixel,
4260 + new->text.calltipBGPixel,
4262 + new->text.continuousWrap, new->text.wrapMargin,
4263 + new->text.showWrapMargin, new->text.backlightCharTypes,
4264 + new->text.showScrolltip);
4266 /* Add mandatory delimiters blank, tab, and newline to the list of
4267 delimiters. The memory use scheme here is that new values are
4268 always copied, and can therefore be safely freed on subsequent
4269 set-values calls or destroy */
4270 @@ -1121,10 +1143,25 @@ static Boolean setValues(TextWidget curr
4271 if (new->text.wrapMargin != current->text.wrapMargin ||
4272 new->text.continuousWrap != current->text.continuousWrap)
4273 TextDSetWrapMode(current->text.textD, new->text.continuousWrap,
4274 new->text.wrapMargin);
4276 + if (new->text.showWrapMargin != current->text.showWrapMargin)
4277 + TextDSetShowWrapMargin(current->text.textD, new->text.showWrapMargin);
4279 /* When delimiters are changed, copy the memory, so that the caller
4280 doesn't have to manage it, and add mandatory delimiters blank,
4281 tab, and newline to the list */
4282 if (new->text.delimiters != current->text.delimiters) {
4283 char *delimiters = XtMalloc(strlen(new->text.delimiters) + 4);
4284 @@ -3750,12 +3787,15 @@ static void selectWord(Widget w, int poi
4285 TextWidget tw = (TextWidget)w;
4286 textBuffer *buf = tw->text.textD->buffer;
4287 int x, y, insertPos = TextDGetInsertPosition(tw->text.textD);
4289 TextPosToXY(w, insertPos, &x, &y);
4290 - if (pointerX < x && insertPos > 0 && BufGetCharacter(buf, insertPos-1) != '\n')
4292 + if (pointerX < x && insertPos > 0
4293 + && BufGetCharacter(buf, insertPos-1) != '\n')
4297 BufSelect(buf, startOfWord(tw, insertPos), endOfWord(tw, insertPos));
4300 static int startOfWord(TextWidget w, int pos)
4302 diff --quilt old/source/text.h new/source/text.h
4303 --- old/source/text.h
4304 +++ new/source/text.h
4306 #define textCSelectBackground "SelectBackground"
4307 #define textNhighlightForeground "highlightForeground"
4308 #define textCHighlightForeground "HighlightForeground"
4309 #define textNhighlightBackground "highlightBackground"
4310 #define textCHighlightBackground "HighlightBackground"
4311 +#define textNshowScrolltip "showScrolltip"
4312 +#define textCshowScrolltip "ShowScrolltip"
4314 #define textNcursorForeground "cursorForeground"
4315 #define textCCursorForeground "CursorForeground"
4316 #define textNlineNumForeground "lineNumForeground"
4317 #define textCLineNumForeground "LineNumForeground"
4318 #define textNcalltipForeground "calltipForeground"
4319 #define textCcalltipForeground "CalltipForeground"
4320 #define textNcalltipBackground "calltipBackground"
4321 #define textCcalltipBackground "CalltipBackground"
4322 +#define textNwrapMarginForeground "wrapMarginForeground"
4323 +#define textCWrapMarginForeground "WrapMarginForeground"
4324 #define textNpendingDelete "pendingDelete"
4325 #define textCPendingDelete "PendingDelete"
4326 #define textNhScrollBar "hScrollBar"
4327 #define textCHScrollBar "HScrollBar"
4328 #define textNvScrollBar "vScrollBar"
4329 @@ -93,10 +105,12 @@
4330 #define textCAutoWrap "AutoWrap"
4331 #define textNcontinuousWrap "continuousWrap"
4332 #define textCContinuousWrap "ContinuousWrap"
4333 #define textNwrapMargin "wrapMargin"
4334 #define textCWrapMargin "WrapMargin"
4335 +#define textNshowWrapMargin "showWrapMargin"
4336 +#define textCShowWrapMargin "ShowWrapMargin"
4337 #define textNautoIndent "autoIndent"
4338 #define textCAutoIndent "AutoIndent"
4339 #define textNsmartIndent "smartIndent"
4340 #define textCSmartIndent "SmartIndent"
4341 #define textNoverstrike "overstrike"
4342 diff --quilt old/source/textDisp.c new/source/textDisp.c
4343 --- old/source/textDisp.c
4344 +++ new/source/textDisp.c
4345 @@ -147,11 +152,12 @@ static int countLines(const char *string
4346 static int measureVisLine(textDisp *textD, int visLineNum);
4347 static int emptyLinesVisible(textDisp *textD);
4348 static void blankCursorProtrusions(textDisp *textD);
4349 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
4350 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
4351 - Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel);
4352 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
4353 + Pixel wrapMarginFGPixel);
4354 static GC allocateGC(Widget w, unsigned long valueMask,
4355 unsigned long foreground, unsigned long background, Font font,
4356 unsigned long dynamicMask, unsigned long dontCareMask);
4357 static void releaseGC(Widget w, GC gc);
4358 static void resetClipRectangles(textDisp *textD);
4359 @@ -177,19 +183,24 @@ static void resetAbsLineNum(textDisp *te
4360 static int measurePropChar(const textDisp* textD, const char c,
4361 const int colNum, const int pos);
4362 static Pixel allocBGColor(Widget w, char *colorName, int *ok);
4363 static Pixel getRangesetColor(textDisp *textD, int ind, Pixel bground);
4364 static void textDRedisplayRange(textDisp *textD, int start, int end);
4365 +static void drawWrapMargin(textDisp* textD);
4366 +static void redisplayCursor(textDisp* textD);
4368 textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar,
4369 Position left, Position top, Position width, Position height,
4370 - Position lineNumLeft, Position lineNumWidth, textBuffer *buffer,
4371 - XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
4372 - Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
4373 - Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
4374 - int continuousWrap, int wrapMargin, XmString bgClassString,
4375 - Pixel calltipFGPixel, Pixel calltipBGPixel)
4376 + Position lineNumLeft, Position lineNumWidth,
4377 + textBuffer *buffer,
4378 + XFontStruct *fontStruct,
4379 + Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
4380 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel cursorFGPixel,
4381 + Pixel lineNumFGPixel, Pixel wrapMarginFGPixel, Pixel calltipFGPixel,
4382 + Pixel calltipBGPixel,
4383 + int continuousWrap, int wrapMargin, Boolean showWrapMargin,
4384 + XmString bgClassString, Boolean showScrolltip)
4390 @@ -230,29 +241,34 @@ textDisp *TextDCreate(Widget widget, Wid
4391 textD->selectFGPixel = selectFGPixel;
4392 textD->highlightFGPixel = highlightFGPixel;
4393 textD->selectBGPixel = selectBGPixel;
4394 textD->highlightBGPixel = highlightBGPixel;
4395 textD->lineNumFGPixel = lineNumFGPixel;
4396 textD->cursorFGPixel = cursorFGPixel;
4397 textD->wrapMargin = wrapMargin;
4398 textD->continuousWrap = continuousWrap;
4399 + textD->showWrapMargin = showWrapMargin;
4400 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
4401 - selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel);
4402 + selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
4403 + wrapMarginFGPixel);
4404 textD->styleGC = allocateGC(textD->w, 0, 0, 0, fontStruct->fid,
4405 GCClipMask|GCForeground|GCBackground, GCArcMode);
4406 textD->lineNumLeft = lineNumLeft;
4407 textD->lineNumWidth = lineNumWidth;
4408 textD->nVisibleLines = (height - 1) / (textD->ascent + textD->descent) + 1;
4409 gcValues.foreground = cursorFGPixel;
4410 textD->cursorFGGC = XtGetGC(widget, GCForeground, &gcValues);
4411 textD->lineStarts = (int *)XtMalloc(sizeof(int) * textD->nVisibleLines);
4412 textD->lineStarts[0] = 0;
4413 - textD->calltipW = NULL;
4414 - textD->calltipShell = NULL;
4415 + textD->calltip.widget = NULL;
4416 textD->calltip.ID = 0;
4417 textD->calltipFGPixel = calltipFGPixel;
4418 textD->calltipBGPixel = calltipBGPixel;
4419 + textD->showScrolltip = showScrolltip;
4420 + textD->scrolltip = NULL;
4421 for (i=1; i<textD->nVisibleLines; i++)
4422 textD->lineStarts[i] = -1;
4423 textD->bgClassPixel = NULL;
4424 textD->bgClass = NULL;
4425 TextDSetupBGClasses(widget, bgClassString, &textD->bgClassPixel,
4426 @@ -316,13 +335,18 @@ void TextDFree(textDisp *textD)
4427 releaseGC(textD->w, textD->highlightGC);
4428 releaseGC(textD->w, textD->selectBGGC);
4429 releaseGC(textD->w, textD->highlightBGGC);
4430 releaseGC(textD->w, textD->styleGC);
4431 releaseGC(textD->w, textD->lineNumGC);
4432 + releaseGC(textD->w, textD->wrapMarginGC);
4434 XtFree((char *)textD->lineStarts);
4435 while (TextDPopGraphicExposeQueueEntry(textD)) {
4438 XtFree((char *)textD->bgClassPixel);
4439 XtFree((char *)textD->bgClass);
4440 XtFree((char *)textD);
4443 @@ -380,11 +404,12 @@ void TextDAttachHighlightData(textDisp *
4446 /* Change the (non syntax-highlit) colors */
4447 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
4448 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
4449 - Pixel lineNoFgP, Pixel cursorFgP)
4450 + Pixel lineNoFgP, Pixel cursorFgP, Pixel wrapMarginFgP)
4453 Display *d = XtDisplay(textD->w);
4455 /* Update the stored pixels */
4456 @@ -394,19 +419,24 @@ void TextDSetColors(textDisp *textD, Pix
4457 textD->selectBGPixel = selectBgP;
4458 textD->highlightFGPixel = hiliteFgP;
4459 textD->highlightBGPixel = hiliteBgP;
4460 textD->lineNumFGPixel = lineNoFgP;
4461 textD->cursorFGPixel = cursorFgP;
4462 + textD->wrapMarginFGPixel = wrapMarginFgP;
4464 releaseGC(textD->w, textD->gc);
4465 releaseGC(textD->w, textD->selectGC);
4466 releaseGC(textD->w, textD->selectBGGC);
4467 releaseGC(textD->w, textD->highlightGC);
4468 releaseGC(textD->w, textD->highlightBGGC);
4469 releaseGC(textD->w, textD->lineNumGC);
4470 + releaseGC(textD->w, textD->wrapMarginGC);
4471 allocateFixedFontGCs(textD, textD->fontStruct, textBgP, textFgP, selectFgP,
4472 - selectBgP, hiliteFgP, hiliteBgP, lineNoFgP);
4473 + selectBgP, hiliteFgP, hiliteBgP, lineNoFgP, wrapMarginFgP);
4475 /* Change the cursor GC (the cursor GC is not shared). */
4476 values.foreground = cursorFgP;
4477 XChangeGC( d, textD->cursorFGGC, GCForeground, &values );
4479 @@ -414,20 +444,32 @@ void TextDSetColors(textDisp *textD, Pix
4480 TextDRedisplayRect(textD, textD->left, textD->top, textD->width,
4482 redrawLineNumbers(textD, True);
4486 ** Change the (non highlight) font
4488 void TextDSetFont(textDisp *textD, XFontStruct *fontStruct)
4490 Display *display = XtDisplay(textD->w);
4491 int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
4492 int width, height, fontWidth;
4493 Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
4494 Pixel highlightFGPixel, highlightBGPixel, lineNumFGPixel;
4495 + Pixel wrapMarginFGPixel;
4497 XFontStruct *styleFont;
4499 /* If font size changes, cursor will be redrawn in a new position */
4500 blankCursorProtrusions(textD);
4501 @@ -475,20 +517,30 @@ void TextDSetFont(textDisp *textD, XFont
4502 selectFGPixel = values.foreground;
4503 selectBGPixel = values.background;
4504 XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values);
4505 highlightFGPixel = values.foreground;
4506 highlightBGPixel = values.background;
4507 XGetGCValues(display, textD->lineNumGC, GCForeground, &values);
4508 lineNumFGPixel = values.foreground;
4509 + XGetGCValues(display, textD->wrapMarginGC, GCForeground, &values);
4510 + wrapMarginFGPixel = values.foreground;
4512 releaseGC(textD->w, textD->gc);
4513 releaseGC(textD->w, textD->selectGC);
4514 releaseGC(textD->w, textD->highlightGC);
4515 releaseGC(textD->w, textD->selectBGGC);
4516 releaseGC(textD->w, textD->highlightBGGC);
4517 releaseGC(textD->w, textD->lineNumGC);
4518 + releaseGC(textD->w, textD->wrapMarginGC);
4519 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
4520 - selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel);
4521 + selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
4522 + wrapMarginFGPixel);
4523 XSetFont(display, textD->styleGC, fontStruct->fid);
4525 /* Do a full resize to force recalculation of font related parameters */
4526 width = textD->width;
4527 height = textD->height;
4528 @@ -642,10 +694,13 @@ void TextDRedisplayRect(textDisp *textD,
4529 redisplayLine(textD, line, left, left+width, 0, INT_MAX);
4531 /* draw the line numbers if exposed area includes them */
4532 if (textD->lineNumWidth != 0 && left <= textD->lineNumLeft + textD->lineNumWidth)
4533 redrawLineNumbers(textD, False);
4535 + /* draw wrap margin incase it got erased */
4536 + drawWrapMargin(textD);
4540 ** Refresh all of the text between buffer positions "start" and "end"
4541 ** not including the character at the position "end".
4542 @@ -654,11 +709,11 @@ void TextDRedisplayRect(textDisp *textD,
4543 ** any range of characters.
4545 static void textDRedisplayRange(textDisp *textD, int start, int end)
4547 int i, startLine, lastLine, startIndex, endIndex;
4550 /* If the range is outside of the displayed text, just return */
4551 if (end < textD->firstChar || (start > textD->lastChar &&
4552 !emptyLinesVisible(textD)))
4555 @@ -711,23 +766,103 @@ static void textDRedisplayRange(textDisp
4556 resetClipRectangles(textD);
4558 /* If the starting and ending lines are the same, redisplay the single
4559 line between "start" and "end" */
4560 if (startLine == lastLine) {
4561 + /* Add one to endIndex to catch the caret at the end of a range. */
4562 redisplayLine(textD, startLine, 0, INT_MAX, startIndex, endIndex);
4565 + if (-1 != textD->lineStarts[startLine] ||
4566 + (BufCountDispChars(textD->buffer, textD->lineStarts[startLine],
4567 + start) <= textD->wrapMargin &&
4568 + BufCountDispChars(textD->buffer, textD->lineStarts[startLine],
4569 + end) >= textD->wrapMargin))
4571 + /* redraw wrap margin if it got erased */
4572 + drawWrapMargin(textD);
4575 + /* Redisplay the first line from "start" */
4576 + redisplayLine(textD, startLine, 0, INT_MAX, startIndex, INT_MAX);
4578 + /* Redisplay the lines in between at their full width */
4579 + for (i = startLine+1; i < lastLine; i++) {
4580 + redisplayLine(textD, i, 0, INT_MAX, 0, INT_MAX);
4583 + /* Redisplay the last line to "end". Add one to the endIndex to catch
4584 + the caret at the end of a range. */
4585 + redisplayLine(textD, lastLine, 0, INT_MAX, 0, endIndex);
4587 + /* redraw wrap margin */
4588 + drawWrapMargin(textD);
4591 - /* Redisplay the first line from "start" */
4592 - redisplayLine(textD, startLine, 0, INT_MAX, startIndex, INT_MAX);
4594 - /* Redisplay the lines in between at their full width */
4595 - for (i=startLine+1; i<lastLine; i++)
4596 - redisplayLine(textD, i, 0, INT_MAX, 0, INT_MAX);
4599 - /* Redisplay the last line to "end" */
4600 - redisplayLine(textD, lastLine, 0, INT_MAX, 0, endIndex);
4602 +** Custom version of TextDRedisplayRange that only updates the area around
4605 +static void redisplayCursor(textDisp* textD)
4607 + int cursorLine, lineStart, start, end, startIndex, endIndex;
4608 + int pos = textD->cursorPos;
4609 + Boolean cursorLineChanged;
4611 + /* If the cursor is outside of the displayed text, just return */
4612 + if (pos + 1 < textD->firstChar || pos - 1 > textD->lastChar) {
4616 + if (!posToVisibleLineNum(textD, pos, &cursorLine)) {
4617 + /* At first sight, this can only be reached when redisplayCursor()
4618 + is miscalled or when the catch above didn't work. There is at
4619 + least one situation though which makes the catch helpless: If
4620 + your caret is in the last line, column 1 and you move it down,
4621 + textD->cursorPos will be changed *before* this function is
4622 + called, the automatic scroll will be done after. */
4626 + /* Find the position right before and after the cursor,
4627 + but make sure that we stay on the same line. */
4628 + lineStart = TextDStartOfLine(textD, pos);
4629 + start = max(lineStart, pos - 1);
4630 + end = min(pos + 1, TextDEndOfLine(textD, lineStart, True) + 1);
4632 + /* Get the starting and ending positions within the line. */
4633 + startIndex = start - lineStart;
4634 + endIndex = end - lineStart;
4636 + /* Reset the clipping rectangles for the drawing GCs which are shared
4637 + using XtAllocateGC, and may have changed since the last use */
4638 + resetClipRectangles(textD);
4641 + cursorLineChanged = (textD->oldCursorPos != textD->cursorPos
4642 + || textD->oldLineStart != lineStart);
4644 + redisplayLine(textD, cursorLine, 0, INT_MAX, startIndex, endIndex);
4647 + if (cursorLineChanged) {
4648 + /* Hairline destroyed in old cursor line! Redraw neccessary. */
4649 + drawWrapMargin(textD);
4653 + if (BufCountDispChars(textD->buffer, lineStart, end) < textD->wrapMargin) {
4654 + /* hairline is off-screen, most common case */
4658 + if (BufCountDispChars(textD->buffer, lineStart, start)
4659 + > textD->wrapMargin) {
4663 + drawWrapMargin(textD);
4667 ** Set the scroll position of the text display vertically by line number and
4668 ** horizontally by pixel offset from the left margin
4669 @@ -769,12 +904,14 @@ void TextDGetScroll(textDisp *textD, int
4670 ** Set the position of the text insertion cursor for text display "textD"
4672 void TextDSetInsertPosition(textDisp *textD, int newPos)
4674 /* make sure new position is ok, do nothing if it hasn't changed */
4675 - if (newPos == textD->cursorPos)
4677 + if (newPos == textD->cursorPos) {
4681 if (newPos < 0) newPos = 0;
4682 if (newPos > textD->buffer->length) newPos = textD->buffer->length;
4684 /* cursor movement cancels vertical cursor motion column */
4685 textD->cursorPreferredCol = -1;
4686 @@ -783,37 +920,45 @@ void TextDSetInsertPosition(textDisp *te
4687 TextDBlankCursor(textD);
4689 /* draw it at its new position */
4690 textD->cursorPos = newPos;
4691 textD->cursorOn = True;
4692 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos + 1);
4694 + redisplayCursor(textD);
4696 + /* We have to force redraw of the hairline here: The hairline will be
4697 + erased if the cursorline changes, but will not be redrawn by
4698 + redisplayCursor() (only works on the area immedietely surrounding
4700 + drawWrapMargin(textD);
4703 void TextDBlankCursor(textDisp *textD)
4705 if (!textD->cursorOn)
4708 blankCursorProtrusions(textD);
4709 textD->cursorOn = False;
4710 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
4711 + redisplayCursor(textD);
4714 void TextDUnblankCursor(textDisp *textD)
4716 if (!textD->cursorOn) {
4717 textD->cursorOn = True;
4718 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
4719 + redisplayCursor(textD);
4723 void TextDSetCursorStyle(textDisp *textD, int style)
4725 textD->cursorStyle = style;
4726 blankCursorProtrusions(textD);
4727 - if (textD->cursorOn) {
4728 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos + 1);
4729 + if (textD->cursorOn)
4731 + redisplayCursor(textD);
4735 void TextDSetWrapMode(textDisp *textD, int wrap, int wrapMargin)
4737 @@ -845,10 +990,19 @@ void TextDSetWrapMode(textDisp *textD, i
4738 /* Do a full redraw */
4739 TextDRedisplayRect(textD, 0, textD->top, textD->width + textD->left,
4743 +void TextDSetShowWrapMargin(textDisp* textD, int state)
4745 + textD->showWrapMargin = state;
4747 + /* Do a full redraw */
4748 + TextDRedisplayRect(textD, 0, textD->top, textD->width + textD->left,
4752 int TextDGetInsertPosition(textDisp *textD)
4754 return textD->cursorPos;
4757 @@ -1341,15 +1495,15 @@ int TextDMoveDown(textDisp *textD, int a
4760 column = textD->cursorPreferredCol >= 0
4761 ? textD->cursorPreferredCol
4762 : BufCountDispChars(textD->buffer, lineStartPos, textD->cursorPos);
4766 nextLineStartPos = BufCountForwardNLines(textD->buffer, lineStartPos, 1);
4769 nextLineStartPos = TextDCountForwardNLines(textD, lineStartPos, 1, True);
4772 newPos = BufCountForwardDispChars(textD->buffer, nextLineStartPos, column);
4774 if (textD->continuousWrap && !absolute) {
4775 newPos = min(newPos, TextDEndOfLine(textD, nextLineStartPos, True));
4776 @@ -2720,12 +2994,13 @@ static void setScroll(textDisp *textD, i
4778 else if (xOffset < 0) {
4779 TextDRedisplayRect(textD, textD->left + textD->width + xOffset,
4780 textD->top, -xOffset, textD->height);
4783 /* Restore protruding parts of the cursor */
4784 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
4785 + redisplayCursor(textD);
4788 /* Refresh line number/calltip display if its up and we've scrolled
4790 if (lineDelta != 0) {
4791 @@ -2886,14 +3161,34 @@ static void redrawLineNumbers(textDisp *
4793 static void vScrollCB(Widget w, XtPointer clientData, XtPointer callData)
4795 textDisp *textD = (textDisp *)clientData;
4796 int newValue = ((XmScrollBarCallbackStruct *)callData)->value;
4797 + int reason = ((XmScrollBarCallbackStruct*) callData)->reason;
4798 int lineDelta = newValue - textD->topLineNum;
4800 - if (lineDelta == 0)
4802 + if (0 == lineDelta) {
4803 + KillScrolltip(textD);
4807 + /* lineDelta is always != 0 for XmCR_DRAG */
4808 + /* Scrolltip does not work for continuous wrap. The only way to get the
4809 + line number is through textDisp->absTopLineNum, but this value is very
4810 + inaccurate for large files. So no tip. */
4811 + if (XmCR_DRAG == reason && !textD->continuousWrap && textD->showScrolltip) {
4812 + /* Display a scrolltip showing the line number about one third down
4813 + from the top, the position a search jumps to. */
4814 + XEvent* event = ((XmScrollBarCallbackStruct*) callData)->event;
4815 + XMotionEvent* motionEvent = (XMotionEvent*) event;
4816 + char valueBuffer[TYPE_INT_STR_SIZE(int)];
4818 + sprintf(valueBuffer, "%i", newValue + (textD->nVisibleLines / 3));
4819 + ShowScrolltip(textD, valueBuffer, motionEvent->x_root - 50,
4820 + motionEvent->y_root);
4823 setScroll(textD, newValue, textD->horizOffset, False, True);
4825 static void hScrollCB(Widget w, XtPointer clientData, XtPointer callData)
4827 textDisp *textD = (textDisp *)clientData;
4828 @@ -3008,11 +3303,12 @@ static void blankCursorProtrusions(textD
4829 ** Allocate shared graphics contexts used by the widget, which must be
4830 ** re-allocated on a font change.
4832 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
4833 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
4834 - Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel)
4835 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
4836 + Pixel wrapMarginFGPixel)
4838 textD->gc = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
4839 fgPixel, bgPixel, fontStruct->fid, GCClipMask, GCArcMode);
4840 textD->selectGC = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
4841 selectFGPixel, selectBGPixel, fontStruct->fid, GCClipMask,
4842 @@ -3022,13 +3318,20 @@ static void allocateFixedFontGCs(textDis
4843 textD->highlightGC = allocateGC(textD->w, GCFont|GCForeground|GCBackground,
4844 highlightFGPixel, highlightBGPixel, fontStruct->fid, GCClipMask,
4846 textD->highlightBGGC = allocateGC(textD->w, GCForeground, highlightBGPixel,
4847 0, fontStruct->fid, GCClipMask, GCArcMode);
4848 textD->lineNumGC = allocateGC(textD->w, GCFont | GCForeground |
4849 GCBackground, lineNumFGPixel, bgPixel, fontStruct->fid,
4850 GCClipMask, GCArcMode);
4851 + textD->wrapMarginGC = allocateGC(textD->w, GCForeground | GCBackground,
4852 + wrapMarginFGPixel, bgPixel, fontStruct->fid, GCClipMask, GCArcMode);
4856 ** X11R4 does not have the XtAllocateGC function for sharing graphics contexts
4857 ** with changeable fields. Unfortunately the R4 call for creating shared
4858 @@ -3097,10 +3400,16 @@ static void resetClipRectangles(textDisp
4859 &clipRect, 1, Unsorted);
4860 XSetClipRectangles(display, textD->highlightBGGC, 0, 0,
4861 &clipRect, 1, Unsorted);
4862 XSetClipRectangles(display, textD->styleGC, 0, 0,
4863 &clipRect, 1, Unsorted);
4864 + XSetClipRectangles(display, textD->wrapMarginGC, 0, 0,
4865 + &clipRect, 1, Unsorted);
4869 ** Return the length of a line (number of displayable characters) by examining
4870 ** entries in the line starts array rather than by scanning for newlines
4871 @@ -3800,5 +4109,47 @@ void TextDSetupBGClasses(Widget w, XmStr
4874 memcpy(*pp_bgClass, bgClass, 256);
4875 memcpy(*pp_bgClassPixel, bgClassPixel, class_no * sizeof (Pixel));
4879 +** Draw wrap margin if requested
4881 +static void drawWrapMargin(textDisp *textD)
4884 + int fontHeight, lineHeight;
4887 + /* attempt to draw the wrap margin # only if
4888 + - widget has been realized
4889 + - font width is not -1, ie. not using different/proportional width fonts
4890 + - show wrap margins is enabled */
4891 + if (XtWindow(textD->w) != 0
4892 + && textD->fixedFontWidth != -1
4893 + && textD->showWrapMargin)
4895 + fromX = textD->left + (textD->fixedFontWidth * textD->wrapMargin)
4896 + - textD->horizOffset - 1;
4898 + /* compute rest of coordinates if line is to right of left margin */
4899 + if (fromX > textD->left)
4901 + fromY = textD->top;
4902 + fontHeight = textD->ascent + textD->descent;
4903 + lineHeight = textD->nVisibleLines * fontHeight - 1;
4904 + XDrawLine(XtDisplay(textD->w), XtWindow(textD->w),
4905 + textD->wrapMarginGC, fromX, fromY, fromX,
4906 + fromY + lineHeight);
4908 + Handle to move wrap margin around with the mouse.
4909 + XDrawLine(XtDisplay(textD->w), XtWindow(textD->w),
4910 + textD->wrapMarginGC, fromX - 1, fromY, fromX - 1,
4912 + XDrawLine(XtDisplay(textD->w), XtWindow(textD->w),
4913 + textD->wrapMarginGC, fromX + 1, fromY, fromX + 1,
4919 diff --quilt old/source/textDisp.h new/source/textDisp.h
4920 --- old/source/textDisp.h
4921 +++ new/source/textDisp.h
4922 @@ -72,10 +72,11 @@ typedef struct _calltipStruct {
4923 Boolean anchored; /* Is it anchored to a position */
4924 int pos; /* Position tip is anchored to */
4925 int hAlign; /* horizontal alignment */
4926 int vAlign; /* vertical alignment */
4927 int alignMode; /* Strict or sloppy alignment */
4928 + Widget widget; /* calltip's widget */
4931 typedef struct _textDisp {
4933 int top, left, width, height, lineNumLeft, lineNumWidth;
4934 @@ -101,17 +102,21 @@ typedef struct _textDisp {
4935 either to a newline or one character
4936 beyond the end of the buffer) */
4937 int continuousWrap; /* Wrap long lines when displaying */
4938 int wrapMargin; /* Margin in # of char positions for
4939 wrapping in continuousWrap mode */
4940 + int showWrapMargin; /* draw line at wrap margin */
4942 - int topLineNum; /* Line number of top displayed line
4943 - of file (first line of file is 1) */
4944 - int absTopLineNum; /* In continuous wrap mode, the line
4945 - number of the top line if the text
4946 - were not wrapped (note that this is
4947 - only maintained as needed). */
4948 + int topLineNum; /* Almost the line number of top displayed line
4949 + of file (first line of file is 1). Actually
4950 + it's off by one screenful or so most of the
4952 + int absTopLineNum; /* In continuous wrap mode, almost the line
4953 + number of the top line if the text were not
4954 + wrapped. Actually it's off by one screenful
4955 + most of the times. (Note that this is only
4956 + maintained as needed). */
4957 int needAbsTopLineNum; /* Externally settable flag to continue
4958 maintaining absTopLineNum even if
4959 it isn't needed for line # display */
4960 int horizOffset; /* Horizontal scroll pos. in pixels */
4961 int visibility; /* Window visibility (see XVisibility event) */
4962 @@ -127,12 +132,15 @@ typedef struct _textDisp {
4963 int ascent, descent; /* Composite ascent and descent for
4964 primary font + all-highlight fonts */
4965 int fixedFontWidth; /* Font width if all current fonts are
4966 fixed and match in width, else -1 */
4967 Widget hScrollBar, vScrollBar;
4968 GC gc, selectGC, highlightGC; /* GCs for drawing text */
4969 GC selectBGGC, highlightBGGC; /* GCs for erasing text */
4970 GC cursorFGGC; /* GC for drawing the cursor */
4971 GC lineNumGC; /* GC for drawing line numbers */
4972 GC styleGC; /* GC with color and font unspecified
4973 for drawing colored/styled text */
4974 Pixel fgPixel, bgPixel; /* Foreground/Background colors */
4975 @@ -143,15 +151,15 @@ typedef struct _textDisp {
4976 Pixel lineNumFGPixel; /* Color for drawing line numbers */
4977 Pixel cursorFGPixel;
4978 Pixel *bgClassPixel; /* table of colors for each BG class */
4979 unsigned char *bgClass; /* obtains index into bgClassPixel[] */
4981 - Widget calltipW; /* The Label widget for the calltip */
4982 - Widget calltipShell; /* The Shell that holds the calltip */
4983 calltipStruct calltip; /* The info for the calltip itself */
4984 Pixel calltipFGPixel;
4985 Pixel calltipBGPixel;
4986 + Pixel wrapMarginFGPixel; /* color for drawing wrap margin */
4987 + GC wrapMarginGC; /* GC for drawing wrap margin */
4988 int suppressResync; /* Suppress resynchronization of line
4989 starts during buffer updates */
4990 int nLinesDeleted; /* Number of lines deleted during
4991 buffer modification (only used
4992 when resynchronization is
4993 @@ -159,28 +167,36 @@ typedef struct _textDisp {
4994 int modifyingTabDist; /* Whether tab distance is being
4996 Boolean pointerHidden; /* true if the mouse pointer is
4998 graphicExposeTranslationEntry *graphicsExposeQueue;
4999 + Boolean showScrolltip;
5003 textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar,
5004 - Position left, Position top, Position width, Position height,
5005 - Position lineNumLeft, Position lineNumWidth, textBuffer *buffer,
5006 - XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
5007 - Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
5008 - Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
5009 - int continuousWrap, int wrapMargin, XmString bgClassString,
5010 - Pixel calltipFGPixel, Pixel calltipBGPixel);
5011 + Position left, Position top, Position width, Position height,
5012 + Position lineNumLeft, Position lineNumWidth,
5013 + textBuffer *buffer,
5014 + XFontStruct *fontStruct,
5015 + Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
5016 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel cursorFGPixel,
5017 + Pixel lineNumFGPixel, Pixel wrapMarginFGPixel, Pixel calltipFGPixel,
5018 + Pixel calltipBGPixel,
5019 + int continuousWrap, int wrapMargin, Boolean showWrapMargin,
5020 + XmString bgClassString, Boolean showScrolltip);
5021 void TextDFree(textDisp *textD);
5022 void TextDSetBuffer(textDisp *textD, textBuffer *buffer);
5023 void TextDAttachHighlightData(textDisp *textD, textBuffer *styleBuffer,
5024 styleTableEntry *styleTable, int nStyles, char unfinishedStyle,
5025 unfinishedStyleCBProc unfinishedHighlightCB, void *cbArg);
5026 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
5027 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
5028 - Pixel lineNoFgP, Pixel cursorFgP);
5029 + Pixel lineNoFgP, Pixel cursorFgP, Pixel wrapMarginFgP);
5030 void TextDSetFont(textDisp *textD, XFontStruct *fontStruct);
5031 int TextDMinFontWidth(textDisp *textD, Boolean considerStyles);
5032 int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles);
5033 void TextDResize(textDisp *textD, int width, int height);
5034 void TextDRedisplayRect(textDisp *textD, int left, int top, int width,
5035 @@ -208,10 +224,11 @@ int TextDMoveUp(textDisp *textD, int abs
5036 int TextDMoveDown(textDisp *textD, int absolute);
5037 void TextDBlankCursor(textDisp *textD);
5038 void TextDUnblankCursor(textDisp *textD);
5039 void TextDSetCursorStyle(textDisp *textD, int style);
5040 void TextDSetWrapMode(textDisp *textD, int wrap, int wrapMargin);
5041 +void TextDSetShowWrapMargin(textDisp *textD, int state);
5042 int TextDEndOfLine(const textDisp* textD, const int pos,
5043 const Boolean startPosIsLineStart);
5044 int TextDStartOfLine(const textDisp* textD, const int pos);
5045 int TextDCountForwardNLines(const textDisp* textD, const int startPos,
5046 const unsigned nLines, const Boolean startPosIsLineStart);
5047 diff --quilt old/source/textP.h new/source/textP.h
5048 --- old/source/textP.h
5049 +++ new/source/textP.h
5050 @@ -57,10 +57,12 @@ extern TextClassRec nTextClassRec;
5052 typedef struct _TextPart {
5054 Pixel selectFGPixel, selectBGPixel, highlightFGPixel, highlightBGPixel;
5055 Pixel cursorFGPixel, lineNumFGPixel, calltipFGPixel, calltipBGPixel;
5056 + Pixel wrapMarginFGPixel;
5057 XFontStruct *fontStruct;
5058 Boolean pendingDelete;
5059 Boolean autoShowInsertPos;
5061 Boolean autoWrapPastedText;
5062 @@ -69,14 +71,17 @@ typedef struct _TextPart {
5063 Boolean smartIndent;
5065 Boolean heavyCursor;
5067 Boolean hidePointer;
5068 + Boolean showScrolltip;
5070 int marginWidth, marginHeight;
5071 int cursorBlinkRate;
5073 + Boolean showWrapMargin;
5077 Cardinal cursorVPadding;
5078 Widget hScrollBar, vScrollBar;
5079 diff --quilt old/source/window.c new/source/window.c
5080 --- old/source/window.c
5081 +++ new/source/window.c
5082 @@ -6,11 +6,11 @@ static const char CVSID[] = "$Id: window
5083 * Copyright (C) 1999 Mark Edel *
5085 * This is free software; you can redistribute it and/or modify it under the *
5086 * terms of the GNU General Public License as published by the Free Software *
5087 * Foundation; either version 2 of the License, or (at your option) any later *
5088 -* version. In addition, you may distribute version of this program linked to *
5089 +* version. In addition, you may distribute versions of this program linked to *
5090 * Motif or Open Motif. See README for details. *
5092 * This software is distributed in the hope that it will be useful, but WITHOUT *
5093 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
5094 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
5095 @@ -167,10 +167,11 @@ static void showStats(WindowInfo *window
5096 static void showISearch(WindowInfo *window, int state);
5097 static void showStatsForm(WindowInfo *window);
5098 static void addToWindowList(WindowInfo *window);
5099 static void removeFromWindowList(WindowInfo *window);
5100 static void focusCB(Widget w, WindowInfo *window, XtPointer callData);
5101 +static void loosingFocusCB(Widget w, WindowInfo *window, XtPointer callData);
5102 static void modifiedCB(int pos, int nInserted, int nDeleted, int nRestyled,
5103 const char *deletedText, void *cbArg);
5104 static void movedCB(Widget w, WindowInfo *window, XtPointer callData);
5105 static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData);
5106 static void dragEndCB(Widget w, WindowInfo *window, dragEndCBStruct *callData);
5107 @@ -257,19 +258,22 @@ WindowInfo *CreateWindow(const char *nam
5108 window->fileMissing = True;
5109 strcpy(window->filename, name);
5110 window->undo = NULL;
5111 window->redo = NULL;
5113 + window->lastFocus = NULL;
5114 window->autoSaveCharCount = 0;
5115 window->autoSaveOpCount = 0;
5116 window->undoOpCount = 0;
5117 window->undoMemUsed = 0;
5118 CLEAR_ALL_LOCKS(window->lockReasons);
5119 + window->transient = False;
5120 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
5121 window->autoSave = GetPrefAutoSave();
5122 window->saveOldVersion = GetPrefSaveOldVersion();
5123 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
5124 + window->showWrapMargin = GetPrefShowWrapMargin();
5125 window->overstrike = False;
5126 window->showMatchingStyle = GetPrefShowMatching();
5127 window->matchSyntaxBased = GetPrefMatchSyntaxBased();
5128 window->showStats = GetPrefStatsLine();
5129 window->showISearchLine = GetPrefISearchLine();
5130 @@ -465,11 +469,12 @@ WindowInfo *CreateWindow(const char *nam
5132 window->iSearchRegexToggle = XtVaCreateManagedWidget("iSearchREToggle",
5133 xmToggleButtonWidgetClass, window->iSearchForm,
5134 XmNlabelString, s1=XmStringCreateSimple("RegExp"),
5135 XmNset, GetPrefSearch() == SEARCH_REGEX_NOCASE
5136 - || GetPrefSearch() == SEARCH_REGEX,
5137 + || GetPrefSearch() == SEARCH_REGEX
5138 + || GetPrefSearch() == SEARCH_REGEX_SMARTCASE,
5139 XmNtopAttachment, XmATTACH_FORM,
5140 XmNbottomAttachment, XmATTACH_FORM,
5141 XmNtopOffset, 1, /* see openmotif note above */
5142 XmNrightAttachment, XmATTACH_WIDGET,
5143 XmNrightWidget, window->iSearchCaseToggle,
5144 @@ -695,23 +700,25 @@ WindowInfo *CreateWindow(const char *nam
5145 text = createTextArea(pane, window, rows,cols,
5146 GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(),
5147 GetPrefWrapMargin(), window->showLineNumbers?MIN_LINE_NUM_COLS:0);
5148 XtManageChild(text);
5149 window->textArea = text;
5150 window->lastFocus = text;
5152 /* Set the initial colors from the globals. */
5154 GetPrefColorName(TEXT_FG_COLOR ),
5155 GetPrefColorName(TEXT_BG_COLOR ),
5156 GetPrefColorName(SELECT_FG_COLOR),
5157 GetPrefColorName(SELECT_BG_COLOR),
5158 GetPrefColorName(HILITE_FG_COLOR),
5159 GetPrefColorName(HILITE_BG_COLOR),
5160 GetPrefColorName(LINENO_FG_COLOR),
5161 - GetPrefColorName(CURSOR_FG_COLOR));
5162 + GetPrefColorName(CURSOR_FG_COLOR),
5163 + GetPrefColorName(WRAPMARGIN_FG_COLOR));
5165 /* Create the right button popup menu (note: order is important here,
5166 since the translation for popping up this menu was probably already
5167 added in createTextArea, but CreateBGMenu requires window->textArea
5168 to be set so it can attach the menu to it (because menu shells are
5169 finicky about the kinds of widgets they are attached to)) */
5170 @@ -1214,14 +1221,15 @@ void SplitPane(WindowInfo *window)
5171 newTextD = ((TextWidget)text)->text.textD;
5173 XmNforeground, textD->fgPixel,
5174 XmNbackground, textD->bgPixel,
5176 - TextDSetColors( newTextD, textD->fgPixel, textD->bgPixel,
5177 - textD->selectFGPixel, textD->selectBGPixel, textD->highlightFGPixel,
5178 - textD->highlightBGPixel, textD->lineNumFGPixel,
5179 - textD->cursorFGPixel );
5180 + TextDSetColors(newTextD, textD->fgPixel, textD->bgPixel,
5181 + textD->selectFGPixel, textD->selectBGPixel,
5182 + textD->highlightFGPixel, textD->highlightBGPixel,
5183 + textD->lineNumFGPixel, textD->cursorFGPixel,
5184 + textD->wrapMarginFGPixel);
5186 /* Set the minimum pane height in the new pane */
5187 UpdateMinPaneHeights(window);
5189 /* adjust the heights, scroll positions, etc., to split the focus pane */
5190 @@ -1292,11 +1300,11 @@ void ClosePane(WindowInfo *window)
5192 short paneHeights[MAX_PANES+1];
5193 int insertPositions[MAX_PANES+1], topLines[MAX_PANES+1];
5194 int horizOffsets[MAX_PANES+1];
5197 + Widget text = NULL;
5199 /* Don't delete the last pane */
5200 if (window->nPanes <= 0)
5203 @@ -1853,11 +1866,12 @@ void SetFonts(WindowInfo *window, const
5204 UpdateMinPaneHeights(window);
5207 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
5208 const char *selectFg, const char *selectBg, const char *hiliteFg,
5209 - const char *hiliteBg, const char *lineNoFg, const char *cursorFg)
5210 + const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
5211 + const char* wrapMarginFg)
5214 Pixel textFgPix = AllocColor( window->textArea, textFg,
5215 &dummy, &dummy, &dummy),
5216 textBgPix = AllocColor( window->textArea, textBg,
5217 @@ -1871,30 +1885,36 @@ void SetColors(WindowInfo *window, const
5218 hiliteBgPix = AllocColor( window->textArea, hiliteBg,
5219 &dummy, &dummy, &dummy),
5220 lineNoFgPix = AllocColor( window->textArea, lineNoFg,
5221 &dummy, &dummy, &dummy),
5222 cursorFgPix = AllocColor( window->textArea, cursorFg,
5223 + &dummy, &dummy, &dummy),
5224 + wrapMarginFgPix = AllocColor( window->textArea, wrapMarginFg,
5225 &dummy, &dummy, &dummy);
5228 /* Update the main pane */
5229 XtVaSetValues(window->textArea,
5230 XmNforeground, textFgPix,
5231 XmNbackground, textBgPix,
5233 textD = ((TextWidget)window->textArea)->text.textD;
5234 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
5235 - hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix );
5236 + hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
5238 /* Update any additional panes */
5239 for (i=0; i<window->nPanes; i++) {
5240 XtVaSetValues(window->textPanes[i],
5241 XmNforeground, textFgPix,
5242 XmNbackground, textBgPix,
5244 textD = ((TextWidget)window->textPanes[i])->text.textD;
5245 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
5246 - hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix );
5247 + hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
5251 /* Redo any syntax highlighting */
5252 if (window->highlightData != NULL)
5253 UpdateHighlightStyles(window);
5254 @@ -1926,15 +1946,18 @@ void SetAutoWrap(WindowInfo *window, int
5255 for (i=0; i<window->nPanes; i++)
5256 XtVaSetValues(window->textPanes[i], textNautoWrap, autoWrap,
5257 textNcontinuousWrap, contWrap, NULL);
5258 window->wrapMode = state;
5260 if (IsTopDocument(window)) {
5261 XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False);
5262 XmToggleButtonSetState(window->continuousWrapItem, contWrap, False);
5263 XmToggleButtonSetState(window->noWrapItem, state == NO_WRAP, False);
5266 + SetShowWrapMargin(window, window->showWrapMargin);
5270 ** Set the auto-scroll margin
5272 @@ -1946,10 +1969,37 @@ void SetAutoScroll(WindowInfo *window, i
5273 for (i=0; i<window->nPanes; i++)
5274 XtVaSetValues(window->textPanes[i], textNcursorVPadding, margin, NULL);
5278 +** Set show-wrap-margin style, one of NEVER, ALWAYS, ON-WRAP
5280 +void SetShowWrapMargin(WindowInfo* window, int state)
5283 + int alwaysShowWrapMargin = (SHOW_WRAP_MARGIN_ALWAYS == state);
5284 + int onWrapShowWrapMargin = (SHOW_WRAP_MARGIN_ON_WRAP == state);
5285 + int autoWrap = (NEWLINE_WRAP == window->wrapMode);
5286 + int contWrap = (CONTINUOUS_WRAP == window->wrapMode);
5287 + /* true or false only. not never/always/on-wrap. text widget does need to know
5288 + exact details. it just needs to know that wrap margin should be shown */
5289 + int showWrapMargin = (alwaysShowWrapMargin
5290 + || (onWrapShowWrapMargin && autoWrap)
5291 + || (onWrapShowWrapMargin && contWrap));
5293 + XtVaSetValues(window->textArea, textNshowWrapMargin, showWrapMargin, NULL);
5294 + for (i = 0; i < window->nPanes; i++) {
5295 + XtVaSetValues(window->textPanes[i],
5296 + textNshowWrapMargin, showWrapMargin,
5299 + /* never/always/on-wrap needs to be stored in window settings, for generating
5301 + window->showWrapMargin = state;
5305 ** Recover the window pointer from any widget in the window, by searching
5306 ** up the widget hierarcy for the top level container widget where the
5307 ** window pointer is stored in the userData field. In a tabbed window,
5308 ** this is the window pointer of the top (active) document, which is
5309 ** returned if w is 'shell-level' widget - menus, find/replace dialogs, etc.
5310 @@ -2203,10 +2253,19 @@ void MakeSelectionVisible(WindowInfo *wi
5311 static Widget createTextArea(Widget parent, WindowInfo *window, int rows,
5312 int cols, int emTabDist, char *delimiters, int wrapMargin,
5315 Widget text, sw, hScrollBar, vScrollBar, frame;
5316 + int alwaysShowWrapMargin = (window->showWrapMargin == SHOW_WRAP_MARGIN_ALWAYS);
5317 + int onWrapShowWrapMargin = (window->showWrapMargin == SHOW_WRAP_MARGIN_ON_WRAP);
5318 + int autoWrap = (window->wrapMode == NEWLINE_WRAP);
5319 + int contWrap = (window->wrapMode == CONTINUOUS_WRAP);
5320 + /* true or false only. not never/always/on-wrap. text widget does need to know
5321 + exact details. it just needs to know that wrap margin should be shown */
5322 + int showWrapMargin = (alwaysShowWrapMargin ||
5323 + (onWrapShowWrapMargin && autoWrap) ||
5324 + (onWrapShowWrapMargin && contWrap) );
5326 /* Create a text widget inside of a scrolled window widget */
5327 sw = XtVaCreateManagedWidget("scrolledW", xmScrolledWindowWidgetClass,
5328 parent, XmNpaneMaximum, SHRT_MAX,
5329 XmNpaneMinimum, PANE_MIN_HEIGHT, XmNhighlightThickness, 0, NULL);
5330 @@ -2226,24 +2285,29 @@ static Widget createTextArea(Widget pare
5331 textNfont, GetDefaultFontStruct(window->fontList),
5332 textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar,
5333 textNreadOnly, IS_ANY_LOCKED(window->lockReasons),
5334 textNwordDelimiters, delimiters,
5335 textNwrapMargin, wrapMargin,
5336 + textNshowWrapMargin, showWrapMargin,
5337 textNautoIndent, window->indentStyle == AUTO_INDENT,
5338 textNsmartIndent, window->indentStyle == SMART_INDENT,
5339 textNautoWrap, window->wrapMode == NEWLINE_WRAP,
5340 textNcontinuousWrap, window->wrapMode == CONTINUOUS_WRAP,
5341 textNoverstrike, window->overstrike,
5342 textNhidePointer, (Boolean) GetPrefTypingHidesPointer(),
5343 textNcursorVPadding, GetVerticalAutoScroll(),
5344 + textNshowScrolltip, GetPrefShowScrolltip(),
5347 XtVaSetValues(sw, XmNworkWindow, frame, XmNhorizontalScrollBar,
5348 hScrollBar, XmNverticalScrollBar, vScrollBar, NULL);
5350 /* add focus, drag, cursor tracking, and smart indent callbacks */
5351 XtAddCallback(text, textNfocusCallback, (XtCallbackProc)focusCB, window);
5352 + XtAddCallback(text, textNlosingFocusCallback,
5353 + (XtCallbackProc) loosingFocusCB, window);
5354 XtAddCallback(text, textNcursorMovementCallback, (XtCallbackProc)movedCB,
5356 XtAddCallback(text, textNdragStartCallback, (XtCallbackProc)dragStartCB,
5358 XtAddCallback(text, textNdragEndCallback, (XtCallbackProc)dragEndCB,
5359 @@ -2292,18 +2356,20 @@ static void movedCB(Widget w, WindowInfo
5360 if (0 != textWidget->text.cursorBlinkProcID)
5362 /* Start blinking the caret again. */
5363 ResetCursorBlink(textWidget, False);
5366 + MacroApplyHook(window, "cursor_moved_hook", 0, NULL, NULL);
5369 static void modifiedCB(int pos, int nInserted, int nDeleted, int nRestyled,
5370 const char *deletedText, void *cbArg)
5372 WindowInfo *window = (WindowInfo *)cbArg;
5373 int selected = window->buffer->primary.selected;
5376 /* update the table of bookmarks */
5377 if (!window->ignoreModify) {
5378 UpdateMarkTable(window, pos, nInserted, nDeleted);
5381 @@ -2363,25 +2429,34 @@ static void modifiedCB(int pos, int nIns
5382 /* Update # of bytes, and line and col statistics */
5383 UpdateStatsLine(window);
5385 /* Check if external changes have been made to file and warn user */
5386 CheckForChangesToFile(window);
5388 + MacroApplyHook(window, "modified_hook", 0, NULL, NULL);
5391 static void focusCB(Widget w, WindowInfo *window, XtPointer callData)
5393 /* record which window pane last had the keyboard focus */
5394 window->lastFocus = w;
5396 /* update line number statistic to reflect current focus pane */
5397 UpdateStatsLine(window);
5399 /* finish off the current incremental search */
5402 /* Check for changes to read-only status and/or file modifications */
5403 CheckForChangesToFile(window);
5405 + MacroApplyHook(window, "focus_hook", 0, NULL, NULL);
5408 +static void loosingFocusCB(Widget w, WindowInfo *window, XtPointer callData)
5410 + MacroApplyHook(window, "loosing_focus_hook", 0, NULL, NULL);
5413 static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData)
5415 /* don't record all of the intermediate drag steps for undo */
5416 @@ -2519,20 +2594,25 @@ void AttachSessionMgrHandler(Widget appS
5417 ** on the shell window. I think this is the most reliable way to tell,
5418 ** but if someone has a better idea please send me a note).
5420 int IsIconic(WindowInfo *window)
5422 - unsigned long *property = NULL;
5423 + /* We expect back a CARD32 (see ICCCM 4.1.3.1) so we use type long to
5424 + get enough room for it, even if it's casted down later on. */
5425 + unsigned long* property = NULL;
5426 unsigned long nItems;
5427 unsigned long leftover;
5428 static Atom wmStateAtom = 0;
5433 - if (wmStateAtom == 0)
5434 - wmStateAtom = XInternAtom(XtDisplay(window->shell), "WM_STATE", False);
5435 + if (0 == wmStateAtom) {
5436 + /* Get Atom for WM_STATE, create if it does not exist. */
5437 + wmStateAtom = XInternAtom(XtDisplay(window->shell), "WM_STATE", False);
5440 if (XGetWindowProperty(XtDisplay(window->shell), XtWindow(window->shell),
5441 wmStateAtom, 0L, 1L, False, wmStateAtom, &actualType, &actualFormat,
5442 &nItems, &leftover, (unsigned char **)&property) != Success ||
5443 nItems != 1 || property == NULL)
5445 @@ -3276,19 +3364,22 @@ WindowInfo* CreateDocument(WindowInfo* s
5446 window->lastModTime = 0;
5447 strcpy(window->filename, name);
5448 window->undo = NULL;
5449 window->redo = NULL;
5451 window->autoSaveCharCount = 0;
5452 window->autoSaveOpCount = 0;
5453 window->undoOpCount = 0;
5454 window->undoMemUsed = 0;
5455 CLEAR_ALL_LOCKS(window->lockReasons);
5456 + window->transient = False;
5457 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
5458 window->autoSave = GetPrefAutoSave();
5459 window->saveOldVersion = GetPrefSaveOldVersion();
5460 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
5461 + window->showWrapMargin = GetPrefShowWrapMargin();
5462 window->overstrike = False;
5463 window->showMatchingStyle = GetPrefShowMatching();
5464 window->matchSyntaxBased = GetPrefMatchSyntaxBased();
5465 window->highlightSyntax = GetPrefHighlightSyntax();
5466 window->backlightCharTypes = NULL;
5467 @@ -3378,23 +3469,25 @@ WindowInfo* CreateDocument(WindowInfo* s
5468 text = createTextArea(pane, window, nRows, nCols,
5469 GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(),
5470 GetPrefWrapMargin(), window->showLineNumbers?MIN_LINE_NUM_COLS:0);
5471 XtManageChild(text);
5472 window->textArea = text;
5473 window->lastFocus = text;
5475 /* Set the initial colors from the globals. */
5477 GetPrefColorName(TEXT_FG_COLOR ),
5478 GetPrefColorName(TEXT_BG_COLOR ),
5479 GetPrefColorName(SELECT_FG_COLOR),
5480 GetPrefColorName(SELECT_BG_COLOR),
5481 GetPrefColorName(HILITE_FG_COLOR),
5482 GetPrefColorName(HILITE_BG_COLOR),
5483 GetPrefColorName(LINENO_FG_COLOR),
5484 - GetPrefColorName(CURSOR_FG_COLOR));
5485 + GetPrefColorName(CURSOR_FG_COLOR),
5486 + GetPrefColorName(WRAPMARGIN_FG_COLOR));
5488 /* Create the right button popup menu (note: order is important here,
5489 since the translation for popping up this menu was probably already
5490 added in createTextArea, but CreateBGMenu requires window->textArea
5491 to be set so it can attach the menu to it (because menu shells are
5492 finicky about the kinds of widgets they are attached to)) */
5493 @@ -3717,10 +3810,11 @@ void RefreshMenuToggleStates(WindowInfo
5495 XmToggleButtonSetState(window->autoSaveItem, window->autoSave, False);
5496 XmToggleButtonSetState(window->overtypeModeItem, window->overstrike, False);
5497 XmToggleButtonSetState(window->matchSyntaxBasedItem, window->matchSyntaxBased, False);
5498 XmToggleButtonSetState(window->readOnlyItem, IS_USER_LOCKED(window->lockReasons), False);
5499 + XmToggleButtonSetState(window->transientItem, window->transient, False);
5501 XtSetSensitive(window->smartIndentItem,
5502 SmartIndentMacrosAvailable(LanguageModeName(window->languageMode)));
5504 SetAutoIndent(window, window->indentStyle);
5505 @@ -4178,11 +4272,12 @@ static void cloneTextPanes(WindowInfo *w
5506 XtVaSetValues(text, XmNforeground, textD->fgPixel,
5507 XmNbackground, textD->bgPixel, NULL);
5508 TextDSetColors(newTextD, textD->fgPixel, textD->bgPixel,
5509 textD->selectFGPixel, textD->selectBGPixel,
5510 textD->highlightFGPixel,textD->highlightBGPixel,
5511 - textD->lineNumFGPixel, textD->cursorFGPixel);
5512 + textD->lineNumFGPixel, textD->cursorFGPixel,
5513 + textD->wrapMarginFGPixel);
5516 /* Set the minimum pane height in the new pane */
5517 UpdateMinPaneHeights(window);
5519 @@ -4330,10 +4425,11 @@ static void cloneDocument(WindowInfo *wi
5520 window->findLastLiteralCase = orgWin->findLastLiteralCase;
5521 window->device = orgWin->device;
5522 window->inode = orgWin->inode;
5523 window->fileClosedAtom = orgWin->fileClosedAtom;
5524 orgWin->fileClosedAtom = None;
5525 + window->transient = orgWin->transient;
5527 /* copy the text/split panes settings, cursor pos & selection */
5528 cloneTextPanes(window, orgWin);
5530 /* copy undo & redo list */
5531 diff --quilt old/source/window.h new/source/window.h
5532 --- old/source/window.h
5533 +++ new/source/window.h
5534 @@ -51,13 +51,16 @@ void SetAutoIndent(WindowInfo *window, i
5535 void SetShowMatching(WindowInfo *window, int state);
5536 void SetFonts(WindowInfo *window, const char *fontName, const char *italicName,
5537 const char *boldName, const char *boldItalicName);
5538 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
5539 const char *selectFg, const char *selectBg, const char *hiliteFg,
5540 - const char *hiliteBg, const char *lineNoFg, const char *cursorFg);
5541 + const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
5542 + const char* wrapMarginFg);
5543 void SetOverstrike(WindowInfo *window, int overstrike);
5544 void SetAutoWrap(WindowInfo *window, int state);
5545 +void SetWrapMargin(WindowInfo *window, int margin);
5546 +void SetShowWrapMargin(WindowInfo *window, int state);
5547 void SetAutoScroll(WindowInfo *window, int margin);
5548 void SplitPane(WindowInfo *window);
5549 Widget GetPaneByIndex(WindowInfo *window, int paneIndex);
5550 int WidgetToPaneIndex(WindowInfo *window, Widget w);
5551 void ClosePane(WindowInfo *window);
5552 diff --quilt old/util/fileUtils.c new/util/fileUtils.c
5553 --- old/util/fileUtils.c
5554 +++ new/util/fileUtils.c
5555 @@ -83,11 +83,11 @@ static void copyThruSlash(char **toStrin
5558 ** Decompose a Unix file name into a file name and a path.
5559 ** Return non-zero value if it fails, zero else.
5560 ** For now we assume that filename and pathname are at
5561 -** least MAXPATHLEN chars long.
5562 +** most MAXPATHLEN chars long.
5563 ** To skip setting filename or pathname pass NULL for that argument.
5566 ParseFilename(const char *fullname, char *filename, char *pathname)
5568 diff --quilt old/util/getfiles.c new/util/getfiles.c
5569 --- old/util/getfiles.c
5570 +++ new/util/getfiles.c
5571 @@ -6,11 +6,11 @@ static const char CVSID[] = "$Id: getfil
5572 * Copyright (C) 1999 Mark Edel *
5574 * This is free software; you can redistribute it and/or modify it under the *
5575 * terms of the GNU General Public License as published by the Free Software *
5576 * Foundation; either version 2 of the License, or (at your option) any later *
5577 -* version. In addition, you may distribute version of this program linked to *
5578 +* version. In addition, you may distribute versions of this program linked to *
5579 * Motif or Open Motif. See README for details. *
5581 * This software is distributed in the hope that it will be useful, but WITHOUT *
5582 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
5583 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
5584 @@ -35,23 +35,19 @@ static const char CVSID[] = "$Id: getfil
5585 * a directory when no filename was specified *
5586 * 6/24/92 by MWE: Made filename list and directory list typeable, *
5587 * set initial focus to filename list *
5588 * 6/25/93 by JMK: Fix memory leaks found by Purify. *
5590 -* Included are two routines written using Motif for accessing files: *
5592 -* GetExistingFilename presents a FileSelectionBox dialog where users can *
5593 -* choose an existing file to open. *
5595 *******************************************************************************/
5597 #ifdef HAVE_CONFIG_H
5598 #include "../config.h"
5601 -#include "getfiles.h"
5602 +#include "DialogF.h"
5603 #include "fileUtils.h"
5604 +#include "getfiles.h"
5610 @@ -73,15 +69,19 @@ static const char CVSID[] = "$Id: getfil
5612 #include <X11/keysym.h>
5614 #include <Xm/FileSB.h>
5615 #include <Xm/Form.h>
5616 +#include <Xm/Label.h>
5617 #include <Xm/List.h>
5618 #include <Xm/MessageB.h>
5619 +#include <Xm/PushB.h>
5620 #include <Xm/PushBG.h>
5621 -#include <Xm/Text.h>
5622 +#include <Xm/RowColumn.h>
5623 #include <Xm/TextF.h>
5624 +#include <Xm/Text.h>
5625 +#include <Xm/ToggleB.h>
5628 #include "../debug.h"
5631 @@ -93,26 +93,29 @@ static const char CVSID[] = "$Id: getfil
5632 #define MAX_LIST_KESTROKE_WAIT 2000 /* Allowable delay in milliseconds
5633 between characters typed to a list
5634 before starting over (throwing
5635 out the accumulated characters */
5637 +#define HFSB_OK 1 /* Get Filename OK constant */
5638 +#define HFSB_CANCEL 2 /* Get Filename Cancel constant */
5640 #define SET_ONE_RSRC(widget, name, newValue) \
5642 static Arg tmpargs[1] = {{name, (XtArgVal)0}}; \
5643 tmpargs[0].value = (XtArgVal)newValue; \
5644 XtSetValues(widget, tmpargs, 1); \
5648 enum yesNoValues {ynNone, ynYes, ynNo};
5650 /* Saved default directory and pattern from last successful call */
5651 static XmString DefaultDirectory = NULL;
5652 static XmString DefaultPattern = NULL;
5654 -/* User settable option for leaving the file name text field in
5655 - GetExistingFilename dialogs. Off by default so new users will get
5656 - used to typing in the list rather than in the text field */
5657 +/* User settable option for leaving the file name text field in file
5658 + dialogs. Off by default so new users will get used to typing in the
5659 + list rather than in the text field */
5660 static int RemoveRedundantTextField = True;
5662 /* Text for help button help display */
5663 /* ... needs variant for VMS */
5665 @@ -131,11 +134,14 @@ If you use the filter field, remember to
5666 either a file name, \"*\" is acceptable, or a trailing \"/\". If \
5667 you don't, the name after the last \"/\" is interpreted as the file name to \
5668 match. When you leave off the file name or trailing \"/\", you won't see \
5669 any files to open in the list \
5670 because the filter specification matched the directory file itself, rather \
5671 -than the files in the directory.";
5672 +than the files in the directory.\n"
5674 +"Hidden files and directories (those whose names begin with a dot) will only "
5675 +"be shown if the 'Show hidden Files' button is activated.";
5677 static const char *HelpNew =
5678 "This dialog allows you to create a new file, or to save the current file \
5679 under a new name. To specify a file \
5680 name in the current directory, complete the name displayed in the \"Save File \
5681 @@ -151,11 +157,14 @@ to move around in the file system hierar
5682 directory names in the list, or selecting them and pressing the \
5683 \"Filter\" button will select that directory. To move upwards \
5684 in the directory tree, double \
5685 click on the directory entry ending in \"..\". You can also move directly \
5686 to a directory by typing the file specification of the path in the \"Filter\" \
5687 -field and pressing the \"Filter\" button.";
5688 +field and pressing the \"Filter\" button."
5690 +"Hidden files and directories (those whose names begins with a dot) will only "
5691 +"be shown if the 'Show hidden Files' button is activated.";
5693 #else /* SGI_CUSTOM */
5694 static const char *HelpExist =
5695 "The \"File to Edit:\" field shows a list of directories and files in the \
5696 current directory.\n\
5697 @@ -175,11 +184,14 @@ will accept icons dragged from the deskt
5698 arrows, to the right, of the field recalls previously selected \
5701 The \"Filter\" button allows you to narrow down the list of files and \
5702 directories shown in the \"File to Edit:\" field. The default filter of \
5703 -\"*\" allows all files to be listed.";
5704 +\"*\" allows all files to be listed."
5706 +"Hidden files and directories (those whose names begins with a dot) will only "
5707 +"be shown if the 'Show hidden Files' button is activated.";
5709 static const char *HelpNew =
5710 "This dialog allows you to create a new file or to save the current file \
5711 under a new name.\n\
5713 @@ -206,15 +218,20 @@ will accept icons dragged from the deskt
5714 arrows, to the right, of the field recalls previously selected \
5717 The \"Filter\" button allows you to narrow down the list of files and \
5718 directories shown in the \"Files\" field. The default filter of \
5719 -\"*\" allows all files to be listed.";
5720 -#endif /* SGI_CUSTOM */
5721 +\"*\" allows all files to be listed."
5723 +"Hidden files and directories (those whose names begins with a dot) will only "
5724 +"be shown if the 'Show hidden Files' button is activated.";
5726 -/* Local Callback Routines and variables */
5727 +#endif /* SGI_CUSTOM */
5730 +** Local Callback Routines and variables
5732 static void newFileOKCB(Widget w, Boolean *client_data,
5733 XmFileSelectionBoxCallbackStruct *call_data);
5734 static void newFileCancelCB(Widget w, Boolean *client_data, caddr_t
5736 static void newHelpCB(Widget w, Widget helpPanel, caddr_t call_data);
5737 @@ -236,104 +253,441 @@ static void listCharEH(Widget w, XtPoint
5738 Boolean *continueDispatch);
5739 static void replacementDirSearchProc(Widget w, XtPointer searchData);
5740 static void replacementFileSearchProc(Widget w, XtPointer searchData);
5741 static void sortWidgetList(Widget listWidget);
5742 static int compareXmStrings(const void *string1, const void *string2);
5743 +static unsigned removeHiddenFiles(Widget listWidget);
5744 +static Boolean removeDotEntry(Widget listWidget);
5745 +static int isHiddenFile(const char* filename);
5746 +static int handleCustomExistFileSB(Widget existFileSB, char *filename);
5747 +static int handleCustomNewFileSB(Widget newFileSB, char *filename, char *defaultName);
5749 -static int SelectResult = GFN_CANCEL; /* Initialize results as cancel */
5750 +static int SelectResult = HFSB_CANCEL; /* Initialize results as cancel */
5751 static Widget YesNoDialog; /* "Overwrite?" dialog widget */
5752 static int YesNoResult; /* Result of overwrite dialog */
5753 static Widget ErrorDialog; /* Dialog widget for error msgs */
5754 static int ErrorDone; /* Flag to mark dialog completed */
5755 static void (*OrigDirSearchProc)(); /* Built in Motif directory search */
5756 static void (*OrigFileSearchProc)(); /* Built in Motif file search proc */
5757 +static void freeFileList(char** list);
5760 - * Do the hard work of setting up a file selection dialog
5762 -Widget getFilenameHelper(Widget parent, char *promptString, char *filename,
5765 - int n; /* number of arguments */
5766 - Arg args[MAX_ARGS]; /* arg list */
5767 - Widget fileSB; /* widget file select box */
5768 - XmString titleString; /* compound string for dialog title */
5769 +static Widget addUtilForm(const Widget fsd, const Boolean showHidden,
5770 + const Boolean haveFormatButtons, const Boolean isContWrapped,
5771 + Boolean* addWrap, int* fileFormat);
5772 +static void hiddenFilesCB(Widget widget, XtPointer client_data,
5773 + XtPointer call_data);
5774 +static void showOptionsCB(Widget pushButton, XtPointer client_data,
5775 + XtPointer call_data);
5776 +static void setFormatCB(Widget widget, XtPointer clientData, XtPointer callData);
5777 +static void addWrapCB(Widget w, XtPointer clientData, XtPointer callData);
5780 +** GetFilenameByDialog()
5782 +** Façade for file dialogs.
5784 +** TODO: Refactor the whole module
5785 +** TODO: The original saved/restored a default directory, but I don't see any
5786 +** adverse effects on OM 2.2.3 or Lesstif 0.95 by just skipping that
5787 +** part. Does this depend on the toolkit and/or version used?
5789 +gfbdValue* GetFilenameByDialog(const gfbdParams params)
5792 + gfbdValue* retValue;
5794 + /* widgets and other GUI stuff */
5796 + XmString titleString;
5799 + unsigned n; /* arg list */
5800 + Arg args[MAX_ARGS]; /* arg list */
5801 + int rc; /* return code of handleCustomExistFileSB() */
5803 + /* Can probably be refactored away. */
5804 + fsbUserDataStruct userData;
5806 + /* some initialization */
5807 + retValue = (gfbdValue*) XtMalloc(sizeof(gfbdValue));
5808 + retValue->status = GFDB_ERROR;
5811 - titleString = XmStringCreateSimple(promptString);
5812 + titleString = XmStringCreateLocalized(params.dialogTitle);
5813 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
5814 XtSetArg(args[n], XmNdialogTitle, titleString); n++;
5815 - fileSB = CreateFileSelectionDialog(parent,"FileSelect",args,n);
5816 + XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++;
5817 + fsd = CreateFileSelectionDialog(params.parentShell, "fsd", args, n);
5818 XmStringFree(titleString);
5820 - if (existing && RemoveRedundantTextField)
5821 - XtUnmanageChild(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_TEXT));
5822 - XtUnmanageChild(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_SELECTION_LABEL));
5824 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_LABEL),
5825 + /* Put mnemonic on labels; this will put the focus in the labeled widget
5826 + if activated. See misc.c:findAndActivateMnemonic() for details. */
5827 + XtVaSetValues(XmFileSelectionBoxGetChild(fsd, XmDIALOG_FILTER_LABEL),
5829 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_TEXT),
5830 + XmNuserData, XmFileSelectionBoxGetChild(fsd, XmDIALOG_FILTER_TEXT),
5832 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST_LABEL),
5833 + XtVaSetValues(XmFileSelectionBoxGetChild(fsd, XmDIALOG_DIR_LIST_LABEL),
5835 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST),
5836 + XmNuserData, XmFileSelectionBoxGetChild(fsd, XmDIALOG_DIR_LIST),
5838 + XtVaSetValues(XmFileSelectionBoxGetChild(fsd, XmDIALOG_LIST_LABEL),
5840 + XmNuserData, XmFileSelectionBoxGetChild(fsd, XmDIALOG_LIST),
5842 + /* The last mnemonic originally used strspn() to find the last mnemonic,
5843 + but used the dialog's title instead of the list's label. Since it broke
5844 + user's GUI expectations I replaced it with a plain letter. */
5846 + /* Unmanage text field and label unless a label is given. */
5847 + if (NULL == params.textfieldLabel) {
5848 + XtUnmanageChild(XmFileSelectionBoxGetChild(fsd, XmDIALOG_TEXT));
5849 + XtUnmanageChild(XmFileSelectionBoxGetChild(fsd, XmDIALOG_SELECTION_LABEL));
5851 + XmString labelString = XmStringCreateLocalized(params.textfieldLabel);
5853 + XtVaSetValues(XmFileSelectionBoxGetChild(fsd, XmDIALOG_SELECTION_LABEL),
5854 + XmNlabelString, labelString,
5856 + XtVaSetValues(XmFileSelectionBoxGetChild(fsd, XmDIALOG_SELECTION_LABEL),
5857 + XmNmnemonic, params.textfieldLabel[strspn(params.textfieldLabel, "lDF")],
5858 + XmNuserData, XmFileSelectionBoxGetChild(fsd, XmDIALOG_TEXT),
5860 + XmStringFree(labelString);
5863 + retValue->fileFormat = params.fileFormat;
5864 + addUtilForm(fsd, params.showHidden, params.haveFormatButtons,
5865 + params.isContWrapped, &(retValue->addWrap), &(retValue->fileFormat));
5867 + /* Do the mnemonic magic. Wait until all mnemonics are prepared. */
5868 + AddDialogMnemonicHandler(fsd, FALSE);
5870 + /* Fix some ancient hardware/toolkit quirks. */
5871 + RemapDeleteKey(XmFileSelectionBoxGetChild(fsd, XmDIALOG_FILTER_TEXT));
5872 + RemapDeleteKey(XmFileSelectionBoxGetChild(fsd, XmDIALOG_TEXT));
5874 + userData.showHidden = params.showHidden;
5875 + XtVaSetValues(fsd, XmNuserData, &userData, NULL);
5877 + /* Refactor this. */
5878 + if (params.fileExists) {
5879 + rc = handleCustomExistFileSB(fsd, retValue->payload);
5881 + rc = handleCustomNewFileSB(fsd, retValue->payload, params.defaultName);
5886 + retValue->status = GFDB_OK;
5889 + retValue->status = GFDB_CANCEL;
5893 + strncpy(retValue->payload, "Something murphied in GetFilenameByDialog, sorry.", MAXPATHLEN);
5894 + retValue->status = GFDB_ERROR;
5902 +** Helper for GetFilenameByDialog()
5904 +** Note: Since mnemonics are set here, wait with your call to activate them
5905 +** via AddDialogMnemonicHandler() until this is done.
5907 +** TODO: The reliance on AddDialogMnemonicHandler() (called in the caller
5908 +** after addUtilForm()) breaks low coupling.
5910 +static Widget addUtilForm(const Widget fsd, const Boolean showHidden,
5911 + const Boolean haveFormatButtons, const Boolean isContWrapped,
5912 + Boolean* addWrap, int* fileFormat)
5914 + Widget utilForm; /* form containing utility widgets */
5915 + Widget optionsForm; /* container for option widgets */
5917 + Widget showOptionsCheckBox; /* (un)display additional options */
5918 + Widget showOptionsPushButton; /* (un)display additional options */
5919 + XmString showOptionsLabel; /* PushButton label */
5921 + Widget hiddenFilesCheckBox; /* (un)displaying hidden files */
5922 + Widget hiddenFilesToggleButton; /* (un)displaying hidden files */
5923 + XmString hiddenFilesLabel; /* ToggleButton label */
5925 + Widget formatBtnsRow;
5926 + Widget unixFormatButton, dosFormatButton, macFormatButton;
5927 + Widget wrapToggle;
5928 + Widget topWidget = NULL;
5930 + XmString s1 = NULL;
5932 + /* Creates a Form containing additional widgets */
5933 + utilForm = XtVaCreateManagedWidget("utilForm", xmFormWidgetClass, fsd, NULL);
5935 + /* Creates a RowColumn containing a PushButton to (un)display the
5937 + showOptionsCheckBox = XtVaCreateManagedWidget("showOptionsCheckBox",
5938 + xmRowColumnWidgetClass, utilForm,
5940 + showOptionsLabel = XmStringCreateLocalized("Less...");
5941 + showOptionsPushButton = XtVaCreateManagedWidget("showOptionsPushButton",
5942 + xmPushButtonWidgetClass, showOptionsCheckBox,
5944 + XmNlabelString, showOptionsLabel,
5947 + XmStringFree(showOptionsLabel);
5948 + XtAddCallback(showOptionsPushButton,
5949 + XmNactivateCallback, showOptionsCB,
5950 + (XtPointer) &fsd);
5952 + /* Creates a Form containing all options. */
5953 + optionsForm = XtVaCreateManagedWidget("optionsForm",
5954 + xmFormWidgetClass, utilForm,
5955 + XmNtopAttachment, XmATTACH_WIDGET,
5956 + XmNtopWidget, showOptionsCheckBox,
5957 + XmNbottomAttachment, XmATTACH_FORM,
5958 + XmNleftAttachment, XmATTACH_FORM,
5959 + XmNrightAttachment, XmATTACH_FORM,
5962 + /* Adds format buttons. */
5963 + if (haveFormatButtons) {
5964 + /* Create RowColumn containing a number of push buttons for file format. */
5965 + formatBtnsRow = XtVaCreateManagedWidget("formatBtnsRow",
5966 + xmRowColumnWidgetClass, optionsForm,
5967 + XmNradioBehavior, XmONE_OF_MANY,
5968 + XmNorientation, XmHORIZONTAL,
5969 + XmNpacking, XmPACK_TIGHT,
5970 + XmNtopAttachment, XmATTACH_FORM,
5971 + XmNleftAttachment, XmATTACH_FORM,
5974 + XtVaCreateManagedWidget("formatBtns",
5975 + xmLabelWidgetClass, formatBtnsRow,
5976 + XmNlabelString, s1 = XmStringCreateSimple("Format:"),
5980 + unixFormatButton = XtVaCreateManagedWidget("unixFormat",
5981 + xmToggleButtonWidgetClass, formatBtnsRow,
5982 + XmNlabelString, s1 = XmStringCreateSimple("Unix"),
5983 + XmNset, UNIX_FILE_FORMAT == *fileFormat,
5984 + XmNuserData, (XtPointer) UNIX_FILE_FORMAT,
5985 + XmNmarginHeight, 0,
5986 + XmNalignment, XmALIGNMENT_BEGINNING,
5990 + XtAddCallback(unixFormatButton, XmNvalueChangedCallback, setFormatCB,
5993 + dosFormatButton = XtVaCreateManagedWidget("dosFormat",
5994 + xmToggleButtonWidgetClass, formatBtnsRow,
5995 + XmNlabelString, s1 = XmStringCreateSimple("DOS"),
5996 + XmNset, DOS_FILE_FORMAT == *fileFormat,
5997 + XmNuserData, (XtPointer) DOS_FILE_FORMAT,
5998 + XmNmarginHeight, 0,
5999 + XmNalignment, XmALIGNMENT_BEGINNING,
6003 + XtAddCallback(dosFormatButton, XmNvalueChangedCallback, setFormatCB,
6006 + macFormatButton = XtVaCreateManagedWidget("macFormat",
6007 + xmToggleButtonWidgetClass, formatBtnsRow,
6008 + XmNlabelString, s1 = XmStringCreateSimple("Macintosh"),
6009 + XmNset, MAC_FILE_FORMAT == *fileFormat,
6010 + XmNuserData, (XtPointer) MAC_FILE_FORMAT,
6011 + XmNmarginHeight, 0,
6012 + XmNalignment, XmALIGNMENT_BEGINNING,
6016 + XtAddCallback(macFormatButton, XmNvalueChangedCallback, setFormatCB,
6019 + if (isContWrapped) {
6020 + wrapToggle = XtVaCreateManagedWidget("addWrap",
6021 + xmToggleButtonWidgetClass, optionsForm,
6023 + s1 = XmStringCreateSimple("Add line breaks where wrapped"),
6024 + XmNalignment, XmALIGNMENT_BEGINNING,
6026 + XmNtopAttachment, XmATTACH_WIDGET,
6027 + XmNtopWidget, formatBtnsRow,
6028 + XmNleftAttachment, XmATTACH_FORM, NULL);
6029 + XtAddCallback(wrapToggle, XmNvalueChangedCallback, addWrapCB, addWrap);
6032 + topWidget = wrapToggle;
6034 + topWidget = formatBtnsRow;
6038 + /* Creates a RowColumn containing a ToggleButton to show/hide
6039 + hidden files in the file lists. */
6040 + hiddenFilesCheckBox = XtVaCreateManagedWidget("hiddenFilesCheckBox",
6041 + xmRowColumnWidgetClass,
6043 + XmNtopAttachment, XmATTACH_WIDGET,
6044 + XmNtopWidget, topWidget,
6045 + XmNbottomAttachment, XmATTACH_FORM,
6046 + XmNleftAttachment, XmATTACH_FORM,
6047 + XmNrightAttachment, XmATTACH_FORM,
6049 - XtVaSetValues(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST_LABEL),
6050 - XmNmnemonic, promptString[strspn(promptString, "lD")],
6051 - XmNuserData, XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST),
6052 + hiddenFilesLabel = XmStringCreateLocalized("Show hidden Files");
6053 + hiddenFilesToggleButton = XtVaCreateManagedWidget("hiddenFilesToggleButton",
6054 + xmToggleButtonWidgetClass,
6055 + hiddenFilesCheckBox,
6057 + XmNlabelString, hiddenFilesLabel,
6058 + XmNset, showHidden,
6060 - AddDialogMnemonicHandler(fileSB, FALSE);
6061 - RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_TEXT));
6062 - RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_TEXT));
6063 + XmStringFree(hiddenFilesLabel);
6064 + XtAddCallback(hiddenFilesToggleButton,
6065 + XmNvalueChangedCallback, hiddenFilesCB,
6066 + (XtPointer) &fsd);
6068 + return optionsForm;
6072 +** Callback for hiddenFilesToggleButton
6073 +** The ToggleButton's state is saved in the FileSelectionBox' XmNuserData
6074 +** field, so that it can be used in the XmN*searchProcs.
6076 +static void hiddenFilesCB(Widget widget,
6077 + XtPointer client_data,
6078 + XtPointer call_data)
6080 + XmToggleButtonCallbackStruct* state =
6081 + (XmToggleButtonCallbackStruct *) call_data;
6082 + Widget* fsbParent = (Widget*) client_data;
6083 + fsbUserDataStruct* userData;
6085 + /* Remember the button's setting for the sort routines */
6086 + XtVaGetValues(*fsbParent, XmNuserData, &userData, NULL);
6087 + userData->showHidden = state->set;
6090 + /* This will take care of the the Motif FSB resource fileFilterStyle. It
6091 + is still honored by NEdit by using it to override the compiled-in
6092 + default (see source/preferences.c, initPrefDefaultsFromResources()),
6093 + but the internal resource will override it. */
6095 + int fileFilterStyle =
6096 + (state->set ? XmFILTER_NONE : XmFILTER_HIDDEN_FILES);
6097 + XtVaSetValues(*fsbParent, XmNfileFilterStyle, fileFilterStyle, NULL);
6102 + /* Reinitialize lists */
6103 + XmFileSelectionDoSearch(*fsbParent, NULL);
6107 +** Callback for showOptionsPushButton
6109 +** client_data ist supposed to carry a pointer to the FSB
6111 +static void showOptionsCB(Widget pushButton,
6112 + XtPointer client_data,
6113 + XtPointer call_data)
6116 + XmString buttonLabel;
6117 + Widget* fsb = (Widget*) client_data;
6118 + Dimension optionFormHeight;
6119 + Widget optionsForm = XtNameToWidget(*fsb, "*optionsForm");
6120 + Dimension fsbHeight;
6122 + XtVaGetValues(pushButton, XmNuserData, &isShown, NULL);
6124 + /* Get initial size of FSB */
6125 + XtVaGetValues(*fsb, XmNheight, &fsbHeight, NULL);
6130 + /* We change the size here because the Less/More button should
6131 + stay under the mouse pointer. */
6132 + XtVaGetValues(optionsForm, XmNheight, &optionFormHeight, NULL);
6133 + XtUnmanageChild(optionsForm);
6134 + XtVaSetValues(*fsb, XmNheight, fsbHeight - optionFormHeight, NULL);
6136 + /* FIXME: Is this a leak? Do we have to delete the old string? */
6137 + buttonLabel = XmStringCreateLocalized("More...");
6138 + XtVaSetValues(pushButton, XmNlabelString, buttonLabel, NULL);
6139 + XmStringFree(buttonLabel);
6143 + /* We change the size here because the Less/More button should
6144 + stay under the mouse pointer. */
6145 + XtManageChild(optionsForm);
6146 + XtVaGetValues(optionsForm, XmNheight, &optionFormHeight, NULL);
6147 + XtVaSetValues(*fsb, XmNheight, fsbHeight + optionFormHeight, NULL);
6149 + /* FIXME: Is this a leak? Do we have to delete the old string? */
6150 + buttonLabel = XmStringCreateLocalized("Less...");
6151 + XtVaSetValues(pushButton, XmNlabelString, buttonLabel, NULL);
6152 + XmStringFree(buttonLabel);
6155 + XtVaSetValues(pushButton, XmNuserData, isShown, NULL);
6158 -/* GetExistingFilename */
6160 -/* This routine will popup a file selection box so that the user can */
6161 -/* select an existing file from the scrollable list. The user is */
6162 -/* prevented from entering a new filename because the edittable text */
6163 -/* area of the file selection box widget is unmanaged. After the user */
6164 -/* selects a file, GetExistingFilename returns the selected filename and */
6165 -/* GFN_OK, indicating that the OK button was pressed. If the user */
6166 -/* pressed the cancel button, the return value is GFN_CANCEL, and the */
6167 -/* filename character string supplied in the call is not altered. */
6171 -/* Widget parent - parent widget id */
6172 -/* char * promptString - prompt string */
6173 -/* char * filename - a string to receive the selected filename */
6174 -/* (this string will not be altered if the */
6175 -/* user pressed the cancel button) */
6177 -/* Returns: GFN_OK - file was selected and OK button pressed */
6178 -/* GFN_CANCEL - Cancel button pressed and no returned file */
6180 -int GetExistingFilename(Widget parent, char *promptString, char *filename)
6182 - Widget existFileSB = getFilenameHelper(parent, promptString, filename,
6184 - return HandleCustomExistFileSB(existFileSB, filename);
6189 - * Same as GetExistingFilename but pick a new file instead of an existing one.
6190 - * In this case the text area of the FSB is *not* unmanaged, so the user can
6191 - * enter a new filename.
6193 -int GetNewFilename(Widget parent, char *promptString, char *filename,
6194 - char *defaultName)
6196 +** Callback procedure for toggle button requesting newlines to be inserted
6197 +** to emulate continuous wrapping.
6199 +static void addWrapCB(Widget w, XtPointer clientData, XtPointer callData)
6201 - Widget fileSB = getFilenameHelper(parent, promptString, filename, False);
6202 - return HandleCustomNewFileSB(fileSB, filename, defaultName);
6204 + int *addWrap = (int *)clientData;
6206 + if (XmToggleButtonGetState(w)) {
6207 + resp = DialogF(DF_WARN, w, 2, "Add Wrap",
6208 + "This operation adds permanent line breaks to\n"
6209 + "match the automatic wrapping done by the\n"
6210 + "Continuous Wrap mode Preferences Option.\n\n"
6211 + "*** This Option is Irreversable ***\n\n"
6212 + "Once newlines are inserted, continuous wrapping\n"
6213 + "will no longer work automatically on these lines", "OK",
6218 + XmToggleButtonSetState(w, False, False);
6227 -** HandleCustomExistFileSB
6228 +** Callback procedure for File Format toggle buttons. Format is stored
6229 +** in userData field of widget button
6231 +static void setFormatCB(Widget widget, XtPointer clientData, XtPointer callData)
6233 + if (XmToggleButtonGetState(widget)) {
6234 + XtPointer userData;
6235 + XtVaGetValues(widget, XmNuserData, &userData, NULL);
6236 + *((int*) clientData) = (int) userData;
6241 +** handleCustomExistFileSB
6243 ** Manage a customized file selection box for opening existing files.
6244 ** Use this if you want to change the standard file selection dialog
6245 ** from the defaults provided in GetExistingFilename, but still
6246 ** want take advantage of the button processing, help messages, and
6247 @@ -344,23 +698,24 @@ int GetNewFilename(Widget parent, char *
6248 ** Widget existFileSB - your custom file selection box widget id
6249 ** char * filename - a string to receive the selected filename
6250 ** (this string will not be altered if the
6251 ** user pressed the cancel button)
6253 -** Returns: GFN_OK - file was selected and OK button pressed
6254 -** GFN_CANCEL - Cancel button pressed and no returned file
6255 +** Returns: HFSB_OK - file was selected and OK button pressed
6256 +** HFSB_CANCEL - Cancel button pressed and no returned file
6259 -int HandleCustomExistFileSB(Widget existFileSB, char *filename)
6260 +int handleCustomExistFileSB(Widget existFileSB, char *filename)
6262 Boolean done_with_dialog=False; /* ok to destroy dialog flag */
6263 char *fileString; /* C string for file selected */
6264 char *dirString; /* C string for dir of file selected */
6265 XmString cFileString; /* compound string for file selected */
6266 XmString cDir; /* compound directory selected */
6267 XmString cPattern; /* compound filter pattern */
6268 Widget help; /* help window form dialog */
6269 + fsbUserDataStruct* userData;
6270 #if XmVersion < 1002
6274 XtAddCallback(existFileSB, XmNokCallback, (XtCallbackProc)existOkCB,
6275 @@ -382,10 +737,17 @@ int HandleCustomExistFileSB(Widget exist
6276 #if XmVersion >= 1002
6277 XtVaSetValues(existFileSB, XmNinitialFocus, XtParent(
6278 XmFileSelectionBoxGetChild(existFileSB, XmDIALOG_LIST)), NULL);
6282 + XtVaGetValues(existFileSB, XmNuserData, &userData, NULL);
6283 + /* FIXME: The nice hidden file patch is broken by Nate's non-factoring. */
6284 + userData->cachedDirList = NULL;
6285 + userData->cachedFileList = NULL;
6286 + XtVaSetValues(existFileSB, XmNuserData, userData, NULL);
6288 ManageDialogCenteredOnPointer(existFileSB);
6291 /* Typing in the directory list is dependent on the list being in the
6292 same form of alphabetical order expected by the character processing
6293 @@ -413,11 +775,11 @@ int HandleCustomExistFileSB(Widget exist
6294 #endif /* SGI_CUSTOM */
6296 while (!done_with_dialog)
6297 XtAppProcessEvent(XtWidgetToApplicationContext(existFileSB), XtIMAll);
6299 - if (SelectResult == GFN_OK) {
6300 + if (SelectResult == HFSB_OK) {
6301 XtVaGetValues(existFileSB, XmNdirSpec, &cFileString, XmNdirectory,
6302 &cDir, XmNpattern, &cPattern, NULL);
6303 /* Undocumented: file selection box widget allocates copies of these
6304 strings on getValues calls. I have risked freeing them to avoid
6305 memory leaks, since I assume other developers have made this same
6306 @@ -457,16 +819,20 @@ int HandleCustomExistFileSB(Widget exist
6307 be necessary as the shell is destroyed automatically when the dialog
6308 is. However, due to a bug in various Lesstif versions, the latter
6309 messes up the grab cascades and leaves new windows without grabs, such
6310 that they appear to be frozen. */
6311 XtDestroyWidget(XtParent(existFileSB));
6313 + freeFileList(userData->cachedDirList);
6314 + freeFileList(userData->cachedFileList);
6316 return SelectResult;
6321 -** HandleCustomNewFileSB
6322 +** handleCustomNewFileSB
6324 ** Manage a customized file selection box for opening new files.
6328 @@ -475,23 +841,24 @@ int HandleCustomExistFileSB(Widget exist
6329 ** (this string will not be altered if the
6330 ** user pressed the cancel button)
6331 ** char* defaultName - default name to be pre-entered in filename
6334 -** Returns: GFN_OK - file was selected and OK button pressed
6335 -** GFN_CANCEL - Cancel button pressed and no returned file
6336 +** Returns: HFSB_OK - file was selected and OK button pressed
6337 +** HFSB_CANCEL - Cancel button pressed and no returned file
6340 -int HandleCustomNewFileSB(Widget newFileSB, char *filename, char *defaultName)
6341 +int handleCustomNewFileSB(Widget newFileSB, char *filename, char *defaultName)
6343 Boolean done_with_dialog=False; /* ok to destroy dialog flag */
6344 Widget help; /* help window form dialog */
6345 XmString cFileString; /* compound string for file selected */
6346 XmString cDir; /* compound directory selected */
6347 XmString cPattern; /* compound filter pattern */
6348 char *fileString; /* C string for file selected */
6349 char *dirString; /* C string for dir of file selected */
6350 + fsbUserDataStruct* userData;
6351 #if XmVersion < 1002
6355 XtAddCallback(newFileSB, XmNokCallback, (XtCallbackProc)newFileOKCB,
6356 @@ -520,10 +887,16 @@ int HandleCustomNewFileSB(Widget newFile
6357 if ( finder != NULL )
6358 XtVaSetValues(newFileSB, XmNinitialFocus, finder, NULL);
6363 + XtVaGetValues(newFileSB, XmNuserData, &userData, NULL);
6364 + userData->cachedDirList = NULL;
6365 + userData->cachedFileList = NULL;
6366 + XtVaSetValues(newFileSB, XmNuserData, userData, NULL);
6368 ManageDialogCenteredOnPointer(newFileSB);
6371 #if XmVersion < 1002
6372 /* To give filename text initial focus, revoke default button status for
6373 @@ -571,11 +944,11 @@ int HandleCustomNewFileSB(Widget newFile
6376 while (!done_with_dialog)
6377 XtAppProcessEvent (XtWidgetToApplicationContext(newFileSB), XtIMAll);
6379 - if (SelectResult == GFN_OK) {
6380 + if (SelectResult == HFSB_OK) {
6381 /* See note in existing file routines about freeing the values
6382 obtained in the following call */
6383 XtVaGetValues(newFileSB, XmNdirSpec, &cFileString, XmNdirectory,
6384 &cDir, XmNpattern, &cPattern, NULL);
6385 if (DefaultDirectory != NULL) XmStringFree(DefaultDirectory);
6386 @@ -603,10 +976,14 @@ int HandleCustomNewFileSB(Widget newFile
6388 XmStringFree(cFileString);
6391 XtDestroyWidget(newFileSB);
6393 + freeFileList(userData->cachedDirList);
6394 + freeFileList(userData->cachedFileList);
6396 return SelectResult;
6400 ** Return current default directory used by GetExistingFilename.
6401 @@ -663,11 +1040,11 @@ void SetFileDialogDefaultPattern(char *p
6402 XmStringFree(DefaultPattern);
6403 DefaultPattern = pattern==NULL ? NULL : XmStringCreateSimple(pattern);
6407 -** Turn on or off the text fiend in the GetExistingFilename file selection
6408 +** Turn on or off the text field in the GetExistingFilename file selection
6409 ** box, where users can enter the filename by typing. This is redundant
6410 ** with typing in the list, and leads users who are new to nedit to miss
6411 ** the more powerful feature in favor of changing the focus and typing
6412 ** in the text field.
6414 @@ -791,11 +1168,11 @@ static void newFileOKCB(Widget w, Boolea
6415 int length; /* length of file name */
6416 int response; /* response to dialog */
6417 struct stat buf; /* status from fstat */
6419 XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename);
6420 - SelectResult = GFN_OK;
6421 + SelectResult = HFSB_OK;
6422 length = strlen(filename);
6423 if (length == 0 || filename[length-1] == '/') {
6424 doErrorDialog("Please supply a name for the file", NULL);
6427 @@ -842,11 +1219,11 @@ static void newFileOKCB(Widget w, Boolea
6431 static void newFileCancelCB(Widget w, Boolean *client_data, caddr_t call_data)
6433 - SelectResult = GFN_CANCEL;
6434 + SelectResult = HFSB_CANCEL;
6435 *client_data = True;
6438 static void newHelpCB(Widget w, Widget helpPanel, caddr_t call_data)
6440 @@ -859,11 +1236,11 @@ static void existOkCB(Widget w, Boolean
6441 char *filename; /* name of chosen file */
6442 int fd; /* file descriptor */
6443 int length; /* length of file name */
6445 XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename);
6446 - SelectResult = GFN_OK;
6447 + SelectResult = HFSB_OK;
6448 length = strlen(filename);
6449 if (length == 0 || filename[length-1] == '/') {
6450 doErrorDialog("Please select a file to open", NULL);
6453 @@ -879,11 +1256,11 @@ static void existOkCB(Widget w, Boolean
6457 static void existCancelCB(Widget w, Boolean * client_data, caddr_t call_data)
6459 - SelectResult = GFN_CANCEL;
6460 + SelectResult = HFSB_CANCEL;
6461 *client_data = True; /* done with dialog */
6464 static void yesNoOKCB(Widget w, caddr_t client_data, caddr_t call_data)
6466 @@ -1066,40 +1443,115 @@ static void listCharEH(Widget w, XtPoint
6467 ** and should be removed. These routines also leak memory like a seive,
6468 ** because Motif's inconsistent treatment of memory in list widgets does
6469 ** not allow us to free lists that we pass in, and most Motif versions
6470 ** don't clean it up properly.
6472 -static void replacementDirSearchProc(Widget w, XtPointer searchData)
6474 +static int restorePreviousList(Widget list, char** prevList)
6480 + while (prevList[count]) {
6483 + XmListDeleteAllItems(list);
6485 + for (i = 0; i < count; ++i) {
6487 + XmListAddItem(list, s = XmStringCreateSimple(prevList[i]), i + 1);
6488 + XtFree(prevList[i]);
6491 + XtFree((char*) prevList);
6495 +static int saveCurrentList(Widget list, char*** saveList)
6500 + XtVaGetValues(list, XmNitems, &items, XmNitemCount, &nItems, NULL);
6501 + *saveList = (char**) XtMalloc(sizeof(char*) * (nItems + 1));
6503 + for (i = 0; i < nItems; ++i) {
6505 + XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &s);
6506 + (*saveList)[i] = s;
6509 + (*saveList)[nItems] = 0;
6513 +static void replacementDirSearchProc(Widget fileSB, XtPointer searchData)
6515 + int fileCount, newFileCount;
6516 + fsbUserDataStruct* userData;
6518 + XtVaGetValues(fileSB, XmNuserData, &userData, NULL);
6520 + if (userData->cachedDirList) {
6521 + restorePreviousList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST),
6522 + userData->cachedDirList);
6523 + userData->cachedDirList = NULL;
6526 /* Call the original search procedure to do the actual search */
6527 - (*OrigDirSearchProc)(w, searchData);
6528 - /* Refreshing a list clears the keystroke history, even if no update. */
6529 + (*OrigDirSearchProc)(fileSB, searchData);
6531 - XtVaGetValues(w, XmNlistUpdated, &updated, NULL);
6536 + fileCount = saveCurrentList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST),
6537 + &userData->cachedDirList);
6539 + if (userData->showHidden)
6541 + /* Remove '.' entry */
6542 + if (removeDotEntry(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST))) {
6543 + newFileCount = fileCount -1;
6545 + newFileCount = fileCount;
6549 + /* Remove hidden files from list */
6550 + removeHiddenFiles(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST));
6552 + XtVaSetValues(fileSB, XmNlistUpdated, True, NULL);
6554 /* Sort the items in the list */
6555 - sortWidgetList(XmFileSelectionBoxGetChild(w, XmDIALOG_DIR_LIST));
6556 + sortWidgetList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_DIR_LIST));
6559 -static void replacementFileSearchProc(Widget w, XtPointer searchData)
6560 +static void replacementFileSearchProc(Widget fileSB, XtPointer searchData)
6565 + fsbUserDataStruct* userData;
6567 + XtVaGetValues(fileSB, XmNuserData, &userData, NULL);
6569 + if (userData->cachedFileList) {
6570 + restorePreviousList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST),
6571 + userData->cachedFileList);
6572 + userData->cachedFileList = NULL;
6575 /* Call the original search procedure to do the actual search */
6576 - (*OrigFileSearchProc)(w, searchData);
6577 - /* Refreshing a list clears the keystroke history, even if no update. */
6578 + (*OrigFileSearchProc)(fileSB, searchData);
6580 - XtVaGetValues(w, XmNlistUpdated, &updated, NULL);
6585 + fileCount = saveCurrentList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST),
6586 + &userData->cachedFileList);
6588 + if (!userData->showHidden) {
6589 + /* Remove hidden files from list */
6590 + removeHiddenFiles(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST));
6592 + XtVaSetValues(fileSB, XmNlistUpdated, True, NULL);
6594 /* Sort the items in the list */
6595 - sortWidgetList(XmFileSelectionBoxGetChild(w, XmDIALOG_LIST));
6596 + sortWidgetList(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_LIST));
6600 ** Sort the items in a list widget "listWidget"
6602 @@ -1132,5 +1584,160 @@ static int compareXmStrings(const void *
6603 result = strcmp(s1, s2);
6610 +** Removes the '.' entry from a listWidget
6613 +** listWidget is an XmList containing filenames
6616 +** first dotEntry in listWidget is removed
6618 +static Boolean removeDotEntry(Widget listWidget)
6620 + /* Items currently in the listWidget */
6626 + /* read values in List into array. */
6627 + XtVaGetValues(listWidget,
6629 + XmNitemCount, &nItems,
6632 + /* Traverse over items; for every item, check whether it's the dotfile;
6633 + if yes, delete it and return True. */
6634 + for (i = 0; i < nItems; i++) {
6635 + /* C string of current list item */
6638 + /* basename of current list item */
6639 + char basename[MAXPATHLEN + 1];
6641 + /* Convert Motif compound string to C string */
6642 + XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &filename);
6644 + /* Get basename from list item */
6645 + ParseFilename(filename, basename, NULL);
6647 + /* Free C string, allocated by XmStringGetLtoR(). */
6650 + /* if this is the dotEntry... */
6651 + if (0 == strcmp(basename, ".")) {
6652 + /* ...delete it and break. */
6653 + XmListDeletePos(listWidget, i + 1);
6662 +** Removes hidden files from an XmList. Hidden files are all list entries
6663 +** which are recognized as such by isHiddenFile().
6666 +** listWidget is an XmList containing filenames
6667 +** 'int isHiddenFile(const char* fullname)' exists and works.
6670 +** Hidden files in listWidget are removed
6673 +** number of hidden files removed
6675 +static unsigned removeHiddenFiles(Widget listWidget)
6677 + /* Items currently in the listWidget */
6681 + /* Array holding list positions of hidden files. It is allocated based
6682 + on the current number of items in the List. */
6683 + int* hiddenFilePositions;
6685 + /* Number of hidden files found */
6686 + unsigned hiddenFileCount = 0;
6690 + /* read values in List into array. */
6691 + XtVaGetValues(listWidget, XmNitems, &items, XmNitemCount, &nItems, NULL);
6693 + /* Allocate array based on number of items in List. */
6694 + hiddenFilePositions = (int*) XtMalloc(sizeof(int*) * nItems);
6696 + /* Traverse over items; for every item, check whether it's a hidden file;
6697 + if yes, put it in hiddenFilePositions[]. */
6698 + for (i = 0; i < nItems; i++) {
6700 + XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &filename);
6701 + if (isHiddenFile(filename)) {
6702 + /* Add one because XmListDeletePositions expects values > 0. */
6703 + hiddenFilePositions[hiddenFileCount++] = i + 1;
6708 + /* Do the removal. */
6709 + XmListDeletePositions(listWidget, hiddenFilePositions, hiddenFileCount);
6711 + /* Free array of positions. */
6712 + XtFree((char*) hiddenFilePositions);
6714 + return hiddenFileCount;
6718 +** Checks whether fullname is a dotfile, ie. starts with a '.'
6721 +** fullname < MAXPATHLEN
6722 +** 'void ParseFilename(fullname, filename, NULL)' exists and works
6725 +** Returns False for '..' and non-dotfiles, True for other dotfiles.
6727 +static int isHiddenFile(const char* fullname)
6729 + /* array to hold basename */
6730 + char basename[MAXPATHLEN + 1];
6732 + /* Extract basename from full filename */
6733 + ParseFilename(fullname, basename, NULL);
6735 + if (0 == strcmp(basename, "..")) {
6736 + /* Return False for parent directory */
6739 + /* Return True for dotfiles, False for other files */
6740 + return (basename[0] == '.');
6744 +static void freeFileList(char** list)
6753 + while (list[count]) {
6757 + for (i = 0; i < count; i++) {
6761 + XtFree((char*) list);
6763 diff --quilt old/util/getfiles.h new/util/getfiles.h
6764 --- old/util/getfiles.h
6765 +++ new/util/getfiles.h
6767 *******************************************************************************/
6769 #ifndef NEDIT_GETFILES_H_INCLUDED
6770 #define NEDIT_GETFILES_H_INCLUDED
6772 +#include <sys/param.h>
6774 #include <X11/Intrinsic.h>
6776 -#define GFN_OK 1 /* Get Filename OK constant */
6777 -#define GFN_CANCEL 2 /* Get Filename Cancel constant */
6779 +** The interface got smaller on functions and bigger on parameters. It's still
6780 +** a big too large for my tastes, but that's what you get.
6783 + /* GUI customization */
6784 + String dialogTitle;
6785 + Boolean showHidden;
6787 + Boolean fileExists;
6788 + /* Usually only used for potentially unexisting files. */
6789 + String textfieldLabel; /* only set on new file || GetPrefStdOpenDialog() */
6790 + Boolean haveFormatButtons; /* only makes sense for new files */
6791 + String defaultName;
6793 + /* document details */
6795 + Boolean isContWrapped;
6797 + /* GUI handling */
6798 + Widget parentShell;
6801 +enum gfdbResult {GFDB_OK, GFDB_CANCEL, GFDB_ERROR};
6804 + char payload[MAXPATHLEN + 1]; /* Usually carries the filename */
6809 -int GetExistingFilename(Widget parent, char *promptString, char *filename);
6810 -int GetNewFilename(Widget parent, char *promptString, char *filename,
6811 - char *defaultName);
6812 -int HandleCustomExistFileSB(Widget existFileSB, char *filename);
6813 -int HandleCustomNewFileSB(Widget newFileSB, char *filename, char *defaultName);
6814 char *GetFileDialogDefaultDirectory(void);
6815 char *GetFileDialogDefaultPattern(void);
6816 void SetFileDialogDefaultDirectory(char *dir);
6817 void SetFileDialogDefaultPattern(char *pattern);
6818 void SetGetEFTextFieldRemoval(int state);
6819 +gfbdValue* GetFilenameByDialog(const gfbdParams params);
6824 + char** cachedDirList;
6825 + char** cachedFileList;
6826 +} fsbUserDataStruct;
6828 #endif /* NEDIT_GETFILES_H_INCLUDED */
6829 diff --quilt old/util/prefFile.c new/util/prefFile.c
6830 --- old/util/prefFile.c
6831 +++ new/util/prefFile.c
6832 @@ -6,11 +6,11 @@ static const char CVSID[] = "$Id: prefFi
6833 * Copyright (C) 1999 Mark Edel *
6835 * This is free software; you can redistribute it and/or modify it under the *
6836 * terms of the GNU General Public License as published by the Free Software *
6837 * Foundation; either version 2 of the License, or (at your option) any later *
6838 -* version. In addition, you may distribute version of this program linked to *
6839 +* version. In addition, you may distribute versions of this program linked to *
6840 * Motif or Open Motif. See README for details. *
6842 * This software is distributed in the hope that it will be useful, but WITHOUT *
6843 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
6844 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
6845 @@ -302,11 +302,11 @@ int SavePreferences(Display *display, co
6848 static int stringToPref(const char *string, PrefDescripRec *rsrcDescrip)
6851 - char *cleanStr, *endPtr, **enumStrings;
6852 + char *cleanStr, *endPtr, **enumStrings, *cleanEnumStr;
6854 switch (rsrcDescrip->dataType) {
6856 cleanStr = removeWhiteSpace(string);
6857 *(int *)rsrcDescrip->valueAddr =
6858 @@ -338,22 +338,25 @@ static int stringToPref(const char *stri
6861 *(int *)rsrcDescrip->valueAddr = False;
6864 - cleanStr = removeWhiteSpace(string);
6865 - enumStrings = (char **)rsrcDescrip->arg;
6866 - for (i=0; enumStrings[i]!=NULL; i++) {
6867 - if (!strcmp(enumStrings[i], cleanStr)) {
6868 - *(int *)rsrcDescrip->valueAddr = i;
6874 - *(int *)rsrcDescrip->valueAddr = 0;
6876 + cleanStr = removeWhiteSpace(string);
6877 + enumStrings = (char **)rsrcDescrip->arg;
6878 + for (i=0; enumStrings[i]!=NULL; i++) {
6879 + cleanEnumStr = removeWhiteSpace(enumStrings[i]);
6880 + if (!strcmp(cleanEnumStr, cleanStr)) {
6881 + *(int *)rsrcDescrip->valueAddr = i;
6883 + XtFree(cleanEnumStr);
6886 + XtFree(cleanEnumStr);
6889 + *(int *)rsrcDescrip->valueAddr = 0;
6892 if ((int)strlen(string) >= (int)rsrcDescrip->arg)
6894 strncpy(rsrcDescrip->valueAddr, string, (int)rsrcDescrip->arg);
6896 diff --quilt old/util/printUtils.c new/util/printUtils.c
6897 --- old/util/printUtils.c
6898 +++ new/util/printUtils.c
6899 @@ -6,11 +6,11 @@ static const char CVSID[] = "$Id: printU
6900 * Copyright (C) 1999 Mark Edel *
6902 * This is free software; you can redistribute it and/or modify it under the *
6903 * terms of the GNU General Public License as published by the Free Software *
6904 * Foundation; either version 2 of the License, or (at your option) any later *
6905 -* version. In addition, you may distribute version of this program linked to *
6906 +* version. In addition, you may distribute versions of this program linked to *
6907 * Motif or Open Motif. See README for details. *
6909 * This software is distributed in the hope that it will be useful, but WITHOUT *
6910 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
6911 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
6912 @@ -324,10 +324,12 @@ static Widget createForm(Widget parent)
6914 XtSetArg(args[argcnt], XmNdialogTitle, (st0=XmStringCreateLtoR(
6915 "Print", XmSTRING_DEFAULT_CHARSET))); argcnt++;
6916 XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++;
6917 form = CreateFormDialog(parent, "printForm", args, argcnt);
6919 + /* Why is this not part of the arg vector? */
6920 XtVaSetValues(form, XmNshadowThickness, 0, NULL);
6922 XmStringFree( st0 );
6924 /*********************** LABEL 1 and TEXT BOX 1 *********************/