*** Makefile.in 1997/10/09 23:29:19 1.1 --- Makefile.in 1997/10/24 18:52:33 1.5 *************** *** 0 **** --- 1,362 ---- + # Makefile.in generated automatically by automake 0.28 from Makefile.am + + # Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy, distribute and modify it. + + + SHELL = /bin/sh + + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ + prefix = @prefix@ + exec_prefix = @exec_prefix@ + + bindir = @bindir@ + sbindir = @sbindir@ + libexecdir = @libexecdir@ + datadir = @datadir@ + sysconfdir = @sysconfdir@ + sharedstatedir = @sharedstatedir@ + localstatedir = @localstatedir@ + libdir = @libdir@ + infodir = @infodir@ + mandir = @mandir@ + includedir = @includedir@ + oldincludedir = /usr/include + + pkgdatadir = $(datadir)/@PACKAGE@ + pkglibdir = $(libdir)/@PACKAGE@ + pkgincludedir = $(includedir)/@PACKAGE@ + + AR = @AR@ + RANLIB = @RANLIB@ + PURIFY = @PURIFY@ + + INSTALL = @INSTALL@ + INSTALL_PROGRAM = @INSTALL_PROGRAM@ + INSTALL_DATA = @INSTALL_DATA@ + INSTALL_SCRIPT = @INSTALL_SCRIPT@ + transform = @program_transform_name@ + + AUTOMAKE_OPTIONS = + + bin_PROGRAMS = nedit nc + + DIST_OTHER = + DISTCLEANFILES = + + INCLUDES = -I.. -I$(top_srcdir)/util -I$(srcdir) + CONFIG_HEADER = ../config.h + + LDADD = version.o ../util/libNUtil.a + PROGRAMS = $(bin_PROGRAMS) + + CC = @CC@ + LEX = @LEX@ + YACC = @YACC@ + + DEFS = @DEFS@ + CPPFLAGS = @CPPFLAGS@ + CFLAGS = @CFLAGS@ + BIGGER_STRINGS = @BIGGER_STRINGS@ + LDFLAGS = @LDFLAGS@ + MOTIF_CFLAGS = @MOTIF_CFLAGS@ + MOTIF_LDFLAGS = @MOTIF_LDFLAGS@ + MOTIF_PRE_LIBS = @MOTIF_PRE_LIBS@ + MOTIF_LIBS = @MOTIF_LIBS@ + MOTIF_EXTRA_LIBS = @MOTIF_EXTRA_LIBS@ + LIBS = @LIBS@ + + ALL_X_LIBS = $(MOTIF_PRE_LIBS) $(MOTIF_LIBS) $(MOTIF_EXTRA_LIBS) + COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(MOTIF_CFLAGS) + LINK = $(PURIFY) $(CC) $(LDFLAGS) $(MOTIF_LDFLAGS) -o $@ + + o = .@U@o + nedit_SOURCES = $(SOURCES) + nedit_OBJECTS = $(OBJECTS) + nedit_LDADD = $(LDADD) + nc_SOURCES = nc.c server_common.c clearcase.c + nc_OBJECTS = nc$o server_common$o clearcase$o + nc_LDADD = $(LDADD) + + DIST_COMMON = + + PACKAGE = @PACKAGE@ + VERSION = @VERSION@ + + DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \ + $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER) $(DATA) + + DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \ + $(TEXINFOS) $(INFO_DEPS) $(MANS) $(DIST_OTHER) $(DATA) + + HEADERS = \ + clearcase.h file.h help.h highlight.h macro.h menu.h nedit.h \ + preferences.h regularExp.h search.h selection.h server.h \ + server_common.h shell.h shift.h tags.h text.h textBuf.h textDisp.h \ + textDrag.h textP.h textSel.h undo.h userCmds.h window.h + + SOURCES = \ + clearcase.c file.c help.c highlight.c highlightData.c \ + interpret.c macro.c menu.c nedit.c parse.c \ + preferences.c regularExp.c search.c selection.c \ + server.c server_common.c shell.c shift.c \ + smartIndent.c strerror.c tags.c text.c textBuf.c \ + textDisp.c textDrag.c textSel.c \ + undo.c userCmds.c window.c + + OBJECTS = \ + clearcase$o file$o help$o highlight$o highlightData$o \ + interpret$o macro$o menu$o nedit$o parse$o \ + preferences$o regularExp$o search$o selection$o \ + server$o server_common$o shell$o shift$o \ + smartIndent$o strerror$o tags$o text$o textBuf$o \ + textDisp$o textDrag$o textSel$o \ + undo$o userCmds$o window$o + + default: all + + #$(srcdir)/Makefile.in: Makefile.am + # cd $(top_srcdir) && automake $(subdir)/Makefile + + Makefile: ../config.status Makefile.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + + help.c: ../config.status help.c.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + + mostlyclean-binPROGRAMS: + + clean-binPROGRAMS: + rm -f $(bin_PROGRAMS) + + distclean-binPROGRAMS: + + maintainer-clean-binPROGRAMS: + + install-binPROGRAMS: all + $(top_srcdir)/mkinstalldirs $(bindir) + for p in $(bin_PROGRAMS); do \ + if test -f $$p; then \ + $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi \ + done + + uninstall-binPROGRAMS: + for p in $(bin_PROGRAMS); do \ + rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ + done + + .c.o: + $(COMPILE) $< + + .y.o: + $(YACC.y) $< + $(COMPILE) -o $@ y.tab.c + $(RM) y.tab.c + + mostlyclean-compile: + rm -f *.o core + + clean-compile: + + distclean-compile: + rm -f *.tab.c + + maintainer-clean-compile: + + nedit: $(nedit_OBJECTS) + $(LINK) $(nedit_OBJECTS) $(nedit_LDADD) $(ALL_X_LIBS) $(LIBS) + $(nedit_OBJECTS): ../config.h + + nc: $(nc_OBJECTS) + $(LINK) $(nc_OBJECTS) $(nc_LDADD) $(ALL_X_LIBS) $(LIBS) + $(nc_OBJECTS): ../config.h + + textBufTest: textBufTest.o textBuf.o + $(LINK) textBufTest.o textBuf.o -lXt -o $@ + + help.o: help.c + $(COMPILE) $(BIGGER_STRINGS) help.c + + text.o: text.c + $(COMPILE) $(BIGGER_STRINGS) text.c + + smartIndent.o: smartIndent.c + $(COMPILE) $(BIGGER_STRINGS) smartIndent.c + + ID: $(HEADERS) $(SOURCES) + here=`pwd` && cd $(srcdir) && mkid -f $$here/ID $(SOURCES) $(HEADERS) + + tags: TAGS + + TAGS: + here=`pwd` && cd $(srcdir) && etags $(ETAGS_ARGS) $(SOURCES) $(HEADERS) -o $$here/TAGS + + mostlyclean-tags: + + clean-tags: + + distclean-tags: + rm -f TAGS ID + + maintainer-clean-tags: + + subdir = source + distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) + dist: $(DEP_DISTFILES) + @for file in $(DISTFILES); do \ + test -f $(distdir)/$$file \ + || ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir)/$$file; \ + done + + all: Makefile help.c $(PROGRAMS) + + info: + + dvi: + + check: + + install-exec: install-binPROGRAMS + + install: install-exec + @: + + uninstall: uninstall-binPROGRAMS + + installdirs: + $(top_srcdir)/mkinstalldirs $(bindir) + + + mostlyclean-generic: + test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + + clean-generic: + test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + + distclean-generic: + rm -f Makefile $(DISTCLEANFILES) + rm -f config.cache config.log $(CONFIG_HEADER) stamp-h + + maintainer-clean-generic: + test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + + clean: clean-binPROGRAMS clean-compile clean-tags \ + clean-generic mostlyclean + + distclean: distclean-binPROGRAMS distclean-compile \ + distclean-tags distclean-generic clean + rm -f config.status + + maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ + maintainer-clean-tags maintainer-clean-generic \ + distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + .PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ + clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ + mostlyclean-compile distclean-compile clean-compile \ + maintainer-clean-compile \ + tags mostlyclean-tags distclean-tags clean-tags \ + maintainer-clean-tags dist all info dvi install-exec \ + install uninstall installdirs mostlyclean-generic distclean-generic \ + clean-generic maintainer-clean-generic clean mostlyclean distclean \ + maintainer-clean + + $(PROGRAMS): $(LDADD) + + version.c: stamp-v + stamp-v: Makefile + rm -f t-version.c + echo '#include ' > t-version.c + echo '#include "version.h"' >> t-version.c + echo 'const char *version_string = "'@PACKAGE@ @VERSION@ MV Patch @MV_PATCH@ @MV_PATCH_DATE@'";' \ + >> t-version.c + echo 'const char *configure_date = "'@CONFIGURE_DATE@'";' \ + >> t-version.c + if cmp -s version.c t-version.c; then \ + rm t-version.c; \ + else \ + mv t-version.c version.c; \ + fi + echo timestamp > $@ + + .SUFFIXES: + .SUFFIXES: .c .o .y + + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. + .NOEXPORT: + + $(nedit_OBJECTS): ../config.h + $(nc_OBJECTS): ../config.h + + clearcase.o: clearcase.h + file.o: ../util/misc.h ../util/DialogF.h ../util/fileUtils.h + file.o: ../util/getfiles.h ../util/printUtils.h textBuf.h text.h nedit.h + file.o: window.h preferences.h undo.h file.h menu.h server.h highlight.h shell.h + file.o: clearcase.h + help.o: ../util/misc.h textBuf.h nedit.h help.h + highlight.o: ../util/misc.h ../util/DialogF.h + highlight.o: textBuf.h textDisp.h text.h textP.h nedit.h + highlight.o: regularExp.h highlight.h highlightData.h preferences.h + highlight.o: window.h search.h + highlightData.o: ../util/misc.h ../util/DialogF.h ../util/managedList.h + highlightData.o: textBuf.h nedit.h highlight.h regularExp.h preferences.h + highlightData.o: help.h window.h highlightData.h + interpret.o: textBuf.h nedit.h menu.h text.h interpret.h + macro.o: ../util/DialogF.h ../util/misc.h textBuf.h text.h nedit.h + macro.o: window.h macro.h preferences.h interpret.h parse.h search.h + macro.o: shell.h userCmds.h selection.h + menu.o: ../util/getfiles.h ../util/fontsel.h ../util/DialogF.h + menu.o: ../util/misc.h ../util/fileUtils.h textBuf.h text.h nedit.h + menu.o: file.h menu.h window.h search.h selection.h undo.h shift.h + menu.o: help.h preferences.h tags.h userCmds.h shell.h macro.h + menu.o: highlight.h highlightData.h interpret.h smartIndent.h + nc.o: ../util/fileUtils.h ../util/prefFile.h server_common.h + nedit.o: ../util/misc.h ../util/printUtils.h ../util/fileUtils.h + nedit.o: ../util/getfiles.h textBuf.h nedit.h file.h preferences.h regularExp.h + nedit.o: selection.h tags.h menu.h macro.h server_common.h server.h interpret.h + nedit.o: parse.h + preferences.o: ../util/prefFile.h ../util/misc.h ../util/DialogF.h + preferences.o: ../util/managedList.h ../util/fontsel.h textBuf.h nedit.h text.h + preferences.o: search.h preferences.h window.h userCmds.h highlight.h highlightData.h + preferences.o: help.h regularExp.h smartIndent.h server_common.h + regularExp.o: regularExp.h + search.o: ../util/DialogF.h ../util/misc.h regularExp.h textBuf.h text.h nedit.h + search.o: search.h window.h preferences.h + selection.o: ../util/DialogF.h ../util/fileUtils.h textBuf.h text.h nedit.h + selection.o: selection.h file.h window.h menu.h search.h + server.o: ../util/fileUtils.h textBuf.h nedit.h window.h file.h selection.h + server.o: macro.h menu.h server_common.h server.h preferences.h + server_common.o: ../util/fileUtils.h textBuf.h nedit.h + server_common.o: clearcase.h server_common.h + shell.o: ../util/DialogF.h ../util/misc.h textBuf.h text.h nedit.h window.h + shell.o: preferences.h file.h shell.h macro.h interpret.h + shift.o: ../util/DialogF.h textBuf.h text.h nedit.h shift.h window.h + smartIndent.o: ../util/DialogF.h ../util/misc.h textBuf.h nedit.h text.h + smartIndent.o: preferences.h interpret.h macro.h window.h parse.h shift.h + smartIndent.o: smartIndent.h + tags.o: ../util/DialogF.h ../util/fileUtils.h textBuf.h text.h nedit.h + tags.o: window.h file.h search.h selection.h preferences.h tags.h + text.o: textBuf.h textDisp.h textP.h textSel.h textDrag.h + textBuf.o: textBuf.h + textDisp.o: textBuf.h textDisp.h + textDrag.o: textBuf.h textDisp.h textP.h textDrag.h + textSel.o: textBuf.h textDisp.h textP.h textSel.h + undo.o: textBuf.h text.h nedit.h undo.h search.h window.h file.h userCmds.h + userCmds.o: ../util/DialogF.h ../util/misc.h ../util/managedList.h textBuf.h + userCmds.o: text.h nedit.h preferences.h window.h menu.h shell.h macro.h file.h + userCmds.o: interpret.h parse.h + window.o: ../util/DialogF.h ../util/misc.h textBuf.h textSel.h text.h textDisp.h + window.o: textP.h nedit.h window.h menu.h file.h search.h undo.h preferences.h + window.o: selection.h highlight.h smartIndent.h userCmds.h nedit.bm n.bm + window.o: clearcase.h server.h shell.h *** clearcase.c 1997/10/09 23:29:19 1.1 --- clearcase.c 1997/10/21 21:33:34 1.3 *************** *** 0 **** --- 1,57 ---- + /******************************************************************************* + * * + * clearcase.c -- Nirvana Editor clearcase support * + * * + * Copyright (c) 1991 Universities Research Association, Inc. * + * All rights reserved. * + * * + * This material resulted from work developed under a Government Contract and * + * is subject to the following license: The Government retains a paid-up, * + * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * + * works, perform publicly and display publicly by or for the Government, * + * including the right to distribute to other Government contractors. Neither * + * the United States nor the United States Department of Energy, nor any of * + * their employees, makes any warrenty, express or implied, or assumes any * + * legal liability or responsibility for the accuracy, completeness, or * + * usefulness of any information, apparatus, product, or process disclosed, or * + * represents that its use would not infringe privately owned rights. * + * * + * Fermilab Nirvana GUI Library * + * September, 1996 * + * * + * Written by Mark Edel * + * * + *******************************************************************************/ + #include + #include + #include + #include "clearcase.h" + + char *GetClearCaseViewTag(void) + { + static char viewTagBuffer[MAXCCASEVIEWTAGLEN] = ""; + static char *viewTag = 0; + char *envPtr; + char *tagPtr; + + if(viewTag) { + return viewTag; + } + + /* viewTag has not been setup */ + viewTag = viewTagBuffer; + viewTag[0] = '\0'; + + envPtr = getenv("CLEARCASE_ROOT"); + if(envPtr) + { + tagPtr = strrchr(envPtr, '/'); + if(tagPtr) + { + strcpy(viewTag, tagPtr + 1); + } + } + + return(viewTag); + } + *** clearcase.h 1997/10/09 23:29:19 1.1 --- clearcase.h 1997/10/10 00:15:13 1.2 *************** *** 0 **** --- 1,29 ---- + + /******************************************************************************* + * * + * clearcase.h -- Nirvana Editor clearcase support * + * * + * Copyright (c) 1991 Universities Research Association, Inc. * + * All rights reserved. * + * * + * This material resulted from work developed under a Government Contract and * + * is subject to the following license: The Government retains a paid-up, * + * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * + * works, perform publicly and display publicly by or for the Government, * + * including the right to distribute to other Government contractors. Neither * + * the United States nor the United States Department of Energy, nor any of * + * their employees, makes any warrenty, express or implied, or assumes any * + * legal liability or responsibility for the accuracy, completeness, or * + * usefulness of any information, apparatus, product, or process disclosed, or * + * represents that its use would not infringe privately owned rights. * + * * + * Fermilab Nirvana GUI Library * + * September, 1996 * + * * + * Written by Mark Edel * + * * + *******************************************************************************/ + + #define MAXCCASEVIEWTAGLEN 80 + + char *GetClearCaseViewTag(void); *** comnedit.com 1997/09/26 18:28:17 1.1 --- comnedit.com 1997/10/10 00:15:13 1.2 *************** *** 33,34 **** --- 33,36 ---- $ COMPILE server.c + $ COMPILE server_common.c + $ COMPILE clearcase.c $ ! *** file.c 1997/09/26 18:28:17 1.1 --- file.c 1997/10/24 00:44:11 1.4 *************** *** 24,28 **** *******************************************************************************/ #include #include ! #include #include --- 24,31 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 38,40 **** #include ! #include #endif /*VMS*/ --- 41,49 ---- #include ! #ifdef HAVE_FCNTL_H ! # include ! #endif ! #include ! #ifdef HAVE_UNISTD_H ! # include ! #endif #endif /*VMS*/ *************** *** 48,49 **** --- 57,59 ---- #include "../util/printUtils.h" + #include "../util/misc.h" #include "textBuf.h" *************** *** 56,60 **** #include "file.h" static int doSave(WindowInfo *window); ! static int doOpen(WindowInfo *window, char *name, char *path, int flags); static void backupFileName(WindowInfo *window, char *name); --- 66,75 ---- #include "file.h" + #include "menu.h" + #include "server.h" + #include "highlight.h" + #include "shell.h" + #include "clearcase.h" static int doSave(WindowInfo *window); ! static int doOpen(WindowInfo *window, char *name, char *path, int flags, long start, long end); static void backupFileName(WindowInfo *window, char *name); *************** *** 69,71 **** ! void EditNewFile(void) { --- 84,86 ---- ! WindowInfo* EditNewFile(WindowInfo *parentWindow) { *************** *** 83,86 **** sprintf(name, "Untitled_%d", i); ! for (w=WindowList; w!=NULL; w=w->next) ! if (!strcmp(w->filename, name)) break; --- 98,101 ---- sprintf(name, "Untitled_%d", i); ! for (w=WindowList; w!=NULL; w=w->next) ! if (!strcmp(w->editorInfo->filename, name)) break; *************** *** 91,102 **** /* create the window */ ! window = CreateWindow(name); ! strcpy(window->filename, name); ! strcpy(window->path, ""); ! window->filenameSet = FALSE; SetWindowModified(window, FALSE); ! window->readOnly = FALSE; ! window->lockWrite = FALSE; UpdateWindowReadOnly(window); UpdateStatsLine(window); ! DetermineLanguageMode(window, True); } --- 106,124 ---- /* create the window */ ! window = CreateWindow(name, NULL); ! strcpy(window->editorInfo->filename, name); ! ! /* Use the path of the window were we were invoked from so that the ! open dialog, etc will be relative to that window. */ ! strcpy(window->editorInfo->path, parentWindow ? parentWindow->editorInfo->path : ""); ! window->editorInfo->filenameSet = FALSE; SetWindowModified(window, FALSE); ! window->editorInfo->readOnly = FALSE; ! window->editorInfo->lockWrite = FALSE; ! DetermineLanguageMode(window, True); UpdateWindowReadOnly(window); UpdateStatsLine(window); ! UpdateWindowTitle(window); ! CheckCloseDim(); ! ! return window; } *************** *** 115,117 **** */ ! void EditExistingFile(WindowInfo *inWindow, char *name, char *path, int flags) { --- 137,139 ---- */ ! WindowInfo* EditExistingFile(WindowInfo *inWindow, char *name, char *path, int flags, Boolean forceRaise) { *************** *** 123,126 **** if (window != NULL) { ! XMapRaised(TheDisplay, XtWindow(window->shell)); ! return; } --- 145,153 ---- if (window != NULL) { ! if(forceRaise) { ! XMapRaised(TheDisplay, XtWindow(window->shell)); ! } ! /* Refresh the file open property to indicate that we have ! ** been reopened .*/ ! CreateFileOpenProperty(window); ! return window; } *************** *** 129,139 **** in use (not Untitled or Untitled and modified), create the window */ ! if (inWindow == NULL || inWindow->filenameSet || inWindow->fileChanged) ! window = CreateWindow(name); ! else window = inWindow; /* Open the file */ ! if (!doOpen(window, name, path, flags)) { CloseWindow(window); ! return; } --- 156,177 ---- in use (not Untitled or Untitled and modified), create the window */ ! if (inWindow == NULL ! || inWindow->editorInfo->filenameSet ! || inWindow->editorInfo->fileChanged ! || IsShellCommandInProgress(inWindow) ! || inWindow->editorInfo->buffer->length > 0 ! ) { ! window = CreateWindow(name, NULL); ! } else { window = inWindow; + } + + /* Make sure the window is displayed to the user */ + if(forceRaise) { + XMapRaised(TheDisplay, XtWindow(window->shell)); + } /* Open the file */ ! if (!doOpen(window, name, path, flags, 0, -1)) { CloseWindow(window); ! return NULL; } *************** *** 142,149 **** not necessarily set the window title or read-only status */ ! if (inWindow != NULL) { ! UpdateWindowTitle(window); ! UpdateWindowReadOnly(window); ! } UpdateStatsLine(window); ! --- 180,185 ---- not necessarily set the window title or read-only status */ ! UpdateWindowReadOnly(window); ! UpdateWindowTitle(window); UpdateStatsLine(window); ! CheckCloseDim(); *************** *** 154,160 **** /* Decide what language mode to use, trigger language specific actions */ DetermineLanguageMode(window, True); } ! void RevertToSaved(WindowInfo *window) { --- 190,204 ---- + /* Create the property used to keep track of the open state of this window */ + CreateFileOpenProperty(window); + + /* Set the checking mode back to the default */ + SetCheckingMode(window, GetPrefCheckingMode()); + /* Decide what language mode to use, trigger language specific actions */ DetermineLanguageMode(window, True); + + return window; } ! void RevertToSaved(WindowInfo *window, int silent) { *************** *** 167,169 **** /* Can't revert untitled windows */ ! if (!window->filenameSet) { DialogF(DF_WARN, window->shell, 1, --- 211,213 ---- /* Can't revert untitled windows */ ! if (!window->editorInfo->filenameSet) { DialogF(DF_WARN, window->shell, 1, *************** *** 173,174 **** --- 217,229 ---- + /* re-reading file is irreversible, prompt the user first */ + if (!silent) { + if (window->editorInfo->fileChanged) { + int b; + b = DialogF(DF_QUES, window->shell, 2, "Discard changes to\n%s%s?", + "Discard Changes", "Cancel", window->editorInfo->path, window->editorInfo->filename); + if (b != 1) + return; + } + } + /* save insert & scroll positions of all of the panes to restore later */ *************** *** 181,187 **** /* re-read the file, update the window title if new file is different */ ! strcpy(name, window->filename); ! strcpy(path, window->path); RemoveBackupFile(window); ClearUndoList(window); ! if (!doOpen(window, name, path, 0)) { CloseWindow(window); --- 236,246 ---- /* re-read the file, update the window title if new file is different */ ! strcpy(name, window->editorInfo->filename); ! strcpy(path, window->editorInfo->path); RemoveBackupFile(window); ClearUndoList(window); ! ! { ! Boolean highlight = (window->highlightSyntax && window->highlightData); ! StopHighlighting(window); ! if (!doOpen(window, name, path, 0, 0, -1)) { CloseWindow(window); *************** *** 189,192 **** } ! UpdateWindowTitle(window); UpdateWindowReadOnly(window); --- 248,255 ---- } ! if(highlight) { ! StartHighlighting(window, False); ! } ! } /* local vars */ UpdateWindowReadOnly(window); + UpdateWindowTitle(window); *************** *** 198,202 **** } } ! static int doOpen(WindowInfo *window, char *name, char *path, int flags) { --- 261,266 ---- } + CheckCloseDim(); } ! static int doOpen(WindowInfo *window, char *name, char *path, int flags, long start, long end) { *************** *** 210,216 **** int resp; /* Update the window data structure */ ! strcpy(window->filename, name); ! strcpy(window->path, path); ! window->filenameSet = TRUE; --- 274,281 ---- int resp; + int newLen; /* Update the window data structure */ ! strcpy(window->editorInfo->filename, name); ! strcpy(window->editorInfo->path, path); ! window->editorInfo->filenameSet = TRUE; *************** *** 221,269 **** /* Open the file */ ! if ((fp = fopen(fullname, "r+")) == NULL) { ! /* Error opening file or file is not writeable */ ! if ((fp = fopen(fullname, "r")) != NULL) { ! /* File is read only */ ! readOnly = TRUE; ! } else if (flags & CREATE && errno == ENOENT) { ! /* Give option to create (or to exit if this is the only window) */ ! if (!(flags & SUPPRESS_CREATE_WARN)) { ! if (WindowList == window && window->next == NULL) ! resp = DialogF(DF_WARN, window->shell, 3, ! "Can't open %s:\n%s", "Create", "Cancel", ! "Exit NEdit", fullname, errorString()); ! else ! resp = DialogF(DF_WARN, window->shell, 2, ! "Can't open %s:\n%s", "Create", "Cancel", ! fullname, errorString()); ! if (resp == 2) ! return FALSE; ! else if (resp == 3) ! exit(0); ! } ! /* Test if new file can be created */ ! if ((fd = creat(fullname, 0666)) == -1) { ! DialogF(DF_ERR, window->shell, 1, "Can't create %s:\n%s", ! "Dismiss", fullname, errorString()); ! return FALSE; ! } else { #ifdef VMS ! /* get correct version number and close before removing */ ! getname(fd, fullname); ! close(fd); #endif ! remove(fullname); ! } ! SetWindowModified(window, FALSE); ! window->readOnly = FALSE; ! window->lockWrite = flags & FORCE_READ_ONLY; ! UpdateWindowReadOnly(window); ! return TRUE; ! } else { ! /* A true error */ ! DialogF(DF_ERR, window->shell, 1, "Could not open %s%s:\n%s", ! "Dismiss", path, name, errorString()); ! return FALSE; } ! } ! /* Get the length of the file and the protection mode */ --- 286,350 ---- /* Open the file */ ! #ifdef USE_ACCESS ! fp = fopen(fullname, "r"); ! #else ! fp = fopen(fullname, "r+"); ! if (fp == NULL && errno == EACCES) { ! readOnly = TRUE; ! fp = fopen(fullname, "r"); ! } ! #endif ! if (fp == NULL) { ! /* Error opening the file. If the CREATE flag is set ! and the error was because the file didn't exist then ! try to create it. */ ! if (flags & CREATE && errno == ENOENT) { ! /* Give option to create (or to exit if this is the only window) */ ! if (!(flags & SUPPRESS_CREATE_WARN)) { ! if (WindowList == window && window->next == NULL) ! resp = DialogF(DF_WARN, window->shell, 3, ! "Can't open %s:\n%s", "Create", "Cancel", ! "Exit NEdit", fullname, errorString()); ! else ! resp = DialogF(DF_WARN, window->shell, 2, ! "Can't open %s:\n%s", "Create", "Cancel", ! fullname, errorString()); ! if (resp == 2) ! return FALSE; ! else if (resp == 3) ! exit(0); ! } ! /* Test if new file can be created */ ! if ((fd = creat(fullname, 0666)) == -1) { ! DialogF(DF_ERR, window->shell, 1, "Can't create %s:\n%s", ! "Dismiss", fullname, errorString()); ! return FALSE; ! } else { #ifdef VMS ! /* get correct version number and close before removing */ ! getname(fd, fullname); ! close(fd); #endif ! remove(fullname); ! } ! SetWindowModified(window, FALSE); ! window->editorInfo->readOnly = FALSE; ! window->editorInfo->lockWrite = flags & FORCE_READ_ONLY; ! UpdateWindowReadOnly(window); ! return TRUE; ! } else { ! /* A true error */ ! DialogF(DF_ERR, window->shell, 1, "Could not open %s%s:\n%s", ! "Dismiss", path, name, errorString()); ! return FALSE; ! } ! } ! ! /* See if the file is writable */ ! #ifdef USE_ACCESS ! if(access(fullname, W_OK) != 0) { ! /* File is read only */ ! readOnly = TRUE; } ! #endif ! /* Get the length of the file and the protection mode */ *************** *** 271,276 **** DialogF(DF_ERR, window->shell, 1, "Error opening %s", "Dismiss", name); return FALSE; } ! fileLen = statbuf.st_size; ! window->fileMode = statbuf.st_mode; --- 352,376 ---- DialogF(DF_ERR, window->shell, 1, "Error opening %s", "Dismiss", name); + fclose(fp); return FALSE; } ! ! /* make sure start is within the range of the file */ ! start = start < 0 ? 0 : start; ! start = start > statbuf.st_size ? statbuf.st_size : start; ! ! /* make sure end is within the range of the file */ ! /* if end is negative then use the end of the file */ ! end = end < 0 ? statbuf.st_size : end; ! end = end > statbuf.st_size ? statbuf.st_size : end; ! ! /* make sure end is greater than start */ ! if(start > end) { ! long tmp; ! tmp = end; ! end = start; ! start = tmp; ! } ! fileLen = end - start; ! window->editorInfo->mtime = statbuf.st_mtime; ! window->editorInfo->st_mode = statbuf.st_mode; *************** *** 281,282 **** --- 381,383 ---- "Dismiss"); + fclose(fp); return FALSE; *************** *** 285,286 **** --- 386,392 ---- /* Read the file into fileString and terminate with a null */ + if(start > 0 && fseek(fp, start, SEEK_SET) != 0) { + DialogF(DF_ERR, window->shell, 1, "Error reading %s", "Dismiss", name); + fclose(fp); + return FALSE; + } readLen = fread(fileString, sizeof(char), fileLen, fp); *************** *** 290,291 **** --- 396,398 ---- free(fileString); + fclose(fp); return FALSE; *************** *** 301,313 **** ! /* Display the file contents in the text widget */ ! window->ignoreModify = True; ! BufSetAll(window->buffer, fileString); ! window->ignoreModify = False; ! ! /* Check that the length that the buffer thinks it has is the same ! as what we gave it. If not, there were probably nuls in the file. Substitute them with another character. If that is impossible, warn the user, make the file read-only, and force a substitution */ ! if (window->buffer->length != readLen) { ! if (!BufSubstituteNullChars(fileString, readLen, window->buffer)) { resp = DialogF(DF_ERR, window->shell, 2, --- 408,415 ---- ! /* Check for nulls in the data read. If the strlen != readLen then were ! probably nuls in the file. Substitute them with another character. If that is impossible, warn the user, make the file read-only, and force a substitution */ ! if (strlen(fileString) != readLen) { ! if (!BufSubstituteNullChars(fileString, readLen, window->editorInfo->buffer)) { resp = DialogF(DF_ERR, window->shell, 2, *************** *** 321,329 **** *c = 0xfe; ! window->buffer->nullSubsChar = 0xfe; ! } ! window->ignoreModify = True; ! BufSetAll(window->buffer, fileString); ! window->ignoreModify = False; } /* Release the memory that holds fileString */ --- 423,439 ---- *c = 0xfe; ! window->editorInfo->buffer->nullSubsChar = 0xfe; ! } } + /* Display the file contents in the text widget */ + window->editorInfo->ignoreModify = True; + if(start == 0 && end == statbuf.st_size) { + BufSetAll(window->editorInfo->buffer, fileString); + newLen = readLen; + } else { + newLen = window->editorInfo->buffer->length - (end - start) + readLen; + BufReplace(window->editorInfo->buffer, start, end, fileString); + } + window->editorInfo->ignoreModify = False; + /* Release the memory that holds fileString */ *************** *** 332,342 **** /* Set window title and file changed flag */ ! window->lockWrite = flags & FORCE_READ_ONLY; if (readOnly) { ! window->readOnly = TRUE; ! window->fileChanged = FALSE; UpdateWindowTitle(window); } else { ! window->readOnly = FALSE; SetWindowModified(window, FALSE); ! if (window->lockWrite) UpdateWindowTitle(window); --- 442,452 ---- /* Set window title and file changed flag */ ! window->editorInfo->lockWrite = flags & FORCE_READ_ONLY; if (readOnly) { ! window->editorInfo->readOnly = TRUE; ! window->editorInfo->fileChanged = FALSE; UpdateWindowTitle(window); } else { ! window->editorInfo->readOnly = FALSE; SetWindowModified(window, FALSE); ! if (window->editorInfo->lockWrite) UpdateWindowTitle(window); *************** *** 390,392 **** /* If the file contained ascii nulls, re-map them */ ! if (!BufSubstituteNullChars(fileString, readLen, window->buffer)) DialogF(DF_ERR, window->shell, 1, "Too much binary data in file", --- 500,502 ---- /* If the file contained ascii nulls, re-map them */ ! if (!BufSubstituteNullChars(fileString, readLen, window->editorInfo->buffer)) DialogF(DF_ERR, window->shell, 1, "Too much binary data in file", *************** *** 403,408 **** position in the window if no selection exists */ ! if (window->buffer->primary.selected) ! BufReplaceSelected(window->buffer, fileString); else ! BufInsert(window->buffer, TextGetCursorPos(window->lastFocus), fileString); --- 513,518 ---- position in the window if no selection exists */ ! if (window->editorInfo->buffer->primary.selected) ! BufReplaceSelected(window->editorInfo->buffer, fileString, False); else ! BufInsert(window->editorInfo->buffer, TextGetCursorPos(window->lastFocus), fileString); *************** *** 421,423 **** while (WindowList->next != NULL || ! WindowList->filenameSet || WindowList->fileChanged) { if (!CloseFileAndWindow(WindowList)) --- 531,533 ---- while (WindowList->next != NULL || ! WindowList->editorInfo->filenameSet || WindowList->editorInfo->fileChanged) { if (!CloseFileAndWindow(WindowList)) *************** *** 432,438 **** ! /* Make sure that the window is not in iconified state */ ! XMapRaised(TheDisplay, XtWindow(window->shell)); /* if window is modified, ask about saving, otherwise just close */ ! if (!window->fileChanged) { CloseWindow(window); --- 542,553 ---- ! /* Don't close the window if a shell command is in progress for ! ** this window. */ ! if(IsShellCommandInProgress(window)) { ! XBell(TheDisplay, 0); ! return FALSE; ! } /* if window is modified, ask about saving, otherwise just close */ ! if (!window->editorInfo->fileChanged || ! window->editorInfo->master->nextSlave != 0) { CloseWindow(window); *************** *** 440,444 **** } else { response = DialogF(DF_WARN, window->shell, 3, "Save %s before closing?", "Yes", "No", "Cancel", ! window->filename); if (response == 1) { --- 555,562 ---- } else { + /* Make sure that the window is not in iconified state */ + XMapRaised(TheDisplay, XtWindow(window->shell)); + response = DialogF(DF_WARN, window->shell, 3, "Save %s before closing?", "Yes", "No", "Cancel", ! window->editorInfo->filename); if (response == 1) { *************** *** 462,466 **** ! if (!window->fileChanged || window->lockWrite) return TRUE; ! if (!window->filenameSet) return SaveWindowAs(window, NULL, False); --- 580,584 ---- ! if (!window->editorInfo->fileChanged || window->editorInfo->lockWrite) return TRUE; ! if (!window->editorInfo->filenameSet) return SaveWindowAs(window, NULL, False); *************** *** 484,485 **** --- 602,609 ---- + /* .b: Gives complete name to PromptForNewFile ("Save As" mode) */ + strcpy(fullname, window->editorInfo->path); + if(window->editorInfo->filenameSet) + strcat(fullname, window->editorInfo->filename); + /* .e */ + /* Get the new name for the file */ *************** *** 498,501 **** ParseFilename(fullname, filename, pathname); ! if (!strcmp(window->filename, filename) && ! !strcmp(window->path, pathname)) { if (writeBckVersion(window)) --- 622,625 ---- ParseFilename(fullname, filename, pathname); ! if (!strcmp(window->editorInfo->filename, filename) && ! !strcmp(window->editorInfo->path, pathname)) { if (writeBckVersion(window)) *************** *** 517,529 **** /* Change the name of the file and save it under the new name */ RemoveBackupFile(window); ! strcpy(window->filename, filename); ! strcpy(window->path, pathname); ! window->filenameSet = TRUE; ! window->readOnly = FALSE; ! window->fileMode = 0; ! window->lockWrite = FALSE; retVal = doSave(window); - UpdateWindowTitle(window); UpdateWindowReadOnly(window); --- 641,657 ---- + /* Destroy the file open property for the original file */ + DestroyFileOpenProperty(window); + /* Change the name of the file and save it under the new name */ RemoveBackupFile(window); ! strcpy(window->editorInfo->filename, filename); ! strcpy(window->editorInfo->path, pathname); ! window->editorInfo->filenameSet = TRUE; ! window->editorInfo->readOnly = FALSE; ! window->editorInfo->mtime = 0; ! window->editorInfo->st_mode = 0; ! window->editorInfo->lockWrite = FALSE; retVal = doSave(window); UpdateWindowReadOnly(window); + UpdateWindowTitle(window); *************** *** 531,532 **** --- 659,661 ---- AddToPrevOpenMenu(fullname); + CreateFileOpenProperty(window); *************** *** 538,539 **** --- 667,873 ---- + static void fileCheckTimerProc(WindowInfo *window, XtIntervalId *id) + { + window->editorInfo->tailMinusFTimeoutID = 0; + CheckForChangesInFile(window); + } + + void SetCheckingMode(WindowInfo *window, CheckingMode checkingMode) + { + WindowInfo *win; + window->editorInfo->checkingMode = checkingMode; + + /* Update Preferences menu */ + for(win = window->editorInfo->master; win; win = win->nextSlave) { + XmToggleButtonSetState(win->checkingModePromptToReloadItem, + checkingMode == CHECKING_MODE_PROMPT_TO_RELOAD, FALSE); + XmToggleButtonSetState(win->checkingModeDisabledItem, + checkingMode == CHECKING_MODE_DISABLED, FALSE); + XmToggleButtonSetState(win->checkingModeTailMinusFItem, + checkingMode == CHECKING_MODE_TAIL_MINUS_F, FALSE); + } + + /* If tail -f mode then lets go and see if anything has already been + ** added to the file */ + if(checkingMode == CHECKING_MODE_TAIL_MINUS_F) { + CheckForChangesInFile(window); + } + /* If not tail -f mode then make sure a previous tail -f timer is + ** removed. */ + else { + if(window->editorInfo->tailMinusFTimeoutID) { + XtRemoveTimeOut(window->editorInfo->tailMinusFTimeoutID); + window->editorInfo->tailMinusFTimeoutID = 0; + } + } + } + + /* + ** Check if the file in the window was changed by an external source. + */ + void CheckForChangesInFile(WindowInfo *window) + { + char fullname[MAXPATHLEN]; + struct stat statbuf; + + /* Don't do anything if file checking is disabled. */ + if(window->editorInfo->checkingMode == CHECKING_MODE_DISABLED) + return; + + /* No file to check, so return. */ + if(!window->editorInfo->filenameSet) + return; + + /* Get the full name of the file */ + strcpy(fullname, window->editorInfo->path); + strcat(fullname, window->editorInfo->filename); + + /* get the current mtime and st_mode */ + if (stat(fullname, &statbuf) != 0) + return; + + /* See if the mode has changed. */ + if(window->editorInfo->st_mode != statbuf.st_mode) { + #ifndef USE_ACCESS + FILE *fp; + #endif + /* if the mode has changed, update the read only status */ + /* if it doesn't exist we should still be able to create it by + doing a save, so it shouldn't be considered read-only. */ + #ifdef USE_ACCESS + if(access(fullname, W_OK) == 0) { + #else + /* This needs to be tested with clearcase to verify that it doesn't + update the mtime value. */ + if((fp = fopen(fullname, "r+")) != NULL) { + fclose(fp); + #endif + window->editorInfo->readOnly = FALSE; + } + else if(errno == ENOENT) { + window->editorInfo->readOnly = FALSE; + } + else { + window->editorInfo->readOnly = TRUE; + } + UpdateWindowReadOnly(window); + window->editorInfo->st_mode = statbuf.st_mode; + } + + /* see if the file was modified by an external source */ + if(window->editorInfo->mtime != statbuf.st_mtime) { + + /* if it was then prompt the user if he wants to revert to the + saved version */ + if(window->editorInfo->checkingMode == CHECKING_MODE_PROMPT_TO_RELOAD) { + int b; + static dialog_popped_up = 0; + + /* ignore multiple calls to ourself from inside the application loop + in DialogF() */ + if(!dialog_popped_up) { + dialog_popped_up = 1; + /* raise window to the top before displaying the dialog. */ + XMapRaised(TheDisplay, XtWindow(window->shell)); + b = DialogF(DF_QUES, window->shell, 3, "%s%s\nwas modified by an external source.\nDo you want to re-read it?", + "Re-read", "Don't Re-read", "Switch Modes...", + window->editorInfo->path, window->editorInfo->filename); + /* Re-read File */ + if(b == 1) { + /* RevertToSaved() will update the mtime. */ + RevertToSaved(window, !window->editorInfo->fileChanged); + } + if(b == 2) { + /* Update the mtime so we don't prompt the user again + ** since he didn't want to reread it at this time. */ + window->editorInfo->mtime = statbuf.st_mtime; + } + /* Switch Checking Mode */ + else if(b == 3) { + b = DialogF(DF_QUES, window->shell, 3, "New Checking Mode?", + "Prompt To Reload", "Tail -f", "Disabled"); + if(b == 1) { + /* Don't update the mtime. The user still wants + ** to be prompted. No need to call SetCheckingMode() + ** we are already in prompt mode. We should just + ** return. */ + } else if(b == 2) { + /* Don't update the mtime. It will be updated in + ** SetCheckingMode(). */ + SetCheckingMode(window, CHECKING_MODE_TAIL_MINUS_F); + } else if(b == 3) { + /* Don't update the mtime. It is not needed since + ** checking is disabled. */ + SetCheckingMode(window, CHECKING_MODE_DISABLED); + } + /* Return since the user wanted to change the mode. */ + dialog_popped_up = 0; + return; + } + dialog_popped_up = 0; + } + } + else if(window->editorInfo->checkingMode == CHECKING_MODE_TAIL_MINUS_F) { + /* reload the file if it has gotten smaller */ + if(statbuf.st_size < window->editorInfo->buffer->length) { + RevertToSaved(window, !window->editorInfo->fileChanged); + + /* move the cursor to the end of the file, which will also scroll + ** the window to the end of the file. + */ + TextSetCursorPos(window->textArea, window->editorInfo->buffer->length); + } + /* Else only read what has been added at the end */ + else { + int eofWasVisible, lineNum, column; + + /* See if the end of file is visible. If it is not then we can + ** assume that the user is looking at something in the file + ** and we shouldn't scroll the window out from under him when + ** we add the text to the window that was added to the file. + */ + eofWasVisible = TextPosToLineAndCol(window->textArea, + window->editorInfo->buffer->length, &lineNum, &column); + + doOpen(window, window->editorInfo->filename, window->editorInfo->path, + FORCE_READ_ONLY, window->editorInfo->buffer->length, -1); + + /* If the end of file was visible before adding to the end then + ** move the cursor to the end of the file, which will also scroll + ** the window to the end of the file. + */ + if(eofWasVisible) { + TextSetCursorPos(window->textArea, window->editorInfo->buffer->length); + } + } + + /* Make all of the text areas read-only */ + if(window->editorInfo->lockWrite == FALSE) { + window->editorInfo->lockWrite = TRUE; + UpdateWindowReadOnly(window); + UpdateWindowTitle(window); + } + } + } + + /* If tail -f mode then add a timer to continually check if the + ** file has changed */ + if(window->editorInfo->checkingMode == CHECKING_MODE_TAIL_MINUS_F) { + /* Only register another timer if one isn't already registered */ + if(window->editorInfo->tailMinusFTimeoutID == 0) { + window->editorInfo->tailMinusFTimeoutID = XtAppAddTimeOut( + XtWidgetToApplicationContext(window->shell), + GetPrefTailMinusFInterval()/*milliseconds*/, + (XtTimerCallbackProc)fileCheckTimerProc, window); + } + } + /* If not tail -f mode then make sure a previous tail -f timer is + ** removed. */ + else { + if(window->editorInfo->tailMinusFTimeoutID) { + XtRemoveTimeOut(window->editorInfo->tailMinusFTimeoutID); + window->editorInfo->tailMinusFTimeoutID = 0; + } + } + } + static int doSave(WindowInfo *window) *************** *** 544,549 **** int fileLen; /* Get the full name of the file */ ! strcpy(fullname, window->path); ! strcat(fullname, window->filename); --- 878,885 ---- int fileLen; + struct stat statbuf; + int mode = -1; /* Get the full name of the file */ ! strcpy(fullname, window->editorInfo->path); ! strcat(fullname, window->editorInfo->filename); *************** *** 554,555 **** --- 890,896 ---- + /* get the current mode bits */ + if (stat(fullname, &statbuf) == 0) { + mode = statbuf.st_mode; + } + /* open the file */ *************** *** 561,563 **** DialogF(DF_WARN, window->shell, 1, "Unable to save %s:\n%s", "Dismiss", ! window->filename, errorString()); return FALSE; --- 902,905 ---- DialogF(DF_WARN, window->shell, 1, "Unable to save %s:\n%s", "Dismiss", ! window->editorInfo->filename, errorString()); ! window->editorInfo->readOnly = TRUE; return FALSE; *************** *** 569,578 **** - /* set the protection for the file */ - if (window->fileMode) - chmod(fullname, window->fileMode); #else /* Unix */ - /* set the protection for the file */ - if (window->fileMode) - fchmod(fileno(fp), window->fileMode); #endif /*VMS/Unix*/ --- 911,914 ---- *************** *** 580,589 **** /* get the text buffer contents and its length */ ! fileString = BufGetAll(window->buffer); ! fileLen = window->buffer->length; /* If null characters are substituted for, put them back */ ! BufUnsubstituteNullChars(fileString, window->buffer); /* add a terminating newline if the file doesn't already have one */ ! if (fileLen != 0 && fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ --- 916,925 ---- /* get the text buffer contents and its length */ ! fileString = BufGetAll(window->editorInfo->buffer); ! fileLen = window->editorInfo->buffer->length; /* If null characters are substituted for, put them back */ ! BufUnsubstituteNullChars(fileString, window->editorInfo->buffer); /* add a terminating newline if the file doesn't already have one */ ! if (fileLen == 0 || fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ *************** *** 598,600 **** DialogF(DF_ERR, window->shell, 1, "%s not saved:\n%s", "Dismiss", ! window->filename, errorString()); fclose(fp); --- 934,936 ---- DialogF(DF_ERR, window->shell, 1, "%s not saved:\n%s", "Dismiss", ! window->editorInfo->filename, errorString()); fclose(fp); *************** *** 618,620 **** /* reflect the fact that NEdit is now editing a new version of the file */ ! ParseFilename(fullname, window->filename, window->path); #endif /*VMS*/ --- 954,956 ---- /* reflect the fact that NEdit is now editing a new version of the file */ ! ParseFilename(fullname, window->editorInfo->filename, window->editorInfo->path); #endif /*VMS*/ *************** *** 623,624 **** --- 959,977 ---- SetWindowModified(window, FALSE); + + /* The file must have been writable. */ + window->editorInfo->readOnly = FALSE; + UpdateWindowReadOnly(window); + + /* set the mode bits back to what they were before we opened the file. + ** For some reason the set-uid bit is being turned off. */ + if(mode != -1) { + chmod(fullname, mode); + } + + /* get the current mtime and st_mode */ + if (stat(fullname, &statbuf) == 0) { + window->editorInfo->mtime = statbuf.st_mtime; + window->editorInfo->st_mode = statbuf.st_mode; + } + return TRUE; *************** *** 629,631 **** ** is generated using the name and path stored in the window and adding a ! ** tilde (~) on UNIX and underscore (_) on VMS to the beginning of the name. */ --- 982,985 ---- ** is generated using the name and path stored in the window and adding a ! ** tilde (~) on UNIX to the end of the name or an underscore (_) on VMS to ! ** the beginning of the name. */ *************** *** 637,638 **** --- 991,993 ---- int fileLen; + WindowInfo *w; *************** *** 654,658 **** "Unable to save backup for %s:\n%s\nAutomatic backup is now off", ! "Dismiss", window->filename, errorString()); ! window->autoSave = FALSE; ! XmToggleButtonSetState(window->autoSaveItem, FALSE, FALSE); return FALSE; --- 1009,1015 ---- "Unable to save backup for %s:\n%s\nAutomatic backup is now off", ! "Dismiss", window->editorInfo->filename, errorString()); ! window->editorInfo->autoSave = FALSE; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XmToggleButtonSetState(w->autoSaveItem, FALSE, FALSE); ! } return FALSE; *************** *** 661,670 **** /* get the text buffer contents and its length */ ! fileString = BufGetAll(window->buffer); ! fileLen = window->buffer->length; /* If null characters are substituted for, put them back */ ! BufUnsubstituteNullChars(fileString, window->buffer); /* add a terminating newline if the file doesn't already have one */ ! if (fileLen != 0 && fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ --- 1018,1027 ---- /* get the text buffer contents and its length */ ! fileString = BufGetAll(window->editorInfo->buffer); ! fileLen = window->editorInfo->buffer->length; /* If null characters are substituted for, put them back */ ! BufUnsubstituteNullChars(fileString, window->editorInfo->buffer); /* add a terminating newline if the file doesn't already have one */ ! if (fileLen == 0 || fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ *************** *** 680,682 **** "Error while saving backup for %s:\n%s\nAutomatic backup is now off", ! "Dismiss", window->filename, errorString()); fclose(fp); --- 1037,1039 ---- "Error while saving backup for %s:\n%s\nAutomatic backup is now off", ! "Dismiss", window->editorInfo->filename, errorString()); fclose(fp); *************** *** 684,686 **** XtFree(fileString); ! window->autoSave = FALSE; return FALSE; --- 1041,1043 ---- XtFree(fileString); ! window->editorInfo->autoSave = FALSE; return FALSE; *************** *** 718,728 **** #ifdef VMS ! if (window->filenameSet) ! sprintf(name, "%s_%s", window->path, window->filename); else ! sprintf(name, "%s_%s", "SYS$LOGIN:", window->filename); #else ! if (window->filenameSet) ! sprintf(name, "%s~%s", window->path, window->filename); else ! sprintf(name, "%s/~%s", getenv("HOME"), window->filename); #endif /*VMS*/ --- 1075,1085 ---- #ifdef VMS ! if (window->editorInfo->filenameSet) ! sprintf(name, "%s_%s", window->editorInfo->path, window->editorInfo->filename); else ! sprintf(name, "%s_%s", "SYS$LOGIN:", window->editorInfo->filename); #else ! if (window->editorInfo->filenameSet) ! sprintf(name, "%s%s~", window->editorInfo->path, window->editorInfo->filename); else ! sprintf(name, "%s/%s~", getenv("HOME"), window->editorInfo->filename); #endif /*VMS*/ *************** *** 732,735 **** ** If saveOldVersion is on, copies the existing version of the file to ! ** .bck in anticipation of a new version being saved. Returns ! ** True if backup fails and user requests that the new file not be written. */ --- 1089,1094 ---- ** If saveOldVersion is on, copies the existing version of the file to ! ** in anticipation of a new version being saved. ! ** comes from the backupSuffix preference resource. ! ** Returns True if backup fails and user requests that the new file not be ! ** written. */ *************** *** 738,740 **** #ifndef VMS ! char fullname[MAXPATHLEN], bckname[MAXPATHLEN]; struct stat statbuf; --- 1097,1099 ---- #ifndef VMS ! char fullname[MAXPATHLEN+1], bckname[MAXPATHLEN+1]; struct stat statbuf; *************** *** 743,747 **** char *fileString; /* Do only if version backups are turned on */ ! if (!window->saveOldVersion) return False; --- 1102,1108 ---- char *fileString; + struct utimbuf file_time[1]; + char *backupSuffix = GetPrefBackupSuffix(); /* Do only if version backups are turned on */ ! if (!window->editorInfo->saveOldVersion) return False; *************** *** 749,757 **** /* Get the full name of the file */ ! strcpy(fullname, window->path); ! strcat(fullname, window->filename); /* Generate name for old version */ ! if (strlen(fullname) + 5 > MAXPATHLEN) ! return bckError(window, "file name too long", window->filename); ! sprintf(bckname, "%s.bck", fullname); --- 1110,1118 ---- /* Get the full name of the file */ ! strcpy(fullname, window->editorInfo->path); ! strcat(fullname, window->editorInfo->filename); /* Generate name for old version */ ! if (strlen(fullname) + strlen(backupSuffix) > MAXPATHLEN) ! return bckError(window, "file name too long", window->editorInfo->filename); ! sprintf(bckname, "%s%s", fullname, backupSuffix); *************** *** 767,768 **** --- 1128,1132 ---- + /* Always make the backup file writable */ + chmod(bckname, statbuf.st_mode | 0222); + /* open the file to receive a copy of the old version */ *************** *** 774,776 **** /* Allocate space for the whole contents of the file */ ! fileString = (char *)malloc(fileLen); if (fileString == NULL) { --- 1138,1140 ---- /* Allocate space for the whole contents of the file */ ! fileString = (char *)XtMalloc(fileLen); if (fileString == NULL) { *************** *** 793,798 **** - /* set the protection for the backup file */ - if (window->fileMode) - fchmod(fileno(outFP), window->fileMode); - /* write to the file */ --- 1157,1158 ---- *************** *** 814,815 **** --- 1174,1181 ---- return bckError(window, errorString(), bckname); + + /* set the protection and times for the backup file */ + chmod(bckname, statbuf.st_mode); + file_time->actime = statbuf.st_atime; + file_time->modtime = statbuf.st_mtime; + utime(bckname, file_time); #endif /* VMS */ *************** *** 828,830 **** resp = DialogF(DF_ERR, window->shell, 3, ! "Couldn't write .bck (last version) file.\n%s: %s", "Cancel Save", "Turn off Backups", "Continue", file, errString); --- 1194,1196 ---- resp = DialogF(DF_ERR, window->shell, 3, ! "Couldn't write backup file of last version.\n%s: %s", "Cancel Save", "Turn off Backups", "Continue", file, errString); *************** *** 833,836 **** if (resp == 2) { ! window->saveOldVersion = FALSE; ! XmToggleButtonSetState(window->saveLastItem, FALSE, FALSE); } --- 1199,1205 ---- if (resp == 2) { ! WindowInfo *w; ! window->editorInfo->saveOldVersion = FALSE; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XmToggleButtonSetState(w->saveLastItem, FALSE, FALSE); ! } } *************** *** 841,843 **** { ! textBuffer *buf = window->buffer; selection *sel = &buf->primary; --- 1210,1212 ---- { ! textBuffer *buf = window->editorInfo->buffer; selection *sel = &buf->primary; *************** *** 845,847 **** int fileLen; ! /* get the contents of the text buffer from the text area widget. Add --- 1214,1216 ---- int fileLen; ! /* get the contents of the text buffer from the text area widget. Add *************** *** 870,872 **** /* Print the string */ ! PrintString(fileString, fileLen, window->shell, window->filename); --- 1239,1241 ---- /* Print the string */ ! PrintString(fileString, fileLen, window->shell, window->editorInfo->filename); *************** *** 936,938 **** */ ! int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname) { --- 1305,1307 ---- */ ! int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname, char *title) { *************** *** 941,943 **** ! /* Temporarily set default directory to window->path, prompt for file, then, if the call was unsuccessful, restore the original default --- 1310,1312 ---- ! /* Temporarily set default directory to window->editorInfo->path, prompt for file, then, if the call was unsuccessful, restore the original default *************** *** 945,949 **** savedDefaultDir = GetFileDialogDefaultDirectory(); ! if (*window->path != '\0') ! SetFileDialogDefaultDirectory(window->path); ! retVal = GetExistingFilename(window->shell, prompt, fullname); if (retVal != GFN_OK) --- 1314,1318 ---- savedDefaultDir = GetFileDialogDefaultDirectory(); ! if (*window->editorInfo->path != '\0') ! SetFileDialogDefaultDirectory(window->editorInfo->path); ! retVal = GetExistingFilename(window->shell, prompt, fullname, title); if (retVal != GFN_OK) *************** *** 973,976 **** savedDefaultDir = GetFileDialogDefaultDirectory(); ! if (*window->path != '\0') ! SetFileDialogDefaultDirectory(window->path); --- 1342,1345 ---- savedDefaultDir = GetFileDialogDefaultDirectory(); ! if (*window->editorInfo->path != '\0') ! SetFileDialogDefaultDirectory(window->editorInfo->path); *************** *** 987,989 **** XmStringFree(s2); ! if (window->wrapMode == CONTINUOUS_WRAP) { wrapToggle = XtVaCreateManagedWidget("addWrap", --- 1356,1358 ---- XmStringFree(s2); ! if (window->editorInfo->wrapMode == CONTINUOUS_WRAP) { wrapToggle = XtVaCreateManagedWidget("addWrap", *************** *** 1028,1030 **** { ! if (window->readOnly || window->lockWrite) { XBell(TheDisplay, 0); --- 1397,1399 ---- { ! if ((!GetPrefAllowReadOnlyEdits() && window->editorInfo->readOnly) || window->editorInfo->lockWrite) { XBell(TheDisplay, 0); *************** *** 1110,1113 **** fileString = TextGetWrapped(window->textArea, 0, ! window->buffer->length, &fileLen); ! BufSetAll(window->buffer, fileString); XtFree(fileString); --- 1479,1482 ---- fileString = TextGetWrapped(window->textArea, 0, ! window->editorInfo->buffer->length, &fileLen); ! BufSetAll(window->editorInfo->buffer, fileString); XtFree(fileString); *** file.h 1997/09/26 18:28:17 1.1 --- file.h 1997/10/10 00:15:13 1.2 *************** *** 29,33 **** ! void EditNewFile(void); ! void EditExistingFile(WindowInfo *inWindow, char *name, char *path, int flags); ! void RevertToSaved(WindowInfo *window); int SaveWindow(WindowInfo *window); --- 29,33 ---- ! WindowInfo* EditNewFile(WindowInfo *parentWindow); ! WindowInfo* EditExistingFile(WindowInfo *inWindow, char *name, char *path, int flags, Boolean forceRaise); ! void RevertToSaved(WindowInfo *window, int silent); int SaveWindow(WindowInfo *window); *************** *** 40,45 **** int IncludeFile(WindowInfo *window, char *name); ! int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname); int PromptForNewFile(WindowInfo *window, char *prompt, char *fullname, int *addWrap); int CheckReadOnly(WindowInfo *window); void RemoveBackupFile(WindowInfo *window); --- 40,47 ---- int IncludeFile(WindowInfo *window, char *name); ! int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname, char *title); int PromptForNewFile(WindowInfo *window, char *prompt, char *fullname, int *addWrap); + void CheckForChangesInFile(WindowInfo *window); int CheckReadOnly(WindowInfo *window); void RemoveBackupFile(WindowInfo *window); + void SetCheckingMode(WindowInfo *window, CheckingMode checkingMode); *** help.c.in 1997/09/26 18:28:17 1.1 --- help.c.in 1997/10/24 19:50:38 1.5 *************** *** 68,75 **** "X Resources", ! "Key Binding", ! "Learn/Replay", ! "Macro Language", ! "Macro Subroutines", ! "Actions Routines", ! "Highlighting Patterns", "Problems/Bugs", --- 68,71 ---- "X Resources", ! "Macros, Learn/Replay", ! "Actions", "Problems/Bugs", *************** *** 80,85 **** static char *HelpText[NUM_TOPICS] = { ! "NEdit Beta Test Version 5.0\n\ ! September 25, 1997\n\ \n\ ! Copyright (c) 1992, 1993, 1994, 1996, 1997\n\ Universities Research Association, Inc.\n\ --- 76,95 ---- static char *HelpText[NUM_TOPICS] = { ! "MV Patch @MV_PATCH@\n\ ! @MV_PATCH_DATE@\n\ ! @target@\n\ ! Configured on @CONFIGURE_DATE@.\n\ ! \n\ ! Max Vohlken\n\ ! max.vohlken@rational.com\n\ ! ftp://ftp.pureatria.com/pub/max/nedit\n\ ! \n\ ! Rational Software nor the company formerly known as Pure Atria make no\n\ ! warranty, expressed or implied, or assumes any legal liability or\n\ ! responsibility for the accuracy, completeness, or usefulness of this\n\ ! code.\n\ \n\ ! @PACKAGE@ @VERSION@\n\ ! @VERSION_DATE@\n\ ! \n\ ! Copyright (c) 1992, 1993, 1994, 1996\n\ Universities Research Association, Inc.\n\ *************** *** 127,134 **** \n\ ! Selecting Text\n\ ! Finding and Replacing Text\n\ ! Cut and Paste\n\ ! Using the Mouse\n\ ! Keyboard Shortcuts\n\ ! Shifting and Filling\n\ \n\ --- 137,144 ---- \n\ ! Selecting Text\n\ ! Finding and Replacing Text\n\ ! Cut and Paste\n\ ! Using the Mouse\n\ ! Keyboard Shortcuts\n\ ! Shifting and Filling\n\ \n\ *************** *** 167,169 **** network failure, or X server crash. These files are saved under the name \ ! ~filename (on Unix) or _filename (on VMS), where filename is the name of \ the file you were editing. If an NEdit process is killed, some of these \ --- 177,179 ---- network failure, or X server crash. These files are saved under the name \ ! filename~ (on Unix) or _filename (on VMS), where filename is the name of \ the file you were editing. If an NEdit process is killed, some of these \ *************** *** 185,190 **** pressing return or enter. The Cancel or Dismiss button can be activated \ ! by pressing escape. For example, to replace the string \"thing\" with \ ! \"things\" type:\n\ \n\ ! thingthings\n\ \n\ --- 195,199 ---- pressing return or enter. The Cancel or Dismiss button can be activated \ ! by pressing escape. For example, to find the string \"thing\" type:\n\ \n\ ! thing\n\ \n\ *************** *** 246,248 **** Search menu, type the string to search for and the string to substitute, and \ ! press the \"R. in Selection\" button in the dialog. Note that selecting text \ in the Replace... dialog will unselect the text in the window.", --- 255,257 ---- Search menu, type the string to search for and the string to substitute, and \ ! press the \"Replace In Selection\" button in the dialog. Note that selecting text \ in the Replace... dialog will unselect the text in the window.", *************** *** 258,260 **** mouse button with the pointer at one end of the text you want to select, \ ! and drag it to the other end. The text will become highlighted. To \ select a whole word, double click (click twice quickly in succession). \ --- 267,270 ---- mouse button with the pointer at one end of the text you want to select, \ ! and drag it to the other end. The text will become highlighted. This is called \ ! the primary selection. To \ select a whole word, double click (click twice quickly in succession). \ *************** *** 264,267 **** dragging. Quadruple clicking selects the whole file. \ ! After releasing the mouse button, you can still adjust a selection \ ! by holding down the shift key and dragging on either end of the selection. \ To delete the selected text, press delete or backspace. To replace it, \ --- 274,279 ---- dragging. Quadruple clicking selects the whole file. \ ! After releasing the mouse button, you can still adjust the selection \ ! by clicking the right mouse button where you want the selection adjusted to \ ! or by holding the right mouse button and dragging on either end of the \ ! selection. \ To delete the selected text, press delete or backspace. To replace it, \ *************** *** 278,292 **** \n\ ! The middle mouse button can be used to make an \ ! additional selection (called the secondary selection). As soon as the \ ! button is released, the contents of this selection will be \ copied to the insert position of the window where the mouse was last \ clicked (the destination window). This position is marked by a caret \ ! shaped cursor when the \ ! mouse is outside of the destination window. \ If there is a (primary) selection, adjacent to the cursor \ ! in the window, \ ! the new text will replace the selected text. Holding the shift key \ ! while making the secondary selection will move the text, deleting it \ ! at the site of the secondary selection, rather than \ ! copying it.\n\ \n\ --- 290,310 ---- \n\ ! If the shift key is depressed while performing any of the above selection \ ! operations \ ! you will be able to create an additional selection (called the secondary \ ! selection). The secondary selection is shown visually by an underline under \ ! the text that is selected. As soon as the shift key is released, the contents \ ! of this selection will be \ copied to the insert position of the window where the mouse was last \ clicked (the destination window). This position is marked by a caret \ ! shaped cursor when the mouse is outside of the destination window. \ If there is a (primary) selection, adjacent to the cursor \ ! in the destination window, the new text will replace the selected text. \ ! \n\ ! The middle mouse button can also be used to create a secondary selection \ ! by dragging it over the text to be selected. \ ! As soon as the button is released, the selection will be \ ! copied just as it is for the shift key. \ ! If the shift key is depressed when the selection is started \ ! the selection will be moved rather than copyied. This will delete\ ! the secondary selection.\n\ \n\ *************** *** 560,565 **** \n\ ! Button 1 (left) Cursor position and primary selection\n\ \n\ Button 2 (middle) Secondary selections, and dragging and\n\ ! copying the primary selection\n\ \n\ --- 578,586 ---- \n\ ! Button 1 (left) Cursor position(click).\n\ ! Primary selection(drag or double/triple click).\n\ \n\ Button 2 (middle) Secondary selections, and dragging and\n\ ! copying primary selection\n\ ! \n\ ! Button 3 (right) Extends the primary selection(click or drag)\n\ \n\ *************** *** 570,579 **** \n\ ! Shift On primary selections, (left mouse button):\n\ ! Extends selection to the mouse pointer\n\ ! On secondary and copy operations, (middle):\n\ ! Toggles between move and copy\n\ \n\ ! Ctrl Makes selection rectangular or insertion\n\ columnar\n\ - \n\ Alt* (on release) Exchange primary and secondary\n\ --- 591,596 ---- \n\ ! Shift Used to extend the primary selection.\n\ \n\ ! Ctrl Makes a selection rectangular or insertion\n\ columnar\n\ Alt* (on release) Exchange primary and secondary\n\ *************** *** 587,610 **** \n\ ! Click Moves the cursor\n\ ! \n\ ! Double Click Selects a whole word\n\ \n\ ! Triple Click Selects a whole line\n\ \n\ ! Quad Click Selects the whole file\n\ \n\ ! Shift Click Adjusts (extends or shrinks) the\n\ ! selection, or if there is no existing\n\ ! selection, begins a new selection\n\ ! between the cursor and the mouse.\n\ \n\ ! Ctrl+Shift+ Adjusts (extends or shrinks) the\n\ ! Click selection rectangularly.\n\ \n\ ! Drag Selects text between where the mouse\n\ ! was pressed and where it was released.\n\ \n\ ! Ctrl+Drag Selects rectangle between where the\n\ ! mouse was pressed and where it was\n\ ! released.\n\ \n\ --- 604,631 ---- \n\ ! Click Moves the cursor.\n\ \n\ ! Double Click Selects a whole word. The word becomes the\n\ ! primary selection.\n\ \n\ ! Triple Click Selects a whole line. The line becomes the\n\ ! primary selection.\n\ \n\ ! Shift+Click Extends or shortens the primary selection to\n\ ! the location where the button is clicked.\n\ \n\ ! Ctrl+Click Starts a rectangular primary selection.\n\ \n\ ! Drag Selects the text between where the mouse button\n\ ! is pressed and where it is released.\n\ \n\ ! Shift+Drag Extends or shortens the primary selection between where\n\ ! the mouse button is pressed and where it is released.\n\ ! \n\ ! Ctrl+Drag Selects the rectangle between where the\n\ ! mouse button is pressed and where it is\n\ ! released.\n\ ! \n\ ! Shift+Ctrl+ Extends or shortens the primary selection to the rectangle\n\ ! Drag between where the mouse button is pressed and where\n\ ! it is released.\n\ \n\ *************** *** 630,649 **** \n\ ! Click Copies the primary selection to the\n\ ! clicked position.\n\ \n\ ! Shift+Click Moves the primary selection to the\n\ ! clicked position, deleting it from its\n\ ! original position.\n\ ! \n\ ! Drag 1) Outside of the primary selection:\n\ ! Begins a secondary selection.\n\ ! 2) Inside of the primary selection:\n\ ! Moves the selection by dragging.\n\ ! \n\ ! Ctrl+Drag 1) Outside of the primary selection:\n\ ! Begins a rectangular secondary\n\ ! selection.\n\ ! 2) Inside of the primary selection:\n\ ! Drags the selection in overlay\n\ ! mode (see below).\n\ \n\ --- 651,670 ---- \n\ ! Click Copies the primary selection to the\n\ ! clicked position.\n\ \n\ ! Shift+Click Moves the primary selection to the\n\ ! clicked position, deleting it from its\n\ ! original position.\n\ ! \n\ ! Drag 1) Outside of the primary selection:\n\ ! Begins a secondary selection.\n\ ! 2) Inside of the primary selection:\n\ ! Moves the selection by dragging.\n\ ! \n\ ! Ctrl+Drag 1) Outside of the primary selection:\n\ ! Begins a rectangular secondary\n\ ! selection.\n\ ! 2) Inside of the primary selection:\n\ ! Drags the selection in overlay\n\ ! mode (see below).\n\ \n\ *************** *** 651,668 **** \n\ ! No Modifiers If there is a primary selection,\n\ ! replaces it with the secondary\n\ ! selection. Otherwise, inserts the\n\ ! secondary selection at the cursor\n\ ! position.\n\ ! \n\ ! Shift Move the secondary selection, deleting\n\ ! it from its original position. If\n\ ! there is a primary selection, the move\n\ ! will replace the primary selection\n\ ! with the secondary selection.\n\ ! Otherwise, moves the secondary\n\ ! selection to to the cursor position.\n\ \n\ ! Alt* Exchange the primary and secondary\n\ ! selections.\n\ \n\ --- 672,689 ---- \n\ ! No Modifiers If there is a primary selection,\n\ ! replaces it with the secondary\n\ ! selection. Otherwise, inserts the\n\ ! secondary selection at the cursor\n\ ! position.\n\ ! \n\ ! Shift Move the secondary selection, deleting\n\ ! it from its original position. If\n\ ! there is a primary selection, the move\n\ ! will replace the primary selection\n\ ! with the secondary selection.\n\ ! Otherwise, moves the secondary\n\ ! selection to to the cursor position.\n\ \n\ ! Alt* Exchange the primary and secondary\n\ ! selections.\n\ \n\ *************** *** 671,680 **** \n\ ! Shift Leaves a copy of the original\n\ ! selection in place rather than\n\ ! removing it or blanking the area.\n\ \n\ ! Ctrl Changes from insert mode to overlay\n\ ! mode (see below).\n\ \n\ - Escape Cancels drag in progress.\n\ \n\ --- 692,718 ---- \n\ ! Shift Leaves a copy of the original\n\ ! selection in place rather than\n\ ! removing it or blanking the area.\n\ \n\ ! Ctrl Changes from insert mode to overlay\n\ ! mode (see below).\n\ ! \n\ ! Escape Cancels drag in progress.\n\ ! \n\ ! \n\ ! BUTTON 3\n\ ! \n\ ! The right mouse button is used to extend the primary selection:\n\ ! \n\ ! Click Extends or shortens the primary selection to\n\ ! the location where the button is clicked.\n\ ! \n\ ! Ctrl+Click Extends or shortens the rectangular primary selection.\n\ ! \n\ ! Drag Extends the primary selection to the location\n\ ! where the mouse button is released.\n\ ! \n\ ! Ctrl+Drag Extends the rectangular primary selection to the\n\ ! location where the mouse button is released.\n\ \n\ \n\ *************** *** 701,703 **** binding, or you can re-configure NEdit to use a different key \ ! combination.", --- 739,889 ---- binding, or you can re-configure NEdit to use a different key \ ! combination.\n\ ! \n\ ! For the users who want an improved secondary selection model add the \ ! following to your X resources:\n\ ! \n\ ! nedit*NEditText.translations: #override \\n\\\n\ ! osfCut: \\n\\\n\ ! osfCopy: \\n\\\n\ ! osfPaste: \\n\\\n\ ! osfCut: secondary-or-clipboard(move, cut)\\n\\\n\ ! osfCopy: secondary-or-clipboard(exchange, copy)\\n\\\n\ ! osfPaste: secondary-or-clipboard(copy, paste)\\n\\\n\ ! osfPrimaryPaste: copy-primary()\\n\n\ ! Mod5 ~Ctrl : grab-focus(secondary)\\n\\\n\ ! Mod5 Ctrl : grab-focus(secondary, rect)\\n\\\n\ ! Shift Ctrl : extend-start(rect)\\n\\\n\ ! Shift : extend-start()\\n\\\n\ ! Ctrl : grab-focus(rect)\\n\\\n\ ! : drag-or-grab-focus()\\n\\\n\ ! Mod5 ~Ctrl Button1: extend-adjust(secondary)\\n\\\n\ ! Mod5 Ctrl Button1: extend-adjust(rect, secondary)\\n\\\n\ ! Ctrl Button1: extend-adjust(rect)\\n\\\n\ ! Button1: drag-or-extend-adjust()\\n\\\n\ ! Mod5 ~Ctrl : extend-end(secondary)\\n\\\n\ ! Mod5 Ctrl : extend-end(secondary, rect)\\n\\\n\ ! Ctrl : extend-end(rect)\\n\\\n\ ! : drag-or-extend-end()\\n\\\n\ ! Mod5 ~Ctrl : extend-start(secondary)\\n\n\ ! Mod5 Ctrl : extend-start(secondary, rect)\\n\n\ ! Shift Ctrl : mouse_pan()\\n\n\ ! Shift : post_window_bg_menu(rect)\\n\n\ ! Ctrl : extend-start(rect)\\n\n\ ! : extend-start()\\n\n\ ! Mod5 ~Ctrl Button3: extend-adjust(secondary)\\n\n\ ! Mod5 Ctrl Button3: extend-adjust(rect, secondary)\\n\n\ ! Shift Ctrl Button3: mouse_pan()\\n\n\ ! Ctrl Button3: extend-adjust(rect)\\n\n\ ! ~Shift Button3: extend-adjust()\\n\n\ ! Mod5 ~Ctrl : extend-end(secondary)\\n\n\ ! Mod5 Ctrl : extend-end(secondary, rect)\\n\n\ ! Shift Ctrl : end_drag()\\n\n\ ! Ctrl : extend-end(rect)\\n\n\ ! ~Shift : extend-end()\n\ ! \n\ ! nedit.bgMenuButton: Shift~Ctrl~Meta~Alt\n\ ! \n\ ! These translation are a combination of xterm and textedit. The left \ ! mouse button is used to start a selection and the right mouse button is \ ! used to extend the selection just like in xterm. Shift plus the right \ ! mouse button will pop up a menu to do Undo/Redo/Cut/Copy/Paste. \ ! Note, the bgMenuButton resource also controls this function. Control plus \ ! shift and the right mouse button is used to scroll the window with the \ ! mouse. The \ ! secondary selection is controlled by holding down either the Copy, Cut, \ ! or Paste keys just like in textedit. When the key is released the \ ! following action will be performed:\n\ ! \n\ ! Copy - The primary and secondary selections will be exchanged.\n\ ! Cut - The secondary selection will be inserted at the destination\n\ ! cursor and then removed from its original location.\n\ ! Paste - The secondary selection will be inserted at the destination\n\ ! cursor.\n\ ! \n\ ! Be aware that the Copy, Cut, and Paste keys must be setup \ ! as Mod5 modifier keys. Run the following command to display \ ! the keys that are setup for Mod5.\n\ ! \n\ ! xmodmap -pm\n\ ! \n\ ! If your Copy, Cut, or Paste keys are not listed then execute the \ ! following to add them.\n\ ! \n\ ! xmodmap -e 'add mod5 = ...'\n\ ! \n\ ! For example, the following applies for Sun workstations:\n\ ! \n\ ! xmodmap -e 'add mod5 = F16 F18 F20'\n\ ! \n\ ! To set these up permanently I recommend adding the above command to your \ ! corresponding .xinitrc file.\n\ ! \n\ ! These translation also provide the ability to drag the primary \ ! selection with the left mouse button just like textedit. \n\ ! \n\ ! If you would also like to use the Shift key to control the secondary \ ! selection then use the following translation table instead.\n\ ! \n\ ! nedit*NEditText.translations: #override \\n\\\n\ ! Alt Shift_L: exchange()\\n\n\ ! Meta Shift_L: exchange()\\n\n\ ! Alt Shift_R: exchange()\\n\n\ ! Meta Shift_R: exchange()\\n\n\ ! Shift_L: copy-secondary()\\n\\\n\ ! Shift_R: copy-secondary()\\n\\\n\ ! osfCut: \\n\\\n\ ! osfCopy: \\n\\\n\ ! osfPaste: \\n\\\n\ ! osfCut: secondary-or-clipboard(move, cut)\\n\\\n\ ! osfCopy: secondary-or-clipboard(exchange, copy)\\n\\\n\ ! osfPaste: secondary-or-clipboard(copy, paste)\\n\\\n\ ! osfPrimaryPaste: copy-primary()\\n\n\ ! Mod5 ~Ctrl : grab-focus(secondary)\\n\\\n\ ! Mod5 Ctrl : grab-focus(secondary, rect)\\n\\\n\ ! Shift~Ctrl : grab-focus(secondary)\\n\\\n\ ! Shift Ctrl : grab-focus(secondary, rect)\\n\\\n\ ! ~Shift Ctrl : grab-focus(rect)\\n\\\n\ ! : drag-or-grab-focus()\\n\\\n\ ! Mod5 ~Ctrl Button1: extend-adjust(secondary)\\n\\\n\ ! Mod5 Ctrl Button1: extend-adjust(rect, secondary)\\n\\\n\ ! Shift~Ctrl Button1: extend-adjust(secondary)\\n\\\n\ ! Shift Ctrl Button1: extend-adjust(rect, secondary)\\n\\\n\ ! ~Shift Ctrl Button1: extend-adjust(rect)\\n\\\n\ ! Button1: drag-or-extend-adjust()\\n\\\n\ ! Mod5 ~Ctrl : extend-end(secondary)\\n\\\n\ ! Mod5 Ctrl : extend-end(secondary, rect)\\n\\\n\ ! Shift~Ctrl : extend-end(secondary)\\n\\\n\ ! Shift Ctrl : extend-end(secondary, rect)\\n\\\n\ ! ~Shift Ctrl : extend-end(rect)\\n\\\n\ ! : drag-or-extend-end()\\n\\\n\ ! Alt Shift Ctrl : mouse_pan()\\n\n\ ! Meta Shift Ctrl : mouse_pan()\\n\n\ ! Alt Shift : post_window_bg_menu(rect)\\n\n\ ! Meta Shift : post_window_bg_menu(rect)\\n\n\ ! Mod5 ~Ctrl : extend-start(secondary)\\n\\\n\ ! Mod5 Ctrl : extend-start(secondary, rect)\\n\\\n\ ! Shift~Ctrl : extend-start(secondary)\\n\\\n\ ! Shift Ctrl : extend-start(secondary, rect)\\n\\\n\ ! ~Shift Ctrl : extend-start(rect)\\n\\\n\ ! : extend-start()\\n\\\n\ ! Alt Shift Ctrl Button3: mouse_pan()\\n\n\ ! Meta Shift Ctrl Button3: mouse_pan()\\n\n\ ! Mod5 ~Ctrl Button3: extend-adjust(secondary)\\n\\\n\ ! Mod5 Ctrl Button3: extend-adjust(rect, secondary)\\n\\\n\ ! Shift~Ctrl Button3: extend-adjust(secondary)\\n\\\n\ ! Shift Ctrl Button3: extend-adjust(rect, secondary)\\n\\\n\ ! ~Shift Ctrl Button3: extend-adjust(rect)\\n\\\n\ ! Button3: extend-adjust()\\n\\\n\ ! Alt Shift Ctrl : end_drag()\\n\n\ ! Meta Shift Ctrl : end_drag()\\n\n\ ! Mod5 ~Ctrl : extend-end(secondary)\\n\\\n\ ! Mod5 Ctrl : extend-end(secondary, rect)\\n\\\n\ ! Shift~Ctrl : extend-end(secondary)\\n\\\n\ ! Shift Ctrl : extend-end(secondary, rect)\\n\\\n\ ! ~Shift Ctrl : extend-end(rect)\\n\\\n\ ! : extend-end()\n\ ! \n\ ! nedit.bgMenuButton: Shift Ctrl Alt\n\ ! \n\ ! ", *************** *** 1051,1053 **** operations or 80 characters typed). This file is has the same name as the \ ! file that you are editing, but with the character \"~\" (tilde) on Unix or \ \"_\" (underscore) on VMS prefixed \ --- 1237,1240 ---- operations or 80 characters typed). This file is has the same name as the \ ! file that you are editing, but with the character \"~\" (tilde) on Unix \ ! appended to the name or \ \"_\" (underscore) on VMS prefixed \ *************** *** 1062,1064 **** \n\ ! mv \\~help.c help.c\n\ \n\ --- 1249,1251 ---- \n\ ! mv help.c~ help.c\n\ \n\ *************** *** 1080,1133 **** \n\ ! Preferences Menu\n\ \n\ ! Default Settings -- Menu of initial settings for\n\ ! future windows. Generally the same as the\n\ ! options in the main part of the menu, but apply\n\ ! as defaults for future windows created during\n\ ! this NEdit session. These settings can be saved\n\ ! using the Save Defaults command below, to be\n\ ! loaded automatically each time NEdit is started.\n\ \n\ ! Save Defaults -- Save the default options as set\n\ ! under Default Settings for future NEdit sessions.\n\ \n\ ! Statistics Line -- Show the full file name, line\n\ ! number, and length of the file being edited.\n\ \n\ ! Language Mode -- Tells NEdit what language (if any) to\n\ ! assume, for selecting language-specific features\n\ ! such as highlight patterns and smart indent macros,\n\ ! and setting language specific preferences like word\n\ ! delimiters, tab emulation, and auto-indent. See\n\ ! Features for Programming -> Programming With NEdit\n\ ! for more information.\n\ ! \n\ ! Auto Indent -- Setting Auto Indent \"on\" maintains a\n\ ! running indent (pressing the return key will line\n\ ! up the cursor with the indent level of the previous\n\ ! line). If smart indent macros are available for\n\ ! the current language mode, smart indent can be\n\ ! selected and NEdit will attempt to guess proper\n\ ! language indentation for each new line. See\n\ ! Help -> Features for Programming -> Automatic\n\ ! Indent for more information.\n\ ! \n\ ! Wrap -- Choose between two styles of automatic wrapping\n\ ! or none. Auto Newline wrap, wraps text at word\n\ ! boundaries when the cursor reaches the right margin,\n\ ! by replacing the space or tab at the last word\n\ ! boundary with a newline character. Continuous Wrap\n\ ! wraps long lines which extend past the right margin.\n\ ! Continuous Wrap mode is typically used to produce\n\ ! files where newlines are ommitted within paragraphs,\n\ ! to make text filling automatic (a kind of poor-man's\n\ ! word processor). Text of this style is common on\n\ ! Macs and PCs but is not necessarily supported very\n\ ! well under Unix (except in programs which deal with\n\ ! e-mail, for which it is often the format of choice).\n\ ! \n\ ! Wrap Margin -- Set margin for Auto Newline Wrap,\n\ ! Continuous Wrap, and Fill Paragraph. Lines may,\n\ ! be wrapped at the right margin of the window, or\n\ ! the margin can be set at a specific column.\n\ \n\ --- 1267,1315 ---- \n\ ! Auto Indent -- Maintain a running indent. Pressing\n\ ! the return key will line up the cursor with the\n\ ! indent level of the previous line.\n\ ! \n\ ! Auto Newline Wrap -- Wrap text at word boundaries when\n\ ! the cursor reaches the right margin, by replacing\n\ ! the space or tab at the last word boundary with a\n\ ! newline character.\n\ ! \n\ ! Continuous Wrap -- Wrap long lines which extend past\n\ ! the right margin. This mode is typically used to\n\ ! produce files where newlines are ommitted within\n\ ! paragraphs, to make text filling automatic (a kind\n\ ! of poor-man's word processor). Text of this style\n\ ! is common on Macs and PCs but is not necessarily\n\ ! supported very well under Unix (except in programs\n\ ! which deal with e-mail, for which it is often the\n\ ! format of choice).\n\ ! \n\ ! Wrap Margin... -- Set margin for Auto Newline Wrap,\n\ ! Continuous Wrap, and Fill Paragraph. By default,\n\ ! lines wrap at the right margin of the window, but a\n\ ! wrap margin can also be set at a specific column.\n\ \n\ ! Preserve Last Version -- On Save, write a backup copy\n\ ! of the file as it existed before the Save command\n\ ! with the extension .bck (Unix only).\n\ ! The extension can be changed with the backupSuffix\n\ ! resouce. (See X Resources).\n\ \n\ ! Incremental Backup -- Periodically make a backup copy\n\ ! of the file being edited under the name ~filename\n\ ! on Unix or _filename on VMS (see Crash Recovery).\n\ \n\ ! Show Matching (..) -- Momentarily highlight matching\n\ ! parenthesis, brackets, and braces when one of\n\ ! these characters is typed, or when the insertion\n\ ! cursor is positioned after it.\n\ \n\ ! Text Font... -- Set the font for the text in this\n\ ! NEdit window. To set the font for all windows\n\ ! use the equivalent item in the Default Settings\n\ ! sub-menu. Note that since the font selection\n\ ! dialog narrows its lists of font characteristics\n\ ! depending on those already selected, it is\n\ ! important to know that you can unselect them\n\ ! by clicking on the selected items a second time.\n\ \n\ *************** *** 1138,1163 **** \n\ ! Text Font... -- Change the font(s) used to display\n\ ! text (fonts for menus and dialogs must be set\n\ ! using X resources for the text area of the window).\n\ ! See below for more information.\n\ ! \n\ ! Highlight Syntax -- If NEdit recognizes the language\n\ ! being edited, and highlighting patterns are\n\ ! available for that language, use fonts and colors\n\ ! to enhance viewing of the file. (See Help ->\n\ ! Features for Programming -> Syntax Highlighting\n\ ! for more information.\n\ \n\ ! Make Backup Copy -- On Save, write a backup copy of\n\ ! the file as it existed before the Save command\n\ ! with the extension .bck (Unix only).\n\ \n\ ! Incremental Backup -- Periodically make a backup copy\n\ ! of the file being edited under the name ~filename\n\ ! on Unix or _filename on VMS (see Crash Recovery).\n\ \n\ ! Show Matching (..) -- Momentarily highlight matching\n\ ! parenthesis, brackets, and braces when one of\n\ ! these characters is typed, or when the insertion\n\ ! cursor is positioned after it.\n\ \n\ --- 1320,1350 ---- \n\ ! Statistics Line -- Show the full file name, line\n\ ! number, and length of the file being edited.\n\ \n\ ! Incremental Search Line -- Enables the incremental\n\ ! search line just below the menu bar.\n\ \n\ ! Default Settings -- Sub-menu of initial settings\n\ ! for future windows. These are the same as the\n\ ! options in the main part of the menu, but apply\n\ ! as defaults for future windows created during\n\ ! this NEdit session. These settings can be saved\n\ ! using the Save Defaults command below, to be\n\ ! loaded automatically each time NEdit is started.\n\ \n\ ! On Exit Open Files Warning -- Enables an on exit\n\ ! confirmation dialog that lists the files that\n\ ! you have open that allows you to cancel the exit\n\ ! operation.\n\ ! \n\ ! Allow Read Only Edits -- Controls if the text area is\n\ ! editable eventhough the file is read only or\n\ ! locked.\n\ ! \n\ ! Save Defaults -- Save the default options as set\n\ ! under Default Settings for future NEdit sessions.\n\ ! \n\ ! The options below operate only \ ! on the current file in the current window, and can not be \ ! used as default preferences:\n\ \n\ *************** *** 1333,1338 **** subroutine get_x, reverse the first and second parameters, add a \ ! third parameter of NULL, and change the name to new_get_x\":\n\ \n\ ! Search string: get_x\\(([^ ,]*), ([^\\)]*)\\)\n\ ! Replace string: new_get_x(\\2, \\1, NULL)\n\ \n\ --- 1520,1525 ---- subroutine get_x, reverse the first and second parameters, add a \ ! third parameter of NULL, and change the name to \"new_get_x\":\n\ \n\ ! Search string: get_x\\(([^ ,]*), ([^\\)]*)\\)\n\ ! Replace string: new_get_x(\\2, \\1, NULL)\n\ \n\ *************** *** 1383,1385 **** Wherever the substitution string contains the character `&', NEdit will \ ! substitute the the entire string that was matched in the Find operation. \ Up to nine sub-expressions of the match string can also be inserted into \ --- 1570,1572 ---- Wherever the substitution string contains the character `&', NEdit will \ ! substitute the entire string that was matched in the Find operation. \ Up to nine sub-expressions of the match string can also be inserted into \ *************** *** 1450,1451 **** --- 1637,1642 ---- session.\n\ + -servername name -- Give the server a unique name.\n\ + Required if you want to have multiple servers on the\n\ + same X window display. The non-default servers are\n\ + accessed using the -sn option to nc.\n\ \n\ *************** *** 1640,1642 **** \n\ ! nedit -server\n\ \n\ --- 1831,1833 ---- \n\ ! nedit -server [-servername name]\n\ \n\ *************** *** 1673,1681 **** \n\ ! Communication between nc and nedit is through the X display. So as long as X \ windows is set up and working properly, nc will will work \ ! properly as well. nc uses the DISPLAY environment variable, the machine name \ ! and your user name to find the appropriate server, meaning, if you have several \ ! machines sharing a common file system, nc will not be able to find a server \ ! that is running on a machine with a different host name, even though it may be \ ! perfectly appropriate for editing a given file.\n\ \n\ --- 1864,1878 ---- \n\ ! Multiple nedit servers can be started and accessed by using the -sn \ ! option to specify a unique name for each server. \ ! \n\ ! Communication between nc and nedit is through the X window display. \ ! So as long as X \ windows is set up and working properly, nc will will work \ ! properly as well. nc searches for an nedit server running on the \ ! display specified by the DISPLAY environment variable. It then searches \ ! for a server started by your user name with the name specified \ ! by the -sn option if supplied. nc can be used from different machines \ ! that share a common file system as long as the DISPLAY environment variable \ ! is set to the same X window display. Be aware that the file access \ ! is still performed by the machine where the nedit server was started.\n\ \n\ *************** *** 1763,1764 **** --- 1960,1965 ---- \n\ + nedit.backupSuffix: .bck -- The suffix of the\n\ + backup file used to hold the version of\n\ + the file before the last save operation.\n\ + \n\ nedit.shell: /bin/csh -- (Unix systems only) The Unix\n\ *************** *** 1855,1856 **** --- 2056,2061 ---- \n\ + nedit.findReplaceUsesSelection: False -- Controls if\n\ + the find and replace dialog is automatically loaded\n\ + with the contents of the primary selection.\n\ + \n\ nedit*scrollBarPlacement: BOTTOM_LEFT -- How scroll\n\ *************** *** 1905,1906 **** --- 2110,2119 ---- \n\ + nedit*text.dragStartsOnCharacter: False -- Controls if\n\ + the character under the mouse is selected when\n\ + dragging to the right eventhough the I-bar is to\n\ + the left of the character.\n\ + \n\ + nedit*text.enableQuadrupleClick: False -- Controls if\n\ + quadruple click is enabled to select all of the text.\n\ + \n\ nedit*statsLine.foreground: black -- Foreground\n\ *************** *** 2005,2007 **** nedit*searchMenu.find.accelerator: Altf\n\ ! nedit*searchMenu.findShift.accelerator: Shift Altf", --- 2218,2222 ---- nedit*searchMenu.find.accelerator: Altf\n\ ! nedit*searchMenu.findShift.accelerator: Shift Altf\n\ ! \n\ ! ", *************** *** 2475,2521 **** \n\ ! File Menu Search Menu\n\ --------------------- -----------------------\n\ ! new() find()\n\ ! open() find_dialog()\n\ ! open_dialog() find_again()\n\ ! open_selected() find_selection()\n\ ! close() replace()\n\ ! save() replace_dialog()\n\ ! save_as() replace_all()\n\ ! save_as_dialog() replace_in_selection()\n\ ! revert_to_saved() replace_again()\n\ ! include_file() goto_line_number()\n\ ! include_file_dialog () goto_line_number_dialog()\n\ ! load_tags_file() goto_selected()\n\ ! load_tags_file_dialog() mark()\n\ ! load_macro_file() mark_dialog()\n\ ! load-macro-file-dialog() goto_mark()\n\ ! print() goto_mark_dialog()\n\ ! print_selection() match()\n\ ! exit() find_definition()\n\ ! split_window()\n\ ! close_pane()\n\ ! Edit Menu \n\ ! --------------------- Shell Menu\n\ ! undo() -----------------------\n\ ! redo() filter_selection_dialog()\n\ ! delete() filter_selection()\n\ ! select_all() execute_command()\n\ ! shift_left() execute_command_dialog()\n\ ! shift_left_by_tab() execute_command_line()\n\ ! shift_right() shell_menu_command()\n\ ! shift_right_by_tab() \n\ ! uppercase() Macro Menu\n\ ! lowercase() -----------------------\n\ ! fill_paragraph() macro_menu_command()\n\ ! control_code_dialog() repeat_macro()\n\ ! repeat_dialog()\n\ \n\ The actions representing menu commands are named the same as the menu item \ ! with punctuation removed, all lower case, and underscores \ ! replacing spaces. Without the \ ! _dialog suffix, commands which normally prompt the user for information, \ instead take the information from the routine's arguments (see below). To \ present a dialog and ask the user for input, rather than supplying it in via \ ! arguments, use the actions with the _dialog suffix.\n\ \n\ --- 2690,2742 ---- \n\ ! File Menu Search Menu\n\ --------------------- -----------------------\n\ ! new() find()\n\ ! open() find-dialog()\n\ ! open-dialog() find-incremental\n\ ! open-selected() find-again()\n\ ! close() find-selection()\n\ ! save() replace()\n\ ! save-as() replace-dialog()\n\ ! save-as-dialog() replace-all()\n\ ! revert-to-saved() replace-in-selection()\n\ ! include-file() replace-again()\n\ ! include-file-dialog () replace-find()\n\ ! load-tags-file() replace-find-again()\n\ ! load-tags-file-dialog() goto-line-number()\n\ ! print() goto-line-number-dialog()\n\ ! print-selection() goto-selected()\n\ ! exit() mark()\n\ ! mark-dialog()\n\ ! goto-mark()\n\ ! goto-mark-dialog()\n\ ! select-matching()\n\ ! goto-matching()\n\ ! Edit Menu find-definition()\n\ ! --------------------- \n\ ! undo() Shell Menu\n\ ! redo() -----------------------\n\ ! cut-clipboard() execute-command()\n\ ! copy-clipboard() execute-command-dialog()\n\ ! paste-clipboard() execute-selection-or-line()\n\ ! delete() filter-selection()\n\ ! select-all() filter-selection-dialog()\n\ ! shift-left() shell-menu-command()\n\ ! shift-left-by-tab() \n\ ! shift-right() Macro Menu\n\ ! shift-right-by-tab() -----------------------\n\ ! uppercase() macro-menu-command()\n\ ! lowercase() \n\ ! fill-paragraph() Windows Menu\n\ ! control-code-dialog() -----------------------\n\ ! split-window()\n\ ! close-pane()\n\ ! clone-window()\n\ \n\ The actions representing menu commands are named the same as the menu item \ ! with \ ! punctuation removed, all lower case, and dashes replacing spaces. Without the \ ! -dialog suffix, commands which normally prompt the user for information, \ instead take the information from the routine's arguments (see below). To \ present a dialog and ask the user for input, rather than supplying it in via \ ! arguments, use the actions with the -dialog suffix.\n\ \n\ *************** *** 2528,2530 **** \n\ ! save_as(filename)\n\ \n\ --- 2749,2751 ---- \n\ ! save-as(filename)\n\ \n\ *************** *** 2532,2544 **** \n\ ! load_tags_file(filename)\n\ \n\ ! find_dialog([search_direction])\n\ \n\ ! find(search_string [, search-direction], [search-type])\n\ \n\ ! find_again([search-direction])\n\ \n\ ! find_selection([search-direction])\n\ \n\ ! replace_dialog([search-direction])\n\ \n\ --- 2753,2767 ---- \n\ ! load-tags-file(filename)\n\ \n\ ! find(search-string [, search-direction], [search-type])\n\ \n\ ! find-dialog([search-direction])\n\ \n\ ! find-incremental(search-string [, search-direction], [search-type])\n\ \n\ ! find-again([search-direction])\n\ \n\ ! find-selection([search-direction])\n\ ! \n\ ! replace-dialog([search-direction])\n\ \n\ *************** *** 2547,2554 **** \n\ ! replace_in_selection(search-string, replace-string\n\ [, search-type])\n\ \n\ ! replace_again([search-direction])\n\ \n\ ! goto_line_number([line-number])\n\ \n\ --- 2770,2782 ---- \n\ ! replace-in-selection(search-string, replace-string\n\ [, search-type])\n\ \n\ ! replace-again([search-direction])\n\ ! \n\ ! replace-find(search-string, replace-string,\n\ ! [, search-direction] [, search-type])\n\ ! \n\ ! replace-find-again([search-direction])\n\ \n\ ! goto-line-number([line-number])\n\ \n\ *************** *** 2556,2566 **** \n\ ! goto_mark(mark-letter)\n\ \n\ ! filter_selection(shell-command)\n\ \n\ ! execute_command(shell-command)\n\ \n\ ! shell_menu_command(shell-menu-item-name)\n\ \n\ ! macro_menu_command(macro-menu-item-name)\n\ \n\ --- 2784,2794 ---- \n\ ! goto-mark(mark-letter)\n\ \n\ ! filter-selection(shell-command)\n\ \n\ ! execute-command(shell-command)\n\ \n\ ! shell-menu-command(shell-menu-item-name)\n\ \n\ ! macro-menu-command(macro-menu-item-name)\n\ \n\ *************** *** 2583,2586 **** (macro or shell) Name of the command exactly as\n\ ! -menu-item-name specified in the Shell Menu or\n\ ! Macro Menu dialogs\n\ \n\ --- 2811,2814 ---- (macro or shell) Name of the command exactly as\n\ ! -menu-item-name specified in the Macro Commands or\n\ ! Shell Commands dialogs\n\ \n\ *************** *** 2589,2594 **** \n\ ! backward_character()\n\ Moves the cursor one character to the left.\n\ \n\ ! backward_paragraph()\n\ Moves the cursor to the beginning of the paragraph, or if the \ --- 2817,2822 ---- \n\ ! backward-character()\n\ Moves the cursor one character to the left.\n\ \n\ ! backward-paragraph()\n\ Moves the cursor to the beginning of the paragraph, or if the \ *************** *** 2598,2600 **** \n\ ! backward_word()\n\ Moves the cursor to the beginning of a word, or, if the \ --- 2826,2828 ---- \n\ ! backward-word()\n\ Moves the cursor to the beginning of a word, or, if the \ *************** *** 2604,2612 **** \n\ ! beginning_of_file()\n\ Moves the cursor to the beginning of the file.\n\ \n\ ! beginning_of_line()\n\ Moves the cursor to the beginning of the line.\n\ \n\ ! beginning_of_selection()\n\ Moves the cursor to the beginning of the selection \ --- 2832,2852 ---- \n\ ! beginning-of-file()\n\ Moves the cursor to the beginning of the file.\n\ \n\ ! beginning-of-line([\"toggle\"], [\"non-space\"])\n\ Moves the cursor to the beginning of the line.\n\ + beginning-of-line()\n\ + always goes to the beginning of the line.\n\ + beginning-of-line(\"non-space\")\n\ + always goes to the first non-whitespace character.\n\ + beginning-of-line(\"toggle\")\n\ + first goes to the beginning of the line and then toggles\n\ + between the first non-whitespace character and the beginning\n\ + of the line.\n\ + beginning-of-line(\"toggle\", \"non-space\")\n\ + first goes to the first non-whitespace character and then\n\ + toggles between the beginning of the line and the first\n\ + non-whitespace character.\n\ \n\ ! beginning-of-selection()\n\ Moves the cursor to the beginning of the selection \ *************** *** 2614,2622 **** \n\ ! copy_clipboard()\n\ Copies the current selection to the clipboard.\n\ \n\ ! copy_primary()\n\ Copies the primary selection to the cursor.\n\ \n\ ! copy_to()\n\ If a secondary selection exists, copies the secondary selection to the \ --- 2854,2867 ---- \n\ ! copy-clipboard()\n\ Copies the current selection to the clipboard.\n\ \n\ ! copy-primary()\n\ Copies the primary selection to the cursor.\n\ \n\ ! copy-secondary()\n\ ! Copies the secondary selection into the primary selection. If \ ! there is no primary selection the secondary selection is inserted \ ! at the destination cursor in the window where the mouse was last clicked. \ ! \n\ ! copy-to()\n\ If a secondary selection exists, copies the secondary selection to the \ *************** *** 2626,2628 **** \n\ ! copy_to_or_end_drag()\n\ Completes either a secondary selection operation, or a primary \ --- 2871,2873 ---- \n\ ! copy-to-or-end-drag()\n\ Completes either a secondary selection operation, or a primary \ *************** *** 2635,2640 **** \n\ ! cut_clipboard()\n\ Deletes the text in the primary selection and places it in the clipboard.\n\ \n\ ! cut_primary()\n\ Copies the primary selection to the cursor and deletes it \ --- 2880,2885 ---- \n\ ! cut-clipboard()\n\ Deletes the text in the primary selection and places it in the clipboard.\n\ \n\ ! cut-primary()\n\ Copies the primary selection to the cursor and deletes it \ *************** *** 2642,2647 **** \n\ ! delete_selection()\n\ Deletes the contents of the primary selection.\n\ \n\ ! delete_next_character()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2887,2892 ---- \n\ ! delete-selection()\n\ Deletes the contents of the primary selection.\n\ \n\ ! delete-next-character()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2649,2651 **** \n\ ! delete_previous_character()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2894,2896 ---- \n\ ! delete-previous-character()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2653,2655 **** \n\ ! delete_next_word()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2898,2900 ---- \n\ ! delete-next-word()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2657,2659 **** \n\ ! delete_previous_word()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2902,2904 ---- \n\ ! delete-previous-word()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2661,2663 **** \n\ ! delete_to_start_of_line()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2906,2908 ---- \n\ ! delete-to-start-of-line()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2666,2668 **** \n\ ! delete_to_end_of_line()\n\ If a primary selection exists, deletes its contents. Otherwise, \ --- 2911,2913 ---- \n\ ! delete-to-end-of-line()\n\ If a primary selection exists, deletes its contents. Otherwise, \ *************** *** 2671,2682 **** \n\ ! deselect_all()\n\ De-selects the primary selection.\n\ \n\ ! end_of_file()\n\ Moves the cursor to the end of the file.\n\ \n\ ! end_of_line()\n\ Moves the cursor to the end of the line.\n\ \n\ ! end_of_selection()\n\ Moves the cursor to the end of the selection \ --- 2916,2966 ---- \n\ ! deselect-all()\n\ De-selects the primary selection.\n\ \n\ ! drag-or-grab-focus()\n\ ! An extention of the grab-focus action that supports dragging of the \ ! primary selection. It prepares for a drag operation if the file is \ ! writable and the multi-click time has expired and the button press \ ! occured within the primary selection and the \"secondary\" argument is \ ! not supplied. If any of the above is not true then the event is passed \ ! on to the grab-focus action. This action should be attached to the \ ! button down event. drag-or-extend-adjust and drag-or-extend-end should \ ! be attached to the button motion notify and button down events \ ! respectively. \ ! \n\ ! drag-or-extend-adjust()\n\ ! An extention of the extend-adjust action that supports dragging of the \ ! primary selection. This action should be attached to the button motion \ ! notify event. \ ! \n\ ! drag-or-extend-end()\n\ ! An extention of the extend-adjust action that supports dragging of the \ ! primary selection. This action should be attached to the button down \ ! event. \ ! \n\ ! end-of-file()\n\ Moves the cursor to the end of the file.\n\ \n\ ! end-of-line([\"toggle\"], [\"non-space\"])\n\ Moves the cursor to the end of the line.\n\ + end-of-line()\n\ + always goes to the end of the line.\n\ + end-of-line(\"non-space\")\n\ + always goes to the last non-whitespace character.\n\ + end-of-line(\"toggle\")\n\ + first goes to the end of the line and then toggles\n\ + between the last non-whitespace character and the end\n\ + of the line.\n\ + end-of-line(\"toggle\", \"non-space\")\n\ + first goes to the last non-whitespace character and then\n\ + toggles between the end of the line and the last\n\ + non-whitespace character.\n\ \n\ ! end-drag()\n\ ! If the user is dragging a block of \ ! text (primary selection), completes the drag operation and deletes the \ ! text from it's current location. If the user is performing a mouse pan, \ ! completes the mouse pan operation.\n\ ! \n\ ! end-of-selection()\n\ Moves the cursor to the end of the selection \ *************** *** 2687,2689 **** \n\ ! extend_adjust()\n\ Attached mouse-movement events to begin a selection between the \ --- 2971,2977 ---- \n\ ! exchange-or-copy-clipboard()\n\ ! If a secondary selection exists perform the exchange() action \ ! otherwise perform the copy-clipboard() action. \ ! \n\ ! extend-adjust()\n\ Attached mouse-movement events to begin a selection between the \ *************** *** 2692,2705 **** \n\ ! extend_end()\n\ Completes a primary drag-selection operation.\n\ \n\ ! extend_start()\n\ Begins a selection between the \ cursor and the mouse. A drag-selection operation can be started with \ ! either extend_start or grab_focus.\n\ \n\ ! forward_character()\n\ Moves the cursor one character to the right.\n\ \n\ ! forward_paragraph()\n\ Moves the cursor to the beginning of the next paragraph. Paragraphs are \ --- 2980,2993 ---- \n\ ! extend-end()\n\ Completes a primary drag-selection operation.\n\ \n\ ! extend-start()\n\ Begins a selection between the \ cursor and the mouse. A drag-selection operation can be started with \ ! either extend-start or grab-focus.\n\ \n\ ! forward-character()\n\ Moves the cursor one character to the right.\n\ \n\ ! forward-paragraph()\n\ Moves the cursor to the beginning of the next paragraph. Paragraphs are \ *************** *** 2707,2709 **** \n\ ! forward_word()\n\ Moves the cursor to the beginning of the next word. Word delimiters \ --- 2995,2997 ---- \n\ ! forward-word()\n\ Moves the cursor to the beginning of the next word. Word delimiters \ *************** *** 2711,2716 **** \n\ ! grab_focus()\n\ Moves the cursor to the mouse pointer location, and prepares for \ ! a possible drag-selection operation (bound to extend_adjust), or \ ! multi-click operation (a further grab_focus action). If a second \ invocation of grab focus follows immediately, it selects a whole word, \ --- 2999,3004 ---- \n\ ! grab-focus()\n\ Moves the cursor to the mouse pointer location, and prepares for \ ! a possible drag-selection operation (bound to extend-adjust), or \ ! multi-click operation (a further grab-focus action). If a second \ invocation of grab focus follows immediately, it selects a whole word, \ *************** *** 2718,2720 **** \n\ ! insert_string(\"string\") \n\ If pending delete is on and the cursor is inside the selection, replaces \ --- 3006,3008 ---- \n\ ! insert-string(\"string\") \n\ If pending delete is on and the cursor is inside the selection, replaces \ *************** *** 2723,2725 **** \n\ ! key_select(\"direction\")\n\ Moves the cursor one character in \ --- 3011,3013 ---- \n\ ! key-select(\"direction\")\n\ Moves the cursor one character in \ *************** *** 2735,2736 **** --- 3023,3030 ---- \n\ + move-secondary()\n\ + Moves the secondary selection into the primary selection. The \ + secondary selection is removed from its original location. If \ + there is no primary selection the secondary selection is inserted \ + at the destination cursor in the window where the mouse was last clicked. \ + \n\ move_to()\n\ *************** *** 2755,2757 **** \n\ ! newline_and_indent()\n\ Inserts a newline character and lines up the indentation \ --- 3049,3051 ---- \n\ ! newline-and-indent()\n\ Inserts a newline character and lines up the indentation \ *************** *** 2759,2761 **** \n\ ! newline_no_indent()\n\ Inserts a newline character, without automatic indentation, regardless of \ --- 3053,3055 ---- \n\ ! newline-no-indent()\n\ Inserts a newline character, without automatic indentation, regardless of \ *************** *** 2763,2774 **** \n\ ! next_page()\n\ Moves the cursor and scroll forward one page.\n\ \n\ ! page_left()\n\ Move the cursor and scroll left one page.\n\ \n\ ! page_right()\n\ Move the cursor and scroll right one page.\n\ \n\ ! paste_clipboard()\n\ Insert the contents of the clipboard at the cursor, or if pending delete \ --- 3057,3068 ---- \n\ ! next-page()\n\ Moves the cursor and scroll forward one page.\n\ \n\ ! page-left()\n\ Move the cursor and scroll left one page.\n\ \n\ ! page-right()\n\ Move the cursor and scroll right one page.\n\ \n\ ! paste-clipboard()\n\ Insert the contents of the clipboard at the cursor, or if pending delete \ *************** *** 2776,2800 **** \n\ ! previous_page()\n\ Moves the cursor and scroll backward one page.\n\ \n\ ! process_bdrag()\n\ ! Same as secondary_or_drag_start for compatibility with previous versions.\n\ \n\ ! process_cancel()\n\ ! Cancels the current extend_adjust, secondary_adjust, or \ ! secondary_or_drag_adjust in progress.\n\ \n\ ! process_down()\n\ Moves the cursor down one line.\n\ \n\ ! process_return()\n\ Same as newline for compatibility with previous versions.\n\ \n\ ! process_shift_down()\n\ ! Same as process_down(\"extend\") for compatibility with previous versions.\n\ \n\ ! process_shift_up()\n\ ! Same as process_up(\"extend\") for compatibility with previous versions.\n\ \n\ ! process_tab()\n\ If tab emulation is turned on, inserts an emulated tab, otherwise inserts \ --- 3070,3094 ---- \n\ ! previous-page()\n\ Moves the cursor and scroll backward one page.\n\ \n\ ! process-bdrag()\n\ ! Same as secondary-or-drag-start for compatibility with previous versions.\n\ \n\ ! process-cancel()\n\ ! Cancels the current extend-adjust, secondary-adjust, or \ ! secondary-or-drag-adjust in progress.\n\ \n\ ! process-down()\n\ Moves the cursor down one line.\n\ \n\ ! process-return()\n\ Same as newline for compatibility with previous versions.\n\ \n\ ! process-shift-down()\n\ ! Same as process-down(\"extend\") for compatibility with previous versions.\n\ \n\ ! process-shift-up()\n\ ! Same as process-up(\"extend\") for compatibility with previous versions.\n\ \n\ ! process-tab()\n\ If tab emulation is turned on, inserts an emulated tab, otherwise inserts \ *************** *** 2802,2813 **** \n\ ! process_up()\n\ Moves the cursor up one line.\n\ \n\ ! scroll_down(nLines)\n\ Scroll the display down (towards the end of the file) by nLines.\n\ \n\ ! scroll_up(nLines)\n\ Scroll the display up (towards the beginning of the file) by nLines.\n\ \n\ ! scroll_to_line(lineNum)\n\ Scroll to position line number lineNum at the top of the \ --- 3096,3107 ---- \n\ ! process-up()\n\ Moves the cursor up one line.\n\ \n\ ! scroll-down(nLines)\n\ Scroll the display down (towards the end of the file) by nLines.\n\ \n\ ! scroll-up(nLines)\n\ Scroll the display up (towards the beginning of the file) by nLines.\n\ \n\ ! scroll-to-line(lineNum)\n\ Scroll to position line number lineNum at the top of the \ *************** *** 2815,2817 **** \n\ ! secondary_adjust()\n\ Attached mouse-movement events to extend the secondary selection to the \ --- 3109,3111 ---- \n\ ! secondary-adjust()\n\ Attached mouse-movement events to extend the secondary selection to the \ *************** *** 2819,2821 **** \n\ ! secondary_or_drag_adjust()\n\ Attached mouse-movement events to extend the secondary selection, or \ --- 3113,3140 ---- \n\ ! secondary-or-clipboard(secondaryAction, clipboardAction)\n\ ! This action will perform the secondaryAction if a secondary selection \ ! exists otherwise it will perform the clipboardAction.\n\ ! \n\ ! secondaryAction is one of the following: \n\ ! \n\ ! move - move the secondary selection into the primary selection. \n\ ! The secondary selection is removed from its original location. \n\ ! If there is no primary selection the secondary selection is \n\ ! inserted at the destination cursor in the window where the \n\ ! mouse was last clicked.\n\ ! copy - copy the secondary selection into the primary selection. If \n\ ! there is no primary selection the secondary selection is \n\ ! inserted at the destination cursor in the window where the \n\ ! mouse was last clicked.\n\ ! exchange - exchange the secondary selection and the primary selection.\n\ ! \n\ ! clipboardAction is one of the following: \n\ ! \n\ ! cut - remove the primary selection and copy it to the clipboard. \n\ ! copy - copy the primary selection to the clipboard. \n\ ! paste - insert the contents of the clipboard in place of the primary \n\ ! selection. If there is no primary selection the contents of \n\ ! the clipboard is inserted at the cursor.\n\ ! \n\ ! secondary-or-drag-adjust()\n\ Attached mouse-movement events to extend the secondary selection, or \ *************** *** 2825,2829 **** mode, meaning the dragged text is laid on top of the existing text, \ ! obscuring and ultimately deleting it when the drag is complete.\n\ \n\ ! secondary_or_drag_start()\n\ To be attached to a mouse down event. Begins drag selecting a secondary \ --- 3144,3148 ---- mode, meaning the dragged text is laid on top of the existing text, \ ! obscuring and ultimately deleteing it when the drag is complete.\n\ \n\ ! secondary-or-drag-start()\n\ To be attached to a mouse down event. Begins drag selecting a secondary \ *************** *** 2832,2834 **** \n\ ! secondary_start()\n\ To be attached to a mouse down event. Begin drag selecting a secondary \ --- 3151,3153 ---- \n\ ! secondary-start()\n\ To be attached to a mouse down event. Begin drag selecting a secondary \ *************** *** 2836,2841 **** \n\ ! select_all()\n\ Select the entire file.\n\ \n\ ! self_insert()\n\ To be attached to a key-press event, inserts the character equivalent \ --- 3155,3160 ---- \n\ ! select-all()\n\ Select the entire file.\n\ \n\ ! self-insert()\n\ To be attached to a key-press event, inserts the character equivalent \ *************** *** 3447,3449 **** Widget appShell, form, btn, dismissBtn; ! Widget sw, hScrollBar, vScrollBar; XmString st1; --- 3766,3768 ---- Widget appShell, form, btn, dismissBtn; ! Widget sw; XmString st1; *************** *** 3516,3531 **** XmNbottomWidget, dismissBtn, 0); - hScrollBar = XtVaCreateManagedWidget("hScrollBar", - xmScrollBarWidgetClass, sw, XmNorientation, XmHORIZONTAL, - XmNrepeatDelay, 10, 0); - vScrollBar = XtVaCreateManagedWidget("vScrollBar", - xmScrollBarWidgetClass, sw, XmNorientation, XmVERTICAL, - XmNrepeatDelay, 10, 0); HelpTextPanes[topic] = XtVaCreateManagedWidget("helpText", textWidgetClass, sw, textNrows, 30, textNcolumns, 60, - textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar, textNreadOnly, True, textNcontinuousWrap, True, textNautoShowInsertPos, True, 0); ! XtVaSetValues(sw, XmNworkWindow, HelpTextPanes[topic], ! XmNhorizontalScrollBar, hScrollBar, ! XmNverticalScrollBar, vScrollBar, 0); BufSetAll(TextGetBuffer(HelpTextPanes[topic]), HelpText[topic]); --- 3835,3841 ---- XmNbottomWidget, dismissBtn, 0); HelpTextPanes[topic] = XtVaCreateManagedWidget("helpText", textWidgetClass, sw, textNrows, 30, textNcolumns, 60, textNreadOnly, True, textNcontinuousWrap, True, textNautoShowInsertPos, True, 0); ! XtVaSetValues(sw, XmNworkWindow, HelpTextPanes[topic], 0); BufSetAll(TextGetBuffer(HelpTextPanes[topic]), HelpText[topic]); *************** *** 3644,3646 **** XMapRaised(TheDisplay, XtWindow(HelpWindows[topic])); ! BufSelect(TextGetBuffer(HelpTextPanes[topic]), beginMatch, endMatch); TextSetCursorPos(HelpTextPanes[topic], endMatch); --- 3954,3956 ---- XMapRaised(TheDisplay, XtWindow(HelpWindows[topic])); ! BufSelect(TextGetBuffer(HelpTextPanes[topic]), beginMatch, endMatch, CHAR_SELECT); TextSetCursorPos(HelpTextPanes[topic], endMatch); *** highlight.c 1997/09/26 18:28:17 1.1 --- highlight.c 1997/10/24 00:50:52 1.5 *************** *** 23,28 **** * Written by Mark Edel * - * * *******************************************************************************/ #include ! #include #ifdef VMS --- 23,31 ---- * Written by Mark Edel * *******************************************************************************/ + #include #include ! #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #ifdef VMS *************** *** 37,38 **** --- 40,42 ---- #endif + #include #include "../util/misc.h" *************** *** 49,50 **** --- 53,63 ---- #include "window.h" + #include "search.h" + #ifdef HAVE_ALLOCA_H + # include + #endif + #ifdef HAVE_ALLOCA + # ifdef _AIX + # pragma alloca + # endif + #endif *************** *** 59,62 **** /* Meanings of style buffer characters (styles) */ - #define UNFINISHED_STYLE 'a' - #define PLAIN_STYLE 'b' #define IS_PLAIN(style) (style == PLAIN_STYLE || style == UNFINISHED_STYLE) --- 72,73 ---- *************** *** 78,79 **** --- 89,94 ---- + /* The number of characters that have to be inserted by the + ** SyntaxHighlightModifyCB to cause the the watch cursor to be displayed. */ + #define DISPLAY_WATCH_CURSOR_LIMIT 10000 + /* "Compiled" version of pattern specification */ *************** *** 101,103 **** information (for both drawing and incremental reparsing) */ ! typedef struct { highlightDataRec *pass1Patterns; --- 116,118 ---- information (for both drawing and incremental reparsing) */ ! typedef struct _windowHighlightData { highlightDataRec *pass1Patterns; *************** *** 161,162 **** --- 176,178 ---- + /* *************** *** 188,190 **** char *insStyle; - int i; --- 204,205 ---- *************** *** 204,211 **** if (nInserted > 0) { insStyle = XtMalloc(sizeof(char) * (nInserted + 1)); ! for (i=0; istyleBuffer, pos, pos+nDeleted, insStyle); XtFree(insStyle); } else --- 219,231 ---- if (nInserted > 0) { + #ifdef HAVE_ALLOCA + insStyle = alloca(sizeof(char) * (nInserted + 1)); + #else insStyle = XtMalloc(sizeof(char) * (nInserted + 1)); ! #endif ! memset(insStyle, UNFINISHED_STYLE, nInserted); ! insStyle[nInserted] = '\0'; BufReplace(highlightData->styleBuffer, pos, pos+nDeleted, insStyle); + #ifndef HAVE_ALLOCA XtFree(insStyle); + #endif } else *************** *** 218,225 **** changes that are already scheduled for redraw */ ! BufSelect(highlightData->styleBuffer, pos, pos+nInserted); /* Re-parse around the changed region */ ! if (highlightData->pass1Patterns) ! incrementalReparse(highlightData, window->buffer, pos, nInserted, GetWindowDelimiters(window)); } --- 238,253 ---- changes that are already scheduled for redraw */ ! BufSelect(highlightData->styleBuffer, pos, pos+nInserted, CHAR_SELECT); /* Re-parse around the changed region */ ! if (highlightData->pass1Patterns) { ! /* Display the watch cursor if there are a lot of changes */ ! if(nInserted >= DISPLAY_WATCH_CURSOR_LIMIT) { ! BeginWait(window->shell); ! } ! incrementalReparse(highlightData, window->editorInfo->buffer, pos, nInserted, GetWindowDelimiters(window)); + if(nInserted >= DISPLAY_WATCH_CURSOR_LIMIT) { + EndWait(window->shell); + } + } } *************** *** 238,240 **** ! /* Find the pattern set matching the window's current language mode, tell the user if it can't be done */ --- 266,272 ---- ! /* Turn off highlighting before turning it on. This way ! ** if we fail the highlight syntax is sure to be off. */ ! StopHighlighting(window); ! ! /* Find the pattern set matching the window's current language mode, tell the user if it can't be done */ *************** *** 250,254 **** ! /* Prepare for a long delay, refresh display and put up a watch cursor */ BeginWait(window->shell); ! XmUpdateDisplay(window->shell); --- 282,286 ---- ! /* Prepare for a long delay, refresh display and put up a watch cursor */ BeginWait(window->shell); ! UpdateDisplay(); *************** *** 256,265 **** the style buffer to all UNFINISHED_STYLE to trigger parsing later */ ! stylePtr = styleString = XtMalloc(window->buffer->length + 1); if (highlightData->pass1Patterns == NULL) { ! for (i=0; ibuffer->length; i++) ! *stylePtr++ = UNFINISHED_STYLE; } else { ! stringPtr = bufString = BufGetAll(window->buffer); parseString(highlightData->pass1Patterns, &stringPtr, &stylePtr, ! window->buffer->length, &isBOL, &isBOW, False, GetWindowDelimiters(window)); --- 288,297 ---- the style buffer to all UNFINISHED_STYLE to trigger parsing later */ ! stylePtr = styleString = XtMalloc(window->editorInfo->buffer->length + 1); if (highlightData->pass1Patterns == NULL) { ! memset(stylePtr, UNFINISHED_STYLE, window->editorInfo->buffer->length); ! *stylePtr += window->editorInfo->buffer->length; } else { ! stringPtr = bufString = BufGetAll(window->editorInfo->buffer); parseString(highlightData->pass1Patterns, &stringPtr, &stylePtr, ! window->editorInfo->buffer->length, &isBOL, &isBOW, False, GetWindowDelimiters(window)); *************** *** 271,272 **** --- 303,306 ---- + window->highlightSyntax = True; + /* install highlight pattern data in the window data structure */ *************** *** 283,284 **** --- 317,320 ---- AttachHighlightToWidget(window->textPanes[i], window); + + XmToggleButtonSetState(window->highlightItem, True, FALSE); *************** *** 300,301 **** --- 336,340 ---- + window->highlightSyntax = False; + XmToggleButtonSetState(window->highlightItem, False, FALSE); + if (window->highlightData==NULL) *************** *** 317,319 **** RemoveWidgetHighlight(window->textPanes[i]); ! /* Re-size the window to fit the primary font properly & tell the window --- 356,358 ---- RemoveWidgetHighlight(window->textPanes[i]); ! /* Re-size the window to fit the primary font properly & tell the window *************** *** 347,348 **** --- 386,388 ---- + /* *************** *** 433,435 **** windowHighlightData *highlightData; ! /* Compile the patterns (passing a random window as a source for fonts, and --- 473,475 ---- windowHighlightData *highlightData; ! /* Compile the patterns (passing a random window as a source for fonts, and *************** *** 466,467 **** --- 506,520 ---- + void printPatterns(highlightDataRec *pass1Patterns, highlightDataRec *pass2Patterns) { + int i; + highlightDataRec *hdrPtr; + + for(i = 0, hdrPtr = pass1Patterns; hdrPtr->style != 0; i++, hdrPtr++) { + printf("pass1Patterns[i].style = %c(%d)\n", hdrPtr->style, hdrPtr->style); + } + printf("\n"); + for(i = 0, hdrPtr = pass2Patterns; hdrPtr->style != 0; i++, hdrPtr++) { + printf("pass2Patterns[i].style = %c(%d)\n", hdrPtr->style, hdrPtr->style); + } + } + /* *************** *** 604,606 **** nPass2Patterns = 0; ! /* Compile patterns */ --- 657,659 ---- nPass2Patterns = 0; ! /* Compile patterns */ *************** *** 638,642 **** for (i=1; istyle!=0; hdrPtr++) { ! if (hdrPtr->startRE != NULL) ! free((char *)hdrPtr->startRE); ! if (hdrPtr->endRE != NULL) ! free((char *)hdrPtr->endRE); ! if (hdrPtr->errorRE != NULL) ! free((char *)hdrPtr->errorRE); ! if (hdrPtr->subPatternRE != NULL) ! free((char *)hdrPtr->subPatternRE); ! } ! for (hdrPtr = patterns; hdrPtr->style!=0; hdrPtr++) ! if (hdrPtr->subPatterns != NULL) ! XtFree((char *)hdrPtr->subPatterns); XtFree((char *)patterns); *************** *** 896,898 **** WindowInfo *window = (WindowInfo *)cbArg; ! textBuffer *buf = window->buffer; textBuffer *styleBuf = textD->styleBuffer; --- 950,952 ---- WindowInfo *window = (WindowInfo *)cbArg; ! textBuffer *buf = window->editorInfo->buffer; textBuffer *styleBuf = textD->styleBuffer; *************** *** 904,906 **** char *string, *styleString, *stringPtr, *stylePtr, c; ! int firstPass2Style = pass2Patterns[1].style; --- 958,960 ---- char *string, *styleString, *stringPtr, *stylePtr, c; ! int firstPass2Style; *************** *** 908,912 **** should never be triggered) */ ! if (pass2Patterns == NULL) return; ! /* Find the point at which to begin parsing to ensure that the character at --- 962,975 ---- should never be triggered) */ ! if (pass2Patterns == NULL) { ! #ifdef PURIFY ! purify_printf_with_call_chain( ! "handleUnparsedRegionCB(pass2Patterns == NULL): pos(%d)\n", ! pos ! ); ! #endif return; ! } ! ! firstPass2Style = pass2Patterns[1].style; ! /* Find the point at which to begin parsing to ensure that the character at *************** *** 917,919 **** for (p=beginParse; p>=beginSafety; p--) { ! c = BufGetCharacter(styleBuf, p); if (c != UNFINISHED_STYLE && c != PLAIN_STYLE && c < firstPass2Style) { --- 980,982 ---- for (p=beginParse; p>=beginSafety; p--) { ! c = _BufGetCharacter(styleBuf, p); if (c != UNFINISHED_STYLE && c != PLAIN_STYLE && c < firstPass2Style) { *************** *** 931,933 **** for (p=pos; pstyleBuffer; ! highlightDataRec *pass1Patterns = highlightData->pass1Patterns; ! highlightDataRec *pass2Patterns = highlightData->pass2Patterns; ! reparseContext *context = &highlightData->contextRequirements; ! char *majorStyles = highlightData->majorStyles; ! /* Find the position "beginParse" at which to begin reparsing. This is ! far enough back in the buffer such that the guranteed number of lines and characters of context are examined. */ --- 1039,1057 ---- int beginParse, endParse, endAt, lastMod, posInStyle, nPasses; ! textBuffer *styleBuf; ! highlightDataRec *pass1Patterns; ! highlightDataRec *pass2Patterns; ! reparseContext *context; ! char *majorStyles; ! if (!highlightData->pass1Patterns) ! return; ! ! styleBuf = highlightData->styleBuffer; ! pass1Patterns = highlightData->pass1Patterns; ! pass2Patterns = highlightData->pass2Patterns; ! context = &highlightData->contextRequirements; ! majorStyles = highlightData->majorStyles; ! ! /* Find the position "beginParse" at which to begin reparsing. This is ! far enough back in the buffer such that the guaranteed number of lines and characters of context are examined. */ *************** *** 1013,1018 **** /* printf("parsing within %c from %d to %d\n", ! BufGetCharacter(styleBuf, beginParse), beginParse, endParse); */ endAt = parseBufferRange(patternOfStyle(pass1Patterns, ! majorStyles[BufGetCharacter(styleBuf, beginParse)-'a']), NULL, buf, styleBuf, context, beginParse, endParse, --- 1085,1090 ---- /* printf("parsing within %c from %d to %d\n", ! _BufGetCharacter(styleBuf, beginParse), beginParse, endParse); */ endAt = parseBufferRange(patternOfStyle(pass1Patterns, ! majorStyles[_BufGetCharacter(styleBuf, beginParse)-UNFINISHED_STYLE]), NULL, buf, styleBuf, context, beginParse, endParse, *************** *** 1069,1071 **** ** allowed to match properly if they begin before beginParse, and a "landing" ! ** safety region beyond endparse so that endParse is guranteed to be parsed ** correctly in both passes. Returns the buffer position at which parsing --- 1141,1143 ---- ** allowed to match properly if they begin before beginParse, and a "landing" ! ** safety region beyond endparse so that endParse is guaranteed to be parsed ** correctly in both passes. Returns the buffer position at which parsing *************** *** 1088,1091 **** beginSafety = backwardOneContext(buf, contextRequirements, beginParse); ! for (p=beginParse; p>=beginSafety; p--) { ! style = BufGetCharacter(styleBuf, p-1); if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style)) { --- 1160,1163 ---- beginSafety = backwardOneContext(buf, contextRequirements, beginParse); ! for (p=beginParse; p>beginSafety; p--) { ! style = _BufGetCharacter(styleBuf, p-1); if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style)) { *************** *** 1097,1101 **** for (beginSafety=max(0,beginParse-1); beginSafety>0; beginSafety--) { ! style = BufGetCharacter(styleBuf, beginSafety); if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style) || ! BufGetCharacter(buf, beginSafety) == '\n') { beginSafety++; --- 1169,1173 ---- for (beginSafety=max(0,beginParse-1); beginSafety>0; beginSafety--) { ! style = _BufGetCharacter(styleBuf, beginSafety); if (!EQUIVALENT_STYLE(style, beginStyle, firstPass2Style) || ! _BufGetCharacter(buf, beginSafety) == '\n') { beginSafety++; *************** *** 1107,1109 **** ! /* Parse one parse context beyond requested end to gurantee that parsing at endParse is complete, unless patterns can't cross line boundaries, --- 1179,1181 ---- ! /* Parse one parse context beyond requested end to guarantee that parsing at endParse is complete, unless patterns can't cross line boundaries, *************** *** 1114,1116 **** endSafety = forwardOneContext(buf, contextRequirements, endParse); ! else if (endParse>=buf->length || (BufGetCharacter(buf,endParse-1)=='\n')) endSafety = endParse; --- 1186,1188 ---- endSafety = forwardOneContext(buf, contextRequirements, endParse); ! else if (endParse>=buf->length || (_BufGetCharacter(buf,endParse-1)=='\n')) endSafety = endParse; *************** *** 1148,1150 **** /* Re-parse the areas before the modification with pass 2 patterns, from ! beginSafety to far enough beyond modStart to gurantee that parsing at modStart is correct (pass 2 patterns must match entirely within one --- 1220,1222 ---- /* Re-parse the areas before the modification with pass 2 patterns, from ! beginSafety to far enough beyond modStart to guarantee that parsing at modStart is correct (pass 2 patterns must match entirely within one *************** *** 1170,1172 **** --- 1242,1248 ---- tempLen = endPass2Safety - modStart; + #ifdef HAVE_ALLOCA + temp = alloca(tempLen); + #else temp = XtMalloc(tempLen); + #endif strncpy(temp, &styleString[modStart-beginSafety], tempLen); *************** *** 1175,1177 **** --- 1251,1255 ---- strncpy(&styleString[modStart-beginSafety], temp, tempLen); + #ifndef HAVE_ALLOCA XtFree(temp); + #endif } *************** *** 1191,1193 **** --- 1269,1275 ---- tempLen = modEnd - startPass2Safety; + #ifdef HAVE_ALLOCA + temp = alloca(tempLen); + #else temp = XtMalloc(tempLen); + #endif strncpy(temp, &styleString[startPass2Safety-beginSafety], tempLen); *************** *** 1199,1201 **** --- 1281,1285 ---- strncpy(&styleString[startPass2Safety-beginSafety], temp, tempLen); + #ifndef HAVE_ALLOCA XtFree(temp); + #endif } *************** *** 1236,1345 **** { ! int i, endExprValid; ! char *stringPtr, *stylePtr; ! signed char *subExpr; ! highlightDataRec *subPat, *subSubPat; ! ! if (length <= 0) return False; ! ! stringPtr = *string; ! stylePtr = *styleString; ! while(ExecRE(pattern->subPatternRE, stringPtr, anchored ? *string+1 : *string+length+1, False, *isBOL, *isBOW, delimiters)) { ! ! /* Combination of all sub-patterns and end pattern matched */ ! /* printf("combined patterns RE matched at %d\n", ! pattern->subPatternRE->startp[0] - *string); */ ! ! /* Fill in the pattern style for the text that was skipped over before ! the match, and advance the pointers to the start of the pattern */ ! fillStyleString(&stringPtr, &stylePtr, pattern->subPatternRE->startp[0], ! pattern->style, isBOL, isBOW); ! ! /* If the combined pattern matched this pattern's end pattern, we're ! done. Fill in the style string, update the pointers, and return */ ! if (pattern->endRE != NULL && ExecRE(pattern->endRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) { ! fillStyleString(&stringPtr, &stylePtr, pattern->endRE->endp[0], ! pattern->style, isBOL, isBOW); ! *string = stringPtr; ! *styleString = stylePtr; ! return True; ! } ! ! /* If the combined pattern matched this pattern's error pattern, we're ! done. Fill in the style string, update the pointers, and return */ ! if (pattern->errorRE != NULL && ExecRE(pattern->errorRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) { ! fillStyleString(&stringPtr, &stylePtr, pattern->errorRE->startp[0], ! pattern->style, isBOL, isBOW); ! *string = stringPtr; ! *styleString = stylePtr; ! return False; ! } ! ! /* Figure out which sub-pattern matched */ ! for (i=0; inSubPatterns; i++) { ! subPat = pattern->subPatterns[i]; ! if (!subPat->colorOnly && ExecRE(subPat->startRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) ! break; } ! if (i == pattern->nSubPatterns) { ! fprintf(stderr, "Internal error, failed to match in parseString\n"); ! return False; ! } ! ! /* the sub-pattern is a simple match, just color it */ ! if (subPat->subPatternRE == NULL) { ! fillStyleString(&stringPtr, &stylePtr, subPat->startRE->endp[0], ! subPat->style, isBOL, isBOW); ! endExprValid = False; ! ! /* Parse the remainder of the sub-pattern */ ! } else { ! ! /* If parsing should start after the start pattern, advance ! to that point */ ! if (!(subPat->flags & PARSE_SUBPATS_FROM_START)) ! fillStyleString(&stringPtr, &stylePtr, ! subPat->startRE->endp[0], subPat->style, isBOL, isBOW); ! ! /* Parse to the end of the subPattern */ ! endExprValid = parseString(subPat, &stringPtr, &stylePtr, length - ! (stringPtr - *string), isBOL, isBOW, False, delimiters); ! } ! ! /* Process color-only sub-patterns of sub-pattern */ ! for (i=0; inSubPatterns; i++) { ! subSubPat = subPat->subPatterns[i]; ! if (subSubPat->colorOnly) { ! for (subExpr=subSubPat->startSubexprs; *subExpr!=-1; subExpr++) ! recolorSubexpr(subPat->startRE, *subExpr, subSubPat->style, ! *string, *styleString); ! if (subPat->endRE != NULL && endExprValid) { ! for (subExpr=subSubPat->endSubexprs; *subExpr!=-1; ! subExpr++) ! recolorSubexpr(subPat->endRE, *subExpr, ! subSubPat->style, *string, *styleString); ! } ! } } ! } ! ! /* If this is an anchored match (must match on first character), and ! nothing matched, return False */ ! if (anchored && stringPtr == *string) ! return False; ! ! /* Reached end of string, fill in the remaining text with pattern style ! (unless this was an anchored match) */ ! if (!anchored) ! fillStyleString(&stringPtr, &stylePtr, *string+length, pattern->style, ! isBOL, isBOW); ! ! /* Advance the string and style pointers to the end of the parsed text */ ! *string = stringPtr; ! *styleString = stylePtr; ! return pattern->endRE == NULL; } --- 1320,1438 ---- { ! int i; ! char *stringPtr, *stylePtr; ! signed char *subExpr; ! highlightDataRec *subPat = 0, *subSubPat; ! ! if (length <= 0) return False; ! ! stringPtr = *string; ! stylePtr = *styleString; ! while(ExecRE(pattern->subPatternRE, stringPtr, anchored ? *string+1 : *string+length+1, False, *isBOL, *isBOW, delimiters)) { ! /* Refresh the display each pass so it doesn't seem like we ! ** are completely hung. This may cause problems when reloading ! ** the file and syntax highlighting is not turned off. */ ! UpdateDisplay(); ! ! /* Combination of all sub-patterns and end pattern matched */ ! /* printf("combined patterns RE matched at %d\n", ! pattern->subPatternRE->startp[0] - *string); */ ! ! /* Fill in the pattern style for the text that was skipped over before ! the match, and advance the pointers to the start of the pattern */ ! fillStyleString(&stringPtr, &stylePtr, pattern->subPatternRE->startp[0], ! pattern->style, isBOL, isBOW); ! ! /* If the combined pattern matched this pattern's end pattern, we're ! done. Fill in the style string, update the pointers, and return */ ! if (pattern->endRE != NULL && ExecRE(pattern->endRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) { ! fillStyleString(&stringPtr, &stylePtr, pattern->endRE->endp[0], ! pattern->style, isBOL, isBOW); ! /* Process color-only sub-patterns based on the end pattern */ ! for (i=0; inSubPatterns; i++) { ! subSubPat = pattern->subPatterns[i]; ! if (subSubPat->colorOnly) { ! for (subExpr=subSubPat->endSubexprs; *subExpr!=-1; ! subExpr++) ! recolorSubexpr(pattern->endRE, *subExpr, ! subSubPat->style, *string, *styleString); ! } ! } ! *string = stringPtr; ! *styleString = stylePtr; ! return True; ! } ! ! /* If the combined pattern matched this pattern's error pattern, we're ! done. Fill in the style string, update the pointers, and return */ ! if (pattern->errorRE != NULL && ExecRE(pattern->errorRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) { ! fillStyleString(&stringPtr, &stylePtr, pattern->errorRE->startp[0], ! pattern->style, isBOL, isBOW); ! *string = stringPtr; ! *styleString = stylePtr; ! return False; ! } ! /* Figure out which sub-pattern matched */ ! for (i=0; inSubPatterns; i++) { ! subPat = pattern->subPatterns[i]; ! if (ExecRE(subPat->startRE, stringPtr, stringPtr+1, False, *isBOL, *isBOW, delimiters)) ! break; ! } ! if (i == pattern->nSubPatterns) { ! fprintf(stderr, "Internal error, failed to match in parseString\n"); ! return False; ! } ! ! /* the sub-pattern is a simple match, just color it */ ! if (subPat->subPatternRE == NULL) { ! fillStyleString(&stringPtr, &stylePtr, subPat->startRE->endp[0], ! subPat->style, isBOL, isBOW); ! ! /* Parse the remainder of the sub-pattern */ ! } else { ! ! /* If parsing should start after the start pattern, advance ! to that point */ ! if (!(subPat->flags & PARSE_SUBPATS_FROM_START)) { ! fillStyleString(&stringPtr, &stylePtr, ! subPat->startRE->endp[0], subPat->style, isBOL, isBOW); ! } ! ! /* Parse to the end of the subPattern */ ! parseString(subPat, &stringPtr, &stylePtr, ! length - (stringPtr - *string), isBOL, isBOW, False, ! delimiters); ! } ! ! /* Process color-only sub-patterns of sub-pattern */ ! for (i=0; inSubPatterns; i++) { ! subSubPat = subPat->subPatterns[i]; ! if (subSubPat->colorOnly) { ! for (subExpr=subSubPat->startSubexprs; *subExpr!=-1; subExpr++) ! recolorSubexpr(subPat->startRE, *subExpr, subSubPat->style, ! *string, *styleString); ! } ! } } ! ! /* If this is an anchored match (must match on first character), and ! nothing matched, return False */ ! if (anchored && stringPtr == *string) ! return False; ! ! /* Reached end of string, fill in the remaining text with pattern style ! (unless this was an anchored match) */ ! if (!anchored) { ! fillStyleString(&stringPtr, &stylePtr, *string+length, pattern->style, ! isBOL, isBOW); } ! ! /* Advance the string and style pointers to the end of the parsed text */ ! *string = stringPtr; ! *styleString = stylePtr; ! return pattern->endRE == NULL; } *************** *** 1357,1359 **** int inParseRegion = False; ! char *stylePtr, *stringPtr, temp, *parseStart, *parseEnd, *s, *c; int firstPass2Style = pattern[1].style; --- 1450,1452 ---- int inParseRegion = False; ! char *stylePtr, *stringPtr, temp, *parseStart = string, *parseEnd, *s, *c; int firstPass2Style = pattern[1].style; *************** *** 1398,1409 **** { ! int i; ! ! if (*stringPtr >= toPtr) return; ! ! for (i=0; i= toPtr) { ! /* this does happen in parseString() after the if(!anchored) test. So I guess it ! ** is not a problem so lets not complain about it. */ ! #ifdef PURIFY ! if(*stringPtr > toPtr) { ! purify_printf_with_call_chain( ! "fillStyleString(*stringPtr > toPtr): *stringPtr(%d) toPtr(%d)\n", ! *stringPtr, toPtr ! ); ! } ! #endif return; ! } ! ! len = toPtr - *stringPtr; ! memset(*stylePtr, style, len); ! ! *stringPtr += len; ! *stylePtr += len; ! ! if (isBOL != NULL) *isBOL = ((*stringPtr)[-1] == '\n'); ! if (isBOW != NULL) *isBOW = isDelim((*stringPtr)[-1]); } *************** *** 1436,1438 **** for (c=styleString, pos=startPos; pos=limit; i--) { ! style = BufGetCharacter(styleBuf, i); ! if (majorStyles[style-'a'] != startStyle) return i + 1; --- 1674,1677 ---- for (i=pos-1; i>=limit; i--) { ! style = _BufGetCharacter(styleBuf, i); ! if (majorStyles[style-UNFINISHED_STYLE] != startStyle) return i + 1; *************** *** 1576,1578 **** ** Back up position pointed to by "pos" enough that parsing from that point on ! ** will satisfy context gurantees for pattern matching for modifications at ** pos. If that can't be done without extending beyond 2X the requested --- 1683,1685 ---- ** Back up position pointed to by "pos" enough that parsing from that point on ! ** will satisfy context guarantees for pattern matching for modifications at ** pos. If that can't be done without extending beyond 2X the requested *************** *** 1597,1599 **** /* Back up far enough to ensure that expressions can match any characters ! within the pattern's guranteed context back from the change */ *pos = backwardOneContext(buf, context, *pos); --- 1704,1706 ---- /* Back up far enough to ensure that expressions can match any characters ! within the pattern's guaranteed context back from the change */ *pos = backwardOneContext(buf, context, *pos); *************** *** 1604,1606 **** return True; ! overlapStyle = BufGetCharacter(styleBuf, *pos); if (IS_PLAIN(overlapStyle)) --- 1711,1713 ---- return True; ! overlapStyle = _BufGetCharacter(styleBuf, *pos); if (IS_PLAIN(overlapStyle)) *************** *** 1618,1620 **** ** the major style (i.e. not the middle of a sub-style), and is far enough ! ** from the beginning and end of the style to gurantee that it's not ** within the start or end expression match. --- 1725,1727 ---- ** the major style (i.e. not the middle of a sub-style), and is far enough ! ** from the beginning and end of the style to guarantee that it's not ** within the start or end expression match. *************** *** 1624,1626 **** safeParseStart = 0; ! overlapMajorStyle = majorStyles[overlapStyle-'a']; for (i = *pos-1; ; i--) { --- 1731,1733 ---- safeParseStart = 0; ! overlapMajorStyle = majorStyles[overlapStyle-UNFINISHED_STYLE]; for (i = *pos-1; ; i--) { *************** *** 1635,1638 **** of the style is required */ ! style = BufGetCharacter(styleBuf, i); ! if (overlapMajorStyle != majorStyles[style-'a']) { *pos = i + 1; --- 1742,1745 ---- of the style is required */ ! style = _BufGetCharacter(styleBuf, i); ! if (overlapMajorStyle != majorStyles[style-UNFINISHED_STYLE]) { *pos = i + 1; *************** *** 1659,1661 **** ** Return a position far enough back in "buf" from "fromPos" to give patterns ! ** their guranteed amount of context for matching (from "context"). If ** backing up by lines yields the greater distance, the returned position will --- 1766,1768 ---- ** Return a position far enough back in "buf" from "fromPos" to give patterns ! ** their guaranteed amount of context for matching (from "context"). If ** backing up by lines yields the greater distance, the returned position will *************** *** 1714,1715 **** --- 1821,1831 ---- stringPtr = re->startp[subexpr]; + #ifdef PURIFY + if(stringPtr < string) { + purify_printf_with_call_chain( + "recolorSubexpr(stringPtr < string): stringPtr(%d) string(%d) subexpr(%d) styleString(%d)\n", + stringPtr, string, subexpr, styleString + ); + return; + } + #endif stylePtr = &styleString[stringPtr - string]; *** highlight.h 1997/09/26 18:28:17 1.1 --- highlight.h 1997/10/10 00:15:13 1.2 *************** *** 25,26 **** --- 25,28 ---- *******************************************************************************/ + #ifndef _highlight_h_ + #define _highlight_h_ *************** *** 60 **** --- 62,64 ---- int TestHighlightPatterns(patternSet *patSet); + + #endif /* _highlight_h_ */ *** highlightData.c 1997/09/26 18:28:17 1.1 --- highlightData.c 1997/10/24 22:01:03 1.5 *************** *** 25,28 **** *******************************************************************************/ #include ! #include #ifdef VMS --- 25,31 ---- *******************************************************************************/ + #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #ifdef VMS *************** *** 186,189 **** ! #define N_DEFAULT_PATTERN_SETS 14 ! static char *DefaultPatternSets[N_DEFAULT_PATTERN_SETS] = { "C:1:0 {\n\ --- 189,191 ---- ! static char *DefaultPatternSets[] = { "C:1:0 {\n\ *************** *** 237,257 **** include comment:\"/\\*\":\"\\*/\"::Comment:include:}", ! "Perl:1:0 {\n\ ! comments:\"#\":\"$\"::Comment::\n\ ! double quote strings:\"\"\"\":\"\"\"\":\"\\n\":String::\n\ ! dq string esc chars:\"\\\\(.|\\n)\":::String1:double quote strings:\n\ ! single quote strings:\"'\":\"'\":\"\\n\":String::\n\ ! sq string esc chars:\"\\\\(.|\\n)\":::String1:single quote strings:\n\ ! subroutine header:\"sub[\\t ]+([a-zA-Z0-9_]+)[\\t ]+{\":::Keyword::\n\ ! subr header coloring:\"\\1\":::Flag:subroutine header:C\n\ ! ignore escaped chars:\"\\\\[#\"\"'\\$msytq]\":::Plain::\n\ ! re matching:\"<((m|q|qq)?/)[^/]*(/[gimsox]?)>\":::String::\n\ ! re match coloring:\"\\1\\3\":::String2:re matching:C\n\ ! re substitution:\"<((s|y|tr)/)[^/]*(/)[^/]*(/[gimsox]?)\":::String::\n\ ! re subs coloring:\"\\1\\3\\4\":::String2:re substitution:C\n\ ! keywords:\"<(my|local|new|if|until|while|elsif|else|eval|unless|for|foreach|continue|exit|die|last|goto|next|redo|return|local|exec|do|use|require|package|eval|BEGIN|END|eq|ne|not|\\|\\||\\&\\&|and|or)>\":::Keyword::D\n\ ! library fns:\"<(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|chmod|chomp|chop|chr|chroot|chown|closedir|close|connect|cos|crypt|dbmclose|dbmopen|defined|delete|die|dump|each|endgrent|endhostent|endnetent|endprotoent|endpwent|endservent|eof|exec|exists|exp|fctnl|fileno|flock|fork|format|formline|getc|getgrent|getgrgid|getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|getppid|getpriority|getprotobyname|getprotobynumber|getprotoent|getpwent|getpwnam|getpwuid|getservbyname|getservbyport|getservent|getsockname|getsockopt|glob|gmtime|grep|hex|import|index|int|ioctl|join|keys|kill|lcfirst|lc|length|link|listen|log|localtime|lstat|map|mkdir|msgctl|msgget|msgrcv|no|oct|opendir|open|ord|pack|pipe|pop|pos|printf|print|push|quotemeta|rand|readdir|read|readlink|recv|ref|rename|reset|reverse|rewinddir|rindex|rmdir|scalar|seekdir|seek|select|semctl|semget|semop|send|setgrent|sethostent|setnetent|setpgrp|setpriority|setprotoent|setpwent|setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|srand|stat|study|substr|symlink|syscall|sysopen|sysread|system|syswrite|telldir|tell|tie|tied|time|times|truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|utime|values|vec|wait|waitpid|wantarray|warn|write|qw|-[rwxoRWXOezsfdlpSbctugkTBMAC])>\":::Subroutine::D\n\ ! variables:\"[$@%]({[^}]*}|[^a-zA-Z0-9_ /\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?\":::Identifier1::\n\ ! variables in strings:\"[$@%&]({[^}]*}|[^a-zA-Z0-9_ /\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?\":::Identifier1:double quote strings:\n\ ! subroutine call:\"&[a-zA-Z0-9_]+\":::Subroutine::\n\ ! braces and parens:\"[\\[\\]{}\\(\\)]\":::Keyword::}", "Ada:1:0 {\n\ --- 239,272 ---- include comment:\"/\\*\":\"\\*/\"::Comment:include:}", ! "Perl:1:0{\n\ ! escaped characters:\"\\\\[\\\\\"\"$`']\":::Escaped Items::\n\ ! double quote strings:\"\"\"\":\"\"\"\":\"\\n\":Double Quoted String::\n\ ! dq escapes:\"\\\\(.|\\n)\":::Escaped Items:double quote strings:\n\ ! dq variables:\"\\$[^a-zA-Z0-9_ \\t\\n{]|\\$[0-9]+|[$@%][a-zA-Z_][a-zA-Z0-9_]*\":::Identifier:double quote strings:\n\ ! single quote strings:\"'\":\"'\":\"\\n\":Single Quoted String::\n\ ! sq escapes:\"\\\\'\":::Escaped Items:single quote strings:\n\ ! command substitution:\"`\":\"`\":\"\\n\":Single Quoted String::\n\ ! cs variables:\"\\$[^a-zA-Z0-9_ \\t\\n{]|\\$[0-9]+|[$@%][a-zA-Z_][a-zA-Z0-9_]*\":::Identifier:command substitution:\n\ ! cs escapes:\"\\\\(.|\\n)\":::Escaped Items:command substitution:\n\ ! numeric constants:\"<((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?>\":::Numeric Const::D\n\ ! comments:\"#\":\"$\"::Comment::\n\ ! subroutine header:\"sub[\\t ]+([a-zA-Z_][a-zA-Z0-9_]*)\":::Keyword::\n\ ! subr header coloring:\"\\1\":\"\"::Subroutine:subroutine header:C\n\ ! re matching:\"<((m|q|qq)?/)\":\"(/[gimsox]?)>\":\"\\n\":Double Quoted String::\n\ ! re match coloring:\"\\1\":\"\\1\"::Operators:re matching:C\n\ ! re match escapes:\"\\\\(.|\\n)\":::Escaped Items:re matching:\n\ ! re match variables:\"\\$[^a-zA-Z0-9_ /\\t\\n{]|\\$[0-9]+|[$@%][a-zA-Z_][a-zA-Z0-9_]*\":::Identifier:re matching:\n\ ! re substitution:\"<((s|y|tr)/)\":\"(/[gimsox]?)>\":\"\\n\":Double Quoted String::\n\ ! re sub escapes:\"\\\\(.|\\n)\":::Escaped Items:re substitution:\n\ ! re sub slash:\"/\":::Operators:re substitution:\n\ ! re sub variables:\"\\$[^a-zA-Z0-9_ /\\t\\n{]|\\$[0-9]+|[$@%][a-zA-Z_][a-zA-Z0-9_]*\":::Identifier:re substitution:\n\ ! re sub coloring:\"\\1\":\"\\1\"::Operators:re substitution:C\n\ ! keywords:\"<(my|local|new|if|until|while|elsif|else|eval|unless|for|foreach|continue|last|goto|next|redo|return|do|use|require|package|eval|BEGIN|END)>\":::Keyword::D\n\ ! library fns:\"<(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|chmod|chomp|chop|chr|chroot|chown|closedir|close|connect|cos|crypt|dbmclose|dbmopen|defined|delete|die|dump|each|endgrent|endhostent|endnetent|endprotoent|endpwent|endservent|eof|exec|exists|exit|exp|fctnl|fileno|flock|fork|format|formline|getc|getgrent|getgrgid|getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|getppid|getpriority|getprotobyname|getprotobynumber|getprotoent|getpwent|getpwnam|getpwuid|getservbyname|getservbyport|getservent|getsockname|getsockopt|glob|gmtime|grep|hex|import|index|int|ioctl|join|keys|kill|lcfirst|lc|length|link|listen|log|localtime|lstat|map|mkdir|msgctl|msgget|msgrcv|no|oct|opendir|open|ord|pack|pipe|pop|pos|printf|print|push|quotemeta|rand|readdir|read|readlink|recv|ref|rename|reset|reverse|rewinddir|rindex|rmdir|scalar|seekdir|seek|select|semctl|semget|semop|send|setgrent|sethostent|setnetent|setpgrp|setpriority|setprotoent|setpwent|setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|srand|stat|study|substr|symlink|syscall|sysopen|sysread|system|syswrite|telldir|tell|tie|tied|time|times|truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|utime|values|vec|wait|waitpid|wantarray|warn|write)>\":::Library Function::D\n\ ! operators:\"<(not|or|xor|eq|ne|lt|gt|le|ge|cmp|qw|-[rwxRWXoOezsfdlSpbcugktTBMAC])>|(\\<=\\>|&&|\\|\\||==|!=|\\<=|\\>=|!|=\\>|=~|!~|\\>|\\<|::|-\\>|<[.&|?:=]>)\":::Operators::D\n\ ! subroutine call 1:\"&[a-zA-Z_][a-zA-Z0-9_]*|&?([a-zA-Z_][a-zA-Z0-9_]*::)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*(\\()\":::Subroutine::D\n\ ! subroutine call 1 paren:\"\\2\":\"\"::Keyword:subroutine call 1:DC\n\ ! package variables:\"[$@%][a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_][a-zA-Z0-9_]*\":::Identifier1::\n\ ! variables:\"\\$[^a-zA-Z0-9_ \\t\\n{]|\\$[0-9]+|[$@%][a-zA-Z_][a-zA-Z0-9_]*\":::Identifier::\n\ ! delimiters:\"[\\[\\]{}\\(\\);,]\":::Delimiters::D\n\ ! }", "Ada:1:0 {\n\ *************** *** 315,316 **** --- 330,370 ---- Include:\"^include[ \\t]\":::Keyword::}", + "Sh Ksh Bash:1:0{\n\ + escaped special characters:\"\\\\[\\\\\"\"$`']\":::Escaped Items::\n\ + single quoted string:\"'\":\"'\"::Single Quoted String::\n\ + double quoted string:\"\"\"\":\"\"\"\"::Double Quoted String::\n\ + double quoted escape:\"\\\\[\\\\\"\"$`]\":::Escaped Items:double quoted string:\n\ + dq command sub:\"`\":\"`\":\"\"\"\":Subroutine:double quoted string:\n\ + dq arithmetic expansion:\"\\$\\(\\(\":\"\\)\\)\":\"\"\"\":Double Quoted String:double quoted string:\n\ + dq new command sub:\"\\$\\(\":\"\\)\":\"\"\"\":Subroutine:double quoted string:\n\ + dq variables:\"\\$([-*@#?$!0-9]|[a-zA-Z_][0-9a-zA-Z_]*)\":::Identifier:double quoted string:\n\ + dq variables2:\"\\${\":\"}\":\"\\n\":Identifier:double quoted string:\n\ + arithmetic expansion:\"\\$\\(\\(\":\"\\)\\)\"::Double Quoted String::\n\ + ae escapes:\"\\\\[\\\\$`\"\"']\":::Escaped Items:arithmetic expansion:\n\ + ae single quoted string:\"'\":\"'\":\"\\)\\)\":Single Quoted String:arithmetic expansion:\n\ + ae command sub:\"`\":\"`\":\"\\)\\)\":Subroutine:arithmetic expansion:\n\ + ae arithmetic expansion:\"\\$\\(\\(\":\"\\)\\)\"::Double Quoted String:arithmetic expansion:\n\ + ae new command sub:\"\\$\\(\":\"\\)\":\"\\)\\)\":Subroutine:arithmetic expansion:\n\ + ae variables:\"\\$([-*@#?$!0-9]|[a-zA-Z_][0-9a-zA-Z_]*)\":::Identifier:arithmetic expansion:\n\ + ae variables2:\"\\${\":\"}\":\"\\)\\)\":Identifier:arithmetic expansion:\n\ + comments:\"^[ \\t]*#\":\"$\"::Comment::\n\ + command substitution:\"`\":\"`\"::Subroutine::\n\ + cs escapes:\"\\\\[\\\\$`\"\"']\":::Escaped Items:command substitution:\n\ + cs single quoted string:\"'\":\"'\":\"`\":Single Quoted String:command substitution:\n\ + cs variables:\"\\$([-*@#?$!0-9]|[a-zA-Z_][0-9a-zA-Z_]*)\":::Identifier:command substitution:\n\ + cs variables2:\"\\${\":\"}\":\"`\":Identifier:command substitution:\n\ + new command substitution:\"\\$\\(\":\"\\)\"::Subroutine::\n\ + ncs escapes:\"\\\\[\\\\$`\"\"']\":::Escaped Items:new command substitution:\n\ + ncs single quoted string:\"'\":\"'\":\"\\)\":Single Quoted String:new command substitution:\n\ + ncs variables:\"\\$([-*@#?$!0-9]|[a-zA-Z_][0-9a-zA-Z_]*)\":::Identifier:new command substitution:\n\ + ncs variables2:\"\\${\":\"}\":\"\\)\":Identifier:new command substitution:\n\ + assignment:\"[a-zA-Z_][0-9a-zA-Z_]*[ \\t]*=\":::Identifier1::\n\ + variables:\"\\$([-*@#?$!0-9_]|[a-zA-Z_][0-9a-zA-Z_]*)\":::Identifier::\n\ + variables2:\"\\${\":\"}\"::Identifier::\n\ + comments in line:\"#\":\"$\"::Comment::\n\ + numbers:\"<((0(x|X)[0-9a-fA-F]*)|[0-9.]+((e|E)(\\+|-)?)?[0-9]*)(L|l|UL|ul|u|U|F|f)?>\":::Numeric Const::D\n\ + keywords:\"<(if|fi|then|else|elif|case|esac|while|for|do|done|in|select|until|function|continue|break|return|exit)>\":::Keyword::D\n\ + test operators:\"<-eq|-ne|-gt|-lt|-ge|-le|-[aorwxfdhcbpugkstznL]>\":::Operators::D\n\ + delimiters:\"[-{};.,<>&~=!|^%[\\]+*|]\":::Delimiters::D\n\ + built ins:\"<(:|\\\\.|\\\\[\\\\[|]]|source|alias|bg|bind|builtin|cd|chdir|command|declare|dirs|echo|enable|eval|exec|export|fc|fg|getopts|hash|help|history|jobs|kill|let|local|logout|popd|print|pushd|pwd|read|readonly|set|shift|stop|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|wait|whence)>\":::Library Function::D\n\ + }", "Csh:1:0 {\n\ *************** *** 465,467 **** highlightStyleRec *style; - outBuf = BufCreate(); --- 519,520 ---- *************** *** 614,615 **** --- 667,690 ---- + void RenameStyle(char *oldStyle, char *newStyle) + { + int i, j; + + for (i=0; inPatterns; j++) { + if (!strcmp(oldStyle, PatternSets[i]->patterns[j].style)) { + XtFree(PatternSets[i]->patterns[j].style); + PatternSets[i]->patterns[j].style = CopyAllocatedString(newStyle); + } + } + } + if (HighlightDialog.shell != NULL) { + for (j=0; jstyle)) { + XtFree(HighlightDialog.patterns[j]->style); + HighlightDialog.patterns[j]->style = CopyAllocatedString(newStyle); + } + } + } + } + /* *************** *** 904,906 **** modeNameLen = strlen(langModeName); ! for (i=0; iname, HSDialog.highlightStyleList[i]->name) != 0) { + RenameStyle(HighlightStyles[i]->name, HSDialog.highlightStyleList[i]->name); + } + } + /* Replace the old highlight styles list with the new one from the dialog */ *************** *** 1618,1619 **** --- 1702,1704 ---- contextFrame, 0); + #if XmVersion >= 1002 contextLbl = XtVaCreateManagedWidget("contextLbl", *************** *** 1624,1625 **** --- 1709,1711 ---- XmStringFree(s1); + #endif *************** *** 1686,1687 **** --- 1772,1774 ---- patternsFrame, 0); + #if XmVersion >= 1002 patternsLbl = XtVaCreateManagedWidget("patternsLbl", xmLabelGadgetClass, *************** *** 1693,1694 **** --- 1780,1782 ---- XmStringFree(s1); + #endif *** interpret.c 1997/09/26 18:28:17 1.1 --- interpret.c 1997/10/21 23:28:11 1.2 *************** *** 1 **** --- 1,2 ---- + #include #include *************** *** 3,5 **** #include ! #include #include --- 4,8 ---- #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *** lnknedit.com 1997/09/26 18:28:17 1.1 --- lnknedit.com 1997/10/10 00:15:13 1.2 *************** *** 4,12 **** $ SET NOVERIFY ! OBJS := nedit, file, menu, window, selection, search, undo, shift, - ! help, preferences, tags, userCmds, regularExp, macro, text, - ! textSel, textDisp, textBuf, textDrag, server, highlight, - ! highlightData, interpret, parse, smartIndent ! $ SET VERIFY $ LINK 'OBJS', NEDIT_OPTIONS_FILE/OPT, [-.util]vmsUtils/lib, libUtil/lib ! $ LINK nc, NEDIT_OPTIONS_FILE/OPT, [-.util]vmsUtils/lib, libUtil/lib --- 4,12 ---- $ SET NOVERIFY ! OBJS := nedit, file, menu, window, selection, search, undo, shift, - ! help, preferences, tags, userCmds, regularExp, macro, text, - ! textSel, textDisp, textBuf, textDrag, server, server_common, - ! clearcase ! OBJS2 := nc, server_common, clearcase $ SET VERIFY $ LINK 'OBJS', NEDIT_OPTIONS_FILE/OPT, [-.util]vmsUtils/lib, libUtil/lib ! $ LINK 'OBJS2', NEDIT_OPTIONS_FILE/OPT, [-.util]vmsUtils/lib, libUtil/lib *** macro.c 1997/09/26 18:28:17 1.1 --- macro.c 1997/10/16 19:55:27 1.3 *************** *** 1 **** --- 1,2 ---- + #include #include *************** *** 13,15 **** #include ! #include #endif /*VMS*/ --- 14,18 ---- #include ! #ifdef HAVE_FCNTL_H ! # include ! #endif #endif /*VMS*/ *************** *** 674,676 **** #ifndef VMS ! if (window->shellCmdData != NULL) AbortShellCommand(window); --- 677,679 ---- #ifndef VMS ! if (IsShellCommandInProgress(window)) AbortShellCommand(window); *************** *** 1257,1259 **** for (w=WindowList; w != NULL; w = w->next) { ! sprintf(fullname, "%s%s", w->path, w->filename); if (!strcmp(string, fullname)) --- 1260,1262 ---- for (w=WindowList; w != NULL; w = w->next) { ! sprintf(fullname, "%s%s", w->editorInfo->path, w->editorInfo->filename); if (!strcmp(string, fullname)) *************** *** 1277,1280 **** result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(w->path)+strlen(w->filename)+1); ! sprintf(result->val.str, "%s%s", w->path, w->filename); return True; --- 1280,1283 ---- result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(w->editorInfo->path)+strlen(w->editorInfo->filename)+1); ! sprintf(result->val.str, "%s%s", w->editorInfo->path, w->editorInfo->filename); return True; *************** *** 1290,1292 **** int from, to; ! textBuffer *buf = window->buffer; char *rangeText; --- 1293,1295 ---- int from, to; ! textBuffer *buf = window->editorInfo->buffer; char *rangeText; *************** *** 1325,1327 **** int pos; ! textBuffer *buf = window->buffer; --- 1328,1330 ---- int pos; ! textBuffer *buf = window->editorInfo->buffer; *************** *** 1353,1355 **** char stringStorage[25], *string; ! textBuffer *buf = window->buffer; --- 1356,1358 ---- char stringStorage[25], *string; ! textBuffer *buf = window->editorInfo->buffer; *************** *** 1376,1378 **** up, stop the macro and tell the user of the failure */ ! if (!BufSubstituteNullChars(string, strlen(string), window->buffer)) { *errMsg = "Too much binary data in file"; --- 1379,1381 ---- up, stop the macro and tell the user of the failure */ ! if (!BufSubstituteNullChars(string, strlen(string), window->editorInfo->buffer)) { *errMsg = "Too much binary data in file"; *************** *** 1408,1410 **** up, stop the macro and tell the user of the failure */ ! if (!BufSubstituteNullChars(string, strlen(string), window->buffer)) { *errMsg = "Too much binary data in file"; --- 1411,1413 ---- up, stop the macro and tell the user of the failure */ ! if (!BufSubstituteNullChars(string, strlen(string), window->editorInfo->buffer)) { *errMsg = "Too much binary data in file"; *************** *** 1414,1416 **** /* Do the replace */ ! BufReplaceSelected(window->buffer, string); result->tag = NO_TAG; --- 1417,1419 ---- /* Do the replace */ ! BufReplaceSelected(window->editorInfo->buffer, string, True); result->tag = NO_TAG; *************** *** 1428,1430 **** char *selText; - XEvent nextEvent; --- 1431,1432 ---- *************** *** 1443,1446 **** } else { ! selText = BufGetSelectionText(window->buffer); ! BufUnsubstituteNullChars(selText, window->buffer); } --- 1445,1448 ---- } else { ! selText = BufGetSelectionText(window->editorInfo->buffer); ! BufUnsubstituteNullChars(selText, window->editorInfo->buffer); } *************** *** 1652,1654 **** newArgList[0].tag = STRING_TAG; ! newArgList[0].val.str = BufGetAll(window->buffer); memcpy(&newArgList[1], argList, nArgs * sizeof(DataValue)); --- 1654,1656 ---- newArgList[0].tag = STRING_TAG; ! newArgList[0].val.str = BufGetAll(window->editorInfo->buffer); memcpy(&newArgList[1], argList, nArgs * sizeof(DataValue)); *************** *** 1824,1826 **** /* Make the selection */ ! BufSelect(window->buffer, start, end); result->tag = NO_TAG; --- 1826,1828 ---- /* Make the selection */ ! BufSelect(window->editorInfo->buffer, start, end, CHAR_SELECT); result->tag = NO_TAG; *************** *** 1847,1849 **** /* Make the selection */ ! BufRectSelect(window->buffer, start, end, left, right); result->tag = NO_TAG; --- 1849,1851 ---- /* Make the selection */ ! BufRectSelect(window->editorInfo->buffer, start, end, left, right); result->tag = NO_TAG; *************** *** 2148,2151 **** result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(window->filename) + 1); ! strcpy(result->val.str, window->filename); return True; --- 2150,2153 ---- result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(window->editorInfo->filename) + 1); ! strcpy(result->val.str, window->editorInfo->filename); return True; *************** *** 2157,2160 **** result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(window->path) + 1); ! strcpy(result->val.str, window->path); return True; --- 2159,2162 ---- result->tag = STRING_TAG; ! result->val.str = AllocString(strlen(window->editorInfo->path) + 1); ! strcpy(result->val.str, window->editorInfo->path); return True; *************** *** 2166,2168 **** result->tag = INT_TAG; ! result->val.n = window->buffer->length; return True; --- 2168,2170 ---- result->tag = INT_TAG; ! result->val.n = window->editorInfo->buffer->length; return True; *************** *** 2174,2177 **** result->tag = INT_TAG; ! result->val.n = window->buffer->primary.selected ? ! window->buffer->primary.start : -1; return True; --- 2176,2179 ---- result->tag = INT_TAG; ! result->val.n = window->editorInfo->buffer->primary.selected ? ! window->editorInfo->buffer->primary.start : -1; return True; *************** *** 2183,2186 **** result->tag = INT_TAG; ! result->val.n = window->buffer->primary.selected ? ! window->buffer->primary.end : -1; return True; --- 2185,2188 ---- result->tag = INT_TAG; ! result->val.n = window->editorInfo->buffer->primary.selected ? ! window->editorInfo->buffer->primary.end : -1; return True; *************** *** 2191,2193 **** { ! selection *sel = &window->buffer->primary; --- 2193,2195 ---- { ! selection *sel = &window->editorInfo->buffer->primary; *************** *** 2201,2203 **** { ! selection *sel = &window->buffer->primary; --- 2203,2205 ---- { ! selection *sel = &window->editorInfo->buffer->primary; *************** *** 2224,2226 **** result->tag = INT_TAG; ! result->val.n = window->buffer->tabDist; return True; --- 2226,2228 ---- result->tag = INT_TAG; ! result->val.n = window->editorInfo->buffer->tabDist; return True; *************** *** 2232,2234 **** result->tag = INT_TAG; ! result->val.n = window->buffer->useTabs; return True; --- 2234,2236 ---- result->tag = INT_TAG; ! result->val.n = window->editorInfo->buffer->useTabs; return True; *** menu.c 1997/09/26 18:28:17 1.1 --- menu.c 1997/10/21 22:06:00 1.4 *************** *** 24,28 **** *******************************************************************************/ #include #include - #include #include --- 24,28 ---- *******************************************************************************/ + #include #include #include #include *************** *** 41,42 **** --- 41,43 ---- #include + #include #include "../util/getfiles.h" *************** *** 75,77 **** --- 76,84 ---- + typedef struct _ActionInfo { + WindowInfo *window; + char *action; + } ActionInfo; + static void doActionCB(Widget w, XtPointer clientData, XtPointer callData); + static ActionInfo *actionInfoRec(WindowInfo* window, char *action); static void readOnlyCB(Widget w, XtPointer clientData, XtPointer callData); *************** *** 80,86 **** static void shiftRightCB(Widget w, XtPointer clientData, XtPointer callData); - static void findCB(Widget w, XtPointer clientData, XtPointer callData); static void findSameCB(Widget w, XtPointer clientData, XtPointer callData); static void findSelCB(Widget w, XtPointer clientData, XtPointer callData); static void replaceCB(Widget w, XtPointer clientData, XtPointer callData); static void replaceSameCB(Widget w, XtPointer clientData, XtPointer callData); static void markCB(Widget w, XtPointer clientData, XtPointer callData); --- 87,95 ---- static void shiftRightCB(Widget w, XtPointer clientData, XtPointer callData); static void findSameCB(Widget w, XtPointer clientData, XtPointer callData); static void findSelCB(Widget w, XtPointer clientData, XtPointer callData); + static void findCB(Widget w, XtPointer clientData, XtPointer callData); static void replaceCB(Widget w, XtPointer clientData, XtPointer callData); static void replaceSameCB(Widget w, XtPointer clientData, XtPointer callData); + static void replaceFindSameCB(Widget w, XtPointer clientData, XtPointer callData); + static void gotoISearchTextCB(Widget w, XtPointer clientData, XtPointer callData); static void markCB(Widget w, XtPointer clientData, XtPointer callData); *************** *** 102,103 **** --- 111,113 ---- static void statsCB(Widget w, WindowInfo *window, caddr_t callData); + static void iSearchLineCB(Widget w, WindowInfo *window, caddr_t callData); static void autoIndentOffDefCB(Widget w, WindowInfo *window, caddr_t callData); *************** *** 112,117 **** static void statsLineDefCB(Widget w, WindowInfo *window, caddr_t callData); ! static void tabsDefCB(Widget w, WindowInfo *window, caddr_t callData); ! static void showMatchingDefCB(Widget w, WindowInfo *window, caddr_t callData); static void highlightOffDefCB(Widget w, WindowInfo *window, caddr_t callData); static void highlightDefCB(Widget w, WindowInfo *window, caddr_t callData); static void fontDefCB(Widget w, WindowInfo *window, caddr_t callData); --- 122,130 ---- static void statsLineDefCB(Widget w, WindowInfo *window, caddr_t callData); ! static void iSearchLineDefCB(Widget w, WindowInfo *window, caddr_t callData); static void highlightOffDefCB(Widget w, WindowInfo *window, caddr_t callData); static void highlightDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void warnOnExitDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void allowReadOnlyEditsDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void tabsDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void showMatchingDefCB(Widget w, WindowInfo *window, caddr_t callData); static void fontDefCB(Widget w, WindowInfo *window, caddr_t callData); *************** *** 136,137 **** --- 149,153 ---- static void sizeCustomCB(Widget w, WindowInfo *window, caddr_t callData); + static void checkingModePromptToReloadDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void checkingModeDisabledDefCB(Widget w, WindowInfo *window, caddr_t callData); + static void checkingModeTailMinusFDefCB(Widget w, WindowInfo *window, caddr_t callData); static void savePrefCB(Widget w, WindowInfo *window, caddr_t callData); *************** *** 215,216 **** --- 231,233 ---- static void findAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); + static void findIncrementalAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); static void findSameAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); *************** *** 220,221 **** --- 237,239 ---- static void replaceAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); + static void replaceFindAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); static void replaceAllAP(Widget w, XEvent *event, String *args, *************** *** 226,227 **** --- 244,247 ---- Cardinal *nArgs); + static void replaceFindSameAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void gotoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); *************** *** 243,244 **** --- 263,266 ---- Cardinal *nArgs); + static void gotoMatchingAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void findDefAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); *************** *** 247,248 **** --- 269,271 ---- static void closePaneAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); + static void cloneWindowAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); static void capitalizeAP(Widget w, XEvent *event, String *args, *************** *** 270,271 **** --- 293,295 ---- Cardinal *nArgs); + static Time timeOfEvent(XEvent *event); static Widget createMenu(Widget parent, char *name, char *label, *************** *** 291,292 **** --- 315,319 ---- static void openPrevCB(Widget w, char *name, caddr_t callData); + static void checkingModePromptToReloadCB(Widget w, WindowInfo *window, caddr_t callData); + static void checkingModeDisabledCB(Widget w, WindowInfo *window, caddr_t callData); + static void checkingModeTailMinusFCB(Widget w, WindowInfo *window, caddr_t callData); static void setWindowSizeDefault(int rows, int cols); *************** *** 294,296 **** static void updateWindowSizeMenu(WindowInfo *win); ! static int strCaseCmp(char *str1, char *str2); static int compareWindowNames(const void *windowA, const void *windowB); --- 321,323 ---- static void updateWindowSizeMenu(WindowInfo *win); ! static void setPrefCheckingMode(WindowInfo *window, CheckingMode mode); static int compareWindowNames(const void *windowA, const void *windowB); *************** *** 320,321 **** --- 347,349 ---- {"revert_to_saved", revertAP}, + {"revert-to-saved_dialog", revertDialogAP}, {"revert_to_saved_dialog", revertDialogAP}, *************** *** 350,352 **** --- 378,388 ---- {"shift_right_by_tab", shiftRightTabAP}, + {"uppercase", capitalizeAP}, + {"lowercase", lowercaseAP}, + {"fill-paragraph", fillAP}, + {"fill_paragraph", fillAP}, + {"control-code-dialog", controlDialogAP}, + {"control_code_dialog", controlDialogAP}, {"find", findAP}, + {"find-incremental", findIncrementalAP}, + {"find_incremental", findIncrementalAP}, {"find-dialog", findDialogAP}, *************** *** 366,367 **** --- 402,409 ---- {"replace_again", replaceSameAP}, + {"replace-find", replaceFindAP}, + {"replace_find", replaceFindAP}, + {"replace-find-same", replaceFindSameAP}, + {"replace_find_same", replaceFindSameAP}, + {"replace-find-again", replaceFindSameAP}, + {"replace_find_again", replaceFindSameAP}, {"goto-line-number", gotoAP}, *************** *** 380,381 **** --- 422,427 ---- {"match", findMatchingAP}, + {"select-matching", findMatchingAP}, + {"select_matching", findMatchingAP}, + {"goto-matching", gotoMatchingAP}, + {"goto_matching", gotoMatchingAP}, {"find-definition", findDefAP}, *************** *** 386,393 **** {"close_pane", closePaneAP}, ! {"uppercase", capitalizeAP}, ! {"lowercase", lowercaseAP}, ! {"fill-paragraph", fillAP}, ! {"fill_paragraph", fillAP}, ! {"control-code-dialog", controlDialogAP}, ! {"control_code_dialog", controlDialogAP}, #ifndef VMS --- 432,435 ---- {"close_pane", closePaneAP}, ! {"clone-window", cloneWindowAP}, ! {"clone_window", cloneWindowAP}, #ifndef VMS *************** *** 403,404 **** --- 445,448 ---- {"execute_command_line", execLineAP}, + {"execute-selection-or-line", execLineAP}, + {"execute_selection_or_line", execLineAP}, {"shell-menu-command", shellMenuAP}, *************** *** 408,410 **** --- 452,456 ---- {"macro_menu_command", macroMenuAP}, + {"bg-menu-command", bgMenuAP}, {"bg_menu_command", bgMenuAP}, + {"post-window-bg-menu", bgMenuPostAP}, {"post_window_bg_menu", bgMenuPostAP}, *************** *** 414,416 **** --- 460,464 ---- {"end_of_selection", endOfSelectionAP}, + {"repeat-macro", repeatMacroAP}, {"repeat_macro", repeatMacroAP}, + {"repeat-dialog", repeatDialogAP}, {"repeat_dialog", repeatDialogAP}, *************** *** 477,483 **** menuPane = createMenu(menuBar, "fileMenu", "File", 0, NULL, SHORT); ! createMenuItem(menuPane, "new", "New", 'N', doActionCB, "new", SHORT); ! createMenuItem(menuPane, "open", "Open...", 'O', doActionCB, "open_dialog", SHORT); createMenuItem(menuPane, "openSelected", "Open Selected", 'd', ! doActionCB, "open_selected", FULL); if (GetPrefMaxPrevOpenFiles() != 0) { --- 525,531 ---- menuPane = createMenu(menuBar, "fileMenu", "File", 0, NULL, SHORT); ! createMenuItem(menuPane, "new", "New", 'N', doActionCB, actionInfoRec(window, "new"), SHORT); ! createMenuItem(menuPane, "open", "Open...", 'O', doActionCB, actionInfoRec(window, "open_dialog"), SHORT); createMenuItem(menuPane, "openSelected", "Open Selected", 'd', ! doActionCB, actionInfoRec(window, "open_selected"), FULL); if (GetPrefMaxPrevOpenFiles() != 0) { *************** *** 491,501 **** window->closeItem = createMenuItem(menuPane, "close", "Close", 'C', ! doActionCB, "close", SHORT); ! createMenuItem(menuPane, "save", "Save", 'S', doActionCB, "save", SHORT); createMenuItem(menuPane, "saveAs", "Save As...", 'A', doActionCB, ! "save_as_dialog", SHORT); createMenuItem(menuPane, "revertToSaved", "Revert to Saved", 'R', ! doActionCB, "revert_to_saved_dialog", SHORT); createMenuSeparator(menuPane, "sep2", SHORT); createMenuItem(menuPane, "includeFile", "Include File...", 'I', ! doActionCB, "include_file_dialog", SHORT); createMenuItem(menuPane, "loadMacroFile", "Load Macro File...", 'M', --- 539,549 ---- window->closeItem = createMenuItem(menuPane, "close", "Close", 'C', ! doActionCB, actionInfoRec(window, "close"), SHORT); ! createMenuItem(menuPane, "save", "Save", 'S', doActionCB, actionInfoRec(window, "save"), SHORT); createMenuItem(menuPane, "saveAs", "Save As...", 'A', doActionCB, ! actionInfoRec(window, "save_as_dialog"), SHORT); createMenuItem(menuPane, "revertToSaved", "Revert to Saved", 'R', ! doActionCB, actionInfoRec(window, "revert_to_saved_dialog"), SHORT); createMenuSeparator(menuPane, "sep2", SHORT); createMenuItem(menuPane, "includeFile", "Include File...", 'I', ! doActionCB, actionInfoRec(window, "include_file_dialog"), SHORT); createMenuItem(menuPane, "loadMacroFile", "Load Macro File...", 'M', *************** *** 503,510 **** createMenuItem(menuPane, "loadTagsFile", "Load Tags File...", 'T', ! doActionCB, "load_tags_file_dialog", FULL); createMenuSeparator(menuPane, "sep3", SHORT); ! createMenuItem(menuPane, "print", "Print...", 'P', doActionCB, "print", SHORT); window->printSelItem = createMenuItem(menuPane, "printSelection", ! "Print Selection...", 't', doActionCB, "print_selection", SHORT); --- 551,558 ---- createMenuItem(menuPane, "loadTagsFile", "Load Tags File...", 'T', ! doActionCB, actionInfoRec(window, "load_tags_file_dialog"), FULL); createMenuSeparator(menuPane, "sep3", SHORT); ! createMenuItem(menuPane, "print", "Print...", 'P', doActionCB, actionInfoRec(window, "print"), SHORT); window->printSelItem = createMenuItem(menuPane, "printSelection", ! "Print Selection...", 't', doActionCB, actionInfoRec(window, "print_selection"), SHORT); *************** *** 512,514 **** createMenuSeparator(menuPane, "sep4", SHORT); ! createMenuItem(menuPane, "exit", "Exit", 'x', doActionCB, "exit", SHORT); CheckCloseDim(); --- 560,562 ---- createMenuSeparator(menuPane, "sep4", SHORT); ! createMenuItem(menuPane, "exit", "Exit", 'x', doActionCB, actionInfoRec(window, "exit"), SHORT); CheckCloseDim(); *************** *** 520,525 **** window->undoItem = createMenuItem(menuPane, "undo", "Undo", 'U', ! doActionCB, "undo", SHORT); XtSetSensitive(window->undoItem, False); window->redoItem = createMenuItem(menuPane, "redo", "Redo", 'R', ! doActionCB, "redo", SHORT); XtSetSensitive(window->redoItem, False); --- 568,573 ---- window->undoItem = createMenuItem(menuPane, "undo", "Undo", 'U', ! doActionCB, actionInfoRec(window, "undo"), SHORT); XtSetSensitive(window->undoItem, False); window->redoItem = createMenuItem(menuPane, "redo", "Redo", 'R', ! doActionCB, actionInfoRec(window, "redo"), SHORT); XtSetSensitive(window->redoItem, False); *************** *** 527,541 **** window->cutItem = createMenuItem(menuPane, "cut", "Cut", 't', doActionCB, ! "cut_clipboard", SHORT); XtSetSensitive(window->cutItem, window->wasSelected); window->copyItem = createMenuItem(menuPane, "copy", "Copy", 'C', doActionCB, ! "copy_clipboard", SHORT); XtSetSensitive(window->copyItem, window->wasSelected); createMenuItem(menuPane, "paste", "Paste", 'P', doActionCB, ! "paste_clipboard", SHORT); createMenuItem(menuPane, "pasteColumn", "Paste Column", 's', pasteColCB, window, SHORT); ! createMenuItem(menuPane, "delete", "Delete", 'D', doActionCB, "delete", SHORT); createMenuItem(menuPane, "selectAll", "Select All", 'A', doActionCB, ! "select_all", SHORT); createMenuSeparator(menuPane, "sep2", SHORT); --- 575,589 ---- window->cutItem = createMenuItem(menuPane, "cut", "Cut", 't', doActionCB, ! actionInfoRec(window, "cut_clipboard"), SHORT); XtSetSensitive(window->cutItem, window->wasSelected); window->copyItem = createMenuItem(menuPane, "copy", "Copy", 'C', doActionCB, ! actionInfoRec(window, "copy_clipboard"), SHORT); XtSetSensitive(window->copyItem, window->wasSelected); createMenuItem(menuPane, "paste", "Paste", 'P', doActionCB, ! actionInfoRec(window, "paste_clipboard"), SHORT); createMenuItem(menuPane, "pasteColumn", "Paste Column", 's', pasteColCB, window, SHORT); ! createMenuItem(menuPane, "delete", "Delete", 'D', doActionCB, actionInfoRec(window, "delete"), SHORT); createMenuItem(menuPane, "selectAll", "Select All", 'A', doActionCB, ! actionInfoRec(window, "select_all"), SHORT); createMenuSeparator(menuPane, "sep2", SHORT); *************** *** 547,554 **** createFakeMenuItem(menuPane, "shiftRightShift", shiftRightCB, window); ! createMenuItem(menuPane, "lowerCase", "Lower-case", 'w', ! doActionCB, "lowercase", SHORT); ! createMenuItem(menuPane, "upperCase", "Upper-case", 'e', ! doActionCB, "uppercase", SHORT); createMenuItem(menuPane, "fillParagraph", "Fill Paragraph", 'F', ! doActionCB, "fill_paragraph", SHORT); createMenuSeparator(menuPane, "sep3", FULL); --- 595,602 ---- createFakeMenuItem(menuPane, "shiftRightShift", shiftRightCB, window); ! createMenuItem(menuPane, "lowerCase", "Lower_case", 'w', ! doActionCB, actionInfoRec(window, "lowercase"), SHORT); ! createMenuItem(menuPane, "upperCase", "Upper_case", 'e', ! doActionCB, actionInfoRec(window, "uppercase"), SHORT); createMenuItem(menuPane, "fillParagraph", "Fill Paragraph", 'F', ! doActionCB, actionInfoRec(window, "fill_paragraph"), SHORT); createMenuSeparator(menuPane, "sep3", FULL); *************** *** 557,566 **** createMenuItem(menuPane, "insertCtrlCode", "Insert Ctrl Code", 'n', ! doActionCB, "control_code_dialog", FULL); ! #ifdef SGI_CUSTOM ! createMenuSeparator(menuPane, "sep4", SHORT); ! createMenuToggle(menuPane, "overtype", "Overtype", 'O', ! overstrikeCB, window, False, SHORT); ! window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only", ! 'y', readOnlyCB, window, window->lockWrite, FULL); ! #endif --- 605,607 ---- createMenuItem(menuPane, "insertCtrlCode", "Insert Ctrl Code", 'n', ! doActionCB, actionInfoRec(window, "control_code_dialog"), FULL); *************** *** 572,573 **** --- 613,618 ---- createFakeMenuItem(menuPane, "findShift", findCB, window); + createMenuItem(menuPane, "findIncremental", "Find Incremental", 'I', + gotoISearchTextCB, window, SHORT); + createFakeMenuItem(menuPane, "findIncrementalShift", gotoISearchTextCB, + window); createMenuItem(menuPane, "findAgain", "Find Again", 'i', findSameCB, window, *************** *** 581,582 **** --- 626,630 ---- createFakeMenuItem(menuPane, "replaceShift", replaceCB, window); + createMenuItem(menuPane, "replaceFindAgain", "Replace Find Again", 'A', + replaceFindSameCB, window, SHORT); + createFakeMenuItem(menuPane, "replaceFindAgainShift", replaceFindSameCB, window); createMenuItem(menuPane, "replaceAgain", "Replace Again", 'p', *************** *** 586,590 **** createMenuItem(menuPane, "gotoLineNumber", "Goto Line Number...", 'L', ! doActionCB, "goto_line_number_dialog", FULL); createMenuItem(menuPane, "gotoSelected", "Goto Selected", 'G', ! doActionCB, "goto_selected", FULL); createMenuSeparator(menuPane, "sep2", FULL); --- 634,638 ---- createMenuItem(menuPane, "gotoLineNumber", "Goto Line Number...", 'L', ! doActionCB, actionInfoRec(window, "goto_line_number_dialog"), FULL); createMenuItem(menuPane, "gotoSelected", "Goto Selected", 'G', ! doActionCB, actionInfoRec(window, "goto_selected"), FULL); createMenuSeparator(menuPane, "sep2", FULL); *************** *** 595,601 **** createMenuSeparator(menuPane, "sep3", FULL); ! createMenuItem(menuPane, "match", "Match (..)", 'M', ! doActionCB, "match", FULL); window->findDefItem = createMenuItem(menuPane, "findDefinition", ! "Find Definition", 'D', doActionCB, "find_definition", FULL); ! XtSetSensitive(window->findDefItem, TagsFileLoaded()); --- 643,650 ---- createMenuSeparator(menuPane, "sep3", FULL); ! createMenuItem(menuPane, "match", "Select Matching", 'M', ! doActionCB, actionInfoRec(window, "select_matching"), FULL); ! createMenuItem(menuPane, "gotoMatching", "Goto Matching", 't', ! doActionCB, actionInfoRec(window, "goto_matching"), FULL); window->findDefItem = createMenuItem(menuPane, "findDefinition", ! "Find Definition", 'D', doActionCB, actionInfoRec(window, "find_definition"), FULL); *************** *** 611,612 **** --- 660,674 ---- + /* Syntax Highlighting sub menu */ + subSubPane = createMenu(subPane, "syntaxHighlighting","Syntax Highlighting", + 'H', NULL, FULL); + window->highlightOffDefItem = createMenuRadioToggle(subSubPane, "off","Off", + 'O', highlightOffDefCB, window, !GetPrefHighlightSyntax(), FULL); + window->highlightDefItem = createMenuRadioToggle(subSubPane, "on", + "On", 'n', highlightDefCB, window, GetPrefHighlightSyntax(), FULL); + createMenuSeparator(subSubPane, "sep1", SHORT); + createMenuItem(subSubPane, "recognitionPatterns", "Recognition Patterns...", + 'R', highlightingDefCB, window, FULL); + createMenuItem(subSubPane, "textDrawingStyles", "Text Drawing Styles...", 'T', + stylesDefCB, window, FULL); + /* Auto Indent sub menu */ *************** *** 641,642 **** --- 703,705 ---- wrapMarginDefCB, window, SHORT); + createMenuItem(subPane, "tabDistance", "Tabs...", 'T', tabsDefCB, window, *************** *** 680,694 **** - /* Syntax Highlighting sub menu */ - subSubPane = createMenu(subPane, "syntaxHighlighting","Syntax Highlighting", - 'H', NULL, FULL); - window->highlightOffDefItem = createMenuRadioToggle(subSubPane, "off","Off", - 'O', highlightOffDefCB, window, !GetPrefHighlightSyntax(), FULL); - window->highlightDefItem = createMenuRadioToggle(subSubPane, "on", - "On", 'n', highlightDefCB, window, GetPrefHighlightSyntax(), FULL); - createMenuSeparator(subSubPane, "sep1", SHORT); - createMenuItem(subSubPane, "recognitionPatterns", "Recognition Patterns...", - 'R', highlightingDefCB, window, FULL); - createMenuItem(subSubPane, "textDrawingStyles", "Text Drawing Styles...", 'T', - stylesDefCB, window, FULL); - window->statsLineDefItem = createMenuToggle(subPane, "statisticsLine", --- 743,744 ---- *************** *** 696,700 **** SHORT); window->saveLastDefItem = createMenuToggle(subPane, "preserveLastVersion", ! "Make Backup Copy (*.bck)", 'e', preserveDefCB, window, GetPrefSaveOldVersion(), SHORT); window->autoSaveDefItem = createMenuToggle(subPane, "incrementalBackup", --- 746,756 ---- SHORT); + window->iSearchLineDefItem = createMenuToggle(subPane, "searchLine", + "Incremental Search Line", 'n', iSearchLineDefCB, window, + GetPrefShowISearchLine(), SHORT); + {char buf[512]; + sprintf(buf, "Make Backup Copy (*%s)", GetPrefBackupSuffix()); window->saveLastDefItem = createMenuToggle(subPane, "preserveLastVersion", ! buf, 'e', preserveDefCB, window, GetPrefSaveOldVersion(), SHORT); + } window->autoSaveDefItem = createMenuToggle(subPane, "incrementalBackup", *************** *** 708,710 **** GetPrefRepositionDialogs(), FULL); ! /* Initial Window Size sub menu (simulates radioBehavior) */ --- 764,789 ---- GetPrefRepositionDialogs(), FULL); ! window->warnOnExitDefItem = createMenuToggle(subPane, "warnOnExit", ! "On Exit Open Files Warning", 0, warnOnExitDefCB, window, ! GetPrefWarnOnExit(), SHORT); ! window->allowReadOnlyEditsDefItem = createMenuToggle(subPane, "allowReadOnlyEdits", ! "Allow Read Only Edits", 0, allowReadOnlyEditsDefCB, window, ! GetPrefAllowReadOnlyEdits(), SHORT); ! {Widget subPane2, btn; ! subPane2 = createMenu(subPane, "checkingModeMenu", "Checking Mode", 'd', ! NULL, FULL); ! window->checkingModePromptToReloadDefItem = btn = createMenuToggle(subPane2, ! "checkingModePromptToReload", "Prompt To Reload", 'N', checkingModePromptToReloadDefCB, ! window, False, SHORT); ! XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, 0); ! window->checkingModeDisabledDefItem = btn = createMenuToggle(subPane2, ! "checkingModePromptToReload", "Disabled", 'D', checkingModeDisabledDefCB, ! window, False, SHORT); ! XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, 0); ! window->checkingModeTailMinusFDefItem = btn = createMenuToggle(subPane2, ! "checkingModeTailMinusF", "Tail -f", 'T', checkingModeTailMinusFDefCB, ! window, False, SHORT); ! XtVaSetValues(btn, XmNindicatorType, XmONE_OF_MANY, 0); ! setPrefCheckingMode(window, GetPrefCheckingMode()); ! } ! /* Initial Window Size sub menu (simulates radioBehavior) */ *************** *** 742,746 **** createMenuToggle(menuPane, "statisticsLine", "Statistics Line", 'S', ! statsCB, window, GetPrefStatsLine(), SHORT); CreateLanguageModeSubMenu(window, menuPane, "languageMode", "Language Mode", 'L'); subPane = createMenu(menuPane, "autoIndent", "Auto Indent", --- 821,830 ---- createMenuToggle(menuPane, "statisticsLine", "Statistics Line", 'S', ! statsCB, window, window->showStats, SHORT); ! window->iSearchLineItem = createMenuToggle(menuPane, "searchLine", "Incremental Search Line", 'n', ! iSearchLineCB, window, window->showISearchLine, SHORT); CreateLanguageModeSubMenu(window, menuPane, "languageMode", "Language Mode", 'L'); + window->highlightItem = createMenuToggle(menuPane, "highlightSyntax", + "Highlight Syntax", 'H', highlightCB, window, + GetPrefHighlightSyntax(), SHORT); subPane = createMenu(menuPane, "autoIndent", "Auto Indent", *************** *** 748,755 **** window->autoIndentOffItem = createMenuRadioToggle(subPane, "off", "Off", ! 'O', autoIndentOffCB, window, window->indentStyle == NO_AUTO_INDENT, SHORT); window->autoIndentItem = createMenuRadioToggle(subPane, "on", "On", 'n', ! autoIndentCB, window, window->indentStyle == AUTO_INDENT, SHORT); window->smartIndentItem = createMenuRadioToggle(subPane, "smart", "Smart", ! 'S', smartIndentCB, window, window->indentStyle == SMART_INDENT, SHORT); --- 832,839 ---- window->autoIndentOffItem = createMenuRadioToggle(subPane, "off", "Off", ! 'O', autoIndentOffCB, window, window->editorInfo->indentStyle == NO_AUTO_INDENT, SHORT); window->autoIndentItem = createMenuRadioToggle(subPane, "on", "On", 'n', ! autoIndentCB, window, window->editorInfo->indentStyle == AUTO_INDENT, SHORT); window->smartIndentItem = createMenuRadioToggle(subPane, "smart", "Smart", ! 'S', smartIndentCB, window, window->editorInfo->indentStyle == SMART_INDENT, SHORT); *************** *** 759,767 **** "None", 'N', noWrapCB, window, ! window->wrapMode==NO_WRAP, SHORT); window->newlineWrapItem = createMenuRadioToggle(subPane, "autoNewlineWrap", "Auto Newline", 'A', newlineWrapCB, window, ! window->wrapMode==NEWLINE_WRAP, SHORT); window->continuousWrapItem = createMenuRadioToggle(subPane, "continuousWrap", "Continuous", 'C', continuousWrapCB, window, ! window->wrapMode==CONTINUOUS_WRAP, SHORT); createMenuSeparator(subPane, "sep1", SHORT); --- 843,851 ---- "None", 'N', noWrapCB, window, ! window->editorInfo->wrapMode==NO_WRAP, SHORT); window->newlineWrapItem = createMenuRadioToggle(subPane, "autoNewlineWrap", "Auto Newline", 'A', newlineWrapCB, window, ! window->editorInfo->wrapMode==NEWLINE_WRAP, SHORT); window->continuousWrapItem = createMenuRadioToggle(subPane, "continuousWrap", "Continuous", 'C', continuousWrapCB, window, ! window->editorInfo->wrapMode==CONTINUOUS_WRAP, SHORT); createMenuSeparator(subPane, "sep1", SHORT); *************** *** 774,794 **** #endif /*IBM_DESTROY_BUG*/ - window->highlightItem = createMenuToggle(menuPane, "highlightSyntax", - "Highlight Syntax", 'H', highlightCB, window, - GetPrefHighlightSyntax(), SHORT); #ifndef VMS window->saveLastItem = createMenuToggle(menuPane, "makeBackupCopy", ! "Make Backup Copy (*.bck)", 'e', preserveCB, window, ! window->saveOldVersion, SHORT); #endif window->autoSaveItem = createMenuToggle(menuPane, "incrementalBackup", ! "Incremental Backup", 'B', autoSaveCB, window, window->autoSave, SHORT); ! createMenuToggle(menuPane, "showMatching", "Show Matching (..)", 'M', ! showMatchingCB, window, window->showMatching, FULL); #ifndef SGI_CUSTOM createMenuSeparator(menuPane, "sep2", SHORT); ! createMenuToggle(menuPane, "overtype", "Overtype", 'O', overstrikeCB, window, False, SHORT); window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only", ! 'y', readOnlyCB, window, window->lockWrite, FULL); #endif --- 858,888 ---- #endif /*IBM_DESTROY_BUG*/ #ifndef VMS + {char buf[512]; + sprintf(buf, "Make Backup Copy (*%s)", GetPrefBackupSuffix()); window->saveLastItem = createMenuToggle(menuPane, "makeBackupCopy", ! buf, 'e', preserveCB, window, ! window->editorInfo->saveOldVersion, SHORT); ! } #endif window->autoSaveItem = createMenuToggle(menuPane, "incrementalBackup", ! "Incremental Backup", 'B', autoSaveCB, window, window->editorInfo->autoSave, SHORT); ! window->showMatchingItem = createMenuToggle(menuPane, "showMatching", "Show Matching (..)", 'M', ! showMatchingCB, window, window->editorInfo->showMatching, FULL); ! {Widget subPane2; ! subPane2 = createMenu(menuPane, "checkingModeMenu", "Checking Mode", 'M', ! NULL, FULL); ! window->checkingModePromptToReloadItem = createMenuToggle(subPane2, "checkingModePromptToReload", "Prompt To Reload", 'N', ! checkingModePromptToReloadCB, window, window->editorInfo->checkingMode == CHECKING_MODE_PROMPT_TO_RELOAD, SHORT); ! window->checkingModeDisabledItem = createMenuToggle(subPane2, "checkingModePromptToReload", "Disabled", 'D', ! checkingModeDisabledCB, window, window->editorInfo->checkingMode == CHECKING_MODE_DISABLED, SHORT); ! window->checkingModeTailMinusFItem = createMenuToggle(subPane2, "checkingModeTailMinusF", "Tail -f", 'T', ! checkingModeTailMinusFCB, window, window->editorInfo->checkingMode == CHECKING_MODE_TAIL_MINUS_F, SHORT); ! } #ifndef SGI_CUSTOM createMenuSeparator(menuPane, "sep2", SHORT); ! window->overstrikeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O', overstrikeCB, window, False, SHORT); window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only", ! 'y', readOnlyCB, window, window->editorInfo->lockWrite, FULL); #endif *************** *** 802,810 **** btn = createMenuItem(menuPane, "executeCommand", "Execute Command...", ! 'E', doActionCB, "execute_command_dialog", SHORT); XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, 0); ! btn = createMenuItem(menuPane, "executeCommandLine", "Execute Command Line", ! 'x', doActionCB, "execute_command_line", SHORT); XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, 0); window->filterItem = createMenuItem(menuPane, "filterSelection", ! "Filter Selection...", 'F', doActionCB, "filter_selection_dialog", SHORT); --- 896,904 ---- btn = createMenuItem(menuPane, "executeCommand", "Execute Command...", ! 'E', doActionCB, actionInfoRec(window, "execute_command_dialog"), SHORT); XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, 0); ! btn = createMenuItem(menuPane, "executeCommandLine", "Execute Selection or \nLine at Cursor", ! 'x', doActionCB, actionInfoRec(window, "execute_command_line"), SHORT); XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, 0); window->filterItem = createMenuItem(menuPane, "filterSelection", ! "Filter Selection...", 'F', doActionCB, actionInfoRec(window, "filter_selection_dialog"), SHORT); *************** *** 857,864 **** window->splitWindowItem = createMenuItem(menuPane, "splitWindow", ! "Split Window", 'S', doActionCB, "split_window", SHORT); XtVaSetValues(window->splitWindowItem, XmNuserData, PERMANENT_MENU_ITEM, 0); window->closePaneItem = createMenuItem(menuPane, "closePane", ! "Close Pane", 'C', doActionCB, "close_pane", SHORT); XtVaSetValues(window->closePaneItem, XmNuserData, PERMANENT_MENU_ITEM, 0); XtSetSensitive(window->closePaneItem, False); btn = createMenuSeparator(menuPane, "sep1", SHORT); --- 951,961 ---- window->splitWindowItem = createMenuItem(menuPane, "splitWindow", ! "Split Window", 'S', doActionCB, actionInfoRec(window, "split_window"), SHORT); XtVaSetValues(window->splitWindowItem, XmNuserData, PERMANENT_MENU_ITEM, 0); window->closePaneItem = createMenuItem(menuPane, "closePane", ! "Close Pane", 'C', doActionCB, actionInfoRec(window, "close_pane"), SHORT); XtVaSetValues(window->closePaneItem, XmNuserData, PERMANENT_MENU_ITEM, 0); XtSetSensitive(window->closePaneItem, False); + btn = createMenuItem(menuPane, "cloneWindow", + "Clone Window", 'W', doActionCB, actionInfoRec(window, "clone_window"), SHORT); + XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, 0); btn = createMenuSeparator(menuPane, "sep1", SHORT); *************** *** 948,956 **** { ! #if XmVersion >= 1002 ! Widget menu = XmGetPostedFromWidget(XtParent(w)); ! #else ! Widget menu = w; ! #endif ! XtCallActionProc(WidgetToWindow(menu)->lastFocus, (char *)clientData, ((XmAnyCallbackStruct *)callData)->event, NULL, 0); --- 1045,1049 ---- { ! ActionInfo *actionInfo = (ActionInfo *)clientData; ! XtCallActionProc(actionInfo->window->lastFocus, actionInfo->action, ((XmAnyCallbackStruct *)callData)->event, NULL, 0); *************** *** 958,959 **** --- 1051,1060 ---- + static ActionInfo *actionInfoRec(WindowInfo* window, char *action) + { + ActionInfo *actionInfo = (ActionInfo *)XtMalloc(sizeof(actionInfo[0])); + actionInfo->window = window; + actionInfo->action = action; + return actionInfo; + } + static void readOnlyCB(Widget w, XtPointer clientData, XtPointer callData) *************** *** 962,964 **** ! window->lockWrite = XmToggleButtonGetState(w); UpdateWindowTitle(window); --- 1063,1065 ---- ! window->editorInfo->lockWrite = XmToggleButtonGetState(w); UpdateWindowTitle(window); *************** *** 979,981 **** ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask ! ? "shift_left_by_tab" : "shift_left", ((XmAnyCallbackStruct *)callData)->event, NULL, 0); --- 1080,1082 ---- ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask ! ? "shift_left" : "shift_left_by_tab", ((XmAnyCallbackStruct *)callData)->event, NULL, 0); *************** *** 987,989 **** ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask ! ? "shift_right_by_tab" : "shift_right", ((XmAnyCallbackStruct *)callData)->event, NULL, 0); --- 1088,1090 ---- ((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask ! ? "shift_right" : "shift_right_by_tab", ((XmAnyCallbackStruct *)callData)->event, NULL, 0); *************** *** 991,999 **** - static void findCB(Widget w, XtPointer clientData, XtPointer callData) - { - XtCallActionProc(((WindowInfo *)clientData)->lastFocus, "find_dialog", - ((XmAnyCallbackStruct *)callData)->event, - shiftKeyToDir(callData), 1); - } - static void findSameCB(Widget w, XtPointer clientData, XtPointer callData) --- 1092,1093 ---- *************** *** 1012,1013 **** --- 1106,1114 ---- + static void findCB(Widget w, XtPointer clientData, XtPointer callData) + { + XtCallActionProc(((WindowInfo *)clientData)->lastFocus, "find_dialog", + ((XmAnyCallbackStruct *)callData)->event, + shiftKeyToDir(callData), 1); + } + static void replaceCB(Widget w, XtPointer clientData, XtPointer callData) *************** *** 1026,1027 **** --- 1127,1150 ---- + static void replaceFindSameCB(Widget w, XtPointer clientData, XtPointer callData) + { + XtCallActionProc(((WindowInfo *)clientData)->lastFocus, "replace_find_same", + ((XmAnyCallbackStruct *)callData)->event, + shiftKeyToDir(callData), 1); + } + + static void gotoISearchTextCB(Widget w, XtPointer clientData, XtPointer callData) + { + WindowInfo *window = (WindowInfo *)clientData; + + if(window->iSearchText) { + ShowISearchLine(window, True); + window->iSearchDirection = + (((XmAnyCallbackStruct *)callData)->event->xbutton.state & ShiftMask) ? + SEARCH_BACKWARD : SEARCH_FORWARD; + XmTextSetString(window->iSearchText, ""); + window->iSearchHistIndex = 0; + XmProcessTraversal(window->iSearchText, XmTRAVERSE_CURRENT); + } + } + static void markCB(Widget w, XtPointer clientData, XtPointer callData) *************** *** 1058,1061 **** { ! window->highlightSyntax = XmToggleButtonGetState(w); ! if (window->highlightSyntax) { StartHighlighting(window, True); --- 1181,1184 ---- { ! int state = XmToggleButtonGetState(w); ! if (state) { StartHighlighting(window, True); *************** *** 1106,1108 **** #endif ! window->autoSave = XmToggleButtonGetState(w); } --- 1229,1231 ---- #endif ! SetAutoSave(window, XmToggleButtonGetState(w)); } *************** *** 1117,1119 **** #endif ! window->saveOldVersion = XmToggleButtonGetState(w); } --- 1240,1242 ---- #endif ! SetSaveOldVersion(window, XmToggleButtonGetState(w)); } *************** *** 1165,1167 **** { ! window->showMatching = XmToggleButtonGetState(w); } --- 1288,1290 ---- { ! SetShowMatching(window, XmToggleButtonGetState(w)); } *************** *** 1182,1197 **** window->showStats = XmToggleButtonGetState(w); ! ShowStatsLine(window, XmToggleButtonGetState(w)); } ! static void autoIndentOffDefCB(Widget w, WindowInfo *window, caddr_t callData) { ! WindowInfo *win; ! /* Set the preference and make the other windows' menus agree */ SetPrefAutoIndent(NO_AUTO_INDENT); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->autoIndentOffDefItem, True, False); - XmToggleButtonSetState(win->autoIndentDefItem, False, False); - XmToggleButtonSetState(win->smartIndentDefItem, False, False); - } } --- 1305,1332 ---- window->showStats = XmToggleButtonGetState(w); ! ShowStatsLine(window, window->showStats); } ! static void iSearchLineCB(Widget w, WindowInfo *window, caddr_t callData) { ! ShowISearchLine(window, XmToggleButtonGetState(w)); ! } ! static void checkingModePromptToReloadCB(Widget w, WindowInfo *window, caddr_t callData) ! { ! SetCheckingMode(window, CHECKING_MODE_PROMPT_TO_RELOAD); ! } ! ! static void checkingModeDisabledCB(Widget w, WindowInfo *window, caddr_t callData) ! { ! SetCheckingMode(window, CHECKING_MODE_DISABLED); ! } ! ! static void checkingModeTailMinusFCB(Widget w, WindowInfo *window, caddr_t callData) ! { ! SetCheckingMode(window, CHECKING_MODE_TAIL_MINUS_F); ! } ! ! static void autoIndentOffDefCB(Widget w, WindowInfo *window, caddr_t callData) ! { SetPrefAutoIndent(NO_AUTO_INDENT); } *************** *** 1200,1210 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefAutoIndent(AUTO_INDENT); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->autoIndentDefItem, True, False); - XmToggleButtonSetState(win->autoIndentOffDefItem, False, False); - XmToggleButtonSetState(win->smartIndentDefItem, False, False); - } } --- 1335,1338 ---- *************** *** 1213,1223 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefAutoIndent(SMART_INDENT); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->smartIndentDefItem, True, False); - XmToggleButtonSetState(win->autoIndentOffDefItem, False, False); - XmToggleButtonSetState(win->autoIndentDefItem, False, False); - } } --- 1341,1344 ---- *************** *** 1226,1234 **** { - WindowInfo *win; - int state = XmToggleButtonGetState(w); - /* Set the preference and make the other windows' menus agree */ ! SetPrefAutoSave(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->autoSaveDefItem, state, False); } --- 1347,1350 ---- { /* Set the preference and make the other windows' menus agree */ ! SetPrefAutoSave(XmToggleButtonGetState(w)); } *************** *** 1237,1245 **** { - WindowInfo *win; - int state = XmToggleButtonGetState(w); - /* Set the preference and make the other windows' menus agree */ ! SetPrefSaveOldVersion(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->saveLastDefItem, state, False); } --- 1353,1356 ---- { /* Set the preference and make the other windows' menus agree */ ! SetPrefSaveOldVersion(XmToggleButtonGetState(w)); } *************** *** 1253,1263 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefWrap(NO_WRAP); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->noWrapDefItem, True, False); - XmToggleButtonSetState(win->newlineWrapDefItem, False, False); - XmToggleButtonSetState(win->contWrapDefItem, False, False); - } } --- 1364,1367 ---- *************** *** 1266,1276 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefWrap(NEWLINE_WRAP); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->newlineWrapDefItem, True, False); - XmToggleButtonSetState(win->contWrapDefItem, False, False); - XmToggleButtonSetState(win->noWrapDefItem, False, False); - } } --- 1370,1373 ---- *************** *** 1279,1289 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefWrap(CONTINUOUS_WRAP); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->contWrapDefItem, True, False); - XmToggleButtonSetState(win->newlineWrapDefItem, False, False); - XmToggleButtonSetState(win->noWrapDefItem, False, False); - } } --- 1376,1379 ---- *************** *** 1302,1310 **** { - WindowInfo *win; - int state = XmToggleButtonGetState(w); - /* Set the preference and make the other windows' menus agree */ ! SetPrefShowMatching(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->showMatchingDefItem, state, False); } --- 1392,1395 ---- { /* Set the preference and make the other windows' menus agree */ ! SetPrefShowMatching(XmToggleButtonGetState(w)); } *************** *** 1313,1322 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefHighlightSyntax(False); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->highlightOffDefItem, True, False); - XmToggleButtonSetState(win->highlightDefItem, False, False); - } } --- 1398,1401 ---- *************** *** 1325,1334 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ SetPrefHighlightSyntax(True); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->highlightOffDefItem, False, False); - XmToggleButtonSetState(win->highlightDefItem, True, False); - } } --- 1404,1407 ---- *************** *** 1374,1382 **** { - WindowInfo *win; - int state = XmToggleButtonGetState(w); - /* Set the preference and make the other windows' menus agree */ ! SetPrefSearchDlogs(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->searchDlogsDefItem, state, False); } --- 1447,1450 ---- { /* Set the preference and make the other windows' menus agree */ ! SetPrefSearchDlogs(XmToggleButtonGetState(w)); } *************** *** 1385,1393 **** { - WindowInfo *win; - int state = XmToggleButtonGetState(w); - /* Set the preference and make the other windows' menus agree */ ! SetPrefKeepSearchDlogs(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->keepSearchDlogsDefItem, state, False); } --- 1453,1456 ---- { /* Set the preference and make the other windows' menus agree */ ! SetPrefKeepSearchDlogs(XmToggleButtonGetState(w)); } *************** *** 1396,1398 **** { - WindowInfo *win; int state = XmToggleButtonGetState(w); --- 1459,1460 ---- *************** *** 1402,1405 **** SetPointerCenteredDialogs(state); - for (win=WindowList; win!=NULL; win=win->next) - XmToggleButtonSetState(win->reposDlogsDefItem, state, False); } --- 1464,1465 ---- *************** *** 1408,1422 **** { ! WindowInfo *win; ! int state = XmToggleButtonGetState(w); /* Set the preference and make the other windows' menus agree */ ! SetPrefStatsLine(state); ! for (win=WindowList; win!=NULL; win=win->next) ! XmToggleButtonSetState(win->statsLineDefItem, state, False); } ! static void searchLiteralCB(Widget w, WindowInfo *window, caddr_t callData) { ! WindowInfo *win; /* Set the preference and make the other windows' menus agree */ --- 1468,1494 ---- { ! /* Set the preference and make the other windows' menus agree */ ! SetPrefStatsLine(XmToggleButtonGetState(w)); ! } + static void iSearchLineDefCB(Widget w, WindowInfo *window, caddr_t callData) + { /* Set the preference and make the other windows' menus agree */ ! SetPrefShowISearchLine(XmToggleButtonGetState(w)); } ! static void warnOnExitDefCB(Widget w, WindowInfo *window, caddr_t callData) { ! /* Set the preference and make the other windows' menus agree */ ! SetPrefWarnOnExit(XmToggleButtonGetState(w)); ! } ! ! static void allowReadOnlyEditsDefCB(Widget w, WindowInfo *window, caddr_t callData) ! { ! /* Set the preference and make the other windows' menus agree */ ! SetPrefAllowReadOnlyEdits(XmToggleButtonGetState(w)); ! UpdateWindowReadOnly(window); ! } + static void searchLiteralCB(Widget w, WindowInfo *window, caddr_t callData) + { /* Set the preference and make the other windows' menus agree */ *************** *** 1424,1430 **** SetPrefSearch(SEARCH_LITERAL); - for (win=WindowList; win!=NULL; win=win->next){ - XmToggleButtonSetState(win->searchLiteralDefItem, True, False); - XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False); - XmToggleButtonSetState(win->searchRegexDefItem, False, False); - } } --- 1496,1497 ---- *************** *** 1434,1437 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ --- 1501,1502 ---- *************** *** 1439,1445 **** SetPrefSearch(SEARCH_CASE_SENSE); - for (win=WindowList; win!=NULL; win=win->next) { - XmToggleButtonSetState(win->searchLiteralDefItem, False, False); - XmToggleButtonSetState(win->searchCaseSenseDefItem, True, False); - XmToggleButtonSetState(win->searchRegexDefItem, False, False); - } } --- 1504,1505 ---- *************** *** 1449,1452 **** { - WindowInfo *win; - /* Set the preference and make the other windows' menus agree */ --- 1509,1510 ---- *************** *** 1454,1460 **** SetPrefSearch(SEARCH_REGEX); - for (win=WindowList; win!=NULL; win=win->next){ - XmToggleButtonSetState(win->searchLiteralDefItem, False, False); - XmToggleButtonSetState(win->searchCaseSenseDefItem, False, False); - XmToggleButtonSetState(win->searchRegexDefItem, True, False); - } } --- 1512,1513 ---- *************** *** 1488,1489 **** --- 1541,1557 ---- + static void checkingModePromptToReloadDefCB(Widget w, WindowInfo *window, caddr_t callData) + { + setPrefCheckingMode(window, CHECKING_MODE_PROMPT_TO_RELOAD); + } + + static void checkingModeDisabledDefCB(Widget w, WindowInfo *window, caddr_t callData) + { + setPrefCheckingMode(window, CHECKING_MODE_DISABLED); + } + + static void checkingModeTailMinusFDefCB(Widget w, WindowInfo *window, caddr_t callData) + { + setPrefCheckingMode(window, CHECKING_MODE_TAIL_MINUS_F); + } + static void savePrefCB(Widget w, WindowInfo *window, caddr_t callData) *************** *** 1701,1703 **** { ! EditNewFile(); CheckCloseDim(); --- 1769,1772 ---- { ! WindowInfo *window = WidgetToWindow(w); ! EditNewFile(window); CheckCloseDim(); *************** *** 1711,1713 **** ! response = PromptForExistingFile(window, "File to Edit:", fullname); if (response != GFN_OK) --- 1780,1782 ---- ! response = PromptForExistingFile(window, "File to Edit:", fullname, "Open"); if (response != GFN_OK) *************** *** 1725,1727 **** if (*nArgs == 0) { ! fprintf(stderr, "NEdit: open action requires file argument\n"); return; --- 1794,1796 ---- if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "open action requires file argument", "OK"); return; *************** *** 1729,1731 **** ParseFilename(args[0], filename, pathname); ! EditExistingFile(window, filename, pathname, False); CheckCloseDim(); --- 1798,1800 ---- ParseFilename(args[0], filename, pathname); ! EditExistingFile(WindowList, filename, pathname, 0, True); CheckCloseDim(); *************** *** 1736,1738 **** { ! OpenSelectedFile(WidgetToWindow(w), event->xbutton.time); CheckCloseDim(); --- 1805,1807 ---- { ! OpenSelectedFile(WidgetToWindow(w), timeOfEvent(event)); CheckCloseDim(); *************** *** 1750,1752 **** ! if (CheckReadOnly(window)) return; --- 1819,1821 ---- ! if(CheckReadOnly(window)) return; *************** *** 1762,1763 **** --- 1831,1838 ---- + /* .b: Gives complete name to PromptForNewFile ("Save As" mode) */ + strcpy(fullname, window->editorInfo->path); + if(window->editorInfo->filenameSet) + strcat(fullname, window->editorInfo->filename); + /* .e */ + response = PromptForNewFile(window, "Save File As:", fullname, &addWrap); *************** *** 1772,1779 **** { if (*nArgs == 0) { ! fprintf(stderr, "NEdit: save_as action requires file argument\n"); return; } ! SaveWindowAs(WidgetToWindow(w), args[0], ! *nArgs == 2 && !strCaseCmp(args[1], "wrapped")); } --- 1847,1855 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "save_as action requires file argument", "OK"); return; } ! SaveWindowAs(window, args[0], ! *nArgs == 2 && !StrCaseCmp(args[1], "wrapped")); } *************** *** 1783,1797 **** { ! WindowInfo *window = WidgetToWindow(w); ! int b; ! ! /* re-reading file is irreversible, prompt the user first */ ! if (window->fileChanged) ! b = DialogF(DF_QUES, window->shell, 2, "Discard changes to\n%s%s?", ! "OK", "Cancel", window->path, window->filename); ! else ! b = DialogF(DF_QUES, window->shell, 2, "Re-load file\n%s%s?", ! "Re-read", "Cancel", window->path, window->filename); ! if (b != 1) ! return; ! XtCallActionProc(window->lastFocus, "revert_to_saved", event, NULL, 0); } --- 1859,1861 ---- { ! RevertToSaved(WidgetToWindow(w), False); } *************** *** 1801,1803 **** { ! RevertToSaved(WidgetToWindow(w)); } --- 1865,1867 ---- { ! RevertToSaved(WidgetToWindow(w), True); } *************** *** 1811,1815 **** ! if (CheckReadOnly(window)) return; ! response = PromptForExistingFile(window, "File to include:", filename); if (response != GFN_OK) --- 1875,1879 ---- ! if(CheckReadOnly(window)) return; ! response = PromptForExistingFile(window, "File to include:", filename, "Include"); if (response != GFN_OK) *************** *** 1824,1832 **** ! if (CheckReadOnly(window)) return; if (*nArgs == 0) { ! fprintf(stderr, "NEdit: include action requires file argument\n"); return; } ! IncludeFile(WidgetToWindow(w), args[0]); } --- 1888,1896 ---- ! if(CheckReadOnly(window)) return; if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "include requires file argument", "OK"); return; } ! IncludeFile(window, args[0]); } *************** *** 1840,1842 **** ! response = PromptForExistingFile(window, "NEdit macro file:", filename); if (response != GFN_OK) --- 1904,1906 ---- ! response = PromptForExistingFile(window, "NEdit macro file:", filename, "Load Macros"); if (response != GFN_OK) *************** *** 1863,1865 **** ! response = PromptForExistingFile(window, "ctags file:", filename); if (response != GFN_OK) --- 1927,1929 ---- ! response = PromptForExistingFile(window, "ctags file:", filename, "Load Tags"); if (response != GFN_OK) *************** *** 1872,1875 **** { if (*nArgs == 0) { ! fprintf(stderr,"NEdit: load_tags_file action requires file argument\n"); return; --- 1936,1940 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "load_tags_file action requires file argument", "OK"); return; *************** *** 1877,1879 **** if (!LoadTagsFile(args[0])) ! DialogF(DF_WARN, WidgetToWindow(w)->shell, 1, "Error reading ctags file,\ntags not loaded", "Dismiss"); --- 1942,1944 ---- if (!LoadTagsFile(args[0])) ! DialogF(DF_WARN, window->shell, 1, "Error reading ctags file,\ntags not loaded", "Dismiss"); *************** *** 1894,1931 **** WindowInfo *window = WidgetToWindow(w); ! #ifdef EXIT_WARNING ! int resp, titleLen; ! char exitMsg[DF_MAX_MSG_LENGTH], *ptr, *title; ! WindowInfo *win; ! #endif ! if (!CheckPrefsChangesSaved(window->shell)) ! return; ! ! #ifdef EXIT_WARNING ! /* If this is the last window, don't ask, just try to close and exit */ ! if (window == WindowList && window->next == NULL) { ! if (CloseAllFilesAndWindows()) ! exit(0); ! else ! return; ! } ! ! /* List the windows being edited and make sure the ! user really wants to exit */ ! ptr = exitMsg; ! strcpy(ptr, "Editing:\n"); ptr += 9; ! for (win=WindowList; win!=NULL; win=win->next) { ! XtVaGetValues(win->shell, XmNtitle, &title, 0); ! titleLen = strlen(title); ! if (titleLen > DF_MAX_MSG_LENGTH - 30) { ! sprintf(ptr, " ...\n"); ptr += 7; ! break; } ! sprintf(ptr, " %s\n", title); ptr += titleLen + 4; } ! sprintf(ptr, " \nExit NEdit?"); ! resp = DialogF(DF_QUES, window->shell, 2, "%s", "Exit", "Cancel", exitMsg); ! if (resp == 2) return; - #endif /* EXIT_WARNING */ --- 1959,2000 ---- WindowInfo *window = WidgetToWindow(w); ! if(GetPrefWarnOnExit()) { ! int resp, titleLen; ! char exitMsg[DF_MAX_MSG_LENGTH], *ptr; ! WindowInfo *win; ! ! /* If this is the last window, don't ask, just try to close and exit */ ! if (window == WindowList && window->next == NULL) { ! if (CloseAllFilesAndWindows()) ! exit(0); ! else ! return; ! } ! /* List the windows being edited and make sure the ! user really wants to exit */ ! ptr = exitMsg; ! strcpy(ptr, "Editing:\n"); ptr += 9; ! for (win=WindowList; win!=NULL; win=win->next) { ! char title[MAXPATHLEN * 2 + 1]; ! strcpy(title, FormatWindowTitle(win)); ! /* Append the full pathname to the end of the title if set */ ! if(win->editorInfo->filenameSet) { ! strcat(title, " - "); ! strcat(title, win->editorInfo->path); ! } ! titleLen = strlen(title); ! if (titleLen > DF_MAX_MSG_LENGTH - 30) { ! sprintf(ptr, " ...\n"); ptr += 7; ! break; ! } ! sprintf(ptr, " %s\n", title); ptr += titleLen + 4; } ! sprintf(ptr, " \nExit NEdit?"); ! resp = DialogF(DF_QUES, window->shell, 2, "%s", "Exit", "Cancel", exitMsg); ! if (resp == 2) ! return; } ! ! if (!CheckPrefsChangesSaved(window->shell)) return; *************** *** 1940,1942 **** ! if (CheckReadOnly(window)) return; --- 2009,2011 ---- ! if(CheckReadOnly(window)) return; *************** *** 1949,1951 **** ! if (CheckReadOnly(window)) return; --- 2018,2020 ---- ! if(CheckReadOnly(window)) return; *************** *** 1958,1962 **** ! if (CheckReadOnly(window)) return; ! BufRemoveSelected(window->buffer); } --- 2027,2031 ---- ! if(CheckReadOnly(window)) return; ! BufRemoveSelected(window->editorInfo->buffer); } *************** *** 1967,1969 **** ! BufSelect(window->buffer, 0, window->buffer->length); } --- 2036,2038 ---- ! BufSelect(window->editorInfo->buffer, 0, window->editorInfo->buffer->length, CHAR_SELECT); } *************** *** 1974,1976 **** ! if (CheckReadOnly(window)) return; --- 2043,2045 ---- ! if(CheckReadOnly(window)) return; *************** *** 1984,1986 **** ! if (CheckReadOnly(window)) return; --- 2053,2055 ---- ! if(CheckReadOnly(window)) return; *************** *** 1993,1995 **** ! if (CheckReadOnly(window)) return; --- 2062,2064 ---- ! if(CheckReadOnly(window)) return; *************** *** 2003,2005 **** ! if (CheckReadOnly(window)) return; --- 2072,2074 ---- ! if(CheckReadOnly(window)) return; *************** *** 2010,2012 **** { ! DoFindDlog(WidgetToWindow(w), searchDirection(0, args, nArgs)); } --- 2079,2083 ---- { ! WindowInfo *window = WidgetToWindow(w); ! ! DoFindReplaceDlog(window, searchDirection(0, args, nArgs), FIND_REPLACE_FIND_BUTTON_DEFAULT, timeOfEvent(event)); } *************** *** 2015,2021 **** { if (*nArgs == 0) { ! fprintf(stderr, "NEdit: find action requires search string argument\n"); return; } ! SearchAndSelect(WidgetToWindow(w), searchDirection(1, args, nArgs), args[0], searchType(1, args, nArgs)); --- 2086,2104 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "find action requires search string argument", "OK"); return; } ! SearchAndSelect(window, searchDirection(1, args, nArgs), args[0], ! searchType(1, args, nArgs)); ! } ! ! static void findIncrementalAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) ! { ! WindowInfo *window = WidgetToWindow(w); ! if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "find_incremental action requires search string argument", "OK"); ! return; ! } ! SearchAndSelectIncremental(window, searchDirection(1, args, nArgs), args[0], searchType(1, args, nArgs)); *************** *** 2031,2033 **** SearchForSelected(WidgetToWindow(w), searchDirection(0, args, nArgs), ! event->xbutton.time); } --- 2114,2116 ---- SearchForSelected(WidgetToWindow(w), searchDirection(0, args, nArgs), ! timeOfEvent(event)); } *************** *** 2039,2043 **** ! if (CheckReadOnly(window)) ! return; ! DoReplaceDlog(window, searchDirection(0, args, nArgs)); } --- 2122,2124 ---- ! DoFindReplaceDlog(window, searchDirection(0, args, nArgs), FIND_REPLACE_REPLACE_BUTTON_DEFAULT, timeOfEvent(event)); } *************** *** 2048,2054 **** ! if (CheckReadOnly(window)) return; if (*nArgs < 2) { ! fprintf(stderr, ! "NEdit: replace action requires search and replace string arguments\n"); return; --- 2129,2134 ---- ! if(CheckReadOnly(window)) return; if (*nArgs < 2) { ! DialogF(DF_WARN, window->shell, 1, "replace action requires search and replace string arguments", "OK"); return; *************** *** 2059,2060 **** --- 2139,2154 ---- + static void replaceFindAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) + { + WindowInfo *window = WidgetToWindow(w); + + if(CheckReadOnly(window)) + return; + if (*nArgs < 2) { + DialogF(DF_WARN, window->shell, 1, "replace_find action requires search and replace string arguments", "OK"); + return; + } + ReplaceAndSearch(window, searchDirection(2, args, nArgs), + args[0], args[1], searchType(2, args, nArgs)); + } + static void replaceAllAP(Widget w, XEvent *event, String *args, *************** *** 2064,2070 **** ! if (CheckReadOnly(window)) return; if (*nArgs < 2) { ! fprintf(stderr, ! "NEdit: replace_all action requires search and replace string arguments\n"); return; --- 2158,2163 ---- ! if(CheckReadOnly(window)) return; if (*nArgs < 2) { ! DialogF(DF_WARN, window->shell, 1, "replace_all action requires search and replace string arguments", "OK"); return; *************** *** 2079,2085 **** ! if (CheckReadOnly(window)) return; if (*nArgs < 2) { ! fprintf(stderr, ! "NEdit: replace_in_selection requires search and replace string arguments\n"); return; --- 2172,2177 ---- ! if(CheckReadOnly(window)) return; if (*nArgs < 2) { ! DialogF(DF_WARN, window->shell, 1, "replace_in_selection action requires search and replace string arguments", "OK"); return; *************** *** 2095,2097 **** ! if (CheckReadOnly(window)) return; --- 2187,2189 ---- ! if(CheckReadOnly(window)) return; *************** *** 2100,2103 **** --- 2192,2206 ---- + static void replaceFindSameAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + WindowInfo *window = WidgetToWindow(w); + + if(CheckReadOnly(window)) + return; + ReplaceFindSame(window, searchDirection(0, args, nArgs)); + } + static void gotoAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { + WindowInfo *window = WidgetToWindow(w); int lineNum; *************** *** 2105,2110 **** if (*nArgs == 0 || sscanf(args[0], "%d", &lineNum) != 1) { ! fprintf(stderr,"NEdit: goto_line_number action requires line number\n"); return; } ! SelectNumberedLine(WidgetToWindow(w), lineNum); } --- 2208,2213 ---- if (*nArgs == 0 || sscanf(args[0], "%d", &lineNum) != 1) { ! DialogF(DF_WARN, window->shell, 1, "goto_line_number action requires line number argument", "OK"); return; } ! SelectNumberedLine(window, lineNum); } *************** *** 2120,2122 **** { ! GotoSelectedLineNumber(WidgetToWindow(w), event->xbutton.time); } --- 2223,2225 ---- { ! GotoSelectedLineNumber(WidgetToWindow(w), timeOfEvent(event)); } *************** *** 2144,2150 **** { if (*nArgs == 0 || strlen(args[0]) != 1 || !isalnum(args[0][0])) { ! fprintf(stderr,"NEdit: mark action requires a single-letter label\n"); return; } ! AddMark(WidgetToWindow(w), w, args[0][0]); } --- 2247,2254 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0 || strlen(args[0]) != 1 || !isalnum(args[0][0])) { ! DialogF(DF_WARN, window->shell, 1, "mark action requires a single-letter label argument", "OK"); return; } ! AddMark(window, w, args[0][0]); } *************** *** 2159,2163 **** { if (*nArgs == 0 || strlen(args[0]) != 1 || !isalnum(args[0][0])) { ! fprintf(stderr, ! "NEdit: goto_mark action requires a single-letter label\n"); return; --- 2263,2267 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0 || strlen(args[0]) != 1 || !isalnum(args[0][0])) { ! DialogF(DF_WARN, window->shell, 1, "goto_mark action requires a single-letter label argument", "OK"); return; *************** *** 2180,2184 **** static void findDefAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { ! FindDefinition(WidgetToWindow(w), event->xbutton.time); } --- 2284,2294 ---- + static void gotoMatchingAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + GotoMatchingCharacter(WidgetToWindow(w)); + } + static void findDefAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { ! FindDefinition(WidgetToWindow(w), timeOfEvent(event)); } *************** *** 2204,2205 **** --- 2314,2320 ---- + static void cloneWindowAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) + { + CreateSlaveWindow(WidgetToWindow(w)); + } + static void capitalizeAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) *************** *** 2208,2210 **** ! if (CheckReadOnly(window)) return; --- 2323,2325 ---- ! if(CheckReadOnly(window)) return; *************** *** 2217,2219 **** ! if (CheckReadOnly(window)) return; --- 2332,2334 ---- ! if(CheckReadOnly(window)) return; *************** *** 2226,2228 **** ! if (CheckReadOnly(window)) return; --- 2341,2343 ---- ! if(CheckReadOnly(window)) return; *************** *** 2239,2241 **** ! if (CheckReadOnly(window)) return; --- 2354,2356 ---- ! if(CheckReadOnly(window)) return; *************** *** 2253,2255 **** params[0] = (char *)charCodeString; ! if (!BufSubstituteNullChars((char *)charCodeString, 1, window->buffer)) { DialogF(DF_ERR, window->shell, 1, "Too much binary data","Dismiss"); --- 2368,2370 ---- params[0] = (char *)charCodeString; ! if (!BufSubstituteNullChars((char *)charCodeString, 1, window->editorInfo->buffer)) { DialogF(DF_ERR, window->shell, 1, "Too much binary data","Dismiss"); *************** *** 2265,2267 **** WindowInfo *window = WidgetToWindow(w); ! char *params[1], cmdText[DF_MAX_PROMPT_LENGTH]; int resp; --- 2380,2383 ---- WindowInfo *window = WidgetToWindow(w); ! char *params[1]; ! static char cmdText[DF_MAX_PROMPT_LENGTH]; int resp; *************** *** 2270,2274 **** ! if (CheckReadOnly(window)) return; ! if (!window->buffer->primary.selected) { XBell(TheDisplay, 0); --- 2386,2390 ---- ! if(CheckReadOnly(window)) return; ! if (!window->editorInfo->buffer->primary.selected) { XBell(TheDisplay, 0); *************** *** 2293,2299 **** ! if (CheckReadOnly(window)) return; if (*nArgs == 0) { ! fprintf(stderr, ! "NEdit: filter_selection requires shell command argument\n"); return; --- 2409,2414 ---- ! if(CheckReadOnly(window)) return; if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "filter_selection action requires shell command argument", "OK"); return; *************** *** 2329,2335 **** ! if (CheckReadOnly(window)) return; if (*nArgs == 0) { ! fprintf(stderr, ! "NEdit: execute_command requires shell command argument\n"); return; --- 2444,2449 ---- ! if(CheckReadOnly(window)) return; if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "execute_command action requires shell command argument", "OK"); return; *************** *** 2344,2346 **** ! if (CheckReadOnly(window)) return; --- 2458,2460 ---- ! if(CheckReadOnly(window)) return; *************** *** 2351,2355 **** { if (*nArgs == 0) { ! fprintf(stderr, ! "NEdit: shell_menu_command requires item-name argument\n"); return; --- 2465,2469 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "shell_menu_command action requires item-name argument", "OK"); return; *************** *** 2363,2370 **** { if (*nArgs == 0) { ! fprintf(stderr, ! "NEdit: macro_menu_command requires item-name argument\n"); return; } ! DoNamedMacroMenuCmd(WidgetToWindow(w), args[0]); } --- 2477,2484 ---- { + WindowInfo *window = WidgetToWindow(w); if (*nArgs == 0) { ! DialogF(DF_WARN, window->shell, 1, "macro_menu_command action requires item-name argument", "OK"); return; } ! DoNamedMacroMenuCmd(window, args[0]); } *************** *** 2570,2572 **** if (WindowList->next==NULL && ! !WindowList->filenameSet && !WindowList->fileChanged) { XtSetSensitive(WindowList->closeItem, FALSE); --- 2684,2686 ---- if (WindowList->next==NULL && ! !WindowList->editorInfo->filenameSet && !WindowList->editorInfo->fileChanged) { XtSetSensitive(WindowList->closeItem, FALSE); *************** *** 2582,2584 **** ** the menus until they're needed (Originally, this was "UpdateWindowMenus", ! ** but creating and destroying manu items for every window every time a ** new window was created or something changed, made things move very --- 2696,2698 ---- ** the menus until they're needed (Originally, this was "UpdateWindowMenus", ! ** but creating and destroying menu items for every window every time a ** new window was created or something changed, made things move very *************** *** 2676,2678 **** WindowInfo *w; - char *title; Widget btn; --- 2790,2791 ---- *************** *** 2711,2716 **** } else { ! XtVaGetValues(windows[windowIndex]->shell, XmNtitle, &title, 0); ! #ifdef SGI_CUSTOM ! title = title + SGI_WINDOW_TITLE_LEN; ! #endif XtVaSetValues(items[n], XmNlabelString, --- 2824,2832 ---- } else { ! char title[MAXPATHLEN * 2 + 1]; ! strcpy(title, FormatWindowTitle(windows[windowIndex])); ! /* Append the full pathname to the end of the title if set */ ! if(windows[windowIndex]->editorInfo->filenameSet) { ! strcat(title, " - "); ! strcat(title, windows[windowIndex]->editorInfo->path); ! } XtVaSetValues(items[n], XmNlabelString, *************** *** 2728,2733 **** for (; windowIndexshell, XmNtitle, &title, 0); ! #ifdef SGI_CUSTOM ! title = title + SGI_WINDOW_TITLE_LEN; ! #endif btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass, --- 2844,2852 ---- for (; windowIndexeditorInfo->filenameSet) { ! strcat(title, " - "); ! strcat(title, windows[windowIndex]->editorInfo->path); ! } btn = XtVaCreateManagedWidget("win", xmPushButtonWidgetClass, *************** *** 2944,2945 **** --- 3063,3069 ---- + static void setPrefCheckingMode(WindowInfo *window, CheckingMode mode) + { + SetPrefCheckingMode(mode); + } + /* *************** *** 2955,2959 **** for (i=ignoreArgs; i<*nArgs; i++) { ! if (!strCaseCmp(args[i], "forward")) return SEARCH_FORWARD; ! if (!strCaseCmp(args[i], "backward")) return SEARCH_BACKWARD; --- 3079,3083 ---- for (i=ignoreArgs; i<*nArgs; i++) { ! if (!StrCaseCmp(args[i], "forward")) return SEARCH_FORWARD; ! if (!StrCaseCmp(args[i], "backward")) return SEARCH_BACKWARD; *************** *** 2974,2980 **** for (i=ignoreArgs; i<*nArgs; i++) { ! if (!strCaseCmp(args[i], "literal")) return SEARCH_LITERAL; ! if (!strCaseCmp(args[i], "case")) return SEARCH_CASE_SENSE; ! if (!strCaseCmp(args[i], "regex")) return SEARCH_REGEX; --- 3098,3104 ---- for (i=ignoreArgs; i<*nArgs; i++) { ! if (!StrCaseCmp(args[i], "literal")) return SEARCH_LITERAL; ! if (!StrCaseCmp(args[i], "case")) return SEARCH_CASE_SENSE; ! if (!StrCaseCmp(args[i], "regex")) return SEARCH_REGEX; *************** *** 3016,3032 **** /* ! ** strCaseCmp compares its arguments and returns 0 if the two strings ! ** are equal IGNORING case differences. Otherwise returns 1. ! */ ! static int strCaseCmp(char *str1, char *str2) ! { ! char *c1, *c2; ! ! for (c1=str1, c2=str2; *c1!='\0' && *c2!='\0'; c1++, c2++) ! if (toupper(*c1) != toupper(*c2)) ! return 1; ! return 0; ! } ! ! /* ! ** Comparison function for sorting windows by title for the window menu */ --- 3140,3144 ---- /* ! ** Comparison function for sorting windows by title for the window menu. ! ** Windows are sorted by Untitled and then alphabetically by filename and ! ** then alphabetically by path. */ *************** *** 3034,3037 **** { ! return strcmp((*((WindowInfo**)windowA))->filename, ! (*((WindowInfo**)windowB))->filename); } --- 3146,3160 ---- { ! int rc; ! const WindowInfo *a = *((WindowInfo**)windowA); ! const WindowInfo *b = *((WindowInfo**)windowB); ! /* Untitled first */ ! rc = a->editorInfo->filenameSet == b->editorInfo->filenameSet ? 0 : ! a->editorInfo->filenameSet && !b->editorInfo->filenameSet ? 1 : -1; ! if(rc != 0) ! return rc; ! rc = strcmp(a->editorInfo->filename, b->editorInfo->filename); ! if(rc != 0) ! return rc; ! rc = strcmp(a->editorInfo->path, b->editorInfo->path); ! return rc; } *************** *** 3083,3084 **** --- 3206,3220 ---- XtMapWidget(window->bgMenuPane); + } + + static Time timeOfEvent(XEvent *event) + { + return event->type == KeyPress ? event->xkey.time : + event->type == KeyRelease ? event->xkey.time : + event->type == ButtonPress ? event->xbutton.time : + event->type == ButtonRelease ? event->xbutton.time : + event->type == MotionNotify ? event->xmotion.time : + event->type == EnterNotify ? event->xcrossing.time : + event->type == LeaveNotify ? event->xcrossing.time : + event->type == PropertyNotify ? event->xproperty.time : + CurrentTime; } *** menu.h 1997/09/26 18:28:17 1.1 --- menu.h 1997/10/10 00:15:13 1.2 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + /* SCCS ID: menu.h 1.4 2/4/94 */ #define PERMANENT_MENU_ITEM 1 *** nc.c 1997/09/26 18:28:17 1.1 --- nc.c 1997/10/10 00:15:13 1.2 *************** *** 24,28 **** *******************************************************************************/ #include #include ! #include #ifdef VMS --- 24,31 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #ifdef VMS *************** *** 38,40 **** #include ! #include #include --- 41,45 ---- #include ! #ifdef HAVE_UNISTD_H ! # include ! #endif #include *************** *** 45,50 **** #include "../util/prefFile.h" ! ! /* If anyone knows where to get this from system include files (in a machine ! independent way), please change this (L_cuserid is apparently not ANSI) */ ! #define MAXUSERNAMELEN 32 --- 50,52 ---- #include "../util/prefFile.h" ! #include "server_common.h" *************** *** 53,67 **** ! #if defined(VMS) || defined(linux) ! #define MAXNODENAMELEN (MAXPATHLEN+2) ! #elif defined(SUNOS) ! #define MAXNODENAMELEN 9 #else ! #define MAXNODENAMELEN SYS_NMLN #endif ! static void deadServerTimerProc(XtPointer clientData, XtIntervalId *id); ! static void startServer(char *message, char *commandLine); static char *parseCommandLine(int argc, char **argv); - static char *getUserName(void); - static void getHostName(char *hostname); static void nextArg(int argc, char **argv, int *argIndex); --- 55,71 ---- ! #ifdef DEBUG ! #define PROPERTY_CHANGE_TIMEOUT (1 * 1) /* milliseconds */ ! #define SERVER_START_TIMEOUT (1 * 1) /* milliseconds */ ! #define REQUEST_TIMEOUT (1 * 1) /* milliseconds */ ! #define FILE_OPEN_TIMEOUT (1 * 1) /* milliseconds */ #else ! #define PROPERTY_CHANGE_TIMEOUT (10 * 1000) /* milliseconds */ ! #define SERVER_START_TIMEOUT (30 * 1000) /* milliseconds */ ! #define REQUEST_TIMEOUT (10 * 1000) /* milliseconds */ ! #define FILE_OPEN_TIMEOUT (30 * 1000) /* milliseconds */ #endif ! static void timeOutProc(Boolean *timeOutReturn, XtIntervalId *id); ! static int startServer(char *message, char *commandLine); static char *parseCommandLine(int argc, char **argv); static void nextArg(int argc, char **argv, int *argIndex); *************** *** 69,70 **** --- 73,76 ---- Display *TheDisplay; + char *appName = APP_NAME; + char *appClass = APP_CLASS; *************** *** 72,75 **** #ifndef VMS ! "Usage: nc [-read] [-create] [-line n | +n] [-do command] [-[no]ask] \n\ ! [-svrname name] [file...]\n"; #else --- 78,81 ---- #ifndef VMS ! "Usage: nc [-read] [-create] [-line n | +n] [-do command] [-[no]ask] \ ! [-sn|-svrname unique_name] [-wait] [-openwait] [file...]\n"; #else *************** *** 82,84 **** char serverCmd[MAXPATHLEN]; ! char serverName[MAXPATHLEN]; } Preferences; --- 88,92 ---- char serverCmd[MAXPATHLEN]; ! char serverName[MAXSERVERNAMELEN]; ! int waitForOpen; ! int waitForClose; } Preferences; *************** *** 89,94 **** &Preferences.autoStart, NULL, True}, ! {"serverCommand", "ServerCommand", PREF_STRING, "nedit -server", Preferences.serverCmd, (void *)sizeof(Preferences.serverCmd), False}, ! {"serverName", "serverName", PREF_STRING, "", Preferences.serverName, ! (void *)sizeof(Preferences.serverName), False}, }; --- 97,106 ---- &Preferences.autoStart, NULL, True}, ! {"serverCommand", "serverCommand", PREF_STRING, "nedit -server", Preferences.serverCmd, (void *)sizeof(Preferences.serverCmd), False}, ! {"serverName", "ServerName", PREF_STRING, DEFAULTSERVERNAME, ! Preferences.serverName, (void *)sizeof(Preferences.serverName), False}, ! {"waitForOpen", "waitForOpen", PREF_BOOLEAN, "False", ! &Preferences.waitForOpen, NULL, False}, ! {"waitForClose", "WaitForClose", PREF_BOOLEAN, "False", ! &Preferences.waitForClose, NULL, False}, }; *************** *** 99,103 **** {"-noask", ".autoStart", XrmoptionNoArg, (caddr_t)"True"}, ! {"-svrname", ".serverName", XrmoptionSepArg, (caddr_t)NULL}, }; int main(int argc, char **argv) --- 111,154 ---- {"-noask", ".autoStart", XrmoptionNoArg, (caddr_t)"True"}, ! {"-sn", ".serverName", XrmoptionSepArg, NULL}, ! {"-svrname", ".serverName", XrmoptionSepArg, NULL}, ! {"-wait", ".waitForClose", XrmoptionNoArg, (caddr_t)"True"}, ! {"-openwait", ".waitForOpen", XrmoptionNoArg, (caddr_t)"True"}, }; + typedef enum _OpenStatus { NONE, OPEN, CLOSED } OpenStatus; + + /* Struct to hold if a file is still being edited. */ + typedef struct _FileOpenStatus { + Atom fileOpenAtom; + OpenStatus openStatus; + struct _FileOpenStatus *next; + } FileOpenStatus; + + FileOpenStatus *fileOpenList = 0; + + /* Create the file open atom for path and initialize its status structure. */ + static void addFileToFileOpenList(char *path) { + Atom atom; + FileOpenStatus *item; + + /* Create the property atom for path. */ + CreateServerFileOpenAtom(Preferences.serverName, path, &atom); + + /* see if the atom already exists in the list */ + for(item = fileOpenList; item; item = item->next) { + if(item->fileOpenAtom == atom) { + break; + } + } + + /* Add the atom to the head of the file open list if it wasn't found. */ + if(item == 0) { + item = malloc(sizeof(item[0])); + item->fileOpenAtom = atom; + item->openStatus = NONE; + item->next = fileOpenList; + fileOpenList = item; + } + } + int main(int argc, char **argv) *************** *** 114,119 **** Atom serverExistsAtom, serverRequestAtom; - char *userName, propName[23+MAXNODENAMELEN+MAXUSERNAMELEN]; - char hostName[MAXNODENAMELEN+1]; - char serverName[MAXPATHLEN+2]; XrmDatabase prefDB; --- 165,171 ---- Atom serverExistsAtom, serverRequestAtom; XrmDatabase prefDB; + XtIntervalId timerId; + Boolean requestTimeOut; + Boolean fileOpenTimeOut; + Boolean noServer; *************** *** 134,136 **** /* Open the display and find the root window */ ! TheDisplay = XtOpenDisplay (context, NULL, APP_NAME, APP_CLASS, NULL, 0, &argc, argv); --- 186,188 ---- /* Open the display and find the root window */ ! TheDisplay = XtOpenDisplay (context, NULL, NULL, APP_CLASS, NULL, 0, &argc, argv); *************** *** 140,141 **** --- 192,194 ---- } + XtGetApplicationNameAndClass(TheDisplay, &appName, &appClass); rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay)); *************** *** 143,146 **** /* Read the application resources into the Preferences data structure */ ! RestorePreferences(prefDB, XtDatabase(TheDisplay), APP_NAME, ! APP_CLASS, PrefDescrip, XtNumber(PrefDescrip)); --- 196,199 ---- /* Read the application resources into the Preferences data structure */ ! RestorePreferences(prefDB, XtDatabase(TheDisplay), appName, ! appClass, PrefDescrip, XtNumber(PrefDescrip)); *************** *** 149,153 **** ! /* Reconstruct the command line in string commandLine in case we have to ! start a server (nc command line args parallel nedit's). Include ! -svrname if nc wants a named server, so nedit will match. Special characters are protected from the shell by escaping EVERYTHING with \ */ --- 202,205 ---- ! /* Reconstruct the command line in string commandLine in case we have ! to start a server (nc command line args parallel nedit's). Special characters are protected from the shell by escaping EVERYTHING with \ */ *************** *** 155,157 **** length += 1 + strlen(argv[i])*2; ! commandLine = XtMalloc(length+1 + 9+strlen(Preferences.serverName)); outPtr = commandLine; --- 207,209 ---- length += 1 + strlen(argv[i])*2; ! commandLine = XtMalloc(length+1); outPtr = commandLine; *************** *** 166,203 **** } - if (Preferences.serverName[0] != '\0') { - sprintf(outPtr, "-svrname %s", Preferences.serverName); - outPtr += 9+strlen(Preferences.serverName); - } *outPtr = '\0'; commandLineLen = outPtr - commandLine; - - /* Create server property atoms. Atom names are generated by - concatenating NEDIT_SERVER_REQUEST_, and NEDIT_SERVER_EXITS_ - with hostname, user name and optional server name */ - userName = getUserName(); - getHostName(hostName); - if (Preferences.serverName[0] != '\0') { - serverName[0] = '_'; - strcpy(&serverName[1], Preferences.serverName); - } else - serverName[0] = '\0'; - sprintf(propName, "NEDIT_SERVER_EXISTS_%s_%s%s", hostName, userName, - serverName); - serverExistsAtom = XInternAtom(TheDisplay, propName, False); - sprintf(propName, "NEDIT_SERVER_REQUEST_%s_%s%s", hostName, userName, - serverName); - serverRequestAtom = XInternAtom(TheDisplay, propName, False); ! /* See if there might be a server (not a guaranty), by translating the ! root window property NEDIT_SERVER_EXISTS__ */ if (XGetWindowProperty(TheDisplay, rootWindow, serverExistsAtom, 0, INT_MAX, False, XA_STRING, &dummyAtom, &getFmt, &nItems, ! &dummyULong, &propValue) != Success || nItems == 0) { ! startServer("No servers available, start one (yes)? ", commandLine); ! return 0; } ! XFree(propValue); ! /* Set the NEDIT_SERVER_REQUEST__ property on the root ! window to activate the server */ XChangeProperty(TheDisplay, rootWindow, serverRequestAtom, XA_STRING, 8, --- 218,328 ---- } *outPtr = '\0'; commandLineLen = outPtr - commandLine; ! /* Monitor the properties on the root window. ! ** Also adding a bunch of other event types to make sure ! ** we get other events so we can detect the timeout. */ ! XSelectInput(TheDisplay, rootWindow, PropertyChangeMask | ! KeyPressMask | KeyReleaseMask | EnterWindowMask | ! LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ! ExposureMask | VisibilityChangeMask | FocusChangeMask); ! ! /* Create the server property atoms on the current DISPLAY. */ ! CreateServerPropertyAtoms(Preferences.serverName, &serverExistsAtom, ! &serverRequestAtom); ! ! /* See if there is a server already running on the current DISPLAY. ! If not then start one on the current host. If the property exists ! make sure the server is running. */ ! noServer = False; if (XGetWindowProperty(TheDisplay, rootWindow, serverExistsAtom, 0, INT_MAX, False, XA_STRING, &dummyAtom, &getFmt, &nItems, ! &dummyULong, &propValue) != Success || dummyAtom == None) { ! noServer = True; ! } else { ! Boolean propertyChangeTimeOut = False; ! ! XFree(propValue); ! ! /* Remove the server exists property to make sure the server is ! ** running. If it is running it will get recreated. ! */ ! XDeleteProperty(TheDisplay, rootWindow, serverExistsAtom); ! XSync(TheDisplay, False); ! timerId = XtAppAddTimeOut(context, PROPERTY_CHANGE_TIMEOUT, ! (XtTimerCallbackProc)timeOutProc, &propertyChangeTimeOut); ! while (!propertyChangeTimeOut) { ! /* NOTE: XtAppNextEvent() does call the timeout routine but ! ** doesn't return unless there are more events. See ! ** XSelectInput above. */ ! XtAppNextEvent(context, &event); ! ! /* We will get a PropertyNewValue when the server recreates ! ** the server exists atom. */ ! if (e->type == PropertyNotify && e->window == rootWindow && e->atom == serverExistsAtom) { ! if(e->state == PropertyNewValue) { ! break; ! } ! } ! XtDispatchEvent(&event); ! } ! /* Start a new server if the timeout expired. The server exists ! ** property was not recreated. */ ! if(propertyChangeTimeOut) { ! #ifdef DEBUG ! fprintf(stderr, "%s: propertyChangeTimeOut has occurred.\n", appName); ! #endif ! noServer = True; ! } else { ! XtRemoveTimeOut(timerId); ! } } ! if(noServer) { ! Boolean serverStartTimeOut; ! ! if(!startServer("No servers available, start one? (y|n)[y]: ", "")) { ! XtCloseDisplay(TheDisplay); ! exit(1); ! } ! /* Set up a timeout proc in case the server is dead. The standard ! selection timeout is probably a good guess at how long to wait ! for this style of inter-client communication as well */ ! timerId = XtAppAddTimeOut(context, SERVER_START_TIMEOUT, ! (XtTimerCallbackProc)timeOutProc, &serverStartTimeOut); ! ! /* Wait for the server to start */ ! serverStartTimeOut = False; ! while (!serverStartTimeOut) { ! /* NOTE: XtAppNextEvent() does call the timeout routine but ! ** doesn't return unless there are more events. See ! ** XSelectInput above. */ ! XtAppNextEvent(context, &event); ! ! /* We will get a PropertyNewValue when the server updates ! ** the server exists atom. If the property is deleted the ! ** the server must have died. */ ! if (e->type == PropertyNotify && e->window == rootWindow && e->atom == serverExistsAtom) { ! if(e->state == PropertyNewValue) { ! break; ! } else if(e->state == PropertyDelete) { ! fprintf(stderr, "%s: The server failed to start.\n", appName); ! XtCloseDisplay(TheDisplay); ! exit(1); ! } ! } ! XtDispatchEvent(&event); ! } ! /* Exit if the timeout expired. */ ! if(serverStartTimeOut) { ! fprintf(stderr, "%s: The server failed to start.\n", appName); ! XtCloseDisplay(TheDisplay); ! exit(1); ! } else { ! XtRemoveTimeOut(timerId); ! } ! } ! ! /* Change the NEDIT_SERVER_REQUEST_... property on the root ! window to communicate the request to the server */ XChangeProperty(TheDisplay, rootWindow, serverRequestAtom, XA_STRING, 8, *************** *** 205,207 **** strlen(commandString)); ! /* Set up a timeout proc in case the server is dead. The standard --- 330,332 ---- strlen(commandString)); ! /* Set up a timeout proc in case the server is dead. The standard *************** *** 209,218 **** for this style of inter-client communication as well */ ! XtAppAddTimeOut(context, XtAppGetSelectionTimeout(context), ! deadServerTimerProc, commandLine); ! /* Wait for the property to be deleted to know the request was processed */ ! XSelectInput(TheDisplay, rootWindow, PropertyChangeMask); ! while (TRUE) { XtAppNextEvent(context, &event); ! if (e->window == rootWindow && e->atom == serverRequestAtom && e->state == PropertyDelete) --- 334,343 ---- for this style of inter-client communication as well */ ! timerId = XtAppAddTimeOut(context, REQUEST_TIMEOUT, ! (XtTimerCallbackProc)timeOutProc, &requestTimeOut); ! /* Wait for the property to be deleted to know the request was processed */ ! requestTimeOut = False; ! while (!requestTimeOut) { XtAppNextEvent(context, &event); ! if (e->type == PropertyNotify && e->window == rootWindow && e->atom == serverRequestAtom && e->state == PropertyDelete) *************** *** 221,223 **** --- 346,427 ---- } + /* Exit if the timeout expired. */ + if(requestTimeOut) { + fprintf(stderr, "%s: The server did not respond to the request.\n", appName); + XtCloseDisplay(TheDisplay); + exit(1); + } else { + XtRemoveTimeOut(timerId); + } + + /* Set up a timeout proc so we don't wait forever if the server is dead. + The standard selection timeout is probably a good guess at how + long to wait for this style of inter-client communication as + well */ + if(Preferences.waitForOpen) { + timerId = XtAppAddTimeOut(context, FILE_OPEN_TIMEOUT, + (XtTimerCallbackProc)timeOutProc, &fileOpenTimeOut); + } + + /* Wait for all of the windows to be closed if -wait was supplied */ + fileOpenTimeOut = False; + while (Preferences.waitForOpen || Preferences.waitForClose) { + FileOpenStatus *item; + + XtAppNextEvent(context, &event); + + /* Update the fileOpenList and check if all of the files have + ** been closed. + */ + if(e->type == PropertyNotify && e->window == rootWindow) { + Boolean stillOpen = False; + Boolean stillToBeOpen = False; + + for(item = fileOpenList; item; item = item->next) { + if (e->atom == item->fileOpenAtom) { + /* The file open property is deleted when the file is closed */ + if(e->state == PropertyDelete) { + item->openStatus = CLOSED; + } + /* The file open property is modified when the file is opened */ + else if(e->state == PropertyNewValue) { + item->openStatus = OPEN; + + /* reset the file open time out if we are waiting for open. */ + if(Preferences.waitForOpen) { + XtRemoveTimeOut(timerId); + timerId = XtAppAddTimeOut(context, FILE_OPEN_TIMEOUT, + (XtTimerCallbackProc)timeOutProc, &fileOpenTimeOut); + } + } + } + if(item->openStatus == OPEN) { + stillOpen = True; + } else if(item->openStatus == NONE && !fileOpenTimeOut) { + stillToBeOpen = True; + } + } + /* we are finished if all of the files are open */ + if(Preferences.waitForOpen && !Preferences.waitForClose && !stillToBeOpen) { + break; + } + /* we are finished if there are no open files */ + if(Preferences.waitForClose && !stillOpen && !stillToBeOpen) { + break; + } + } + + /* we are finished if we are only waiting for the files to open and + ** the file open timeout has expired. */ + if(Preferences.waitForOpen && !Preferences.waitForClose && fileOpenTimeOut) { + #ifdef DEBUG + fprintf(stderr, "%s: fileOpenTimeOut has occurred.\n", appName); + #endif + break; + } + + XtDispatchEvent(&event); + } XtFree(commandString); + XtCloseDisplay(TheDisplay); + exit(0); return 0; *************** *** 227,234 **** /* ! ** Xt timer procedure for timeouts on NEdit server requests */ ! static void deadServerTimerProc(XtPointer clientData, XtIntervalId *id) ! { ! startServer("No servers responding, start one (yes)? ", (char *)clientData); ! exit(0); } --- 431,438 ---- /* ! ** Xt timer procedure for timeouts on NEdit server startup */ ! static void timeOutProc(Boolean *timeOutReturn, XtIntervalId *id) ! { ! /* Flag that the timeout has occurred. */ ! *timeOutReturn = True; } *************** *** 238,242 **** */ ! static void startServer(char *message, char *commandLineArgs) { char c, *commandLine; #ifdef VMS --- 442,447 ---- */ ! static int startServer(char *message, char *commandLineArgs) { char c, *commandLine; + char *display_string; #ifdef VMS *************** *** 256,265 **** if (c != 'Y' && c != 'y' && c != '\n') ! return; } /* start the server */ ! commandLine = XtMalloc(strlen(Preferences.serverCmd) + ! strlen(commandLineArgs) + 3); #ifdef VMS ! sprintf(commandLine, "%s %s", Preferences.serverCmd, commandLineArgs); cmdDesc = NulStrToDesc(commandLine); /* build command descriptor */ --- 461,482 ---- if (c != 'Y' && c != 'y' && c != '\n') ! return False; } + /* get the display value to pass to nedit */ + display_string = DisplayString(TheDisplay); + /* start the server */ ! commandLine = XtMalloc( ! strlen(Preferences.serverCmd) + ! strlen(" -display ") + ! strlen(display_string) + ! strlen(" -svrname ") + ! strlen(Preferences.serverName) + ! strlen(commandLineArgs) + ! 512/* some extra space to cover the whitespace and other chars ! we may add in the future to the command in the sprintf ! below */ ! ); #ifdef VMS ! sprintf(commandLine, "%s -display \"%s\" -svrname \"%s\" %s", Preferences.serverCmd, display_string, Preferences.serverName, commandLineArgs); cmdDesc = NulStrToDesc(commandLine); /* build command descriptor */ *************** *** 270,272 **** fprintf(stderr, "Nedit server not started.\n"); ! return; } --- 487,489 ---- fprintf(stderr, "Nedit server not started.\n"); ! return False; } *************** *** 274,276 **** #else ! sprintf(commandLine, "%s %s&", Preferences.serverCmd, commandLineArgs); system(commandLine); --- 491,493 ---- #else ! sprintf(commandLine, "%s -display \"%s\" -svrname \"%s\" %s", Preferences.serverCmd, display_string, Preferences.serverName, commandLineArgs); system(commandLine); *************** *** 278,279 **** --- 495,497 ---- XtFree(commandLine); + return True; } *************** *** 313,315 **** if (nRead != 1) ! fprintf(stderr, "nc: argument to line should be a number\n"); else --- 531,533 ---- if (nRead != 1) ! fprintf(stderr, "%s: argument to line should be a number\n", appName); else *************** *** 319,321 **** if (nRead != 1) ! fprintf(stderr, "nc: argument to + should be a number\n"); else --- 537,539 ---- if (nRead != 1) ! fprintf(stderr, "%s: argument to + should be a number\n", appName); else *************** *** 326,330 **** #endif /*VMS*/ ! fprintf(stderr, "nc: Unrecognized option %s\n%s", argv[i], cmdLineHelp); ! exit(0); } else { --- 544,549 ---- #endif /*VMS*/ ! fprintf(stderr, "%s: Unrecognized option %s\n%s", appName, argv[i], cmdLineHelp); ! XtCloseDisplay(TheDisplay); ! exit(1); } else { *************** *** 351,352 **** --- 570,574 ---- free(nameList[j]); + + /* Create the file open atoms for the paths supplied */ + addFileToFileOpenList(path); } *************** *** 369,370 **** --- 591,595 ---- *outPtr++ = '\n'; + + /* Create the file open atoms for the paths supplied */ + addFileToFileOpenList(path); #endif *************** *** 379,441 **** - /* - ** Return a pointer to the username of the current user in a statically - ** allocated string. - */ - static char *getUserName(void) - { - #ifdef VMS - return cuserid(NULL); - #else - /* This should be simple, but cuserid has apparently been dropped from - the ansi C standard, and if strict ansi compliance is turned on (on - Sun anyhow, maybe others), calls to cuserid fail to compile. - Unfortunately the alternative is this weird sequence of getlogin - followed by getpwuid. Getlogin only works if a terminal is attached & - there can be more than one name associated with a uid (really?). Both - calls return a pointer to a static area. */ - char *name; - struct passwd *passwdEntry; - - name = getlogin(); - if (name == NULL || name[0] == '\0') { - passwdEntry = getpwuid(getuid()); - name = passwdEntry->pw_name; - } - return name; - #endif - } - - /* - ** Writes the hostname of the current system in string "hostname". - */ - static void getHostName(char *hostname) - { - #ifdef VMS - /* This should be simple, but uname is not supported in the DEC C RTL and - gethostname on VMS depends either on Multinet or UCX. So use uname - on Unix, and use LIB$GETSYI on VMS. Note the VMS hostname will - be in DECNET format with trailing double colons, e.g. "FNALV1::". */ - int syi_status; - struct dsc$descriptor_s *hostnameDesc; - unsigned long int syiItemCode = SYI$_NODENAME; /* get Nodename */ - unsigned long int unused = 0; - unsigned short int hostnameLen = MAXNODENAMELEN+1; - - hostnameDesc = NulStrWrtDesc(hostname, MAXNODENAMELEN+1); - syi_status = lib$getsyi(&syiItemCode, &unused, hostnameDesc, &hostnameLen, - 0, 0); - if (syi_status != SS$_NORMAL) { - fprintf(stderr, "Error return from lib$getsyi: %d", syi_status); - strcpy(hostname, "VMS"); - } else - hostname[hostnameLen] = '\0'; - FreeStrDesc(hostnameDesc); - #else - struct utsname nameStruct; - - uname(&nameStruct); - strcpy(hostname, nameStruct.nodename); - #endif - } - static void nextArg(int argc, char **argv, int *argIndex) --- 604,605 ---- *************** *** 448,449 **** --- 612,614 ---- cmdLineHelp); + XtCloseDisplay(TheDisplay); exit(1); *** nedit.c 1997/09/26 18:28:17 1.1 --- nedit.c 1997/10/24 00:54:17 1.5 *************** *** 28,32 **** *******************************************************************************/ #include #include ! #ifdef USE_XMIM #include --- 28,33 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_X11_XLOCALE_H #include *************** *** 60,61 **** --- 61,63 ---- #include "macro.h" + #include "server_common.h" #include "server.h" *************** *** 80,92 **** "*foreground: black", ! "*statsLine.background: #b3b3b3", ! "*text.background: #e5e5e5", ! "*text.foreground: black", ! "*text.highlightBackground: red", ! "*text.highlightForeground: black", "*XmText*foreground: black", "*XmText*background: #cccccc", - "*helpText.background: #cccccc", - "*helpText.foreground: black", - "*helpText.selectBackground: #b3b3b3", - "*helpText.font: -adobe-courier-medium-r-normal-*-14-*-*-*-*-*-*-*", "*XmText.translations: #override \ --- 82,100 ---- "*foreground: black", ! "*mainForm.spacing: 0", ! "*mainForm.marginWidth: 0", ! "*mainForm.marginHeight: 0", ! "*statsLine.shadowThickness: 1", ! "*statsLine.marginHeight: 1", ! "*iSearchLabel.labelString: Search:", ! "*iSearchText.shadowThickness: 1", ! "*iSearchText.marginHeight: 1", ! "*iSearchText.translations: #override \ ! ShiftReturn: activate()\n", ! "*NEditText*background: #e5e5e5", ! "*NEditText*foreground: black", ! "*NEditText*highlightBackground: red", ! "*NEditText*highlightForeground: black", ! "*NEditText*font: -adobe-courier-medium-r-normal-*-14-*-*-*-*-*-*-*", "*XmText*foreground: black", "*XmText*background: #cccccc", "*XmText.translations: #override \ *************** *** 99,100 **** --- 107,109 ---- "*XmTextField*foreground: black", + "*.multiClickTime: 350", "*fileMenu.tearOffModel: XmTEAR_OFF_ENABLED", *************** *** 160,161 **** --- 169,176 ---- "*searchMenu.findShift.accelerator: Shift Ctrlf", + "*searchMenu.findIncremental.accelerator: Ctrlt", + "*searchMenu.findIncremental.acceleratorText: [Shift]Ctrl+T", + "*searchMenu.findIncrementalShift.accelerator: Shift Ctrlt", + "*searchMenu.findReplace.accelerator: Ctrlr", + "*searchMenu.findReplace.acceleratorText: [Shift]Ctrl+R", + "*searchMenu.findReplaceShift.accelerator: Shift Ctrlr", "*searchMenu.findAgain.accelerator: Ctrlg", *************** *** 169,173 **** "*searchMenu.replaceShift.accelerator: Shift Ctrlr", ! "*searchMenu.replaceAgain.accelerator: Ctrlt", ! "*searchMenu.replaceAgain.acceleratorText: [Shift]Ctrl+T", ! "*searchMenu.replaceAgainShift.accelerator: Shift Ctrlt", "*searchMenu.gotoLineNumber.accelerator: Ctrll", --- 184,191 ---- "*searchMenu.replaceShift.accelerator: Shift Ctrlr", ! "*searchMenu.replaceAgain.accelerator: Altt", ! "*searchMenu.replaceAgain.acceleratorText: [Shift]Alt+T", ! "*searchMenu.replaceAgainShift.accelerator: Shift Altt", ! "*searchMenu.replaceFindAgain.accelerator: ", ! "*searchMenu.replaceFindAgain.acceleratorText: ", ! "*searchMenu.replaceFindAgainShift.accelerator: ", "*searchMenu.gotoLineNumber.accelerator: Ctrll", *************** *** 181,184 **** "*searchMenu.gotoMarkShift.accelerator: Shift Altg", ! "*searchMenu.match.accelerator: Ctrlm", ! "*searchMenu.match.acceleratorText: Ctrl+M", "*searchMenu.findDefinition.accelerator: Ctrld", --- 199,204 ---- "*searchMenu.gotoMarkShift.accelerator: Shift Altg", ! "*searchMenu.match.accelerator: Shift Ctrlm", ! "*searchMenu.match.acceleratorText: Shift+Ctrl+M", ! "*searchMenu.gotoMatching.accelerator: Ctrlm", ! "*searchMenu.gotoMatching.acceleratorText: Ctrl+M", "*searchMenu.findDefinition.accelerator: Ctrld", *************** *** 213,214 **** --- 233,236 ---- "*windowsMenu.splitWindow.acceleratorText: Ctrl+2", + "*windowsMenu.cloneWindow.accelerator: Ctrl3", + "*windowsMenu.cloneWindow.acceleratorText: Ctrl+3", "*windowsMenu.closePane.accelerator: Ctrl1", *************** *** 216,217 **** --- 238,241 ---- "*helpMenu.mnemonic: H", + "*iSearchCaseToggle.labelString: Case", + "*iSearchRegExpToggle.labelString: RegEx", 0 *************** *** 231,232 **** --- 255,258 ---- + int isServer = FALSE; + int main(int argc, char **argv) *************** *** 234,236 **** int i, lineNum, nRead, fileSpecified = FALSE, editFlags = CREATE; ! int isServer = FALSE, gotoLine = False, macroFileRead = False; char *stoppedAt, *errMsg, *toDoCommand = NULL, *doPtr; --- 260,262 ---- int i, lineNum, nRead, fileSpecified = FALSE, editFlags = CREATE; ! int gotoLine = False, macroFileRead = False; char *stoppedAt, *errMsg, *toDoCommand = NULL, *doPtr; *************** *** 240,244 **** XrmDatabase prefDB; ! #ifdef USE_XMIM /* Set local for C library and X, and Motif input functions */ --- 266,271 ---- XrmDatabase prefDB; + WindowInfo *window = NULL; ! #ifdef HAVE_X11_XLOCALE_H /* Set local for C library and X, and Motif input functions */ *************** *** 253,254 **** --- 280,282 ---- } + #ifdef HAVE_XSUPPORTSLOCALE if (!XSupportsLocale()) { *************** *** 260,261 **** --- 288,290 ---- fprintf(stderr,"NEdit: cannot set locale modifiers.\n"); + #endif #else *************** *** 372,385 **** for (j = 0; j < numFiles; ++j) { ! ParseFilename(nameList[j], filename, pathname); ! EditExistingFile(WindowList, filename, pathname, editFlags); ! if (!macroFileRead) { ! ReadMacroInitFile(WindowList); ! macroFileRead = True; ! } ! if (toDoCommand != NULL) ! DoMacro(WindowList, toDoCommand); ! if (gotoLine) ! SelectNumberedLine(WindowList, lineNum); ! fileSpecified = TRUE; ! free(nameList[j]); } --- 401,414 ---- for (j = 0; j < numFiles; ++j) { ! ParseFilename(nameList[j], filename, pathname); ! window = EditExistingFile(WindowList, filename, pathname, editFlags, False); ! if (!macroFileRead) { ! ReadMacroInitFile(window); ! macroFileRead = True; ! } ! if (toDoCommand != NULL) ! DoMacro(window, toDoCommand); ! if (gotoLine) ! SelectNumberedLine(window, lineNum); ! fileSpecified = TRUE; ! free(nameList[j]); } *************** *** 389,391 **** ParseFilename(argv[i], filename, pathname); ! EditExistingFile(WindowList, filename, pathname, editFlags); fileSpecified = TRUE; --- 418,420 ---- ParseFilename(argv[i], filename, pathname); ! window = EditExistingFile(WindowList, filename, pathname, editFlags, False); fileSpecified = TRUE; *************** *** 396,400 **** if (toDoCommand != NULL) ! DoMacro(WindowList, toDoCommand); if (gotoLine) ! SelectNumberedLine(WindowList, lineNum); #endif /*VMS*/ --- 425,429 ---- if (toDoCommand != NULL) ! DoMacro(window, toDoCommand); if (gotoLine) ! SelectNumberedLine(window, lineNum); #endif /*VMS*/ *************** *** 415,422 **** if (!fileSpecified) { ! EditNewFile(); ! ReadMacroInitFile(WindowList); ! if (toDoCommand != NULL) ! DoMacro(WindowList, toDoCommand); } ! /* Begin remembering last command invoked for "Repeat" menu item */ --- 444,451 ---- if (!fileSpecified) { ! window = EditNewFile(NULL); ! ReadMacroInitFile(window); ! if (toDoCommand != NULL) ! DoMacro(window, toDoCommand); } ! /* Begin remembering last command invoked for "Repeat" menu item */ *************** *** 425,428 **** /* Set up communication port and write ~/.nedit_server_process file */ ! if (isServer) ! InitServerCommunication(); --- 454,459 ---- /* Set up communication port and write ~/.nedit_server_process file */ ! if (isServer) { ! DaemonInit(); ! InitServerCommunication(GetPrefServerName()); ! } *** nedit.h 1997/09/26 18:28:17 1.1 --- nedit.h 1997/10/24 01:24:43 1.4 *************** *** 24,28 **** *******************************************************************************/ /* Tuning parameters */ ! #define SEARCHMAX 511 /* Maximum length of search/replace strings */ #define MAX_SEARCH_HISTORY 100 /* Maximum length of search string history */ --- 24,30 ---- *******************************************************************************/ + #ifndef _nedit_h_ + #define _nedit_h_ /* Tuning parameters */ ! #define SEARCHMAX 10239 /* Maximum length of search/replace strings */ #define MAX_SEARCH_HISTORY 100 /* Maximum length of search string history */ *************** *** 74,75 **** --- 76,89 ---- + typedef enum _CheckingMode { + CHECKING_MODE_DISABLED, + CHECKING_MODE_PROMPT_TO_RELOAD, + CHECKING_MODE_TAIL_MINUS_F + } CheckingMode; + + typedef enum _HighlightSyntaxMode { + HIGHLIGHT_SYNTAX_DISABLED, + HIGHLIGHT_SYNTAX_ENABLED_IF_KNOWN, + HIGHLIGHT_SYNTAX_ENABLED_ALL + } HighlightSyntaxMode; + #define CHARSET (XmStringCharSet)XmSTRING_DEFAULT_CHARSET *************** *** 118,121 **** --- 132,176 ---- + typedef struct _EditorInfo { + char filename[MAXPATHLEN]; /* name component of file being edited*/ + char path[MAXPATHLEN]; /* path component of file being edited*/ + int mtime; /* the st_mtime value from the last call to stat */ + int st_mode; /* the st_mode value from the last call to stat */ + CheckingMode checkingMode; + UndoInfo *undo; /* info for undoing last operation */ + UndoInfo *redo; /* info for redoing last undone op */ + textBuffer *buffer; /* holds the text being edited */ + int autoSaveCharCount; /* count of single characters typed + since last backup file generated */ + int autoSaveOpCount; /* count of editing operations "" */ + int undoOpCount; /* count of stored undo operations */ + int undoMemUsed; /* amount of memory (in bytes) + dedicated to the undo list */ + XtIntervalId flashTimeoutID; /* timer procedure id for getting rid + of highlighted matching paren. Non- + zero val. means highlight is drawn */ + int flashPos; /* position saved for erasing matching + paren highlight (if one is drawn) */ + Boolean filenameSet; /* is the window still "Untitled"? */ + Boolean fileChanged; /* has window been modified? */ + Boolean readOnly; /* is current file read only? */ + Boolean lockWrite; /* is Read Only selected in menu? */ + Boolean autoSave; /* is autosave turned on? */ + Boolean saveOldVersion; /* keep old version in filename.bck */ + Boolean overstrike; /* is overstrike mode turned on ? */ + Boolean showMatching; /* is paren matching mode on? */ + Boolean ignoreModify; /* ignore modifications to text area */ + char indentStyle; /* whether/how to auto indent */ + char wrapMode; /* line wrap style: NO_WRAP, + NEWLINE_WRAP or CONTINUOUS_WRAP */ + void *smartIndentData; /* compiled macros for smart indent */ + Atom fileOpenAtom; /* Atom used to tell nc that the file is still open */ + XtIntervalId tailMinusFTimeoutID; /* timer procedure id to monitor if the + file has changed */ + struct _WindowInfo *master; + } EditorInfo; + typedef struct _WindowInfo { struct _WindowInfo *next; + struct _WindowInfo *nextSlave; + EditorInfo *editorInfo; Widget shell; /* application shell of window */ *************** *** 124,127 **** --- 179,188 ---- Widget textPanes[MAX_PANES]; /* additional ones created on demand */ + int nPanes; /* number of additional text editing + areas, created by splitWindow */ Widget lastFocus; /* the last pane to have kbd. focus */ Widget statsLine; /* file stats information display */ + Widget iSearchForm; + Widget iSearchText; + Widget iSearchCaseToggle; + Widget iSearchRegExpToggle; Widget menuBar; *************** *** 138,157 **** Widget replaceBtn; Widget replaceInSelBtn; Widget replaceSearchTypeBox; - Widget findDlog; /* find dialog */ - Widget findText; /* find dialog setable widgets... */ - Widget findLiteralBtn; - Widget findCaseBtn; - Widget findRegExpBtn; - Widget findFwdBtn; - Widget findRevBtn; - Widget findKeepBtn; - Widget findBtns; Widget findBtn; - Widget findSearchTypeBox; Widget fontDialog; /* NULL, unless font dialog is up */ Widget readOnlyItem; /* menu bar setable widgets... */ - Widget autoSaveItem; - Widget saveLastItem; Widget closeItem; Widget printSelItem; --- 199,210 ---- Widget replaceBtn; + Widget replaceFindBtn; Widget replaceInSelBtn; Widget replaceSearchTypeBox; Widget findBtn; Widget fontDialog; /* NULL, unless font dialog is up */ Widget readOnlyItem; /* menu bar setable widgets... */ Widget closeItem; + Widget checkingModePromptToReloadItem; + Widget checkingModeDisabledItem; + Widget checkingModeTailMinusFItem; Widget printSelItem; *************** *** 162,164 **** Widget langModeCascade; - Widget findDefItem; Widget autoIndentOffItem; --- 215,216 ---- *************** *** 167,168 **** --- 219,221 ---- Widget noWrapItem; + Widget findDefItem; Widget newlineWrapItem; *************** *** 177,178 **** --- 230,239 ---- Widget filterItem; + Widget autoWrapItem; + Widget saveLastItem; + Widget autoSaveItem; + Widget showMatchingItem; + Widget overstrikeItem; + Widget statisticsLineItem; + Widget iSearchLineItem; + Widget highlightSyntaxItem; Widget autoIndentOffDefItem; *************** *** 192,193 **** --- 253,260 ---- Widget statsLineDefItem; + Widget iSearchLineDefItem; + Widget highlightSyntaxEnabledKnownDefItem; + Widget highlightSyntaxEnabledAllDefItem; + Widget highlightSyntaxDisabledDefItem; + Widget warnOnExitDefItem; + Widget allowReadOnlyEditsDefItem; Widget searchLiteralDefItem; *************** *** 200,201 **** --- 267,271 ---- Widget sizeCustomDefItem; + Widget checkingModePromptToReloadDefItem; + Widget checkingModeDisabledDefItem; + Widget checkingModeTailMinusFDefItem; Widget cancelShellItem; *************** *** 217,232 **** #endif - char filename[MAXPATHLEN]; /* name component of file being edited*/ - char path[MAXPATHLEN]; /* path component of file being edited*/ - int fileMode; /* permissions of file being edited */ - UndoInfo *undo; /* info for undoing last operation */ - UndoInfo *redo; /* info for redoing last undone op */ - textBuffer *buffer; /* holds the text being edited */ - int nPanes; /* number of additional text editing - areas, created by splitWindow */ - int autoSaveCharCount; /* count of single characters typed - since last backup file generated */ - int autoSaveOpCount; /* count of editing operations "" */ - int undoOpCount; /* count of stored undo operations */ - int undoMemUsed; /* amount of memory (in bytes) - dedicated to the undo list */ char fontName[MAX_FONT_LEN]; /* names of the text fonts in use */ --- 287,288 ---- *************** *** 239,259 **** XFontStruct *boldItalicFontStruct; - XtIntervalId flashTimeoutID; /* timer procedure id for getting rid - of highlighted matching paren. Non- - zero val. means highlight is drawn */ - int flashPos; /* position saved for erasing matching - paren highlight (if one is drawn) */ int wasSelected; /* last selection state (for dim/undim of selection related menu items */ - Boolean filenameSet; /* is the window still "Untitled"? */ - Boolean fileChanged; /* has window been modified? */ - Boolean readOnly; /* is current file read only? */ - Boolean lockWrite; /* is Read Only selected in menu? */ - Boolean autoSave; /* is autosave turned on? */ - Boolean saveOldVersion; /* keep old version in filename.bck */ - char indentStyle; /* whether/how to auto indent */ - char wrapMode; /* line wrap style: NO_WRAP, - NEWLINE_WRAP or CONTINUOUS_WRAP */ - Boolean overstrike; /* is overstrike mode turned on ? */ - Boolean showMatching; /* is paren matching mode on? */ Boolean showStats; /* is stats line supposed to be shown */ Boolean highlightSyntax; /* is syntax highlighting turned on? */ --- 295,300 ---- XFontStruct *boldItalicFontStruct; int wasSelected; /* last selection state (for dim/undim of selection related menu items */ Boolean showStats; /* is stats line supposed to be shown */ + Boolean showISearchLine; /* is the incremental search line supposed to be shown */ Boolean highlightSyntax; /* is syntax highlighting turned on? */ *************** *** 261,266 **** and shell command executing modes */ - Boolean ignoreModify; /* ignore modifications to text area */ Boolean windowMenuValid; /* is window menu is up to date? */ Boolean prevOpenMenuValid; /* Prev. Opened Files menu up to date?*/ ! int rHistIndex, fHistIndex; /* stupid globals for find and replace dialogs */ --- 302,306 ---- and shell command executing modes */ Boolean windowMenuValid; /* is window menu is up to date? */ Boolean prevOpenMenuValid; /* Prev. Opened Files menu up to date?*/ ! int rHistIndex; /* stupid globals for find and replace dialogs */ *************** *** 269,277 **** Bookmark markTable[MAX_MARKS]; /* marked locations in window */ ! void *highlightData; /* info for syntax highlighting */ ! void *shellCmdData; /* when a shell command is executing, info. about it, otherwise, NULL */ ! void *macroCmdData; /* same for macro commands */ ! void *smartIndentData; /* compiled macros for smart indent */ int languageMode; /* identifies language mode currently selected in the window */ } WindowInfo; --- 309,320 ---- Bookmark markTable[MAX_MARKS]; /* marked locations in window */ ! struct _windowHighlightData *highlightData; /* info for syntax highlighting */ ! void *shellCmdData; /* when a shell command is executing, info. about it, otherwise, NULL */ ! void *macroCmdData; /* same for macro commands */ int languageMode; /* identifies language mode currently selected in the window */ + int iSearchDirection; /* The incremental search direction */ + char iSearchLastSearchString[SEARCHMAX+1]; /* The last incremental search value */ + int iSearchLastSearchType; /* The last incremental search type */ + int iSearchHistIndex; /* The incremental search index into the search history */ } WindowInfo; *************** *** 280 **** --- 323,327 ---- extern Display *TheDisplay; + extern char serverName[]; + extern int isServer; + + #endif /* _nedit_h_ */ *** parse.y 1997/09/26 18:28:17 1.1 --- parse.y 1997/10/21 21:35:06 1.2 *************** *** 1,2 **** --- 1,3 ---- %{ + #include #include *** preferences.c 1997/09/26 18:28:17 1.1 --- preferences.c 1997/10/24 21:48:33 1.4 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 64,65 **** --- 65,67 ---- #include "smartIndent.h" + #include "server_common.h" *************** *** 79,85 **** #define N_WRAP_STYLES 3 ! static char *AutoWrapTypes[N_WRAP_STYLES+2] = {"None", "Newline", "Continuous", ! "True", "False"}; #define N_INDENT_STYLES 3 ! static char *AutoIndentTypes[N_INDENT_STYLES+2] = {"None", "Auto", ! "Smart", "True", "False"}; --- 81,89 ---- #define N_WRAP_STYLES 3 ! static char *AutoWrapTypes[] = {"None", "Newline", "Continuous", ! "True", "False", NULL}; #define N_INDENT_STYLES 3 ! static char *AutoIndentTypes[] = {"None", "Auto", ! "Smart", "True", "False", NULL}; ! char *CheckingModeTypes[] = {"Disabled", "Prompt", "Tail-f", NULL}; ! *************** *** 183,184 **** --- 187,197 ---- posting of background menu */ + int showISearchLine; /* whether to show the incremental search line */ + int warnOnExit; /* whether to warn about open files when exiting */ + int allowReadOnlyEdits; /* whether the text is editable if the file is not */ + int findReplaceUsesSelection; /* whether the find replace dialog is automatically + loaded with the primary selection */ + char backupSuffix[MAXPATHLEN]; /* The suffix to append to the file name to generate + the name of the backup file. */ + CheckingMode checkingMode; /* The default file checking mode */ + int tailMinusFInterval; /* interval to check for changes in the tail -f mode */ } PrefData; *************** *** 427,428 **** --- 440,442 ---- Tcl:Default\n\ + Sh Ksh Bash:Default\n\ Csh:Default\n\ *************** *** 442,443 **** --- 456,458 ---- Tcl:.tcl::::::\n\ + Sh Ksh Bash:.sh .ksh .bash:\"^#![^ \\t]*/(sh|ksh|bash)\":::::\n\ Csh:.csh:\"^[ \\t]*#[ \\t]*![ \\t]*/bin/csh\":::::\n\ *************** *** 464,465 **** --- 479,486 ---- Subroutine1:chocolate:Plain\n\ + Library Function:brown:Plain\n\ + Double Quoted String:SeaGreen:Plain\n\ + Single Quoted String:darkGreen:Plain\n\ + Escaped Items:SeaGreen:Plain\n\ + Delimiters:black:Plain\n\ + Operators:black:Plain\n\ Ada Attributes:plum:Bold\n\ *************** *** 494,496 **** &PrefData.searchDlogs, NULL, True}, ! {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "False", &PrefData.keepSearchDlogs, NULL, True}, --- 515,517 ---- &PrefData.searchDlogs, NULL, True}, ! {"retainSearchDialogs", "RetainSearchDialogs", PREF_BOOLEAN, "True", &PrefData.keepSearchDlogs, NULL, True}, *************** *** 533,535 **** PrefData.shell, (void *)sizeof(PrefData.shell), False}, ! {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "True", &PrefData.mapDelete, NULL, False}, --- 554,556 ---- PrefData.shell, (void *)sizeof(PrefData.shell), False}, ! {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False", &PrefData.mapDelete, NULL, False}, *************** *** 540,544 **** {"wordDelimiters", "WordDelimiters", PREF_STRING, ! ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?", PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False}, ! {"serverName", "serverName", PREF_STRING, "", PrefData.serverName, (void *)sizeof(PrefData.serverName), False}, --- 561,565 ---- {"wordDelimiters", "WordDelimiters", PREF_STRING, ! ".,/\\`'!|@#%^&*()-=+{}[]\":;<>?~", PrefData.delimiters, (void *)sizeof(PrefData.delimiters), False}, ! {"serverName", "serverName", PREF_STRING, DEFAULTSERVERNAME, PrefData.serverName, (void *)sizeof(PrefData.serverName), False}, *************** *** 553,554 **** --- 574,589 ---- #endif + {"searchLine", "SearchLine", PREF_BOOLEAN, "True", + &PrefData.showISearchLine, NULL, True}, + {"warnOnExit", "WarnOnExit", PREF_BOOLEAN, "True", + &PrefData.warnOnExit, NULL, True}, + {"allowReadOnlyEdits", "AllowReadOnlyEdits", PREF_BOOLEAN, "False", + &PrefData.allowReadOnlyEdits, NULL, True}, + {"findReplaceUsesSelection", "FindReplaceUsesSelection", PREF_BOOLEAN, "False", + &PrefData.findReplaceUsesSelection, NULL, False}, + {"backupSuffix", "BackupSuffix", PREF_STRING, + ".bck", PrefData.backupSuffix, (void *)sizeof(PrefData.backupSuffix), False}, + {"checkingMode", "CheckingMode", PREF_ENUM, "Prompt", + &PrefData.checkingMode, CheckingModeTypes, True}, + {"tailMinusFInterval", "TailMinusFInterval", PREF_INT, "1000"/*milliseconds*/, + &PrefData.tailMinusFInterval, NULL, False}, }; *************** *** 632,634 **** XtPointer callData); ! static void browseFont(Widget parent, Widget fontTextW); static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData); --- 667,669 ---- XtPointer callData); ! static void browseFont(Widget parent, Widget fontTextW, char *title); static void fontDestroyCB(Widget w, XtPointer clientData, XtPointer callData); *************** *** 677,679 **** XFontStruct *font; ! /* Load preferences */ --- 712,714 ---- XFontStruct *font; ! /* Load preferences */ *************** *** 767,769 **** --- 802,810 ---- { + WindowInfo *win; setIntPref(&PrefData.wrapStyle, state); + for (win=WindowList; win!=NULL; win=win->next) { + XmToggleButtonSetState(win->noWrapDefItem, state==NO_WRAP, False); + XmToggleButtonSetState(win->newlineWrapDefItem, state==NEWLINE_WRAP, False); + XmToggleButtonSetState(win->contWrapDefItem, state==CONTINUOUS_WRAP, False); + } } *************** *** 790,792 **** --- 831,839 ---- { + WindowInfo *win; setIntPref(&PrefData.searchMethod, searchType); + for (win=WindowList; win!=NULL; win=win->next){ + XmToggleButtonSetState(win->searchLiteralDefItem, searchType==SEARCH_LITERAL, False); + XmToggleButtonSetState(win->searchCaseSenseDefItem, searchType==SEARCH_CASE_SENSE, False); + XmToggleButtonSetState(win->searchRegexDefItem, searchType==SEARCH_REGEX, False); + } } *************** *** 800,802 **** --- 847,855 ---- { + WindowInfo *win; setIntPref(&PrefData.autoIndent, state); + for (win=WindowList; win!=NULL; win=win->next) { + XmToggleButtonSetState(win->autoIndentOffDefItem, state==NO_AUTO_INDENT, False); + XmToggleButtonSetState(win->autoIndentDefItem, state==AUTO_INDENT, False); + XmToggleButtonSetState(win->smartIndentDefItem, state==SMART_INDENT, False); + } } *************** *** 813,815 **** --- 866,871 ---- { + WindowInfo *win; setIntPref(&PrefData.autoSave, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->autoSaveDefItem, state, False); } *************** *** 823,825 **** --- 879,884 ---- { + WindowInfo *win; setIntPref(&PrefData.saveOldVersion, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->saveLastDefItem, state, False); } *************** *** 843,845 **** --- 902,907 ---- { + WindowInfo *win; setIntPref(&PrefData.keepSearchDlogs, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->keepSearchDlogsDefItem, state, False); } *************** *** 853,855 **** --- 915,920 ---- { + WindowInfo *win; setIntPref(&PrefData.statsLine, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->statsLineDefItem, state, False); } *************** *** 861,862 **** --- 926,977 ---- + void SetPrefShowISearchLine(int state) + { + WindowInfo *win; + setIntPref(&PrefData.showISearchLine, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->iSearchLineDefItem, state, False); + } + + int GetPrefShowISearchLine(void) + { + return PrefData.showISearchLine; + } + + void SetPrefWarnOnExit(int state) + { + WindowInfo *win; + setIntPref(&PrefData.warnOnExit, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->warnOnExitDefItem, state, False); + } + + int GetPrefWarnOnExit(void) + { + return PrefData.warnOnExit; + } + + void SetPrefAllowReadOnlyEdits(int state) + { + WindowInfo *win; + setIntPref(&PrefData.allowReadOnlyEdits, state); + for (win=WindowList; win!=NULL; win=win->next) { + XmToggleButtonSetState(win->allowReadOnlyEditsDefItem, state, False); + } + } + + int GetPrefAllowReadOnlyEdits(void) + { + return PrefData.allowReadOnlyEdits; + } + + void SetPrefFindReplaceUsesSelection(int state) + { + setIntPref(&PrefData.findReplaceUsesSelection, state); + } + + int GetPrefFindReplaceUsesSelection(void) + { + return PrefData.findReplaceUsesSelection; + } + void SetPrefMapDelete(int state) *************** *** 939,941 **** --- 1054,1059 ---- { + WindowInfo *win; setIntPref(&PrefData.showMatching, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->showMatchingDefItem, state, False); } *************** *** 949,951 **** --- 1067,1074 ---- { + WindowInfo *win; setIntPref(&PrefData.highlightSyntax, state); + for (win=WindowList; win!=NULL; win=win->next) { + XmToggleButtonSetState(win->highlightOffDefItem, state==False, False); + XmToggleButtonSetState(win->highlightDefItem, state==True, False); + } } *************** *** 959,961 **** --- 1082,1087 ---- { + WindowInfo *win; setIntPref(&PrefData.repositionDialogs, state); + for (win=WindowList; win!=NULL; win=win->next) + XmToggleButtonSetState(win->reposDlogsDefItem, state, False); } *************** *** 977,978 **** --- 1103,1124 ---- + void SetPrefBackupSuffix(char *suffix) + { + strcpy(PrefData.backupSuffix, suffix); + } + + char *GetPrefBackupSuffix(void) + { + char *start; + char *end; + + /* remove leading and trailing whitespace */ + for(start = PrefData.backupSuffix; *start && isspace(*start); start++) { + } + for(end = start + strlen(start) - 1; end >= start && isspace(*end); end--) { + } + end++; + *end = 0; + return start; + } + char *GetPrefDelimiters(void) *************** *** 1084,1085 **** --- 1230,1260 ---- + void SetPrefCheckingMode(CheckingMode checkingMode) + { + WindowInfo *win; + setIntPref((int*)&PrefData.checkingMode, (int)checkingMode); + for (win=WindowList; win!=NULL; win=win->next) { + XmToggleButtonSetState(win->checkingModePromptToReloadDefItem, + checkingMode == CHECKING_MODE_PROMPT_TO_RELOAD, False); + XmToggleButtonSetState(win->checkingModeDisabledDefItem, + checkingMode == CHECKING_MODE_DISABLED, False); + XmToggleButtonSetState(win->checkingModeTailMinusFDefItem, + checkingMode == CHECKING_MODE_TAIL_MINUS_F, False); + } + } + + CheckingMode GetPrefCheckingMode(void) + { + return PrefData.checkingMode; + } + + void SetPrefTailMinusFInterval(int interval) + { + setIntPref(&PrefData.tailMinusFInterval, interval); + } + + int GetPrefTailMinusFInterval(void) + { + return PrefData.tailMinusFInterval; + } + /* *************** *** 1106,1108 **** "Default Preferences have changed.\nSave changes to .nedit file?", ! "Save", "Don't Save", "Cancel"); if (resp == 2) --- 1281,1283 ---- "Default Preferences have changed.\nSave changes to .nedit file?", ! "Save Preferences", "Don't Save", "Cancel"); if (resp == 2) *************** *** 1153,1160 **** /* Select the correct language mode in the sub-menu */ ! XtVaGetValues(window->langModeCascade, XmNsubMenuId, &menu, 0); ! XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems,0); ! for (n=0; nlangModeCascade, XmNsubMenuId, &menu, 0); ! XtVaGetValues(menu, XmNchildren, &items, XmNnumChildren, &nItems,0); ! for (n=0; ntextArea, textNemulateTabs, &emTabDist, 0); ! useTabs = forWindow->buffer->useTabs; ! tabDist = BufGetTabDistance(forWindow->buffer); } --- 1543,1546 ---- XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, 0); ! useTabs = forWindow->editorInfo->buffer->useTabs; ! tabDist = BufGetTabDistance(forWindow->editorInfo->buffer); } *************** *** 1450,1452 **** setEmTabDist(window, emTabDist); ! window->buffer->useTabs = useTabs; } --- 1625,1627 ---- setEmTabDist(window, emTabDist); ! window->editorInfo->buffer->useTabs = useTabs; } *************** *** 1457,1462 **** { ! if (window->buffer->tabDist != tabDist) { ! window->ignoreModify = True; ! BufSetTabDistance(window->buffer, tabDist); ! window->ignoreModify = False; } --- 1632,1637 ---- { ! if (window->editorInfo->buffer->tabDist != tabDist) { ! window->editorInfo->ignoreModify = True; ! BufSetTabDistance(window->editorInfo->buffer, tabDist); ! window->editorInfo->ignoreModify = False; } *************** *** 1793,1794 **** --- 1968,1970 ---- overrideFrame, 0); + #if XmVersion >= 1002 overrideLbl = XtVaCreateManagedWidget("overrideLbl", xmLabelGadgetClass, *************** *** 1799,1800 **** --- 1975,1977 ---- XmStringFree(s1); + #endif *************** *** 2462,2463 **** --- 2639,2641 ---- primaryFrame, 0); + #if XmVersion >= 1002 primaryLbl = XtVaCreateManagedWidget("primaryFont", xmLabelGadgetClass, *************** *** 2469,2470 **** --- 2647,2649 ---- XmStringFree(s1); + #endif *************** *** 2507,2508 **** --- 2686,2688 ---- highlightFrame, 0); + #if XmVersion >= 1002 highlightLbl = XtVaCreateManagedWidget("highlightFonts", xmLabelGadgetClass, *************** *** 2514,2515 **** --- 2694,2696 ---- XmStringFree(s1); + #endif *************** *** 2806,2808 **** ! browseFont(fd->shell, fd->primaryW); } --- 2987,2989 ---- ! browseFont(fd->shell, fd->primaryW, "Primary Font Selector"); } *************** *** 2812,2814 **** ! browseFont(fd->shell, fd->italicW); } --- 2993,2995 ---- ! browseFont(fd->shell, fd->italicW, "Italic Font Selector"); } *************** *** 2818,2820 **** ! browseFont(fd->shell, fd->boldW); } --- 2999,3001 ---- ! browseFont(fd->shell, fd->boldW, "Bold Font Selector"); } *************** *** 2825,2827 **** ! browseFont(fd->shell, fd->boldItalicW); } --- 3006,3008 ---- ! browseFont(fd->shell, fd->boldItalicW, "Bold Italic Font Selector"); } *************** *** 2935,2937 **** */ ! static void browseFont(Widget parent, Widget fontTextW) { --- 3116,3118 ---- */ ! static void browseFont(Widget parent, Widget fontTextW, char *title) { *************** *** 2940,2942 **** origFontName = XmTextGetString(fontTextW); ! newFontName = FontSel(parent, PREF_FIXED, origFontName); XtFree(origFontName); --- 3121,3123 ---- origFontName = XmTextGetString(fontTextW); ! newFontName = FontSel(parent, PREF_FIXED, origFontName, title); XtFree(origFontName); *************** *** 3006,3014 **** otherwise, leave it alone */ ! wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode); ! tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode); XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, 0); emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode); ! indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) || (GetPrefAutoIndent(oldMode) == SMART_INDENT && ! window->indentStyle == AUTO_INDENT && !SmartIndentMacrosAvailable(LanguageModeName(oldMode))); --- 3187,3195 ---- otherwise, leave it alone */ ! wrapModeIsDef = window->editorInfo->wrapMode == GetPrefWrap(oldMode); ! tabDistIsDef = BufGetTabDistance(window->editorInfo->buffer) == GetPrefTabDist(oldMode); XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, 0); emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode); ! indentStyleIsDef = window->editorInfo->indentStyle == GetPrefAutoIndent(oldMode) || (GetPrefAutoIndent(oldMode) == SMART_INDENT && ! window->editorInfo->indentStyle == AUTO_INDENT && !SmartIndentMacrosAvailable(LanguageModeName(oldMode))); *************** *** 3018,3022 **** wrapMode = wrapModeIsDef || forceDefaults ? ! GetPrefWrap(mode) : window->wrapMode; tabDist = tabDistIsDef || forceDefaults ? ! GetPrefTabDist(mode) : BufGetTabDistance(window->buffer); emTabDist = emTabDistIsDef || forceDefaults ? --- 3199,3203 ---- wrapMode = wrapModeIsDef || forceDefaults ? ! GetPrefWrap(mode) : window->editorInfo->wrapMode; tabDist = tabDistIsDef || forceDefaults ? ! GetPrefTabDist(mode) : BufGetTabDistance(window->editorInfo->buffer); emTabDist = emTabDistIsDef || forceDefaults ? *************** *** 3024,3026 **** indentStyle = indentStyleIsDef || forceDefaults ? ! GetPrefAutoIndent(mode) : window->indentStyle; highlight = highlightIsDef || forceDefaults ? --- 3205,3207 ---- indentStyle = indentStyleIsDef || forceDefaults ? ! GetPrefAutoIndent(mode) : window->editorInfo->indentStyle; highlight = highlightIsDef || forceDefaults ? *************** *** 3042,3044 **** window->highlightSyntax = highlight; - XmToggleButtonSetState(window->highlightItem, highlight, False); StopHighlighting(window); --- 3223,3224 ---- *************** *** 3048,3052 **** /* Force a change of smart indent macros (SetAutoIndent will re-start) */ ! if (window->indentStyle == SMART_INDENT) { EndSmartIndent(window); ! window->indentStyle = AUTO_INDENT; } --- 3228,3232 ---- /* Force a change of smart indent macros (SetAutoIndent will re-start) */ ! if (window->editorInfo->indentStyle == SMART_INDENT) { EndSmartIndent(window); ! window->editorInfo->indentStyle = AUTO_INDENT; } *************** *** 3077,3080 **** /* Do a regular expression search on for recognition pattern */ ! first200 = BufGetRange(window->buffer, 0, 200); for (i=0; ieditorInfo->buffer, + LanguageModes[i].languageSearchList[j].startLine, + LanguageModes[i].languageSearchList[j].endLine); + found = SearchString(string, LanguageModes[i].languageSearchList[j].searchRE, + SEARCH_FORWARD, SEARCH_REGEX, FALSE, 0, &startPos, &endPos); + XtFree(string); + if(found) { + fileMode = i; + break; + } + } + if(fileMode != -1) + break; + } + #endif + /* Do a regular expression search on for recognition pattern */ ! first200 = BufGetRange(window->editorInfo->buffer, 0, 200); for (i=0; ifilename); for (i=0; ieditorInfo->filenameSet) + return PLAIN_LANGUAGE_MODE; + /* Look at file extension */ ! fileNameLen = strlen(window->editorInfo->filename); for (i=0; i= 0 && !strcmp(&window->filename[start], ext)) return i; --- 3304,3306 ---- start = fileNameLen - strlen(ext); ! if (start >= 0 && !strcmp(&window->editorInfo->filename[start], ext)) return i; *** preferences.h 1997/09/26 18:28:17 1.1 --- preferences.h 1997/10/14 05:03:04 1.3 *************** *** 48,49 **** --- 48,57 ---- int GetPrefStatsLine(void); + void SetPrefShowISearchLine(int state); + int GetPrefShowISearchLine(); + void SetPrefWarnOnExit(int state); + int GetPrefWarnOnExit(void); + void SetPrefAllowReadOnlyEdits(int state); + int GetPrefAllowReadOnlyEdits(); + void SetPrefFindReplaceUsesSelection(int state); + int GetPrefFindReplaceUsesSelection(void); void SetPrefSearch(int searchType); *************** *** 74,75 **** --- 82,85 ---- char *GetPrefTagFile(void); + void SetPrefBackupSuffix(char *suffix); + char *GetPrefBackupSuffix(void); void SetPrefFont(char *fontName); *************** *** 124 **** --- 134,138 ---- char *label, char mnemonic); + void SetPrefCheckingMode(CheckingMode checkingMode); + CheckingMode GetPrefCheckingMode(void); + void SetPrefTailMinusFInterval(int interval); + int GetPrefTailMinusFInterval(void); *** regularExp.c 1997/09/26 18:28:17 1.1 --- regularExp.c 1997/10/10 00:15:13 1.2 *************** *** 35,36 **** --- 35,37 ---- */ + #include #include *************** *** 290,292 **** register char *ender; ! register int parno; int flags; --- 291,293 ---- register char *ender; ! register int parno = 0; int flags; *************** *** 318,319 **** --- 319,322 ---- regparse++; + if (*regparse == ')' || *regparse == '|') + FAIL("empty alternative"); br = regbranch(&flags); *************** *** 902,904 **** } ! if (!isdelimiter[*(reginput-1)]) return(0); --- 905,907 ---- } ! if (!isdelimiter[(unsigned char)(*(reginput-1))]) return(0); *************** *** 906,908 **** case EOWORD: ! if (!isdelimiter[*reginput]) return(0); --- 909,911 ---- case EOWORD: ! if (!isdelimiter[(unsigned char)(*reginput)]) return(0); *** regularExp.h 1997/09/26 18:28:17 1.1 --- regularExp.h 1997/10/10 00:15:13 1.2 *************** *** 6,8 **** */ ! #define NSUBEXP 40 typedef struct regexp { --- 6,8 ---- */ ! #define NSUBEXP 50 typedef struct regexp { *** search.c 1997/09/26 18:28:17 1.1 --- search.c 1997/10/10 00:15:13 1.2 *************** *** 24,25 **** --- 24,27 ---- *******************************************************************************/ + #include + #include #include *************** *** 39,40 **** --- 41,43 ---- #include + #include #include *************** *** 56,57 **** --- 59,66 ---- + typedef struct _SelectionInfo { + int done; + WindowInfo* window; + char* selection; + } SelectionInfo; + /* History mechanism for search and replace strings */ *************** *** 63,70 **** static void createReplaceDlog(Widget parent, WindowInfo *window); - static void createFindDlog(Widget parent, WindowInfo *window); - static void fFocusCB(Widget w, WindowInfo *window, caddr_t *callData); static void rFocusCB(Widget w, WindowInfo *window, caddr_t *callData); static void rKeepCB(Widget w, WindowInfo *window, caddr_t *callData); - static void fKeepCB(Widget w, WindowInfo *window, caddr_t *callData); static void replaceCB(Widget w, WindowInfo *window, --- 72,78 ---- + static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *selection, + Atom *type, char *value, int *length, int *format); static void createReplaceDlog(Widget parent, WindowInfo *window); static void rFocusCB(Widget w, WindowInfo *window, caddr_t *callData); static void rKeepCB(Widget w, WindowInfo *window, caddr_t *callData); static void replaceCB(Widget w, WindowInfo *window, *************** *** 76,83 **** static void rCancelCB(Widget w, WindowInfo *window, caddr_t callData); - static void fCancelCB(Widget w, WindowInfo *window, caddr_t callData); static void rFindCB(Widget w,WindowInfo *window,XmAnyCallbackStruct *callData); static void rFindArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event); static void replaceArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event); - static void findArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event); - static void findCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData); static void flashTimeoutProc(XtPointer clientData, XtIntervalId *id); --- 84,93 ---- static void rCancelCB(Widget w, WindowInfo *window, caddr_t callData); static void rFindCB(Widget w,WindowInfo *window,XmAnyCallbackStruct *callData); + static void iSearchTextActivateCB(Widget w,WindowInfo *window,XmAnyCallbackStruct *callData); + static void iSearchTextValueChangedCB(Widget w,WindowInfo *window,XmAnyCallbackStruct *callData); + static void iSearchTextArrowKeyEH(Widget w, WindowInfo *window, XKeyEvent *event); + static void replaceFindCB(Widget w, WindowInfo *window, + XmAnyCallbackStruct *callData); static void rFindArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event); static void replaceArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event); static void flashTimeoutProc(XtPointer clientData, XtIntervalId *id); *************** *** 86,89 **** char *searchString, char *replaceString, int *searchType); - static int getFindDlogInfo(WindowInfo *window, int *direction, - char *searchString, int *searchType); static void selectedSearchCB(Widget w, XtPointer callData, Atom *selection, --- 96,97 ---- *************** *** 100,102 **** static void downCaseString(char *outString, char *inString); - static void resetFindTabGroup(WindowInfo *window); static void resetReplaceTabGroup(WindowInfo *window); --- 108,109 ---- *************** *** 104,111 **** int searchType, int *left, int *right); ! static int findMatchingChar(textBuffer *buf, char toMatch, int charPos, ! int startLimit, int endLimit, int *matchPos); static void replaceUsingRE(char *searchStr, char *replaceStr, char *sourceStr, char *destStr, int maxDestLen, char *delimiters); - static void saveSearchHistory(char *searchString, char *replaceString, - int searchType); static int historyIndex(int nCycles); --- 111,116 ---- int searchType, int *left, int *right); ! static int findMatchingChar(textBuffer *buf, int charPos,int startLimit, ! int endLimit, int *matchBeginPos, int *matchPos); static void replaceUsingRE(char *searchStr, char *replaceStr, char *sourceStr, char *destStr, int maxDestLen, char *delimiters); static int historyIndex(int nCycles); *************** *** 117,144 **** typedef struct _charMatchTable { ! char c; ! char match; ! char direction; } charMatchTable; ! #define N_MATCH_CHARS 13 ! #define N_FLASH_CHARS 6 ! static charMatchTable MatchingChars[N_MATCH_CHARS] = { ! {'{', '}', SEARCH_FORWARD}, ! {'}', '{', SEARCH_BACKWARD}, ! {'(', ')', SEARCH_FORWARD}, ! {')', '(', SEARCH_BACKWARD}, ! {'[', ']', SEARCH_FORWARD}, ! {']', '[', SEARCH_BACKWARD}, ! {'<', '>', SEARCH_FORWARD}, ! {'>', '<', SEARCH_BACKWARD}, ! {'/', '/', SEARCH_FORWARD}, ! {'"', '"', SEARCH_FORWARD}, ! {'\'', '\'', SEARCH_FORWARD}, ! {'`', '`', SEARCH_FORWARD}, ! {'\\', '\\', SEARCH_FORWARD}, }; ! void DoReplaceDlog(WindowInfo *window, int direction) { ! Widget button; --- 122,148 ---- typedef struct _charMatchTable { ! char begin; ! char end; } charMatchTable; ! static charMatchTable MatchingChars[] = { ! {'{', '}'}, ! {'(', ')'}, ! {'[', ']'}, ! {'<', '>'}, ! {'"', '"'}, ! {'\'', '\''}, ! {'`', '`'}, ! #if 0 ! {'/', '/'}, ! {'\\', '\\'}, ! #endif ! {0, 0} }; ! void DoFindReplaceDlog(WindowInfo *window, int direction, FindReplaceDlogDefaultButton defaultButton, Time time) { ! FindReplaceDlogDefaultButton oldDefaultButton; ! Widget newDefaultButtonWidget; ! XEvent nextEvent; ! char *primary_selection = 0; *************** *** 148,157 **** /* If the window is already up, just pop it to the top */ if (XtIsManaged(window->replaceDlog)) { ! XMapRaised(TheDisplay, XtWindow(XtParent(window->replaceDlog))); ! XSetInputFocus(TheDisplay, XtWindow(XtParent(window->replaceDlog)), ! RevertToParent, CurrentTime); ! return; } /* Set the initial search type */ --- 152,212 ---- + if(GetPrefFindReplaceUsesSelection()) { + SelectionInfo selectionInfo; + + selectionInfo.done = 0; + selectionInfo.window = window; + selectionInfo.selection = 0; + XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, + (XtSelectionCallbackProc)getSelectionCB, &selectionInfo, time); + while (selectionInfo.done == 0) { + XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), &nextEvent); + XtDispatchEvent(&nextEvent); + } + primary_selection = selectionInfo.selection; + } + if(primary_selection == 0) { + primary_selection = XtNewString(""); + } + + /* Update the String to find field */ + XmTextSetString(window->replaceText, primary_selection); + + XtVaGetValues(window->findBtn, XmNuserData, &oldDefaultButton, 0); + + /* Use the userData field of the find button to keep track of the + current default button */ + SET_ONE_RSRC(window->findBtn, XmNuserData, defaultButton); + + newDefaultButtonWidget = defaultButton == FIND_REPLACE_FIND_BUTTON_DEFAULT ? window->findBtn : + defaultButton == FIND_REPLACE_REPLACE_BUTTON_DEFAULT ? window->replaceFindBtn : + window->findBtn; + /* if we are setting a new default button then update the + XmNshowAsDefault value on the old default button */ + if(oldDefaultButton != FIND_REPLACE_NO_BUTTON_DEFAULT && oldDefaultButton != defaultButton) { + Widget old = defaultButton == FIND_REPLACE_FIND_BUTTON_DEFAULT ? window->findBtn : + defaultButton == FIND_REPLACE_REPLACE_BUTTON_DEFAULT ? window->replaceFindBtn : + window->findBtn; + + SET_ONE_RSRC(old, XmNshowAsDefault, 0); + } + /* if we are setting a new default button then update the + XmNshowAsDefault value on the new default button */ + if(oldDefaultButton == FIND_REPLACE_NO_BUTTON_DEFAULT || oldDefaultButton != defaultButton) { + SET_ONE_RSRC(newDefaultButtonWidget, XmNshowAsDefault, 1); + } + + SET_ONE_RSRC(window->replaceDlog, XmNdefaultButton, newDefaultButtonWidget); + /* If the window is already up, just pop it to the top */ if (XtIsManaged(window->replaceDlog)) { ! XMapRaised(TheDisplay, XtWindow(XtParent(window->replaceDlog))); ! XSetInputFocus(TheDisplay, XtWindow(XtParent(window->replaceDlog)), ! RevertToParent, CurrentTime); ! XtFree(primary_selection); ! return; } + /* Blank the Replace with field */ + XmTextSetString(window->replaceWithText, ""); + /* Set the initial search type */ *************** *** 159,170 **** case SEARCH_LITERAL: ! button = window->replaceLiteralBtn; break; case SEARCH_CASE_SENSE: ! button = window->replaceCaseBtn; break; case SEARCH_REGEX: ! button = window->replaceRegExpBtn; break; } - XmToggleButtonSetState(button, True, True); --- 214,224 ---- case SEARCH_LITERAL: ! XmToggleButtonSetState(window->replaceLiteralBtn, True, True); break; case SEARCH_CASE_SENSE: ! XmToggleButtonSetState(window->replaceCaseBtn, True, True); break; case SEARCH_REGEX: ! XmToggleButtonSetState(window->replaceRegExpBtn, True, True); break; } *************** *** 178,183 **** - /* Blank the text fields */ - XmTextSetString(window->replaceText, ""); - XmTextSetString(window->replaceWithText, ""); - /* Start the search history mechanism at the current history item */ --- 232,233 ---- *************** *** 185,186 **** --- 235,238 ---- + XtFree(primary_selection); + /* Display the dialog */ *************** *** 189,236 **** ! void DoFindDlog(WindowInfo *window, int direction) { ! Widget button; ! /* Create the dialog if it doesn't already exist */ ! if (window->findDlog == NULL) ! createFindDlog(window->shell, window); ! ! /* If the window is already up, just pop it to the top */ ! if (XtIsManaged(window->findDlog)) { ! XMapRaised(TheDisplay, XtWindow(XtParent(window->findDlog))); ! XSetInputFocus(TheDisplay, XtWindow(XtParent(window->findDlog)), ! RevertToParent, CurrentTime); ! return; } ! ! /* Set the initial search type */ ! switch (GetPrefSearch()) { ! case SEARCH_LITERAL: ! button = window->findLiteralBtn; ! break; ! case SEARCH_CASE_SENSE: ! button = window->findCaseBtn; ! break; ! case SEARCH_REGEX: ! button = window->findRegExpBtn; ! break; } ! XmToggleButtonSetState(button, True, True); ! ! /* Set the initial direction based on the direction argument */ ! XmToggleButtonSetState(direction == SEARCH_FORWARD ? ! window->findFwdBtn : window->findRevBtn, True, True); ! ! /* Set the state of the Keep Dialog Up button */ ! XmToggleButtonSetState(window->findKeepBtn, GetPrefKeepSearchDlogs(), ! True); ! ! /* Blank the text field */ ! XmTextSetString(window->findText, ""); ! ! /* start the search history mechanism at the current history item */ ! window->fHistIndex = 0; ! ! /* Display the dialog */ ! ManageDialogCenteredOnPointer(window->findDlog); } --- 241,277 ---- ! static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *selection, ! Atom *type, char *value, int *length, int *format) { ! WindowInfo *window = selectionInfo->window; ! /* return an empty string if we can't get the selection data */ ! if (*type == XT_CONVERT_FAIL || *type != XA_STRING || value == NULL || *length == 0) { ! XtFree(value); ! selectionInfo->selection = 0; ! selectionInfo->done = 1; ! return; } ! /* return an empty string if the data is not of the correct format. */ ! if (*format != 8) { ! DialogF(DF_WARN, window->shell, 1, "NEdit can't handle non 8-bit text", "OK"); ! XtFree(value); ! selectionInfo->selection = 0; ! selectionInfo->done = 1; ! return; } ! selectionInfo->selection = XtMalloc(*length+1); ! memcpy(selectionInfo->selection, value, *length); ! selectionInfo->selection[*length] = 0; ! XtFree(value); ! selectionInfo->done = 1; ! } ! ! void SetISearchTextCallbacks (WindowInfo *window) ! { ! XtAddCallback(window->iSearchText, XmNactivateCallback, ! (XtCallbackProc) iSearchTextActivateCB, window); ! XtAddCallback(window->iSearchText, XmNvalueChangedCallback, ! (XtCallbackProc) iSearchTextValueChangedCB, window); ! XtAddEventHandler(window->iSearchText, KeyPressMask, False, ! (XtEventHandler)iSearchTextArrowKeyEH, window); } *************** *** 240,242 **** Arg args[50]; ! int argcnt, defaultBtnOffset; XmString st1; --- 281,283 ---- Arg args[50]; ! int argcnt; XmString st1; *************** *** 246,250 **** Widget findBtn, replaceAllBtn, rInSelBtn, cancelBtn, replaceBtn; Widget searchDirBox, forwardBtn, reverseBtn, keepBtn; char title[MAXPATHLEN + 14]; - Dimension shadowThickness; --- 287,291 ---- Widget findBtn, replaceAllBtn, rInSelBtn, cancelBtn, replaceBtn; + Widget replaceFindBtn; Widget searchDirBox, forwardBtn, reverseBtn, keepBtn; char title[MAXPATHLEN + 14]; *************** *** 254,260 **** XtVaSetValues(form, XmNshadowThickness, 0, 0); ! if (GetPrefKeepSearchDlogs()) { ! sprintf(title, "Replace (in %s)", window->filename); ! XtVaSetValues(XtParent(form), XmNtitle, title, 0); ! } else ! XtVaSetValues(XtParent(form), XmNtitle, "Replace", 0); --- 295,298 ---- XtVaSetValues(form, XmNshadowThickness, 0, 0); ! sprintf(title, "NEdit - Find/Replace (%s)", window->editorInfo->filename); ! XtVaSetValues(XtParent(form), XmNtitle, title, 0); *************** *** 385,387 **** st1=MKSTRING("Regular Expression")); argcnt++; ! XtSetArg(args[argcnt], XmNmnemonic, 'R'); argcnt++; regExpBtn = XmCreateToggleButton(searchTypeBox, "regExp", args, argcnt); --- 423,425 ---- st1=MKSTRING("Regular Expression")); argcnt++; ! XtSetArg(args[argcnt], XmNmnemonic, 'x'); argcnt++; regExpBtn = XmCreateToggleButton(searchTypeBox, "regExp", args, argcnt); *************** *** 428,431 **** XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNrightOffset, 4); argcnt++; keepBtn = XmCreateToggleButton(form, "keep", args, argcnt); --- 466,470 ---- XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; ! XtSetArg(args[argcnt], XmNleftOffset, 4); argcnt++; ! XtSetArg(args[argcnt], XmNleftWidget, searchDirBox); argcnt++; keepBtn = XmCreateToggleButton(form, "keep", args, argcnt); *************** *** 452,469 **** XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; ! XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Replace")); argcnt++; ! XtSetArg(args[argcnt], XmNshowAsDefault, (short)1); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNleftPosition, 0); argcnt++; ! XtSetArg(args[argcnt], XmNrightPosition, 21); argcnt++; ! replaceBtn = XmCreatePushButton(btnForm, "replace", args, argcnt); ! XtAddCallback(replaceBtn, XmNactivateCallback, (XtCallbackProc)replaceCB, ! window); XmStringFree(st1); ! XtManageChild(replaceBtn); ! XtVaGetValues(replaceBtn, XmNshadowThickness, &shadowThickness, 0); ! defaultBtnOffset = shadowThickness + 4; ! argcnt = 0; --- 491,505 ---- XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; ! XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING(" Find ")); argcnt++; ! XtSetArg(args[argcnt], XmNdefaultButtonShadowThickness, 1); argcnt++; ! XtSetArg(args[argcnt], XmNmnemonic, 'F'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNuserData, FIND_REPLACE_NO_BUTTON_DEFAULT); argcnt++; ! findBtn = XmCreatePushButton(btnForm, "find", args, argcnt); ! XtAddCallback(findBtn, XmNactivateCallback, (XtCallbackProc)rFindCB,window); XmStringFree(st1); ! XtManageChild(findBtn); ! argcnt = 0; *************** *** 471,485 **** XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; ! XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Find")); argcnt++; ! XtSetArg(args[argcnt], XmNmnemonic, 'F'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNleftPosition, 21); argcnt++; ! XtSetArg(args[argcnt], XmNrightPosition, 33); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++; ! findBtn = XmCreatePushButton(btnForm, "find", args, argcnt); ! XtAddCallback(findBtn, XmNactivateCallback, (XtCallbackProc)rFindCB,window); XmStringFree(st1); ! XtManageChild(findBtn); --- 507,520 ---- XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; ! XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Replace\n& Find")); argcnt++; ! XtSetArg(args[argcnt], XmNmnemonic, 'd'); argcnt++; ! XtSetArg(args[argcnt], XmNdefaultButtonShadowThickness, 1); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; ! XtSetArg(args[argcnt], XmNleftWidget, findBtn); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; ! replaceFindBtn = XmCreatePushButton(btnForm, "replacefind", args, argcnt); ! XtAddCallback(replaceFindBtn, XmNactivateCallback, (XtCallbackProc)replaceFindCB,window); XmStringFree(st1); ! XtManageChild(replaceFindBtn); *************** *** 488,499 **** XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; XtSetArg(args[argcnt], XmNlabelString, ! st1=MKSTRING("Replace All")); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'A'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNleftPosition, 33); argcnt++; ! XtSetArg(args[argcnt], XmNrightPosition, 56); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++; replaceAllBtn = XmCreatePushButton(btnForm, "all", args, argcnt); --- 523,552 ---- XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; + XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Replace")); argcnt++; + XtSetArg(args[argcnt], XmNmnemonic, 'R'); argcnt++; + XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; + XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; + XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; + XtSetArg(args[argcnt], XmNleftWidget, replaceFindBtn); argcnt++; + XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; + XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; + XtSetArg(args[argcnt], XmNbottomOffset, 6); argcnt++; + replaceBtn = XmCreatePushButton(btnForm, "replace", args, argcnt); + XtAddCallback(replaceBtn, XmNactivateCallback, (XtCallbackProc)replaceCB, + window); + XmStringFree(st1); + XtManageChild(replaceBtn); + + argcnt = 0; + XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; + XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; XtSetArg(args[argcnt], XmNlabelString, ! st1=MKSTRING("Replace\nAll")); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'A'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; ! XtSetArg(args[argcnt], XmNleftWidget, replaceBtn); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; ! XtSetArg(args[argcnt], XmNbottomOffset, 6); argcnt++; replaceAllBtn = XmCreatePushButton(btnForm, "all", args, argcnt); *************** *** 508,519 **** XtSetArg(args[argcnt], XmNlabelString, ! st1=MKSTRING("R. In Selection")); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'S'); argcnt++; - XtSetArg(args[argcnt], XmNsensitive, window->wasSelected); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNleftPosition, 56); argcnt++; ! XtSetArg(args[argcnt], XmNrightPosition, 85); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++; rInSelBtn = XmCreatePushButton(btnForm, "inSel", args, argcnt); --- 561,571 ---- XtSetArg(args[argcnt], XmNlabelString, ! st1=MKSTRING("Replace\nIn Selection")); argcnt++; XtSetArg(args[argcnt], XmNmnemonic, 'S'); argcnt++; XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; ! XtSetArg(args[argcnt], XmNleftWidget, replaceAllBtn); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; ! XtSetArg(args[argcnt], XmNbottomOffset, 6); argcnt++; rInSelBtn = XmCreatePushButton(btnForm, "inSel", args, argcnt); *************** *** 529,536 **** XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; ! XtSetArg(args[argcnt], XmNleftPosition, 85); argcnt++; ! XtSetArg(args[argcnt], XmNrightPosition, 100); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++; cancelBtn = XmCreatePushButton(btnForm, "cancel", args, argcnt); --- 581,588 ---- XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++; ! XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++; ! XtSetArg(args[argcnt], XmNleftWidget, rInSelBtn); argcnt++; ! XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; ! XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; ! XtSetArg(args[argcnt], XmNbottomOffset, 6); argcnt++; cancelBtn = XmCreatePushButton(btnForm, "cancel", args, argcnt); *************** *** 541,542 **** --- 593,595 ---- + XtVaSetValues(form, XmNcancelButton, cancelBtn, 0); *************** *** 555,556 **** --- 608,611 ---- window->replaceBtn = replaceBtn; + window->replaceFindBtn = replaceFindBtn; + window->findBtn = findBtn; window->replaceInSelBtn = rInSelBtn; *************** *** 559,782 **** - static void createFindDlog(Widget parent, WindowInfo *window) - { - Arg args[50]; - int argcnt, defaultBtnOffset; - XmString st1; - Widget form, btnForm, searchTypeBox, literalBtn, caseBtn, regExpBtn; - Widget findText, label1, label2, cancelBtn, findBtn; - Widget searchDirBox, forwardBtn, reverseBtn, keepBtn; - char title[MAXPATHLEN + 11]; - Dimension shadowThickness; - - argcnt = 0; - XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++; - form = XmCreateFormDialog(parent, "findDialog", args, argcnt); - XtVaSetValues(form, XmNshadowThickness, 0, 0); - if (GetPrefKeepSearchDlogs()) { - sprintf(title, "Find (in %s)", window->filename); - XtVaSetValues(XtParent(form), XmNtitle, title, 0); - } else - XtVaSetValues(XtParent(form), XmNtitle, "Find", 0); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("String to Find:")); - argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'S'); argcnt++; - label1 = XmCreateLabel(form, "label1", args, argcnt); - XmStringFree(st1); - XtManageChild(label1); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNtopOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_END); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING( - "(use up arrow key to recall previous)")); argcnt++; - label2 = XmCreateLabel(form, "label2", args, argcnt); - XmStringFree(st1); - XtManageChild(label2); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNtopWidget, label1); argcnt++; - XtSetArg(args[argcnt], XmNleftOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNrightOffset, 6); argcnt++; - XtSetArg(args[argcnt], XmNmaxLength, SEARCHMAX); argcnt++; - findText = XmCreateText(form, "searchString", args, argcnt); - XtAddCallback(findText, XmNfocusCallback, (XtCallbackProc)fFocusCB, window); - XtAddEventHandler(findText, KeyPressMask, False, - (XtEventHandler)findArrowKeyCB, window); - RemapDeleteKey(findText); - XtManageChild(findText); - XmAddTabGroup(findText); - XtVaSetValues(label1, XmNuserData, findText, 0); /* mnemonic processing */ - - argcnt = 0; - XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++; - XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++; - XtSetArg(args[argcnt], XmNmarginHeight, 0); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNtopWidget, findText); argcnt++; - XtSetArg(args[argcnt], XmNleftOffset, 2); argcnt++; - XtSetArg(args[argcnt], XmNrightOffset, 4); argcnt++; - XtSetArg(args[argcnt], XmNradioBehavior, True); argcnt++; - XtSetArg(args[argcnt], XmNradioAlwaysOne, True); argcnt++; - searchTypeBox = XmCreateRowColumn(form, "searchTypeBox", args, argcnt); - XtManageChild(searchTypeBox); - XmAddTabGroup(searchTypeBox); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Literal")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'L'); argcnt++; - literalBtn = XmCreateToggleButton(searchTypeBox, "literal", args, argcnt); - XmStringFree(st1); - XtManageChild(literalBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, - st1=MKSTRING("Case Sensitive Literal")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'C'); argcnt++; - caseBtn = XmCreateToggleButton(searchTypeBox, "caseSenseLiteral", args, argcnt); - XmStringFree(st1); - XtManageChild(caseBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, - st1=MKSTRING("Regular Expression")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'R'); argcnt++; - regExpBtn = XmCreateToggleButton(searchTypeBox, "regExp", args, argcnt); - XmStringFree(st1); - XtManageChild(regExpBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++; - XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++; - XtSetArg(args[argcnt], XmNmarginHeight, 0); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; - XtSetArg(args[argcnt], XmNtopOffset, 0); argcnt++; - XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNleftOffset, 2); argcnt++; - XtSetArg(args[argcnt], XmNradioBehavior, True); argcnt++; - XtSetArg(args[argcnt], XmNradioAlwaysOne, True); argcnt++; - searchDirBox = XmCreateRowColumn(form, "searchDirBox", args, argcnt); - XtManageChild(searchDirBox); - XmAddTabGroup(searchDirBox); - - argcnt = 0; - XtSetArg(args[argcnt], XmNlabelString, - st1=MKSTRING("Search Forward")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'o'); argcnt++; - forwardBtn = XmCreateToggleButton(searchDirBox, "forward", args, argcnt); - XmStringFree(st1); - XtManageChild(forwardBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNlabelString, - st1=MKSTRING("Search Backward")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'B'); argcnt++; - reverseBtn = XmCreateToggleButton(searchDirBox, "reverse", args, argcnt); - XmStringFree(st1); - XtManageChild(reverseBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNlabelString, - st1=MKSTRING("Keep Dialog")); argcnt++; - XtSetArg(args[argcnt], XmNmnemonic, 'K'); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; - XtSetArg(args[argcnt], XmNtopOffset, 0); argcnt++; - XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightOffset, 4); argcnt++; - keepBtn = XmCreateToggleButton(form, "keep", args, argcnt); - XtAddCallback(keepBtn, XmNvalueChangedCallback, - (XtCallbackProc)fKeepCB, window); - XmStringFree(st1); - XtManageChild(keepBtn); - XmAddTabGroup(keepBtn); - - argcnt = 0; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNtopWidget, searchDirBox); argcnt++; - XtSetArg(args[argcnt], XmNleftOffset, 2); argcnt++; - XtSetArg(args[argcnt], XmNrightOffset, 4); argcnt++; - btnForm = XmCreateForm(form, "buttons", args, argcnt); - XtManageChild(btnForm); - XmAddTabGroup(btnForm); - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Find")); argcnt++; - XtSetArg(args[argcnt], XmNshowAsDefault, (short)1); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftPosition, 20); argcnt++; - XtSetArg(args[argcnt], XmNbottomOffset, 6); argcnt++; - findBtn = XmCreatePushButton(btnForm, "find", args, argcnt); - XtAddCallback(findBtn, XmNactivateCallback, (XtCallbackProc)findCB, window); - XmStringFree(st1); - XtManageChild(findBtn); - XtVaGetValues(findBtn, XmNshadowThickness, &shadowThickness, 0); - defaultBtnOffset = shadowThickness + 4; - - argcnt = 0; - XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++; - XtSetArg(args[argcnt], XmNhighlightThickness, 2); argcnt++; - XtSetArg(args[argcnt], XmNlabelString, st1=MKSTRING("Cancel")); argcnt++; - XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++; - XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++; - XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++; - XtSetArg(args[argcnt], XmNrightPosition, 80); argcnt++; - XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++; - cancelBtn = XmCreatePushButton(btnForm, "cancel", args, argcnt); - XtAddCallback(cancelBtn, XmNactivateCallback, (XtCallbackProc)fCancelCB, - window); - XmStringFree(st1); - XtManageChild(cancelBtn); - XtVaSetValues(form, XmNcancelButton, cancelBtn, 0); - AddDialogMnemonicHandler(form); - - window->findDlog = form; - window->findText = findText; - window->findLiteralBtn = literalBtn; - window->findCaseBtn = caseBtn; - window->findRegExpBtn = regExpBtn; - window->findFwdBtn = forwardBtn; - window->findRevBtn = reverseBtn; - window->findKeepBtn = keepBtn; - window->findBtns = btnForm; - window->findBtn = findBtn; - window->findSearchTypeBox = searchTypeBox; - } --- 614,615 ---- *************** *** 789,797 **** */ - static void fFocusCB(Widget w, WindowInfo *window, caddr_t *callData) - { - SET_ONE_RSRC(window->findDlog, XmNdefaultButton, window->findBtn); - } static void rFocusCB(Widget w, WindowInfo *window, caddr_t *callData) { ! SET_ONE_RSRC(window->replaceDlog, XmNdefaultButton, window->replaceBtn); } --- 622,633 ---- */ static void rFocusCB(Widget w, WindowInfo *window, caddr_t *callData) { ! FindReplaceDlogDefaultButton defaultButton = FIND_REPLACE_NO_BUTTON_DEFAULT; ! XtVaGetValues(window->findBtn, XmNuserData, &defaultButton, 0); ! if(defaultButton != FIND_REPLACE_NO_BUTTON_DEFAULT) { ! Widget new = defaultButton == FIND_REPLACE_FIND_BUTTON_DEFAULT ? window->findBtn : ! defaultButton == FIND_REPLACE_REPLACE_BUTTON_DEFAULT ? window->replaceFindBtn : ! window->findBtn; ! SET_ONE_RSRC(window->replaceDlog, XmNdefaultButton, new); ! } } *************** *** 803,819 **** ! if (XmToggleButtonGetState(w)) { ! sprintf(title, "Replace (in %s)", window->filename); ! XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title, 0); ! } else ! XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, "Replace", 0); ! } ! static void fKeepCB(Widget w, WindowInfo *window, caddr_t *callData) ! { ! char title[MAXPATHLEN + 11]; ! ! if (XmToggleButtonGetState(w)) { ! sprintf(title, "Find (in %s)", window->filename); ! XtVaSetValues(XtParent(window->findDlog), XmNtitle, title, 0); ! } else ! XtVaSetValues(XtParent(window->findDlog), XmNtitle, "Find", 0); } --- 639,642 ---- ! sprintf(title, "NEdit - Find/Replace (%s)", window->editorInfo->filename); ! XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title, 0); } *************** *** 823,825 **** { ! char searchString[SEARCHMAX], replaceString[SEARCHMAX]; int direction, searchType; --- 646,648 ---- { ! char searchString[SEARCHMAX+1], replaceString[SEARCHMAX+1]; int direction, searchType; *************** *** 851,853 **** { ! char searchString[SEARCHMAX], replaceString[SEARCHMAX]; int direction, searchType; --- 674,676 ---- { ! char searchString[SEARCHMAX+1], replaceString[SEARCHMAX+1]; int direction, searchType; *************** *** 879,881 **** { ! char searchString[SEARCHMAX], replaceString[SEARCHMAX]; int direction, searchType; --- 702,704 ---- { ! char searchString[SEARCHMAX+1], replaceString[SEARCHMAX+1]; int direction, searchType; *************** *** 913,928 **** ! static void fCancelCB(Widget w, WindowInfo *window, caddr_t callData) { ! /* Set the initial focus of the dialog back to the search string */ ! resetFindTabGroup(window); ! /* pop down the dialog */ ! XtUnmanageChild(window->findDlog); } ! static void rFindCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData) { ! char searchString[SEARCHMAX], replaceString[SEARCHMAX]; int direction, searchType; ! char *params[3]; --- 736,886 ---- ! static void rFindCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData) ! { ! char searchString[SEARCHMAX+1], replaceString[SEARCHMAX+1]; ! int direction, searchType; ! char *params[3]; ! ! /* Validate and transfer find and replace strings from the ! dialog to the global saved search information */ ! if (!getReplaceDlogInfo(window, &direction, searchString, replaceString, ! &searchType)) ! return; ! ! /* Set the initial focus of the dialog back to the search string */ ! resetReplaceTabGroup(window); ! ! /* Toggle the search direction if the Ctrl or Shift key was pressed */ ! if(callData->event->xbutton.state & (ShiftMask | ControlMask)) { ! direction = direction == SEARCH_FORWARD ? SEARCH_BACKWARD : SEARCH_FORWARD; ! } ! ! /* find the text and mark it */ ! params[0] = searchString; ! params[1] = directionArg(direction); ! params[2] = searchTypeArg(searchType); ! XtCallActionProc(window->lastFocus, "find", callData->event, params, 3); ! ! /* pop down the dialog */ ! if (!XmToggleButtonGetState(window->replaceKeepBtn)) ! XtUnmanageChild(window->replaceDlog); ! } ! ! /* ! * The direction of the search is toggled if the Ctrl key or the Shift key is ! * pressed when the text field is activated. ! */ ! static void iSearchTextActivateCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData) ! { ! char *params[3]; ! ! char searchString[SEARCHMAX+1]; ! char *text; ! int searchDirection = window->iSearchDirection; ! int searchType; ! ! text = XmTextFieldGetString(window->iSearchText); ! strcpy(searchString, text); ! XtFree(text); ! ! /* Toggle the search direction if the Ctrl or Shift key was pressed */ ! if(callData->event->xbutton.state & (ShiftMask | ControlMask)) { ! searchDirection = searchDirection == SEARCH_FORWARD ? SEARCH_BACKWARD : SEARCH_FORWARD; ! } ! ! searchType = XmToggleButtonGetState(window->iSearchCaseToggle) ? SEARCH_CASE_SENSE : SEARCH_LITERAL; ! searchType = XmToggleButtonGetState(window->iSearchRegExpToggle) ? SEARCH_REGEX : searchType; ! ! /* .b */ ! if (searchType == SEARCH_REGEX) { ! regexp *compiledRE = NULL; ! char *compileMsg; ! ! /* If the search type is a regular expression, test compile it */ ! compiledRE = CompileRE(searchString, &compileMsg); ! if (compiledRE == NULL){ ! return; ! } else ! free((char *)compiledRE); ! } ! /* .e */ ! ! /* find the text and mark it */ ! params[0] = searchString; ! params[1] = directionArg(searchDirection); ! params[2] = searchTypeArg(searchType); ! SaveSearchHistory (params[0], NULL, searchType); ! XtCallActionProc(window->lastFocus, "find", callData->event, params, 3); ! } ! ! static void iSearchTextValueChangedCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData) ! { ! char *params[3]; ! char searchString[SEARCHMAX+1]; ! char *text; ! int searchType; ! ! text = XmTextFieldGetString(window->iSearchText); ! strcpy(searchString, text); ! XtFree(text); ! ! searchType = XmToggleButtonGetState(window->iSearchCaseToggle) ? SEARCH_CASE_SENSE : SEARCH_LITERAL; ! searchType = XmToggleButtonGetState(window->iSearchRegExpToggle) ? SEARCH_REGEX : searchType; ! ! /* .b */ ! if (searchType == SEARCH_REGEX) { ! regexp *compiledRE = NULL; ! char *compileMsg; ! ! /* If the search type is a regular expression, test compile it */ ! compiledRE = CompileRE(searchString, &compileMsg); ! if (compiledRE == NULL){ ! return; ! } else ! free((char *)compiledRE); ! } ! /* .e */ ! ! /* find the text and mark it */ ! params[0] = searchString; ! params[1] = directionArg(window->iSearchDirection); ! params[2] = searchTypeArg(searchType); ! XtCallActionProc(window->lastFocus, "find-incremental", callData->event, params, 3); ! } ! ! static void iSearchTextArrowKeyEH(Widget w, WindowInfo *window, XKeyEvent *event) { ! KeySym keysym = XLookupKeysym(event, 0); ! int index = window->iSearchHistIndex; ! char *searchStr; ! /* only process up and down arrow keys */ ! if (keysym != XK_Up && keysym != XK_Down) ! return; ! ! /* increment or decrement the index depending on which arrow was pressed */ ! index += (keysym == XK_Up) ? 1 : -1; ! ! /* if the index is out of range, beep and return */ ! if (index != 0 && historyIndex(index) == -1) { ! XBell(TheDisplay, 100); ! return; ! } ! ! /* determine the strings and button settings to use */ ! if (index == 0) { ! searchStr = ""; ! } else { ! searchStr = SearchHistory[historyIndex(index)]; ! } ! ! XmTextFieldSetString(window->iSearchText, searchStr); ! window->iSearchHistIndex = index; } ! static void replaceFindCB(Widget w, WindowInfo *window, ! XmAnyCallbackStruct *callData) { ! char searchString[SEARCHMAX+1], replaceString[SEARCHMAX+1]; int direction, searchType; ! char *params[4]; *************** *** 934,945 **** ! /* Set the initial focus of the dialog back to the search string */ resetReplaceTabGroup(window); ! /* find the text and mark it */ params[0] = searchString; ! params[1] = directionArg(direction); ! params[2] = searchTypeArg(searchType); ! XtCallActionProc(window->lastFocus, "find", callData->event, params, 3); ! ! /* pop down the dialog */ if (!XmToggleButtonGetState(window->replaceKeepBtn)) --- 892,904 ---- ! /* Set the initial focus of the dialog back to the search string */ resetReplaceTabGroup(window); ! /* Find the text and replace it */ params[0] = searchString; ! params[1] = replaceString; ! params[2] = directionArg(direction); ! params[3] = searchTypeArg(searchType); ! XtCallActionProc(window->lastFocus, "replace-find", callData->event, params, 4); ! ! /* Pop down the dialog */ if (!XmToggleButtonGetState(window->replaceKeepBtn)) *************** *** 954,956 **** int searchType; - Widget button; --- 913,914 ---- *************** *** 965,967 **** if (index != 0 && historyIndex(index) == -1) { ! XBell(TheDisplay, 0); return; --- 923,925 ---- if (index != 0 && historyIndex(index) == -1) { ! XBell(TheDisplay, 100); return; *************** *** 983,994 **** case SEARCH_LITERAL: ! button = window->replaceLiteralBtn; break; case SEARCH_CASE_SENSE: ! button = window->replaceCaseBtn; break; case SEARCH_REGEX: ! button = window->replaceRegExpBtn; break; } - XmToggleButtonSetState(button, True, True); XmTextSetString(window->replaceText, searchStr); --- 941,951 ---- case SEARCH_LITERAL: ! XmToggleButtonSetState(window->replaceLiteralBtn, True, True); break; case SEARCH_CASE_SENSE: ! XmToggleButtonSetState(window->replaceCaseBtn, True, True); break; case SEARCH_REGEX: ! XmToggleButtonSetState(window->replaceRegExpBtn, True, True); break; } XmTextSetString(window->replaceText, searchStr); *************** *** 1012,1014 **** if (index != 0 && historyIndex(index) == -1) { ! XBell(TheDisplay, 0); return; --- 969,971 ---- if (index != 0 && historyIndex(index) == -1) { ! XBell(TheDisplay, 100); return; *************** *** 1025,1097 **** - static void findArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event) - { - KeySym keysym = XLookupKeysym(event, 0); - int index = window->fHistIndex; - char *searchStr; - int searchType; - Widget button; - - /* only process up and down arrow keys */ - if (keysym != XK_Up && keysym != XK_Down) - return; - - /* increment or decrement the index depending on which arrow was pressed */ - index += (keysym == XK_Up) ? 1 : -1; - - /* if the index is out of range, beep and return */ - if (index != 0 && historyIndex(index) == -1) { - XBell(TheDisplay, 0); - return; - } - - /* determine the strings and button settings to use */ - if (index == 0) { - searchStr = ""; - searchType = GetPrefSearch(); - } else { - searchStr = SearchHistory[historyIndex(index)]; - searchType = SearchTypeHistory[historyIndex(index)]; - } - - /* Set the buttons and fields with the selected search type */ - switch (searchType) { - case SEARCH_LITERAL: - button = window->findLiteralBtn; - break; - case SEARCH_CASE_SENSE: - button = window->findCaseBtn; - break; - case SEARCH_REGEX: - button = window->findRegExpBtn; - break; - } - XmToggleButtonSetState(button, True, True); - XmTextSetString(window->findText, searchStr); - window->fHistIndex = index; - } - - static void findCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData) - { - char searchString[SEARCHMAX]; - int direction, searchType; - char *params[3]; - - /* save find string from the dialog in the global search string */ - if (!getFindDlogInfo(window, &direction, searchString, &searchType)) - return; - - /* Set the initial focus of the dialog back to the search string */ - resetFindTabGroup(window); - - /* find the text and mark it */ - params[0] = searchString; - params[1] = directionArg(direction); - params[2] = searchTypeArg(searchType); - XtCallActionProc(window->lastFocus, "find", callData->event, params, 3); - - /* pop down the dialog */ - if (!XmToggleButtonGetState(window->findKeepBtn)) - XtUnmanageChild(window->findDlog); - } - /* --- 982,983 ---- *************** *** 1138,1140 **** /* Save a copy in the search history */ ! saveSearchHistory(replaceText, replaceWithText, type); --- 1024,1026 ---- /* Save a copy in the search history */ ! SaveSearchHistory(replaceText, replaceWithText, type); *************** *** 1145,1195 **** XtFree(replaceWithText); ! return TRUE; ! } ! ! /* ! ** Fetch and verify (particularly regular expression) search string, ! ** direction, and search type from the Find dialog. If the search string ! ** is ok, save a copy in the search history, copy it to "searchString", ! ** which is assumed to be at least SEARCHMAX in length, return search type ! ** in "searchType", and return TRUE as the function value. Otherwise, ! ** return FALSE. ! */ ! static int getFindDlogInfo(WindowInfo *window, int *direction, ! char *searchString, int *searchType) ! { ! char *findText; ! regexp *compiledRE = NULL; ! char *compileMsg; ! int type; ! ! /* Get the search string, search type, and direction from the dialog */ ! findText = XmTextGetString(window->findText); ! if (XmToggleButtonGetState(window->findLiteralBtn)) ! type = SEARCH_LITERAL; ! else if (XmToggleButtonGetState(window->findCaseBtn)) ! type = SEARCH_CASE_SENSE; ! else ! type = SEARCH_REGEX; ! *direction = XmToggleButtonGetState(window->findFwdBtn) ? SEARCH_FORWARD : ! SEARCH_BACKWARD; ! *searchType = type; ! ! /* If the search type is a regular expression, test compile it immediately ! and present error messages */ ! if (type == SEARCH_REGEX) { ! compiledRE = CompileRE(findText, &compileMsg); ! if (compiledRE == NULL) { ! DialogF(DF_WARN, XtParent(window->findDlog), 1, ! "Please respecify the search string:\n%s", "OK", compileMsg); ! return FALSE; ! } ! XtFree((char *)compiledRE); ! } ! ! /* Save a copy in the search history */ ! saveSearchHistory(findText, "", type); ! ! /* Return the search string */ ! strcpy(searchString, findText); ! XtFree(findText); return TRUE; --- 1031,1033 ---- XtFree(replaceWithText); ! free((char *)compiledRE); return TRUE; *************** *** 1200,1202 **** if (NHist < 1) { ! XBell(TheDisplay, 0); return FALSE; --- 1038,1040 ---- if (NHist < 1) { ! XBell(TheDisplay, 100); return FALSE; *************** *** 1252,1254 **** if (selStart==startPos && selEnd==endPos) { ! XBell(TheDisplay, 0); return FALSE; --- 1090,1092 ---- if (selStart==startPos && selEnd==endPos) { ! XBell(TheDisplay, 100); return FALSE; *************** *** 1257,1259 **** /* select the text found string */ ! BufSelect(window->buffer, startPos, endPos); MakeSelectionVisible(window, window->lastFocus); --- 1095,1097 ---- /* select the text found string */ ! BufSelect(window->editorInfo->buffer, startPos, endPos, CHAR_SELECT); MakeSelectionVisible(window, window->lastFocus); *************** *** 1264,1265 **** --- 1102,1173 ---- + int SearchAndSelectIncremental(WindowInfo *window, int direction, char *searchString, + int searchType) + { + int startPos, endPos; + int beginPos, cursorPos, selStart, selEnd; + + /* set the position to start the search so we include the same + string that was found on the last search */ + if (searchMatchesSelection(window, window->iSearchLastSearchString, window->iSearchLastSearchType, + &selStart, &selEnd)) { + + if (direction == SEARCH_FORWARD) { + beginPos = selStart; + } else { + beginPos = selEnd; + } + } else { + selStart = -1; selEnd = -1; + /* no selection, or no match, search relative cursor */ + cursorPos = TextGetCursorPos(window->lastFocus); + if (direction == SEARCH_BACKWARD) { + /* use the insert position - 1 for backward searches */ + beginPos = cursorPos-1; + } else { + /* use the insert position for forward searches */ + beginPos = cursorPos; + } + } + + /* if the searchString is empty then clear the selection + and set the cursor to what would be the beginning of the search + and return. */ + if(strcmp(searchString, "") == 0) { + BufUnselect(window->editorInfo->buffer); + TextSetCursorPos(window->lastFocus, beginPos); + return TRUE; + } + + /* do the search. SearchWindow does appropriate dialogs and beeps */ + if (!SearchWindow(window, direction, searchString, searchType, + beginPos, &startPos, &endPos)) + return FALSE; + + /* remember this search it there was a match. */ + strncpy(window->iSearchLastSearchString, searchString, sizeof(window->iSearchLastSearchString)); + window->iSearchLastSearchString[sizeof(window->iSearchLastSearchString)] = 0; + window->iSearchLastSearchType = searchType; + + /* if the search matched an empty string (possible with regular exps) + beginning at the start of the search, go to the next occurrence, + otherwise repeated finds will get "stuck" at zero-length matches */ + if (direction==SEARCH_FORWARD && beginPos==startPos && beginPos==endPos) + if (!SearchWindow(window, direction, searchString, searchType, + beginPos+1, &startPos, &endPos)) + return FALSE; + + /* if matched text is already selected, just beep */ + if (selStart==startPos && selEnd==endPos) { + XBell(TheDisplay, 100); + return FALSE; + } + + /* select the text found string */ + BufSelect(window->editorInfo->buffer, startPos, endPos, CHAR_SELECT); + MakeSelectionVisible(window, window->lastFocus); + TextSetCursorPos(window->lastFocus, endPos); + + return TRUE; + } + void SearchForSelected(WindowInfo *window, int direction, Time time) *************** *** 1285,1287 **** else ! XBell(TheDisplay, 0); return; --- 1193,1195 ---- else ! XBell(TheDisplay, 100); return; *************** *** 1292,1294 **** else ! XBell(TheDisplay, 0); XtFree(value); --- 1200,1202 ---- else ! XBell(TheDisplay, 100); XtFree(value); *************** *** 1297,1299 **** if (*length == 0) { ! XBell(TheDisplay, 0); XtFree(value); --- 1205,1207 ---- if (*length == 0) { ! XBell(TheDisplay, 100); XtFree(value); *************** *** 1304,1306 **** fprintf(stderr, "NEdit: can't handle non 8-bit text\n"); ! XBell(TheDisplay, 0); XtFree(value); --- 1212,1214 ---- fprintf(stderr, "NEdit: can't handle non 8-bit text\n"); ! XBell(TheDisplay, 100); XtFree(value); *************** *** 1320,1322 **** /* record the search parameters for recall with up arrow */ ! saveSearchHistory(searchString, NULL, searchType); --- 1228,1230 ---- /* record the search parameters for recall with up arrow */ ! SaveSearchHistory(searchString, NULL, searchType); *************** *** 1334,1344 **** { ! char c; ! int pos, matchIndex; ! int startPos, endPos, searchPos, matchPos; /* if a marker is already drawn, erase it and cancel the timeout */ ! if (window->flashTimeoutID != 0) { eraseFlash(window); ! XtRemoveTimeOut(window->flashTimeoutID); ! window->flashTimeoutID = 0; } --- 1242,1250 ---- { ! int startPos, endPos, matchBeginPos, matchPos; /* if a marker is already drawn, erase it and cancel the timeout */ ! if (window->editorInfo->flashTimeoutID != 0) { eraseFlash(window); ! XtRemoveTimeOut(window->editorInfo->flashTimeoutID); ! window->editorInfo->flashTimeoutID = 0; } *************** *** 1346,1348 **** /* don't do anything if showMatching isn't on */ ! if (!window->showMatching) return; --- 1252,1254 ---- /* don't do anything if showMatching isn't on */ ! if (!window->editorInfo->showMatching) return; *************** *** 1350,1384 **** /* don't flash matching characters if there's a selection */ ! if (window->buffer->primary.selected) return; - /* get the character to match and the position to start from */ - pos = TextGetCursorPos(textW) - 1; - if (pos < 0) - return; - c = BufGetCharacter(window->buffer, pos); - - /* is the character one we want to flash? */ - for (matchIndex = 0; matchIndexnPanes == 0 ? TextFirstVisiblePos(textW) : 0; ! endPos = pos; ! searchPos = endPos; ! } else { ! startPos = pos; ! endPos = window->nPanes == 0 ? TextLastVisiblePos(textW) : ! window->buffer->length; ! searchPos = startPos; ! } /* do the search */ ! if (!findMatchingChar(window->buffer, c, searchPos, startPos, endPos, ! &matchPos)) return; --- 1256,1269 ---- /* don't flash matching characters if there's a selection */ ! if (window->editorInfo->buffer->primary.selected) return; /* Constrain the search to visible text (unless we're in split-window mode, then search the whole buffer), and get the string to search */ ! startPos = window->nPanes == 0 ? TextFirstVisiblePos(textW) : 0; ! endPos = window->nPanes == 0 ? TextLastVisiblePos(textW) : ! window->editorInfo->buffer->length; /* do the search */ ! if (!findMatchingChar(window->editorInfo->buffer, TextGetCursorPos(textW), ! startPos, endPos, &matchBeginPos, &matchPos)) return; *************** *** 1386,1394 **** /* highlight the matched character */ ! BufHighlight(window->buffer, matchPos, matchPos+1); /* Set up a timer to erase the box after 1.5 seconds */ ! window->flashTimeoutID = XtAppAddTimeOut( XtWidgetToApplicationContext(window->shell), 1500, flashTimeoutProc, window); ! window->flashPos = matchPos; } --- 1271,1279 ---- /* highlight the matched character */ ! BufHighlight(window->editorInfo->buffer, matchPos, matchPos+1); /* Set up a timer to erase the box after 1.5 seconds */ ! window->editorInfo->flashTimeoutID = XtAppAddTimeOut( XtWidgetToApplicationContext(window->shell), 1500, flashTimeoutProc, window); ! window->editorInfo->flashPos = matchPos; } *************** *** 1397,1449 **** { ! int selStart, selEnd; ! int startPos, endPos, matchPos; ! textBuffer *buf = window->buffer; ! ! /* get the character to match and its position from the selection, or ! the character before the insert point if nothing is selected. ! Give up if too many characters are selected */ ! if (!GetSimpleSelection(buf, &selStart, &selEnd)) { ! selEnd = TextGetCursorPos(window->lastFocus); ! selStart = selEnd - 1; ! if (selStart < 0) { ! XBell(TheDisplay, 0); ! return; } - } - if ((selEnd - selStart) != 1) { - XBell(TheDisplay, 0); - return; - } ! /* Search for it in the buffer */ ! if (!findMatchingChar(buf, BufGetCharacter(buf, selStart), selStart, 0, ! buf->length, &matchPos)) { ! XBell(TheDisplay, 0); ! return; ! } ! startPos = (matchPos > selStart) ? selStart : matchPos; ! endPos = (matchPos > selStart) ? matchPos : selStart; ! /* select the text between the matching characters */ ! BufSelect(buf, startPos, endPos+1); } ! static int findMatchingChar(textBuffer *buf, char toMatch, int charPos, ! int startLimit, int endLimit, int *matchPos) { ! int nestDepth, matchIndex, direction, beginPos, pos; ! char matchChar, c; ! /* Look up the matching character and match direction */ ! for (matchIndex = 0; matchIndexeditorInfo->buffer; ! ! /* get the character to match and its position from the selection, or ! the character before the insert point if nothing is selected. ! Give up if too many characters are selected */ ! if (GetSimpleSelection(buf, &selStart, &selEnd)) { ! if ((selEnd - selStart) != 1) { ! XBell(TheDisplay, 100); ! return; ! } ! } ! else { ! selEnd = TextGetCursorPos(window->lastFocus); ! selStart = selEnd - 1; } ! /* Search for it in the buffer */ ! if (!findMatchingChar(buf, selEnd, 0, buf->length, &matchBeginPos, &matchPos)) { ! XBell(TheDisplay, 100); ! return; ! } ! startPos = (matchPos > matchBeginPos) ? matchBeginPos : matchPos; ! endPos = (matchPos > matchBeginPos) ? matchPos : matchBeginPos; ! /* select the text between the matching characters */ ! BufSelect(buf, startPos, endPos+1, CHAR_SELECT); } ! void GotoMatchingCharacter(WindowInfo *window) { ! int pos, matchBeginPos, matchPos; ! textBuffer *buf = window->editorInfo->buffer; ! ! pos = TextGetCursorPos(window->lastFocus); ! /* Search for it in the buffer */ ! if (!findMatchingChar(buf, pos, 0, buf->length, &matchBeginPos, &matchPos)) { ! XBell(TheDisplay, 100); ! return; ! } ! /* Move the cursor inside the beginning match character. */ ! if(matchPos < matchBeginPos) { ! matchPos++; ! } ! /* Move the cursor to the matching character. */ ! TextSetCursorPos(window->lastFocus, matchPos); ! } ! ! static int findMatchingChar(textBuffer *buf, int charPos,int startLimit, ! int endLimit, int *matchBeginPos, int *matchPos) ! { ! int beforePos, afterPos, beginPos, pos; ! char beforeChar, beginChar, endChar; ! int nestDepth, matchIndex, direction; ! char c; + /* Check for the beginning character before the cursor and for + the ending character after the cursor. */ + afterPos = charPos; + /* Nothing to match if the cursor is at the beginning of the buffer. */ + if (afterPos <= 0) + return FALSE; + + beginPos = -1; + beforePos = (afterPos - 1); + beforeChar = BufGetCharacter(buf, beforePos); + + /* Search forward for the ending character when the + ** the character left of the cursor is one of the beginning + ** match character. + */ + for (matchIndex = 0; MatchingChars[matchIndex].begin != 0; matchIndex++) { + if (MatchingChars[matchIndex].begin == beforeChar) { + direction = SEARCH_FORWARD; + beginPos = beforePos + 1; + break; + } + } + /* Else search backwards for the beginning character for the + ** the character left of the cursor only if the begin and + ** end match characters are unique. + ** {({({()})})} + */ + if (beginPos == -1) { + for (matchIndex = 0; MatchingChars[matchIndex].begin != 0; matchIndex++) { + if (MatchingChars[matchIndex].end != MatchingChars[matchIndex].begin && + MatchingChars[matchIndex].end == beforeChar) { + direction = SEARCH_BACKWARD; + beginPos = beforePos - 1; + break; + } + } + } + /* Else search backwards for the beginning character if the + ** character right of the cursor is one of the ending + ** match character. Also make sure the character right of the cursor + ** is not the end of the buffer. + ** {(({({()})}))} + */ + if (beginPos == -1 && afterPos < buf->length) { + char afterChar; + afterChar = BufGetCharacter(buf, afterPos); + for (matchIndex = 0; MatchingChars[matchIndex].begin != 0; matchIndex++) { + if (MatchingChars[matchIndex].end == afterChar) { + direction = SEARCH_BACKWARD; + beginPos = afterPos - 1; + break; + } + } + } + if (beginPos == -1) + return FALSE; + + beginChar = MatchingChars[matchIndex].begin; + endChar = MatchingChars[matchIndex].end; + /* find it in the buffer */ nestDepth = 1; *************** *** 1452,1454 **** c=BufGetCharacter(buf, pos); ! if (c == matchChar) { nestDepth--; --- 1405,1407 ---- c=BufGetCharacter(buf, pos); ! if (c == endChar) { nestDepth--; *************** *** 1456,1460 **** *matchPos = pos; return TRUE; } ! } else if (c == toMatch) nestDepth++; --- 1409,1414 ---- *matchPos = pos; + *matchBeginPos = beginPos-1; return TRUE; } ! } else if (c == beginChar) nestDepth++; *************** *** 1464,1472 **** c=BufGetCharacter(buf, pos); ! if (c == matchChar) { nestDepth--; if (nestDepth == 0) { ! *matchPos = pos; return TRUE; } ! } else if (c == toMatch) nestDepth++; --- 1418,1427 ---- c=BufGetCharacter(buf, pos); ! if (c == beginChar) { nestDepth--; if (nestDepth == 0) { ! *matchPos = pos; ! *matchBeginPos = beginPos+1; return TRUE; } ! } else if (c == endChar) nestDepth++; *************** *** 1483,1485 **** eraseFlash((WindowInfo *)clientData); ! ((WindowInfo *)clientData)->flashTimeoutID = 0; } --- 1438,1440 ---- eraseFlash((WindowInfo *)clientData); ! ((WindowInfo *)clientData)->editorInfo->flashTimeoutID = 0; } *************** *** 1492,1494 **** { ! BufUnhighlight(window->buffer); } --- 1447,1449 ---- { ! BufUnhighlight(window->editorInfo->buffer); } *************** *** 1502,1504 **** if (NHist < 1) { ! XBell(TheDisplay, 0); return FALSE; --- 1457,1459 ---- if (NHist < 1) { ! XBell(TheDisplay, 100); return FALSE; *************** *** 1512,1513 **** --- 1467,1484 ---- /* + ** Search and replace using previously entered search strings (from dialog + ** or selection). + */ + int ReplaceFindSame(WindowInfo *window, int direction) + { + if (NHist < 1) { + XBell(TheDisplay, 100); + return FALSE; + } + + return ReplaceAndSearch(window, direction, SearchHistory[historyIndex(1)], + ReplaceHistory[historyIndex(1)], + SearchTypeHistory[historyIndex(1)]); + } + + /* ** Search for string "searchString" in window "window", using algorithm *************** *** 1518,1577 **** { ! int startPos, endPos, replaceLen; ! int found; ! int beginPos, cursorPos; ! ! /* If the text selected in the window matches the search string, */ ! /* the user is probably using search then replace method, so */ ! /* replace the selected text regardless of where the cursor is. */ ! /* Otherwise, search for the string. */ ! if (!searchMatchesSelection(window, searchString, searchType, ! &startPos, &endPos)) { ! /* get the position to start the search */ ! cursorPos = TextGetCursorPos(window->lastFocus); ! if (direction == SEARCH_BACKWARD) { ! /* use the insert position - 1 for backward searches */ ! beginPos = cursorPos-1; } else { ! /* use the insert position for forward searches */ ! beginPos = cursorPos; } /* do the search */ ! found = SearchWindow(window, direction, searchString, searchType, ! beginPos, &startPos, &endPos); if (!found) ! return FALSE; ! } ! ! /* replace the text */ ! if (searchType == SEARCH_REGEX) { ! char replaceResult[SEARCHMAX], *foundString; ! foundString = BufGetRange(window->buffer, startPos, endPos); ! replaceUsingRE(searchString, replaceString, foundString, ! replaceResult, SEARCHMAX, GetWindowDelimiters(window)); ! XtFree(foundString); ! BufReplace(window->buffer, startPos, endPos, replaceResult); ! replaceLen = strlen(replaceResult); ! } else { ! BufReplace(window->buffer, startPos, endPos, replaceString); ! replaceLen = strlen(replaceString); ! } ! ! /* after successfully completing a replace, selected text attracts ! attention away from the area of the replacement, particularly ! when the selection represents a previous search. so deselect */ ! BufUnselect(window->buffer); ! ! /* temporarily shut off autoShowInsertPos before setting the cursor ! position so MakeSelectionVisible gets a chance to place the replaced ! string at a pleasing position on the screen (otherwise, the cursor would ! be automatically scrolled on screen and MakeSelectionVisible would do ! nothing) */ ! XtVaSetValues(window->lastFocus, textNautoShowInsertPos, False, 0); ! TextSetCursorPos(window->lastFocus, startPos + ! ((direction == SEARCH_FORWARD) ? replaceLen : 0)); ! MakeSelectionVisible(window, window->lastFocus); ! XtVaSetValues(window->lastFocus, textNautoShowInsertPos, True, 0); ! ! return TRUE; ! } --- 1489,1595 ---- { ! int startPos, endPos, replaceLen; ! int found; ! int beginPos, cursorPos; ! ! /* If the text selected in the window matches the search string, */ ! /* the user is probably using search then replace method, so */ ! /* replace the selected text regardless of where the cursor is. */ ! /* Otherwise, search for the string. */ ! if (!searchMatchesSelection(window, searchString, searchType, ! &startPos, &endPos)) { ! /* get the position to start the search */ ! cursorPos = TextGetCursorPos(window->lastFocus); ! if (direction == SEARCH_BACKWARD) { ! /* use the insert position - 1 for backward searches */ ! beginPos = cursorPos-1; ! } else { ! /* use the insert position for forward searches */ ! beginPos = cursorPos; ! } ! /* do the search */ ! found = SearchWindow(window, direction, searchString, searchType, ! beginPos, &startPos, &endPos); ! if (!found) ! return FALSE; ! } ! ! /* replace the text */ ! if (searchType == SEARCH_REGEX) { ! char replaceResult[SEARCHMAX+1], *foundString; ! foundString = BufGetRange(window->editorInfo->buffer, startPos, endPos); ! replaceUsingRE(searchString, replaceString, foundString, ! replaceResult, SEARCHMAX, GetWindowDelimiters(window)); ! XtFree(foundString); ! BufReplace(window->editorInfo->buffer, startPos, endPos, replaceResult); ! replaceLen = strlen(replaceResult); } else { ! BufReplace(window->editorInfo->buffer, startPos, endPos, replaceString); ! replaceLen = strlen(replaceString); ! } ! ! /* after successfully completing a replace, selected text attracts ! attention away from the area of the replacement, particularly ! when the selection represents a previous search. so deselect */ ! BufUnselect(window->editorInfo->buffer); ! ! /* temporarily shut off autoShowInsertPos before setting the cursor ! position so MakeSelectionVisible gets a chance to place the replaced ! string at a pleasing position on the screen (otherwise, the cursor would ! be automatically scrolled on screen and MakeSelectionVisible would do ! nothing) */ ! XtVaSetValues(window->lastFocus, textNautoShowInsertPos, False, 0); ! TextSetCursorPos(window->lastFocus, startPos + ! ((direction == SEARCH_FORWARD) ? replaceLen : 0)); ! MakeSelectionVisible(window, window->lastFocus); ! XtVaSetValues(window->lastFocus, textNautoShowInsertPos, True, 0); ! ! return TRUE; ! } ! ! /* ! ** Replace selection with "replaceString" and search for string "searchString" in window "window", ! ** using algorithm "searchType" and direction "direction" ! */ ! int ReplaceAndSearch(WindowInfo *window, int direction, char *searchString, ! char *replaceString, int searchType) ! { ! int startPos = 0, endPos = 0, replaceLen = 0; ! int found, replaced; ! ! replaced = 0; ! ! /* Replace the selected text only if it matches the search string */ ! if (searchMatchesSelection(window, searchString, searchType, ! &startPos, &endPos)) { ! /* replace the text */ ! if (searchType == SEARCH_REGEX) { ! char replaceResult[SEARCHMAX+1], *foundString; ! foundString = BufGetRange(window->editorInfo->buffer, startPos, endPos); ! replaceUsingRE(searchString, replaceString, foundString, ! replaceResult, SEARCHMAX, GetWindowDelimiters(window)); ! XtFree(foundString); ! BufReplace(window->editorInfo->buffer, startPos, endPos, replaceResult); ! replaceLen = strlen(replaceResult); ! } else { ! BufReplace(window->editorInfo->buffer, startPos, endPos, replaceString); ! replaceLen = strlen(replaceString); ! } ! ! /* Position the cursor so the next search will work correctly based */ ! /* on the direction of the search */ ! TextSetCursorPos(window->lastFocus, startPos + ! ((direction == SEARCH_FORWARD) ? replaceLen : 0)); ! ! replaced = 1; } + /* do the search */ ! found = SearchAndSelect(window, direction, searchString, searchType); ! if (!found) ! XBell(TheDisplay, 100); ! ! return replaced; ! } ! *************** *** 1590,1592 **** /* find out where the selection is */ ! if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) --- 1608,1610 ---- /* find out where the selection is */ ! if (!BufGetSelectionPos(window->editorInfo->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) *************** *** 1596,1602 **** if (isRect) { ! selStart = BufStartOfLine(window->buffer, selStart); ! selEnd = BufEndOfLine(window->buffer, selEnd); ! fileString = BufGetRange(window->buffer, selStart, selEnd); } else ! fileString = BufGetSelectionText(window->buffer); --- 1614,1620 ---- if (isRect) { ! selStart = BufStartOfLine(window->editorInfo->buffer, selStart); ! selEnd = BufEndOfLine(window->editorInfo->buffer, selEnd); ! fileString = BufGetRange(window->editorInfo->buffer, selStart, selEnd); } else ! fileString = BufGetSelectionText(window->editorInfo->buffer); *************** *** 1613,1659 **** beginPos = 0; realOffset = 0; ! while (found) { ! found = SearchString(fileString, searchString, SEARCH_FORWARD, searchType, FALSE, beginPos, &startPos, &endPos, GetWindowDelimiters(window)); ! if (!found) ! break; ! /* if the selection is rectangular, verify that the found ! string is in the rectangle */ ! if (isRect) { ! lineStart = BufStartOfLine(tempBuf, startPos+realOffset); ! if (BufCountDispChars(tempBuf, lineStart, startPos+realOffset) < ! rectStart || BufCountDispChars(tempBuf, lineStart, ! endPos+realOffset) > rectEnd) { beginPos = (startPos == endPos) ? endPos+1 : endPos; ! continue; ! } } - /* Make sure the match did not start past the end (regular expressions - can consider the artificial end of the range as the end of a line, - and match a fictional whole line beginning there) */ - if (startPos == selEnd - selStart) { - found = False; - break; - } - /* replace the string and compensate for length change */ - if (searchType == SEARCH_REGEX) { - char replaceResult[SEARCHMAX], *foundString; - foundString = BufGetRange(tempBuf, startPos+realOffset, - endPos+realOffset); - replaceUsingRE(searchString, replaceString, foundString, - replaceResult, SEARCHMAX, GetWindowDelimiters(window)); - XtFree(foundString); - BufReplace(tempBuf, startPos+realOffset, endPos+realOffset, - replaceResult); - replaceLen = strlen(replaceResult); - } else - BufReplace(tempBuf, startPos+realOffset, endPos+realOffset, - replaceString); - realOffset += replaceLen - (endPos - startPos); - /* start again after match unless match was empty, then endPos+1 */ - beginPos = (startPos == endPos) ? endPos+1 : endPos; - cursorPos = endPos; - anyFound = TRUE; - } XtFree(fileString); --- 1631,1678 ---- beginPos = 0; + cursorPos = 0; realOffset = 0; ! while (found) { ! found = SearchString(fileString, searchString, SEARCH_FORWARD, searchType, FALSE, beginPos, &startPos, &endPos, GetWindowDelimiters(window)); ! if (!found) ! break; ! /* if the selection is rectangular, verify that the found ! string is in the rectangle */ ! if (isRect) { ! lineStart = BufStartOfLine(tempBuf, startPos+realOffset); ! if (BufCountDispChars(tempBuf, lineStart, startPos+realOffset) < ! rectStart || BufCountDispChars(tempBuf, lineStart, ! endPos+realOffset) > rectEnd) { ! beginPos = (startPos == endPos) ? endPos+1 : endPos; ! continue; ! } ! } ! /* Make sure the match did not start past the end (regular expressions ! can consider the artificial end of the range as the end of a line, ! and match a fictional whole line beginning there) */ ! if (startPos == selEnd - selStart) { ! found = False; ! break; ! } ! /* replace the string and compensate for length change */ ! if (searchType == SEARCH_REGEX) { ! char replaceResult[SEARCHMAX+1], *foundString; ! foundString = BufGetRange(tempBuf, startPos+realOffset, ! endPos+realOffset); ! replaceUsingRE(searchString, replaceString, foundString, ! replaceResult, SEARCHMAX, GetWindowDelimiters(window)); ! XtFree(foundString); ! BufReplace(tempBuf, startPos+realOffset, endPos+realOffset, ! replaceResult); ! replaceLen = strlen(replaceResult); ! } else ! BufReplace(tempBuf, startPos+realOffset, endPos+realOffset, ! replaceString); ! realOffset += replaceLen - (endPos - startPos); ! /* start again after match unless match was empty, then endPos+1 */ beginPos = (startPos == endPos) ? endPos+1 : endPos; ! cursorPos = endPos; ! anyFound = TRUE; } XtFree(fileString); *************** *** 1665,1669 **** before DialogF */ - if (window->findDlog && XtIsManaged(window->findDlog) && - !XmToggleButtonGetState(window->findKeepBtn)) - XtUnmanageChild(window->findDlog); if (window->replaceDlog && XtIsManaged(window->replaceDlog) && --- 1684,1685 ---- *************** *** 1673,1675 **** } else ! XBell(TheDisplay, 0); BufFree(tempBuf); --- 1689,1691 ---- } else ! XBell(TheDisplay, 100); BufFree(tempBuf); *************** *** 1681,1683 **** BufFree(tempBuf); ! BufReplace(window->buffer, selStart, selEnd, fileString); XtFree(fileString); --- 1697,1699 ---- BufFree(tempBuf); ! BufReplace(window->editorInfo->buffer, selStart, selEnd, fileString); XtFree(fileString); *************** *** 1690,1692 **** if (!isRect) ! BufSelect(window->buffer, selStart, selEnd + realOffset); --- 1706,1708 ---- if (!isRect) ! BufSelect(window->editorInfo->buffer, selStart, selEnd + realOffset, CHAR_SELECT); *************** *** 1709,1711 **** /* get the entire text buffer from the text area widget */ ! fileString = BufGetAll(window->buffer); --- 1725,1727 ---- /* get the entire text buffer from the text area widget */ ! fileString = BufGetAll(window->editorInfo->buffer); *************** *** 1716,1720 **** if (GetPrefSearchDlogs()) { - if (window->findDlog && XtIsManaged(window->findDlog) && - !XmToggleButtonGetState(window->findKeepBtn)) - XtUnmanageChild(window->findDlog); if (window->replaceDlog && XtIsManaged(window->replaceDlog) && --- 1732,1733 ---- *************** *** 1730,1732 **** /* replace the contents of the text widget with the substituted text */ ! BufReplace(window->buffer, copyStart, copyEnd, newFileString); --- 1743,1745 ---- /* replace the contents of the text widget with the substituted text */ ! BufReplace(window->editorInfo->buffer, copyStart, copyEnd, newFileString); *************** *** 1786,1787 **** --- 1799,1801 ---- } + if (nFound == 0) *************** *** 1828,1830 **** - /* --- 1842,1843 ---- *************** *** 1843,1845 **** /* get the entire text buffer from the text area widget */ ! fileString = BufGetAll(window->buffer); --- 1856,1858 ---- /* get the entire text buffer from the text area widget */ ! fileString = BufGetAll(window->editorInfo->buffer); *************** *** 1847,1893 **** dialogs, or just beep */ ! if (GetPrefSearchDlogs()) { ! found = SearchString(fileString, searchString, direction, searchType, ! FALSE, beginPos, startPos, endPos, GetWindowDelimiters(window)); ! /* Avoid Motif 1.1 bug by putting away search dialog before DialogF */ ! if (window->findDlog && XtIsManaged(window->findDlog) && ! !XmToggleButtonGetState(window->findKeepBtn)) ! XtUnmanageChild(window->findDlog); ! if (window->replaceDlog && XtIsManaged(window->replaceDlog) && ! !XmToggleButtonGetState(window->replaceKeepBtn)) ! XtUnmanageChild(window->replaceDlog); ! if (!found) { ! fileEnd = window->buffer->length - 1; ! if (direction == SEARCH_FORWARD && beginPos != 0) { ! resp = DialogF(DF_QUES, window->shell, 2, ! "Continue search from\nbeginning of file?", "Continue", ! "Cancel"); ! if (resp == 2) { ! XtFree(fileString); ! return False; ! } ! found = SearchString(fileString, searchString, direction, searchType, FALSE, 0, startPos, endPos, GetWindowDelimiters(window)); ! } else if (direction == SEARCH_BACKWARD && beginPos != fileEnd) { ! resp = DialogF(DF_QUES, window->shell, 2, ! "Continue search\nfrom end of file?", "Continue", ! "Cancel"); ! if (resp == 2) { ! XtFree(fileString); ! return False; } ! found = SearchString(fileString, searchString, direction, ! searchType, FALSE, fileEnd, startPos, endPos, ! GetWindowDelimiters(window)); ! } ! if (!found) ! DialogF(DF_INF, window->shell,1,"String was not found","OK"); ! } ! } else { /* no dialogs */ ! found = SearchString(fileString, searchString, direction, ! searchType, TRUE, beginPos, startPos, endPos, ! GetWindowDelimiters(window)); ! if (!found) ! XBell(TheDisplay, 0); ! } --- 1860,1912 ---- dialogs, or just beep */ ! found = SearchString(fileString, searchString, direction, searchType, ! FALSE, beginPos, startPos, endPos, GetWindowDelimiters(window)); ! /* Avoid Motif 1.1 bug by putting away search dialog before DialogF */ ! if (GetPrefSearchDlogs() && window->replaceDlog && ! XtIsManaged(window->replaceDlog) && ! !XmToggleButtonGetState(window->replaceKeepBtn)) ! XtUnmanageChild(window->replaceDlog); ! if (!found) { ! fileEnd = window->editorInfo->buffer->length - 1; ! if (direction == SEARCH_FORWARD && beginPos != 0) { ! if (GetPrefSearchDlogs()) { ! resp = DialogF(DF_QUES, window->shell, 2, ! "Continue search from\nbeginning of file?", "Continue", ! "Cancel"); ! if (resp == 2) { ! XtFree(fileString); ! return False; ! } ! } else { ! /* Ring the bell to indicate that we have wrapped */ ! XBell(TheDisplay, 100); ! } ! found = SearchString(fileString, searchString, direction, searchType, FALSE, 0, startPos, endPos, GetWindowDelimiters(window)); ! } else if (direction == SEARCH_BACKWARD && beginPos != fileEnd) { ! if (GetPrefSearchDlogs()) { ! resp = DialogF(DF_QUES, window->shell, 2, ! "Continue search\nfrom end of file?", "Continue", ! "Cancel"); ! if (resp == 2) { ! XtFree(fileString); ! return False; ! } ! } else { ! /* Ring the bell to indicate that we have wrapped */ ! XBell(TheDisplay, 100); ! } ! found = SearchString(fileString, searchString, direction, ! searchType, FALSE, fileEnd, startPos, endPos, ! GetWindowDelimiters(window)); } ! if (!found) { ! if (GetPrefSearchDlogs()) { ! DialogF(DF_INF, window->shell,1,"String was not found","OK"); ! } else { ! /* Ring the bell to indicate that we have wrapped */ ! XBell(TheDisplay, 100); ! } ! } ! } *************** *** 1949,1951 **** register char *filePtr, *tempPtr, *ucPtr, *lcPtr; ! char lcString[SEARCHMAX], ucString[SEARCHMAX]; --- 1968,1970 ---- register char *filePtr, *tempPtr, *ucPtr, *lcPtr; ! char lcString[SEARCHMAX+1], ucString[SEARCHMAX+1]; *************** *** 2023,2025 **** *endPos = compiledRE->endp[0] - string; ! XtFree((char *)compiledRE); return TRUE; --- 2042,2044 ---- *endPos = compiledRE->endp[0] - string; ! free((char *)compiledRE); return TRUE; *************** *** 2029,2034 **** if (!wrap) { ! XtFree((char *)compiledRE); return FALSE; } ! /* search from the beginning of the string to beginPos */ --- 2048,2053 ---- if (!wrap) { ! free((char *)compiledRE); return FALSE; } ! /* search from the beginning of the string to beginPos */ *************** *** 2038,2040 **** *endPos = compiledRE->endp[0] - string; ! XtFree((char *)compiledRE); return TRUE; --- 2057,2059 ---- *endPos = compiledRE->endp[0] - string; ! free((char *)compiledRE); return TRUE; *************** *** 2042,2044 **** ! XtFree((char *)compiledRE); return FALSE; --- 2061,2063 ---- ! free((char *)compiledRE); return FALSE; *************** *** 2065,2067 **** *endPos = compiledRE->endp[0] - string; ! XtFree((char *)compiledRE); return TRUE; --- 2084,2086 ---- *endPos = compiledRE->endp[0] - string; ! free((char *)compiledRE); return TRUE; *************** *** 2072,2074 **** if (!wrap && beginPos >= 0) { ! XtFree((char *)compiledRE); return FALSE; --- 2091,2093 ---- if (!wrap && beginPos >= 0) { ! free((char *)compiledRE); return FALSE; *************** *** 2085,2090 **** *endPos = compiledRE->endp[0] - string; ! XtFree((char *)compiledRE); return TRUE; } ! XtFree((char *)compiledRE); return FALSE; --- 2104,2109 ---- *endPos = compiledRE->endp[0] - string; ! free((char *)compiledRE); return TRUE; } ! free((char *)compiledRE); return FALSE; *************** *** 2113,2115 **** /* ! ** resetFindTabGroup & resetReplaceTabGroup are really gruesome kludges to ** set the keyboard traversal. XmProcessTraversal does not work at --- 2132,2134 ---- /* ! ** resetReplaceTabGroup are really gruesome kludges to ** set the keyboard traversal. XmProcessTraversal does not work at *************** *** 2118,2131 **** */ - static void resetFindTabGroup(WindowInfo *window) - { - #ifdef MOTIF10 - XmRemoveTabGroup(window->findText); - XmRemoveTabGroup(window->findSearchTypeBox); - XmRemoveTabGroup(window->findBtns); - XmAddTabGroup(window->findText); - XmAddTabGroup(window->findSearchTypeBox); - XmAddTabGroup(window->findBtns); - #endif - XmProcessTraversal(window->findText, XmTRAVERSE_CURRENT); - } static void resetReplaceTabGroup(WindowInfo *window) --- 2137,2138 ---- *************** *** 2158,2160 **** /* find length of selection, give up on no selection or too long */ ! if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) --- 2165,2167 ---- /* find length of selection, give up on no selection or too long */ ! if (!BufGetSelectionPos(window->editorInfo->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) *************** *** 2166,2169 **** if (isRect) { ! lineStart = BufStartOfLine(window->buffer, selStart); ! if (lineStart != BufStartOfLine(window->buffer, selEnd)) return FALSE; --- 2173,2176 ---- if (isRect) { ! lineStart = BufStartOfLine(window->editorInfo->buffer, selStart); ! if (lineStart != BufStartOfLine(window->editorInfo->buffer, selEnd)) return FALSE; *************** *** 2172,2174 **** /* get the selected text */ ! string = BufGetSelectionText(window->buffer); if (*string == '\0') { --- 2179,2181 ---- /* get the selected text */ ! string = BufGetSelectionText(window->editorInfo->buffer); if (*string == '\0') { *************** *** 2194,2196 **** if (isRect) ! GetSimpleSelection(window->buffer, left, right); else { --- 2201,2203 ---- if (isRect) ! GetSimpleSelection(window->editorInfo->buffer, left, right); else { *************** *** 2220,2222 **** SubstituteRE(compiledRE, replaceStr, destStr, maxDestLen); ! XtFree((char *)compiledRE); } --- 2227,2229 ---- SubstituteRE(compiledRE, replaceStr, destStr, maxDestLen); ! free((char *)compiledRE); } *************** *** 2227,2229 **** */ ! static void saveSearchHistory(char *searchString, char *replaceString, int searchType) --- 2234,2236 ---- */ ! void SaveSearchHistory(char *searchString, char *replaceString, int searchType) *************** *** 2268,2270 **** ** return an index into the circular buffer arrays of history information ! ** for search strings, given the number of saveSearchHistory cycles back from ** the current time. --- 2275,2277 ---- ** return an index into the circular buffer arrays of history information ! ** for search strings, given the number of SaveSearchHistory cycles back from ** the current time. *** search.h 1997/09/26 18:28:17 1.1 --- search.h 1997/10/10 00:15:13 1.2 *************** *** 26,29 **** enum SearchDirection {SEARCH_FORWARD, SEARCH_BACKWARD}; ! ! void DoReplaceDlog(WindowInfo *window, int direction); void DoFindDlog(WindowInfo *window, int direction); --- 26,34 ---- enum SearchDirection {SEARCH_FORWARD, SEARCH_BACKWARD}; ! typedef enum _FindReplaceDlogDefaultButton { ! FIND_REPLACE_NO_BUTTON_DEFAULT, ! FIND_REPLACE_FIND_BUTTON_DEFAULT, ! FIND_REPLACE_REPLACE_BUTTON_DEFAULT ! } FindReplaceDlogDefaultButton; ! void DoFindReplaceDlog(WindowInfo *window, int direction, FindReplaceDlogDefaultButton defaultButton, Time time); ! void SetISearchTextCallbacks(WindowInfo *window); void DoFindDlog(WindowInfo *window, int direction); *************** *** 31,32 **** --- 36,41 ---- int searchType); + int SearchAndSelectIncremental(WindowInfo *window, int direction, char *searchString, + int searchType); + void SaveSearchHistory(char *searchString, char *replaceString, + int searchType); int SearchAndSelectSame(WindowInfo *window, int direction); *************** *** 35,37 **** --- 44,49 ---- char *replaceString, int searchType); + int ReplaceAndSearch(WindowInfo *window, int direction, char *searchString, + char *replaceString, int searchType); int ReplaceSame(WindowInfo *window, int direction); + int ReplaceFindSame(WindowInfo *window, int direction); int ReplaceAll(WindowInfo *window, char *searchString, char *replaceString, *************** *** 50 **** --- 62,63 ---- void MatchSelectedCharacter(WindowInfo *window); + void GotoMatchingCharacter(WindowInfo *window); *** selection.c 1997/09/26 18:28:17 1.1 --- selection.c 1997/10/24 01:05:02 1.4 *************** *** 24,26 **** --- 24,28 ---- *******************************************************************************/ + #include #include + #include #include *************** *** 31,34 **** #endif /*VMS*/ ! #if !defined(DONT_HAVE_GLOB) && !defined(USE_MOTIF_GLOB) ! #include #endif --- 33,36 ---- #endif /*VMS*/ ! #ifdef HAVE_GLOB_H ! # include #endif *************** *** 45,51 **** #include "menu.h" ! static void gotoCB(Widget widget, WindowInfo *window, Atom *sel, ! Atom *type, char *value, int *length, int *format); ! static void fileCB(Widget widget, WindowInfo *window, Atom *sel, ! Atom *type, char *value, int *length, int *format); static void getAnySelectionCB(Widget widget, char **result, Atom *sel, --- 47,57 ---- #include "menu.h" + #include "search.h" ! typedef struct _SelectionInfo { ! int done; ! WindowInfo* window; ! char* selection; ! } SelectionInfo; ! ! static void normalizePathToWindow(WindowInfo *window, char *path); static void getAnySelectionCB(Widget widget, char **result, Atom *sel, *************** *** 59,66 **** Boolean *continueDispatch); - static void gotoMarkExtendKeyCB(Widget w, XtPointer clientData, XEvent *event, - Boolean *continueDispatch); static void maintainSelection(selection *sel, int pos, int nInserted, int nDeleted); static void maintainPosition(int *position, int modPos, int nInserted, int nDeleted); --- 65,74 ---- Boolean *continueDispatch); static void maintainSelection(selection *sel, int pos, int nInserted, int nDeleted); + static void gotoMarkExtendKeyCB(Widget w, XtPointer clientData, XEvent *event, + Boolean *continueDispatch); static void maintainPosition(int *position, int modPos, int nInserted, int nDeleted); + static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *sel, + Atom *type, char *value, int *length, int *format); *************** *** 86,89 **** { XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)gotoCB, window, time); } --- 94,118 ---- { + int lineNum; + SelectionInfo selectionInfo; + + selectionInfo.done = 0; + selectionInfo.window = window; + selectionInfo.selection = 0; XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)getSelectionCB, &selectionInfo, time); ! while (selectionInfo.done == 0) { ! XEvent nextEvent; ! XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), &nextEvent); ! XtDispatchEvent(&nextEvent); ! } ! if(selectionInfo.selection == 0) { ! return; ! } ! if (sscanf(selectionInfo.selection, "%d", &lineNum) != 1) { ! XBell(TheDisplay, 0); ! XtFree(selectionInfo.selection); ! return; ! } ! XtFree(selectionInfo.selection); ! SelectNumberedLine(window, lineNum); } *************** *** 92,166 **** { ! XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)fileCB, window, time); ! } ! /* ! ** Getting the current selection by making the request, and then blocking ! ** (processing events) while waiting for a reply. On failure (timeout or ! ** bad format) returns NULL, otherwise returns the contents of the selection. ! */ ! char *GetAnySelection(WindowInfo *window) ! { ! char waitingMarker[1] = ""; ! char *selText = waitingMarker; ! XEvent nextEvent; ! ! /* If the selection is in the window's own buffer get it from there, ! but substitute null characters as if it were an external selection */ ! if (window->buffer->primary.selected) { ! selText = BufGetSelectionText(window->buffer); ! BufUnsubstituteNullChars(selText, window->buffer); ! return selText; ! } ! ! /* Request the selection value to be delivered to getAnySelectionCB */ XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)getAnySelectionCB, &selText, ! XtLastTimestampProcessed(XtDisplay(window->textArea))); ! /* Wait for the value to appear */ ! while (selText == waitingMarker) { ! XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), ! &nextEvent); ! XtDispatchEvent(&nextEvent); } ! return selText; } ! static void gotoCB(Widget widget, WindowInfo *window, Atom *sel, ! Atom *type, char *value, int *length, int *format) { ! char lineText[21]; ! int nRead, lineNum; ! ! /* skip if we can't get the selection data, or it's obviously not a number */ ! if (*type == XT_CONVERT_FAIL || value == NULL) { ! XBell(TheDisplay, 0); ! return; ! } ! if (*length > 20) { ! XBell(TheDisplay, 0); ! XtFree(value); ! return; ! } ! /* should be of type text??? */ ! if (*format != 8) { ! fprintf(stderr, "NEdit: Can't handle non 8-bit text\n"); ! XBell(TheDisplay, 0); ! XtFree(value); ! return; ! } ! strncpy(lineText, value, *length); ! lineText[*length] = '\0'; ! ! nRead = sscanf(lineText, "%d", &lineNum); ! XtFree(value); ! if (nRead != 1) { ! XBell(TheDisplay, 0); ! return; ! } ! ! SelectNumberedLine(window, lineNum); } static void fileCB(Widget widget, WindowInfo *window, Atom *sel, --- 121,267 ---- { ! char *line, *term, *term2; ! int lineNum; ! char buf1[MAXPATHLEN], buf2[MAXPATHLEN]; ! char filename[MAXPATHLEN], pathname[MAXPATHLEN]; ! WindowInfo *windowToSearch; ! #ifdef VMS ! static char badFilenameChars[] = "\n \t*?(){}"; ! #ifndef __DECC ! static char includeDir[] = "sys$library:"; ! #else ! static char includeDir[] = "decc$library_include:"; ! #endif ! #else ! static char badFilenameChars[] = "\n \t*?()[]{}@"; ! static char includeDir[] = "/usr/include/"; ! #endif /* VMS */ ! SelectionInfo selectionInfo; ! selectionInfo.done = 0; ! selectionInfo.window = window; ! selectionInfo.selection = 0; XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)getSelectionCB, &selectionInfo, time); ! while (selectionInfo.done == 0) { ! XEvent nextEvent; ! XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), &nextEvent); ! XtDispatchEvent(&nextEvent); ! } ! if(selectionInfo.selection == 0) { ! return; ! } ! ! /* for each line in the selection */ ! for(line = selectionInfo.selection; ; line = term + 1) { ! char searchString[SEARCHMAX+1]; ! term = strpbrk(line, "\n\f"); ! if(term) ! *term = 0; ! /* extract name from #include syntax */ ! if (sscanf(line, "#include \"%[^\"]\"", buf1) == 1) { ! normalizePathToWindow(window, buf1); ! ParseFilename(buf1, filename, pathname); ! EditExistingFile(WindowList, filename, pathname, CREATE, True); ! } ! else if (sscanf(line, "#include <%[^<>]>", buf1) == 1) { ! sprintf(buf2, "%s%s", includeDir, buf1); ! normalizePathToWindow(window, buf2); ! ParseFilename(buf2, filename, pathname); ! EditExistingFile(WindowList, filename, pathname, CREATE, True); ! } ! /* goto file/line from compiler output */ ! else if (sscanf(line, "%[^:\n \t]: %d", buf1, &lineNum) == 2 ! /* .b: cc output: any selection including <"file.c", line nn:> */ ! || sscanf(line, " \"%[^\"]\", %*s %d", buf1, &lineNum) == 2 ! || sscanf(line, "%*s \"%[^\"]\", %*s %d", buf1, &lineNum) == 2 ! /* .e */ ! || sscanf(line, "\"%[^\"]\", line %d", buf1, &lineNum) == 2) { ! normalizePathToWindow(window, buf1); ! ParseFilename(buf1, filename, pathname); ! windowToSearch = EditExistingFile(WindowList, filename, pathname, CREATE, True); ! if (windowToSearch != NULL) { ! SelectNumberedLine(windowToSearch, lineNum); ! } ! } ! /* goto file/line from grep output */ ! else if (sscanf(line, "%[^:\n \t]: %[^\n]", buf1, searchString) == 2) { ! normalizePathToWindow(window, buf1); ! ParseFilename(buf1, filename, pathname); ! windowToSearch = EditExistingFile(WindowList, filename, pathname, CREATE, True); ! if (windowToSearch != NULL) { ! /* record the search parameters for recall with up arrow */ ! SaveSearchHistory(searchString, NULL, SEARCH_CASE_SENSE); ! ! /* search for it in the window */ ! SearchAndSelect(windowToSearch, SEARCH_FORWARD, searchString, SEARCH_CASE_SENSE); ! } ! } ! else { ! char *path; ! /* edit all of the files on the line using whitespace ! * and other special characters as a delimiters ! */ ! for(path = line; ; path = term2 + 1) { ! /* skip leading non file characters */ ! path += strspn(path, badFilenameChars); ! ! /* stop if empty string */ ! if(*path == 0) ! break; ! ! /* find the end of the filename */ ! term2 = strpbrk(path, badFilenameChars); ! if(term2) { ! *term2 = 0; ! } ! ! if(strlen(path) == 0) { ! break; ! } ! /* Open the file */ ! strcpy(buf1, path); ! #ifndef VMS ! /* Process ~ characters in name */ ! ExpandTilde(buf1); ! #endif ! normalizePathToWindow(window, buf1); ! ParseFilename(buf1, filename, pathname); ! if(EditExistingFile(WindowList, filename, pathname, CREATE, True) == NULL) { ! break; ! } ! ! if(term2 == 0) { ! break; ! } ! } ! } ! ! if(term == 0) { ! break; ! } } ! ! XtFree(selectionInfo.selection); } ! /* ! ** If path is a relative path then make it an absolute path relative ! ** to the current window. If it is already absolute then it is not modified. ! */ ! static void normalizePathToWindow(WindowInfo *window, char *path) { ! char buf1[MAXPATHLEN]; ! int len; ! if(window == 0 || window->editorInfo->path[0] == 0 || path == 0 || *path == '/') ! return; ! strcpy(buf1, window->editorInfo->path); ! len = strlen(buf1); ! if(len > 0 && buf1[len-1] != '/') ! strcat(buf1, "/"); ! strcat(buf1, path); ! strcpy(path, buf1); } + #if 0 static void fileCB(Widget widget, WindowInfo *window, Atom *sel, *************** *** 239,245 **** guranteed to be available, but in practice is there and does work. */ ! #if defined(DONT_HAVE_GLOB) || defined(VMS) ! /* Open the file */ ! ParseFilename(nameText, filename, pathname); ! EditExistingFile(WindowList, filename, pathname, False); ! #elif defined(USE_MOTIF_GLOB) { char **nameList = NULL; int i, nFiles = 0, maxFiles = 30; --- 340,351 ---- guranteed to be available, but in practice is there and does work. */ ! #if defined(HAVE_GLOB_H) ! { glob_t globbuf; int i; ! glob(nameText, GLOB_NOCHECK, NULL, &globbuf); ! for (i=0; ieditorInfo->buffer->primary.selected) { + selText = BufGetSelectionText(window->editorInfo->buffer); + BufUnsubstituteNullChars(selText, window->editorInfo->buffer); + return selText; + } + + /* Request the selection value to be delivered to getAnySelectionCB */ + XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, + (XtSelectionCallbackProc)getAnySelectionCB, &selText, + XtLastTimestampProcessed(XtDisplay(window->textArea))); + + /* Wait for the value to appear */ + while (selText == waitingMarker) { + XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), + &nextEvent); + XtDispatchEvent(&nextEvent); + } + return selText; + } *************** *** 291,293 **** { ! int i, lineStart, lineEnd; --- 426,428 ---- { ! int i, lineStart = 0, lineEnd; *************** *** 297,305 **** lineEnd = -1; ! for (i=1; i<=lineNum && lineEndbuffer->length; i++) { lineStart = lineEnd + 1; ! lineEnd = BufEndOfLine(window->buffer, lineStart); } /* highlight the line */ ! BufSelect(window->buffer, lineStart, lineEnd+1); MakeSelectionVisible(window, window->lastFocus); --- 432,451 ---- lineEnd = -1; ! for (i=1; i<=lineNum && lineEndeditorInfo->buffer->length; i++) { lineStart = lineEnd + 1; ! lineEnd = BufEndOfLine(window->editorInfo->buffer, lineStart); } + + /* .b: Warn if file has less lines than numbered */ + if (lineNum > i-1) { + char msg[40]; + + XBell(TheDisplay, 0); + sprintf(msg, "Last line number: %d", i-1); + DialogF(DF_WARN, window->shell, 1, msg, "OK"); + return; + } + /* .e */ /* highlight the line */ ! BufSelect(window->editorInfo->buffer, lineStart, lineEnd+1, CHAR_SELECT); MakeSelectionVisible(window, window->lastFocus); *************** *** 458,460 **** if (index >= MAX_MARKS) { ! fprintf(stderr, "no more marks allowed\n"); /* shouldn't happen */ return; --- 604,606 ---- if (index >= MAX_MARKS) { ! DialogF(DF_WARN, window->shell, 1, "No more marks allowed.", "OK"); /* shouldn't happen */ return; *************** *** 466,468 **** window->markTable[index].label = label; ! memcpy(&window->markTable[index].sel, &window->buffer->primary, sizeof(selection)); --- 612,614 ---- window->markTable[index].label = label; ! memcpy(&window->markTable[index].sel, &window->editorInfo->buffer->primary, sizeof(selection)); *************** *** 489,491 **** sel = &window->markTable[index].sel; ! oldSel = &window->buffer->primary; cursorPos = window->markTable[index].cursorPos; --- 635,637 ---- sel = &window->markTable[index].sel; ! oldSel = &window->editorInfo->buffer->primary; cursorPos = window->markTable[index].cursorPos; *************** *** 496,499 **** newEnd = sel->selected ? sel->end : cursorPos; ! BufSelect(window->buffer, oldStart < newStart ? oldStart : newStart, ! oldEnd > newEnd ? oldEnd : newEnd); } else { --- 642,645 ---- newEnd = sel->selected ? sel->end : cursorPos; ! BufSelect(window->editorInfo->buffer, oldStart < newStart ? oldStart : newStart, ! oldEnd > newEnd ? oldEnd : newEnd, CHAR_SELECT); } else { *************** *** 501,508 **** if (sel->rectangular) ! BufRectSelect(window->buffer, sel->start, sel->end, sel->rectStart, sel->rectEnd); else ! BufSelect(window->buffer, sel->start, sel->end); } else ! BufUnselect(window->buffer); } --- 647,654 ---- if (sel->rectangular) ! BufRectSelect(window->editorInfo->buffer, sel->start, sel->end, sel->rectStart, sel->rectEnd); else ! BufSelect(window->editorInfo->buffer, sel->start, sel->end, sel->type); } else ! BufUnselect(window->editorInfo->buffer); } *************** *** 566,567 **** --- 712,741 ---- *position = modPos; + } + + static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *sel, + Atom *type, char *value, int *length, int *format) + { + WindowInfo *window = selectionInfo->window; + + /* skip if we can't get the selection data or it's too long */ + if (*type == XT_CONVERT_FAIL || *type != XA_STRING || value == NULL || *length == 0) { + XBell(TheDisplay, 0); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + /* should be of type text??? */ + if (*format != 8) { + DialogF(DF_WARN, window->shell, 1, "NEdit can't handle non 8-bit text", "OK"); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + selectionInfo->selection = XtMalloc(*length+1); + memcpy(selectionInfo->selection, value, *length); + selectionInfo->selection[*length] = 0; + XtFree(value); + selectionInfo->done = 1; } *** server.c 1997/09/26 18:28:17 1.1 --- server.c 1997/10/10 00:15:48 1.2 *************** *** 24,28 **** *******************************************************************************/ #include #include ! #include #ifdef VMS --- 24,34 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif ! #ifdef HAVE_FCNTL_H ! # include ! #endif #ifdef VMS *************** *** 37,41 **** #include ! #include #include #endif #include --- 43,50 ---- #include ! #ifdef HAVE_UNISTD_H ! # include ! #endif #include #endif + #include #include *************** *** 49,50 **** --- 58,60 ---- #include "menu.h" + #include "server_common.h" #include "server.h" *************** *** 52,69 **** - /* If anyone knows where to get this from system include files (in a machine - independent way), please change this (L_cuserid is apparently not ANSI) */ - #define MAXUSERNAMELEN 32 - - #if defined(VMS) || defined(linux) - #define MAXNODENAMELEN (MAXPATHLEN+2) - #elif defined(SUNOS) - #define MAXNODENAMELEN 9 - #else - #define MAXNODENAMELEN SYS_NMLN - #endif - static void processServerCommand(void); static void cleanUpServerCommunication(void); - static char *getUserName(void); - static void getHostName(char *hostname); static void processServerCommandString(char *string); --- 62,65 ---- *************** *** 74,75 **** --- 70,104 ---- /* + ** Make NEdit a daemon/background process. + */ + int DaemonInit(void) + { + pid_t pid; + int fd; + + if((pid = fork()) < 0) { + return(-1); + } else if(pid != 0) { + exit(0); /* parent exits */ + } + + /* The child should do the following: + ** - Become the session leader which sets the process group ID + ** and session ID to our process ID, and releases the process's + ** controlling terminal. + */ + setsid(); + + /* Attach stdin, stderr, stdout to /dev/null so rsh won't hang + ** because we had stdout/stderr open back to it. + */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + return(0); + } + + /* ** Set up inter-client communication for NEdit server end, expected to be *************** *** 77,101 **** */ ! void InitServerCommunication(void) { Window rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay)); ! char *userName, propName[23+MAXNODENAMELEN+MAXUSERNAMELEN]; ! char hostName[MAXNODENAMELEN+1]; ! char serverName[MAXPATHLEN+2]; ! ! /* Create server property atoms. Atom names are generated by ! concatenating NEDIT_SERVER_REQUEST_, and NEDIT_SERVER_EXITS_ ! with hostname and user name. */ ! userName = getUserName(); ! getHostName(hostName); ! if (GetPrefServerName()[0] != '\0') { ! serverName[0] = '_'; ! strcpy(&serverName[1], GetPrefServerName()); ! } else ! serverName[0] = '\0'; ! sprintf(propName, "NEDIT_SERVER_EXISTS_%s_%s%s", hostName, userName, ! serverName); ! ServerExistsAtom = XInternAtom(TheDisplay, propName, False); ! sprintf(propName, "NEDIT_SERVER_REQUEST_%s_%s%s", hostName, userName, ! serverName); ! ServerRequestAtom = XInternAtom(TheDisplay, propName, False); --- 106,114 ---- */ ! void InitServerCommunication(char *serverName) { Window rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay)); ! ! /* Create the server property atoms on the current DISPLAY. */ ! CreateServerPropertyAtoms(serverName, &ServerExistsAtom, ! &ServerRequestAtom); *************** *** 105,110 **** XChangeProperty(TheDisplay, rootWindow, ServerExistsAtom, XA_STRING, 8, ! PropModeReplace, (unsigned char *)"True", 4); /* Set up exit handler for cleaning up server-exists property */ atexit(cleanUpServerCommunication); --- 118,129 ---- XChangeProperty(TheDisplay, rootWindow, ServerExistsAtom, XA_STRING, 8, ! PropModeReplace, (unsigned char *)"Running", 7); /* Set up exit handler for cleaning up server-exists property */ + #ifdef HAVE_ATEXIT atexit(cleanUpServerCommunication); + #else + # ifdef HAVE_ON_EXIT + on_exit(cleanUpServerCommunication, 0); + # endif + #endif *************** *** 119,120 **** --- 138,141 ---- { + WindowInfo *w; + /* Delete the server-exists property from the root window (if it was *************** *** 125,128 **** DefaultScreen(TheDisplay)), ServerExistsAtom); - XSync(TheDisplay, True); } } --- 146,158 ---- DefaultScreen(TheDisplay)), ServerExistsAtom); } + + /* Delete any file open properties that still exist */ + for(w = WindowList; w; w = w->next) { + if(w->editorInfo->fileOpenAtom != None) { + XDeleteProperty(TheDisplay, RootWindow(TheDisplay, + DefaultScreen(TheDisplay)), w->editorInfo->fileOpenAtom); + w->editorInfo->fileOpenAtom = None; + } + } + XSync(TheDisplay, True); } *************** *** 142,143 **** --- 172,174 ---- Window rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay)); + WindowInfo *w; *************** *** 145,147 **** XtAppNextEvent(context, &event); ! if (e->window == rootWindow) { if (e->atom == ServerRequestAtom && e->state == PropertyNewValue) --- 176,178 ---- XtAppNextEvent(context, &event); ! if (e->type == PropertyNotify && e->window == rootWindow) { if (e->atom == ServerRequestAtom && e->state == PropertyNewValue) *************** *** 150,152 **** XChangeProperty(TheDisplay, rootWindow, ServerExistsAtom, ! XA_STRING, 8, PropModeReplace, (unsigned char *)"True", 4); } --- 181,192 ---- XChangeProperty(TheDisplay, rootWindow, ServerExistsAtom, ! XA_STRING, 8, PropModeReplace, (unsigned char *)"Running", 7); ! else if(e->state == PropertyDelete) { ! /* If the property for an open window was deleted then recreate it. */ ! for(w = WindowList; w; w = w->next) { ! if(w->editorInfo->fileOpenAtom == e->atom) { ! XChangeProperty(TheDisplay, rootWindow, w->editorInfo->fileOpenAtom, ! XA_STRING, 8, PropModeReplace, (unsigned char *)"Open", 4); ! } ! } ! } } *************** *** 156,157 **** --- 196,241 ---- + /* + ** Update the file open property on the root window to inform nc that + ** the file is open. + */ + void CreateFileOpenProperty(WindowInfo *window) { + char path[MAXPATHLEN]; + + if(!window->editorInfo->filenameSet) { + /* If the filename is not set then make sure the atom has been + ** destroyed. + */ + DestroyFileOpenProperty(window); + return; + } + + strcpy(path, window->editorInfo->path); + strcat(path, window->editorInfo->filename); + + /* Get the property atom for path. */ + if(window->editorInfo->fileOpenAtom == None) { + CreateServerFileOpenAtom(GetPrefServerName(), path, &window->editorInfo->fileOpenAtom); + } + + /* Create the file open property on the root window to communicate + to nc that the file has been opened. */ + if(window->editorInfo->fileOpenAtom != None) { + XChangeProperty(TheDisplay, RootWindow(TheDisplay, + DefaultScreen(TheDisplay)), window->editorInfo->fileOpenAtom, XA_STRING, 8, + PropModeReplace, (unsigned char *)"Open", 4); + } + } + + void DestroyFileOpenProperty(WindowInfo *window) { + /* destroy the file open atom to inform nc that this file has + ** been closed. + */ + if(window->editorInfo->fileOpenAtom != None) { + XDeleteProperty(TheDisplay, RootWindow(TheDisplay, + DefaultScreen(TheDisplay)), window->editorInfo->fileOpenAtom); + XSync(TheDisplay, False); + window->editorInfo->fileOpenAtom = None; + } + } + static void processServerCommand(void) *************** *** 175,237 **** - /* - ** Return a pointer to the username of the current user in a statically - ** allocated string. - */ - static char *getUserName(void) - { - #ifdef VMS - return cuserid(NULL); - #else - /* This should be simple, but cuserid has apparently been dropped from - the ansi C standard, and if strict ansi compliance is turned on (on - Sun anyhow, maybe others), calls to cuserid fail to compile. - Unfortunately the alternative is this weird sequence of getlogin - followed by getpwuid. Getlogin only works if a terminal is attached & - there can be more than one name associated with a uid (really?). Both - calls return a pointer to a static area. */ - char *name; - struct passwd *passwdEntry; - - name = getlogin(); - if (name == NULL || name[0] == '\0') { - passwdEntry = getpwuid(getuid()); - name = passwdEntry->pw_name; - } - return name; - #endif - } - - /* - ** Writes the hostname of the current system in string "hostname". - */ - static void getHostName(char *hostname) - { - #ifdef VMS - /* This should be simple, but uname is not supported in the DEC C RTL and - gethostname on VMS depends either on Multinet or UCX. So use uname - on Unix, and use LIB$GETSYI on VMS. Note the VMS hostname will - be in DECNET format with trailing double colons, e.g. "FNALV1::". */ - int syi_status; - struct dsc$descriptor_s *hostnameDesc; - unsigned long int syiItemCode = SYI$_NODENAME; /* get Nodename */ - unsigned long int unused = 0; - unsigned short int hostnameLen = MAXNODENAMELEN+1; - - hostnameDesc = NulStrWrtDesc(hostname, MAXNODENAMELEN+1); - syi_status = lib$getsyi(&syiItemCode, &unused, hostnameDesc, &hostnameLen, - 0, 0); - if (syi_status != SS$_NORMAL) { - fprintf(stderr, "Error return from lib$getsyi: %d", syi_status); - strcpy(hostname, "VMS"); - } else - hostname[hostnameLen] = '\0'; - FreeStrDesc(hostnameDesc); - #else - struct utsname nameStruct; - - uname(&nameStruct); - strcpy(hostname, nameStruct.nodename); - #endif - } - static void processServerCommandString(char *string) --- 259,260 ---- *************** *** 242,244 **** int lineNum, createFlag, readFlag, fileLen, doLen, charsRead, itemsRead; ! WindowInfo *window; --- 265,267 ---- int lineNum, createFlag, readFlag, fileLen, doLen, charsRead, itemsRead; ! WindowInfo *window = 0; *************** *** 248,253 **** for (window=WindowList; window!=NULL; window=window->next) ! if (!window->filenameSet && !window->fileChanged) break; if (window == NULL) { ! EditNewFile(); CheckCloseDim(); --- 271,276 ---- for (window=WindowList; window!=NULL; window=window->next) ! if (!window->editorInfo->filenameSet && !window->editorInfo->fileChanged) break; if (window == NULL) { ! EditNewFile(NULL); CheckCloseDim(); *************** *** 293,298 **** ParseFilename(fullname, filename, pathname); ! window = FindWindowWithFile(filename, pathname); ! if (window == NULL) { ! EditExistingFile(WindowList, filename, pathname, editFlags); ! window = WindowList; } --- 316,328 ---- ParseFilename(fullname, filename, pathname); ! window = EditExistingFile(WindowList, filename, pathname, editFlags, False); ! if (window == NULL) { ! continue; ! } ! /* See if the iconic resource is set. If it is not then force the ! ** window to the top. */ ! {Boolean iconic; ! XtVaGetValues(window->shell, XmNiconic, &iconic, 0); ! if(!iconic) { ! XMapRaised(TheDisplay, XtWindow(window->shell)); ! } } *************** *** 301,303 **** command can do anything, including closing the window!) */ - XMapRaised(TheDisplay, XtWindow(window->shell)); if (lineNum > 0) --- 331,332 ---- *************** *** 306,307 **** --- 335,339 ---- DoMacro(window, doCommand); + + UpdateWindowReadOnly(window); + UpdateWindowTitle(window); } *************** *** 314 **** --- 346,348 ---- } + + *** server.h 1997/09/26 18:28:17 1.1 --- server.h 1997/10/10 00:15:48 1.2 *************** *** 1 **** --- 1,26 ---- + /******************************************************************************* + * * + * server.c -- Nirvana Editor edit-server component * + * * + * Copyright (c) 1991 Universities Research Association, Inc. * + * All rights reserved. * + * * + * This material resulted from work developed under a Government Contract and * + * is subject to the following license: The Government retains a paid-up, * + * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * + * works, perform publicly and display publicly by or for the Government, * + * including the right to distribute to other Government contractors. Neither * + * the United States nor the United States Department of Energy, nor any of * + * their employees, makes any warrenty, express or implied, or assumes any * + * legal liability or responsibility for the accuracy, completeness, or * + * usefulness of any information, apparatus, product, or process disclosed, or * + * represents that its use would not infringe privately owned rights. * + * * + * Fermilab Nirvana GUI Library * + * November, 1995 * + * * + * Written by Mark Edel * + * * + *******************************************************************************/ + #define NO_CONNECTION -1 *************** *** 4,7 **** ! void InitServerCommunication(void); void ServerMainLoop(XtAppContext context); ! char *CreateServerPropName(char *propType); --- 29,34 ---- ! int DaemonInit(void); ! void InitServerCommunication(char *serverName); void ServerMainLoop(XtAppContext context); ! void CreateFileOpenProperty(WindowInfo *window); ! void DestroyFileOpenProperty(WindowInfo *window); *** server_common.c 1997/10/09 23:29:19 1.1 --- server_common.c 1997/10/21 21:37:42 1.3 *************** *** 0 **** --- 1,159 ---- + /******************************************************************************* + * * + * server_common.c -- Nirvana Editor common server stuff * + * * + * Copyright (c) 1991 Universities Research Association, Inc. * + * All rights reserved. * + * * + * This material resulted from work developed under a Government Contract and * + * is subject to the following license: The Government retains a paid-up, * + * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * + * works, perform publicly and display publicly by or for the Government, * + * including the right to distribute to other Government contractors. Neither * + * the United States nor the United States Department of Energy, nor any of * + * their employees, makes any warrenty, express or implied, or assumes any * + * legal liability or responsibility for the accuracy, completeness, or * + * usefulness of any information, apparatus, product, or process disclosed, or * + * represents that its use would not infringe privately owned rights. * + * * + * Fermilab Nirvana GUI Library * + * September, 1996 * + * * + * Written by Mark Edel * + * * + *******************************************************************************/ + #include + #include + #include + #ifdef HAVE_LIMITS_H + # include + #endif + #ifdef VMS + #include + #include ssdef + #include syidef + #include "../util/VMSparam.h" + #include "../util/VMSutils.h" + #else + #include + #include + #include + #ifdef HAVE_UNISTD_H + # include + #endif + #include + #endif + #include + #include "../util/fileUtils.h" + #include "textBuf.h" + #include "nedit.h" + #include "clearcase.h" + #include "server_common.h" + + /* + ** Return a pointer to the username of the real user in a statically + ** allocated string. If we can not get the user name from the + ** password info then return the real uid as a static string. + */ + static char *getUserName(void) + { + #ifdef VMS + return cuserid(NULL); + #else + struct passwd *passwdEntry; + static char name[16] = ""; + + passwdEntry = getpwuid(getuid()); + if (passwdEntry == NULL) { + sprintf(name, "%05d", (unsigned int)getuid()); + } + else { + strncpy(name, passwdEntry->pw_name, sizeof(name)); + name[sizeof(name)-1] = 0; + } + return name; + #endif + } + + /* + * Create the server property atoms for the server with serverName. + * Atom names are generated as follows: + * + * NEDIT_SERVER_EXISTS__[_] + * NEDIT_SERVER_REQUEST__[_] + * + * is the name that can be set by the user to allow + * for multiple servers to run on the same display. + * defaults to "" if not supplied by the user. + * + * is the user name of the current user. + * + * is the clearcase view tag attached to the + * current process. + */ + void CreateServerPropertyAtoms( + char *serverName, + Atom *serverExistsAtomReturn, + Atom *serverRequestAtomReturn + ) { + char propName[23+MAXSERVERNAMELEN+MAXUSERNAMELEN+MAXCCASEVIEWTAGLEN]; + char *userName; + char *ccaseViewTag; + + userName = getUserName(); + ccaseViewTag = GetClearCaseViewTag(); + if(ccaseViewTag && strcmp(ccaseViewTag, "") != 0) { + sprintf(propName, "NEDIT_SERVER_EXISTS_%s_%s_%s", serverName, userName, ccaseViewTag); + *serverExistsAtomReturn = XInternAtom(TheDisplay, propName, False); + sprintf(propName, "NEDIT_SERVER_REQUEST_%s_%s_%s", serverName, userName, ccaseViewTag); + *serverRequestAtomReturn = XInternAtom(TheDisplay, propName, False); + } + else { + sprintf(propName, "NEDIT_SERVER_EXISTS_%s_%s", serverName, userName); + *serverExistsAtomReturn = XInternAtom(TheDisplay, propName, False); + sprintf(propName, "NEDIT_SERVER_REQUEST_%s_%s", serverName, userName); + *serverRequestAtomReturn = XInternAtom(TheDisplay, propName, False); + } + return; + } + + /* + * Create the individual property atoms for each file being + * opened by the server with serverName. This atom is used + * by nc to monitor if the file has been closed. + * + * Atom names are generated as follows: + * + * NEDIT_FILE__[_]_ + * + * is the name that can be set by the user to allow + * for multiple servers to run on the same display. + * defaults to "" if not supplied by the user. + * + * is the user name of the current user. + * + * is the clearcase view tag attached to the + * current process. + * + * is the path of the file being edited. + */ + void CreateServerFileOpenAtom( + char *serverName, + char *path, + Atom *fileOpenAtomReturn + ) { + char propName[18+MAXSERVERNAMELEN+1+MAXUSERNAMELEN+1+MAXCCASEVIEWTAGLEN+1+MAXPATHLEN+1]; + char *userName; + char *ccaseViewTag; + + userName = getUserName(); + ccaseViewTag = GetClearCaseViewTag(); + if(ccaseViewTag && strcmp(ccaseViewTag, "") != 0) { + sprintf(propName, "NEDIT_SERVER_FILE_%s_%s_%s_%s", serverName, userName, ccaseViewTag, path); + } + else { + sprintf(propName, "NEDIT_SERVER_FILE_%s_%s_%s", serverName, userName, path); + } + *fileOpenAtomReturn = XInternAtom(TheDisplay, propName, False); + return; + } *** server_common.h 1997/10/09 23:29:19 1.1 --- server_common.h 1997/10/10 00:15:48 1.2 *************** *** 0 **** --- 1,50 ---- + + /******************************************************************************* + * * + * server_common.h -- Nirvana Editor common server stuff * + * * + * Copyright (c) 1991 Universities Research Association, Inc. * + * All rights reserved. * + * * + * This material resulted from work developed under a Government Contract and * + * is subject to the following license: The Government retains a paid-up, * + * nonexclusive, irrevocable worldwide license to reproduce, prepare derivative * + * works, perform publicly and display publicly by or for the Government, * + * including the right to distribute to other Government contractors. Neither * + * the United States nor the United States Department of Energy, nor any of * + * their employees, makes any warrenty, express or implied, or assumes any * + * legal liability or responsibility for the accuracy, completeness, or * + * usefulness of any information, apparatus, product, or process disclosed, or * + * represents that its use would not infringe privately owned rights. * + * * + * Fermilab Nirvana GUI Library * + * September, 1996 * + * * + * Written by Mark Edel * + * * + *******************************************************************************/ + + #ifndef _server_common_h_ + #define _server_common_h_ + + /* If anyone knows where to get this from system include files (in a machine + independent way), please change this (L_cuserid is apparently not ANSI) */ + #define MAXUSERNAMELEN 32 + + /* Lets limit the unique server name to MAXPATHLEN */ + #define MAXSERVERNAMELEN MAXPATHLEN + + #define DEFAULTSERVERNAME "" + + void CreateServerPropertyAtoms( + char *serverName, + Atom *serverExistsAtomReturn, + Atom *serverRequestAtomReturn + ); + void CreateServerFileOpenAtom( + char *serverName, + char *path, + Atom *fileOpenAtomReturn + ); + + #endif *** shell.c 1997/09/26 18:28:17 1.1 --- shell.c 1997/10/24 22:15:53 1.5 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 27,40 **** #include ! #include #include ! #include ! #include ! #include ! #ifdef notdef ! #ifdef IBM ! #define NBBY 8 ! #include #endif ! #include #endif #include --- 28,63 ---- #include ! #include #include ! #ifdef HAVE_SYS_WAIT_H ! # include ! #endif ! #ifndef WEXITSTATUS ! # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) ! #endif ! #ifndef WIFEXITED ! # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) ! #endif ! #ifdef HAVE_SYS_SELECT_H ! # include #endif ! #ifdef HAVE_UNISTD_H ! # include #endif + #ifdef HAVE_FCNTL_H + # include + #endif + #ifdef HAVE_LIMITS_H + # include + #endif + #if TIME_WITH_SYS_TIME + # include + # include + #else + # if HAVE_SYS_TIME_H + # include + # else + # include + # endif + #endif + #include #include *************** *** 46,47 **** --- 69,71 ---- #include + #include #include "../util/DialogF.h" *************** *** 60,62 **** #define IO_BUF_SIZE 4096 /* size of buffers for collecting cmd output */ ! #define MAX_SHELL_CMD_LEN 1024 /* max length of a shell command (should be eliminated, but substitutePercent needs) */ --- 84,86 ---- #define IO_BUF_SIZE 4096 /* size of buffers for collecting cmd output */ ! #define MAX_SHELL_CMD_LEN 2048 /* max length of a shell command (should be eliminated, but substitutePercent needs) */ *************** *** 76,77 **** --- 100,102 ---- #define OUTPUT_TO_STRING 32 + #define OUTPUT_TO_NEW_WINDOW 64 *************** *** 115,117 **** static void removeTrailingNewlines(char *string); ! static void createOutputDialog(Widget parent, char *text); static void destroyOutDialogCB(Widget w, XtPointer callback, XtPointer closure); --- 140,143 ---- static void removeTrailingNewlines(char *string); ! static Widget createOutputDialog(WindowInfo *window, char *text, ! unsigned char dialogStyle); static void destroyOutDialogCB(Widget w, XtPointer callback, XtPointer closure); *************** *** 119,122 **** static void truncateString(char *string, int length); ! static int substitutePercent(char *outStr, char *inStr, char *subsStr, ! int outLen); static void bannerTimeoutProc(XtPointer clientData, XtIntervalId *id); --- 145,148 ---- static void truncateString(char *string, int length); ! static int substitutePercent(WindowInfo *window, char *outStr, char *inStr, ! char *subsStr, int outLen); static void bannerTimeoutProc(XtPointer clientData, XtIntervalId *id); *************** *** 133,134 **** --- 159,161 ---- char *text; + char subsCommand[MAX_SHELL_CMD_LEN], fullName[MAXPATHLEN]; *************** *** 142,144 **** occupies. Beep and return if no selection */ ! text = BufGetSelectionText(window->buffer); if (*text == '\0') { --- 169,171 ---- occupies. Beep and return if no selection */ ! text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { *************** *** 148,156 **** } textLen = strlen(text); ! BufUnsubstituteNullChars(text, window->buffer); ! left = window->buffer->primary.start; ! right = window->buffer->primary.end; /* Issue the command and collect its output */ ! issueCommand(window, command, text, textLen, ACCUMULATE | ERROR_DIALOGS | REPLACE_SELECTION, window->lastFocus, left, right, fromMacro); --- 175,193 ---- } + + /* Substitute the current file name for % in the shell command */ + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); + /* .b: Dialog message is now inside function */ + if (!substitutePercent(window, subsCommand, command, fullName, + MAX_SHELL_CMD_LEN)) + return; + /* .e */ + textLen = strlen(text); ! BufUnsubstituteNullChars(text, window->editorInfo->buffer); ! left = window->editorInfo->buffer->primary.start; ! right = window->editorInfo->buffer->primary.end; /* Issue the command and collect its output */ ! issueCommand(window, subsCommand, text, textLen, ACCUMULATE | ERROR_DIALOGS | REPLACE_SELECTION, window->lastFocus, left, right, fromMacro); *************** *** 166,168 **** int left, right, flags = 0; ! /* Can't do two shell commands at once in the same window */ --- 203,206 ---- int left, right, flags = 0; ! char subsCommand[MAX_SHELL_CMD_LEN], fullName[MAXPATHLEN]; ! /* Can't do two shell commands at once in the same window */ *************** *** 174,176 **** /* get the selection or the insert position */ ! if (GetSimpleSelection(window->buffer, &left, &right)) flags = ACCUMULATE | REPLACE_SELECTION; --- 212,214 ---- /* get the selection or the insert position */ ! if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags = ACCUMULATE | REPLACE_SELECTION; *************** *** 179,182 **** /* issue the command */ ! issueCommand(window, command, NULL, 0, flags, window->lastFocus, left, right, fromMacro); --- 217,229 ---- + /* Substitute the current file name for % in the shell command */ + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); + /* .b: Dialog message is now inside function */ + if (!substitutePercent(window, subsCommand, command, fullName, + MAX_SHELL_CMD_LEN)) + return; + /* .e */ + /* issue the command */ ! issueCommand(window, subsCommand, NULL, 0, flags, window->lastFocus, left, right, fromMacro); *************** *** 217,230 **** /* get all of the text on the line with the insert position */ ! if (!GetSimpleSelection(window->buffer, &left, &right)) { left = right = TextGetCursorPos(window->lastFocus); ! left = BufStartOfLine(window->buffer, left); ! right = BufEndOfLine(window->buffer, right); insertPos = right; } else ! insertPos = BufEndOfLine(window->buffer, right); ! cmdText = BufGetRange(window->buffer, left, right); ! BufUnsubstituteNullChars(cmdText, window->buffer); /* insert a newline after the entire line */ ! BufInsert(window->buffer, insertPos, "\n"); --- 264,277 ---- /* get all of the text on the line with the insert position */ ! if (!GetSimpleSelection(window->editorInfo->buffer, &left, &right)) { left = right = TextGetCursorPos(window->lastFocus); ! left = BufStartOfLine(window->editorInfo->buffer, left); ! right = BufEndOfLine(window->editorInfo->buffer, right); insertPos = right; } else ! insertPos = BufEndOfLine(window->editorInfo->buffer, right); ! cmdText = BufGetRange(window->editorInfo->buffer, left, right); ! BufUnsubstituteNullChars(cmdText, window->editorInfo->buffer); /* insert a newline after the entire line */ ! BufInsert(window->editorInfo->buffer, insertPos, "\n"); *************** *** 233,234 **** --- 280,282 ---- insertPos+1, fromMacro); + XtFree(cmdText); *************** *** 257,269 **** - /* Substitute the current file name for % in the shell command */ - strcpy(fullName, window->path); - strcat(fullName, window->filename); - if (!substitutePercent(subsCommand, command, fullName, - MAX_SHELL_CMD_LEN)) { - DialogF(DF_ERR, window->shell, 1, - "Shell command is too long due to\nfilename substitutions with '%%'", - "OK"); - return; - } - /* Get the command input as a text string. If there is input, errors --- 305,306 ---- *************** *** 271,273 **** if (input == FROM_SELECTION) { ! text = BufGetSelectionText(window->buffer); if (*text == '\0') { --- 308,310 ---- if (input == FROM_SELECTION) { ! text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { *************** *** 279,287 **** } else if (input == FROM_WINDOW) { ! text = BufGetAll(window->buffer); flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_EITHER) { ! text = BufGetSelectionText(window->buffer); if (*text == '\0') { XtFree(text); ! text = BufGetAll(window->buffer); } --- 316,324 ---- } else if (input == FROM_WINDOW) { ! text = BufGetAll(window->editorInfo->buffer); flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_EITHER) { ! text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { XtFree(text); ! text = BufGetAll(window->editorInfo->buffer); } *************** *** 294,299 **** if (text != NULL) { ! textLen = strlen(text); ! BufUnsubstituteNullChars(text, window->buffer); } else ! textLen = 0; --- 331,336 ---- if (text != NULL) { ! textLen = strlen(text); ! BufUnsubstituteNullChars(text, window->editorInfo->buffer); } else ! textLen = 0; *************** *** 304,311 **** outWidget = NULL; ! flags |= OUTPUT_TO_DIALOG; left = right = 0; } else if (output == TO_NEW_WINDOW) { ! EditNewFile(); ! outWidget = WindowList->textArea; ! inWindow = WindowList; left = right = 0; --- 341,348 ---- outWidget = NULL; ! flags |= OUTPUT_TO_DIALOG; left = right = 0; } else if (output == TO_NEW_WINDOW) { ! inWindow = EditNewFile(window); ! outWidget = inWindow->textArea; ! flags |= OUTPUT_TO_NEW_WINDOW; left = right = 0; *************** *** 316,323 **** left = 0; ! right = window->buffer->length; } else if (input == FROM_SELECTION) { ! GetSimpleSelection(window->buffer, &left, &right); flags |= ACCUMULATE | REPLACE_SELECTION; } else if (input == FROM_EITHER) { ! if (GetSimpleSelection(window->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; --- 353,360 ---- left = 0; ! right = window->editorInfo->buffer->length; } else if (input == FROM_SELECTION) { ! GetSimpleSelection(window->editorInfo->buffer, &left, &right); flags |= ACCUMULATE | REPLACE_SELECTION; } else if (input == FROM_EITHER) { ! if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; *************** *** 325,327 **** left = 0; ! right = window->buffer->length; } --- 362,364 ---- left = 0; ! right = window->editorInfo->buffer->length; } *************** *** 329,331 **** } else { ! if (GetSimpleSelection(window->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; --- 366,368 ---- } else { ! if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; *************** *** 336,337 **** --- 373,380 ---- + /* Catch errors in the command if the user wants the file loaded + ** after the command. */ + if (loadAfter) { + flags |= ACCUMULATE | ERROR_DIALOGS; + } + /* If the command requires the file be saved first, save it */ *************** *** 345,346 **** --- 388,398 ---- + /* Substitute the current file name for % in the shell command */ + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); + /* .b: Dialog message is now inside function */ + if (!substitutePercent(window, subsCommand, command, fullName, + MAX_SHELL_CMD_LEN)) + return; + /* .e */ + /* If the command requires the file to be reloaded after execution, set *************** *** 369,370 **** --- 421,430 ---- /* + ** Function to check if there is a shell command active for window. + */ + Boolean IsShellCommandInProgress(WindowInfo *window) + { + return (window->shellCmdData != NULL); + } + + /* ** Issue a shell command and feed it the string "input". Output can be *************** *** 385,386 **** --- 445,447 ---- ** OUTPUT_TO_DIALOG Send output to a pop-up dialog instead of textW + ** OUTPUT_TO_NEW_WINDOW textW is in a new window ** OUTPUT_TO_STRING Output to a macro-language string instead of a text *************** *** 420,422 **** /* fork the subprocess and issue the command */ ! childPid = forkCommand(window->shell, command, window->path, &stdinFD, &stdoutFD, (flags & ERROR_DIALOGS) ? &stderrFD : NULL); --- 481,483 ---- /* fork the subprocess and issue the command */ ! childPid = forkCommand(window->shell, command, window->editorInfo->path, &stdinFD, &stdoutFD, (flags & ERROR_DIALOGS) ? &stderrFD : NULL); *************** *** 491,492 **** --- 552,554 ---- + /* *************** *** 661,665 **** textBuffer *buf; ! int status, failure, errorReport, reselectStart, outTextLen, errTextLen; int resp, cancel = False, fromMacro = cmdData->fromMacro; char *outText, *errText; --- 723,728 ---- textBuffer *buf; ! int status, failure, errorReport, outTextLen, errTextLen; int resp, cancel = False, fromMacro = cmdData->fromMacro; char *outText, *errText; + int loadAfter = (cmdData->flags & RELOAD_FILE_AFTER); *************** *** 751,754 **** removeTrailingNewlines(outText); ! if (*outText != '\0') ! createOutputDialog(window->shell, outText); } else if (cmdData->flags & OUTPUT_TO_STRING) { --- 814,835 ---- removeTrailingNewlines(outText); ! if (*outText != '\0') { ! Widget widget; ! widget = createOutputDialog(window, outText, ! loadAfter ? XmDIALOG_PRIMARY_APPLICATION_MODAL : XmDIALOG_MODELESS); ! ! /* Wait for the dialog to be dismissed if loadAfter is set */ ! if(loadAfter) { ! CheckingMode checkingModeSave; ! ! /* disable file modification checking inside the application loop ! below. */ ! checkingModeSave = window->editorInfo->checkingMode; ! window->editorInfo->checkingMode = CHECKING_MODE_DISABLED; ! while(XtIsManaged(widget)) { ! XtAppProcessEvent(XtWidgetToApplicationContext(window->shell), XtIMAll); ! } ! /* reenable modification checking */ ! window->editorInfo->checkingMode = checkingModeSave; ! } ! } } else if (cmdData->flags & OUTPUT_TO_STRING) { *************** *** 756,772 **** } else { ! buf = TextGetBuffer(cmdData->textW); ! if (!BufSubstituteNullChars(outText, outTextLen, buf)) { ! fprintf(stderr,"NEdit: Too much binary data in shell cmd output\n"); ! outText[0] = '\0'; ! } ! if (cmdData->flags & REPLACE_SELECTION) { ! reselectStart = buf->primary.rectangular ? -1 : buf->primary.start; ! BufReplaceSelected(buf, outText); ! TextSetCursorPos(cmdData->textW, buf->cursorPosHint); ! if (reselectStart != -1) ! BufSelect(buf, reselectStart, reselectStart + strlen(outText)); ! } else { ! BufReplace(buf, cmdData->leftPos, cmdData->rightPos, outText); ! TextSetCursorPos(cmdData->textW, cmdData->leftPos+strlen(outText)); ! } } --- 837,858 ---- } else { ! buf = TextGetBuffer(cmdData->textW); ! if (!BufSubstituteNullChars(outText, outTextLen, buf)) { ! fprintf(stderr,"NEdit: Too much binary data in shell cmd output\n"); ! outText[0] = '\0'; ! } ! if (cmdData->flags & REPLACE_SELECTION) { ! BufReplaceSelected(buf, outText, True); ! TextSetCursorPos(cmdData->textW, buf->cursorPosHint); ! } else { ! BufReplace(buf, cmdData->leftPos, cmdData->rightPos, outText); ! if (cmdData->flags & OUTPUT_TO_NEW_WINDOW) { ! /* If the output is to a new window then turn off the modified ! status so the window can be closed without being prompted to ! save it. Also move the cursor to the beginning of the text .*/ ! SetWindowModified(window, False); ! TextSetCursorPos(window->textArea, 0); ! } else { ! TextSetCursorPos(cmdData->textW, cmdData->leftPos+strlen(outText)); ! } ! } } *************** *** 774,777 **** /* If the command requires the file to be reloaded afterward, reload it */ ! if (cmdData->flags & RELOAD_FILE_AFTER) ! RevertToSaved(window); --- 860,895 ---- /* If the command requires the file to be reloaded afterward, reload it */ ! if (loadAfter) { ! if (window->editorInfo->filenameSet && window->editorInfo->fileChanged) { ! int b; ! CheckingMode checkingModeSave; ! ! /* disable file modification checking inside the application loop ! in DialogF()*/ ! checkingModeSave = window->editorInfo->checkingMode; ! window->editorInfo->checkingMode = CHECKING_MODE_DISABLED; ! b = DialogF(DF_QUES, window->shell, 2, ! "Attemping to re-load file after executing command.\nThis will overwrite your changes.\nDo you want to re-load it anyway?", ! "Re-load", "Don't Re-load"); ! /* reenable modification checking */ ! window->editorInfo->checkingMode = checkingModeSave; ! if(b == 1) { ! RevertToSaved(window, True); ! } else { ! /* If they answered no then don't prompt that the file changed */ ! char fullname[MAXPATHLEN]; ! struct stat statbuf; ! ! /* Get the full name of the file */ ! strcpy(fullname, window->editorInfo->path); ! strcat(fullname, window->editorInfo->filename); ! ! /* get the current mtime */ ! if (stat(fullname, &statbuf) == 0) { ! window->editorInfo->mtime = statbuf.st_mtime; ! } ! } ! } else { ! RevertToSaved(window, True); ! } ! } *************** *** 863,871 **** setsid(); ! ! /* change the current working directory to the directory of the current ! file. */ ! if(cmdDir[0] != 0) ! if(chdir(cmdDir) == -1) ! perror("chdir to directory of current file failed"); ! /* execute the command using the shell specified by preferences */ --- 981,989 ---- setsid(); ! ! /* change the current working directory to the directory of the current ! file. */ ! if(cmdDir[0] != 0) ! if(chdir(cmdDir) == -1) ! perror("chdir to directory of current file failed"); ! /* execute the command using the shell specified by preferences */ *************** *** 972,974 **** */ ! static void createOutputDialog(Widget parent, char *text) { --- 1090,1093 ---- */ ! static Widget createOutputDialog(WindowInfo *window, char *text, ! unsigned char dialogStyle) { *************** *** 992,994 **** ac = 0; ! form = XmCreateFormDialog(parent, "shellOutForm", al, ac); --- 1111,1114 ---- ac = 0; ! XtSetArg(al[ac], XmNdialogStyle, dialogStyle); ac++; ! form = XmCreateFormDialog(window->shell, "shellOutForm", al, ac); *************** *** 1006,1030 **** ! ac = 0; ! XtSetArg(al[ac], XmNrows, rows); ac++; ! XtSetArg(al[ac], XmNcolumns, cols); ac++; ! XtSetArg(al[ac], XmNresizeHeight, False); ac++; ! XtSetArg(al[ac], XmNtraversalOn, False); ac++; ! XtSetArg(al[ac], XmNwordWrap, True); ac++; ! XtSetArg(al[ac], XmNscrollHorizontal, False); ac++; ! XtSetArg(al[ac], XmNscrollVertical, hasScrollBar); ac++; ! XtSetArg(al[ac], XmNhighlightThickness, 0); ac++; ! XtSetArg(al[ac], XmNspacing, 0); ac++; ! XtSetArg(al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++; ! XtSetArg(al[ac], XmNeditable, False); ac++; ! XtSetArg(al[ac], XmNvalue, text); ac++; ! XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; ! XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; ! XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; ! XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; ! XtSetArg(al[ac], XmNbottomWidget, button); ac++; ! textW = XmCreateScrolledText(form, "outText", al, ac); ! XtManageChild(textW); ! XtVaSetValues(XtParent(form), XmNtitle, "Output from Command", 0); ManageDialogCenteredOnPointer(form); } --- 1126,1169 ---- ! { ! Widget sw; ! int emTabDist, wrapMargin; ! char *delimiters; ! /* Create a text widget inside of a scrolled window widget */ ! sw = XtVaCreateManagedWidget("scrolledW", xmScrolledWindowWidgetClass, form, ! XmNspacing, 0, ! #if 0 ! XmNpaneMaximum, SHRT_MAX, ! XmNpaneMinimum, PANE_MIN_HEIGHT, ! #endif ! XmNhighlightThickness, 0, ! XmNtopAttachment, XmATTACH_FORM, ! XmNleftAttachment, XmATTACH_FORM, ! XmNbottomAttachment, XmATTACH_WIDGET, ! XmNrightAttachment, XmATTACH_FORM, ! XmNbottomWidget, button, ! 0); ! XtVaGetValues(window->textArea, ! textNemulateTabs, &emTabDist, ! textNwrapMargin, &wrapMargin, ! textNwordDelimiters, &delimiters, ! 0); ! textW = XtVaCreateManagedWidget("text", textWidgetClass, sw, ! textNrows, rows, ! textNcolumns, cols, ! textNfont, GetDefaultFontStruct(window->fontList), ! textNemulateTabs, emTabDist, ! textNwrapMargin, wrapMargin, ! textNwordDelimiters, delimiters, ! textNautoIndent, window->editorInfo->indentStyle == AUTO_INDENT, ! textNsmartIndent, window->editorInfo->indentStyle == SMART_INDENT, ! textNautoWrap, window->editorInfo->wrapMode == NEWLINE_WRAP, ! textNcontinuousWrap, window->editorInfo->wrapMode == CONTINUOUS_WRAP, ! textNoverstrike, window->editorInfo->overstrike, ! 0); ! TextSetString(textW, text); ! } ! XtVaSetValues(XtParent(form), XmNtitle, "Nedit - Output from Command", 0); ManageDialogCenteredOnPointer(form); + return form; } *************** *** 1045,1047 **** { ! int maxCols = 0, line = 1, col = 0; char *c; --- 1184,1186 ---- { ! int maxCols = 0, line = 0, col = 0; char *c; *************** *** 1061,1062 **** --- 1200,1206 ---- } + /* If there is no newline before the end of the string then add + ** another line for the end of the string. + */ + if(c[-1] != '\n') line++; + *rows = line; *************** *** 1081,1087 **** */ ! static int substitutePercent(char *outStr, char *inStr, char *subsStr, ! int outLen) { char *inChar, *outChar, *c; ! inChar = inStr; --- 1225,1233 ---- */ ! /* .b: argument change */ ! static int substitutePercent(WindowInfo *window, char *outStr, char *inStr, ! char *subsStr, int outLen) ! /* .e */ { char *inChar, *outChar, *c; ! inChar = inStr; *************** *** 1089,1090 **** --- 1235,1241 ---- while (*inChar != '\0') { + /* pass an escaped % to the output */ + if (*inChar == '\\' && inChar[1] == '%') { + inChar++; + *outChar++ = *inChar++; + } if (*inChar == '%') { *************** *** 1093,1094 **** --- 1244,1291 ---- *outChar++ = '%'; + + /* .b: Replace "%t" and parse "%:message:default_value%" syntax */ + } else if (*(inChar+1) == 't') { /* %t is tabDist */ + sprintf(outChar, "%d", window->editorInfo->buffer->tabDist); + inChar += 2; + outChar += strlen(outChar); + } else if (*(inChar+1) == ':') { /* Ask for arguments */ + + /* Saves outChar position */ + c = outChar; + + /* Creates dialog_message */ + for (inChar += 2; *inChar != ':'; inChar++, outChar++) { + if (*inChar == '\0') { + DialogF(DF_ERR, window->shell, 1, + "Syntax error: Separator ':' not found", "OK"); + return False; + } else if (*inChar == '\\') { + inChar++; + } + *outChar = *inChar; + } + *outChar++ = ':'; + *outChar++ = '\0'; + + /* Creates default_value */ + for (inChar++; *inChar != '%'; inChar++, outChar++) { + if (*inChar == '\0') { + DialogF(DF_ERR, window->shell, 1, + "Syntax error: Final '%%' not found", "OK"); + return False; + } else if (*inChar == '\\') { + inChar++; + } + *outChar = *inChar; + } + inChar++; + *outChar = '\0'; + + /* Display request dialog */ + if (DialogF(DF_PROMPT2, window->shell, 2,c, + c+strlen(c)+1, c, "OK", "Cancel") == 2) + return False; + + outChar=outStr+strlen(outStr); + /* .e */ } else { *************** *** 1100,1103 **** *outChar++ = *inChar++; ! if (outChar - outStr >= outLen) return False; } --- 1297,1306 ---- *outChar++ = *inChar++; ! /* .b: Now dialog is inside this function */ ! if (outChar - outStr >= outLen) { ! DialogF(DF_ERR, window->shell, 1, ! "Shell command is too long due to\nfilename substitutions with '%%'", ! "OK"); return False; + } + /* .e */ } *** shell.h 1997/09/26 18:28:17 1.1 --- shell.h 1997/10/10 00:15:48 1.2 *************** *** 36 **** --- 36,37 ---- void AbortShellCommand(WindowInfo *window); + Boolean IsShellCommandInProgress(WindowInfo *window); *** shift.c 1997/09/26 18:28:17 1.1 --- shift.c 1997/10/21 21:40:17 1.3 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #ifdef VMS *************** *** 29,31 **** #endif /*VMS*/ ! #include #include --- 30,34 ---- #endif /*VMS*/ ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 66,70 **** int selStart, selEnd, isRect, rectStart, rectEnd; ! int shiftedLen, newEndPos, cursorPos, origLength, emTabDist, shiftDist; char *text, *shiftedText; ! textBuffer *buf = window->buffer; --- 69,73 ---- int selStart, selEnd, isRect, rectStart, rectEnd; ! int shiftedLen, cursorPos, origLength, emTabDist, shiftDist; char *text, *shiftedText; ! textBuffer *buf = window->editorInfo->buffer; *************** *** 78,80 **** selEnd++; ! BufSelect(buf, selStart, selEnd); isRect = False; --- 81,83 ---- selEnd++; ! BufSelect(buf, selStart, selEnd, CHAR_SELECT); isRect = False; *************** *** 96,98 **** } ! BufSelect(buf, selStart, selEnd); text = BufGetRange(buf, selStart, selEnd); --- 99,101 ---- } ! BufSelect(buf, selStart, selEnd, CHAR_SELECT); text = BufGetRange(buf, selStart, selEnd); *************** *** 106,115 **** shiftDist = 1; ! shiftedText = ShiftText(text, direction, buf->useTabs, buf->tabDist, ! shiftDist, &shiftedLen); XtFree(text); ! BufReplaceSelected(buf, shiftedText); XtFree(shiftedText); - - newEndPos = selStart + shiftedLen; - BufSelect(buf, selStart, newEndPos); } --- 109,116 ---- shiftDist = 1; ! shiftedText = ShiftText(text, direction, ! byTab ? buf->useTabs : False, /* only use tabs when shifting by tabs */ ! buf->tabDist, shiftDist, &shiftedLen); XtFree(text); ! BufReplaceSelected(buf, shiftedText, True); XtFree(shiftedText); } *************** *** 120,122 **** int offset, emTabDist; ! textBuffer *tempBuf, *buf = window->buffer; char *text; --- 121,123 ---- int offset, emTabDist; ! textBuffer *tempBuf, *buf = window->editorInfo->buffer; char *text; *************** *** 178,180 **** { ! textBuffer *buf = window->buffer; char *text, *c; --- 179,181 ---- { ! textBuffer *buf = window->editorInfo->buffer; char *text, *c; *************** *** 197,204 **** *c = makeUpper ? toupper(*c) : tolower(*c); ! BufReplaceSelected(buf, text); XtFree(text); - if (isRect) - BufRectSelect(buf, start, end, rectStart, rectEnd); - else - BufSelect(buf, start, end); } --- 198,201 ---- *c = makeUpper ? toupper(*c) : tolower(*c); ! BufReplaceSelected(buf, text, True); XtFree(text); } *************** *** 208,210 **** { ! textBuffer *buf = window->buffer; char *c, *text, *filledText; --- 205,207 ---- { ! textBuffer *buf = window->editorInfo->buffer; char *c, *text, *filledText; *************** *** 213,215 **** int insertPos = TextGetCursorPos(window->lastFocus); ! int hasSelection = window->buffer->primary.selected; --- 210,212 ---- int insertPos = TextGetCursorPos(window->lastFocus); ! int hasSelection = window->editorInfo->buffer->primary.selected; *************** *** 239,241 **** } ! BufSelect(buf, left, right); text = BufGetRange(buf, left, right); --- 236,238 ---- } ! BufSelect(buf, left, right, CHAR_SELECT); text = BufGetRange(buf, left, right); *************** *** 267,278 **** /* Replace the text in the window */ ! if (hasSelection && isRect) { ! BufReplaceRect(buf, left, right, rectStart, INT_MAX, filledText); ! BufRectSelect(buf, left, ! BufEndOfLine(buf, BufCountForwardNLines(buf, left, ! countLines(filledText)-1)), rectStart, rectEnd); } else { ! BufReplace(buf, left, right, filledText); ! if (hasSelection) ! BufSelect(buf, left, left + len); } XtFree(filledText); --- 264,271 ---- /* Replace the text in the window */ ! if (hasSelection) { ! BufReplaceSelected(buf, filledText, True); } else { ! BufReplace(buf, left, right, filledText); } + XtFree(filledText); *** smartIndent.c 1997/09/26 18:28:17 1.1 --- smartIndent.c 1997/10/16 19:21:33 1.4 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 573,575 **** } ! window->smartIndentData = (void *)winData; } --- 574,576 ---- } ! window->editorInfo->smartIndentData = (void *)winData; } *************** *** 579,581 **** windowSmartIndentData *winData = ! (windowSmartIndentData *)window->smartIndentData; --- 580,582 ---- windowSmartIndentData *winData = ! (windowSmartIndentData *)window->editorInfo->smartIndentData; *************** *** 589,591 **** XtFree((char *)winData); ! window->smartIndentData = NULL; } --- 590,592 ---- XtFree((char *)winData); ! window->editorInfo->smartIndentData = NULL; } *************** *** 611,613 **** ! if (window->smartIndentData == NULL) return; --- 612,614 ---- ! if (window->editorInfo->smartIndentData == NULL) return; *************** *** 626,628 **** windowSmartIndentData *winData = ! (windowSmartIndentData *)window->smartIndentData; static DataValue posValue = {INT_TAG, {0}}; --- 627,629 ---- windowSmartIndentData *winData = ! (windowSmartIndentData *)window->editorInfo->smartIndentData; static DataValue posValue = {INT_TAG, {0}}; *************** *** 669,671 **** windowSmartIndentData *winData = ! (windowSmartIndentData *)window->smartIndentData; static DataValue args[2] = {{INT_TAG, {0}}, {STRING_TAG, {0}}}; --- 670,672 ---- windowSmartIndentData *winData = ! (windowSmartIndentData *)window->editorInfo->smartIndentData; static DataValue args[2] = {{INT_TAG, {0}}, {STRING_TAG, {0}}}; *************** *** 1447,1449 **** for (window=WindowList; window!=NULL; window=window->next) { ! if (window->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { --- 1448,1450 ---- for (window=WindowList; window!=NULL; window=window->next) { ! if (window->editorInfo->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { *************** *** 1509,1511 **** for (window=WindowList; window!=NULL; window=window->next) { ! if (window->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { --- 1510,1512 ---- for (window=WindowList; window!=NULL; window=window->next) { ! if (window->editorInfo->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { *** strerror.c 1997/10/09 23:29:19 1.1 --- strerror.c 1997/10/10 00:15:48 1.2 *************** *** 0 **** --- 1,67 ---- + /* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #if defined(LIBC_SCCS) && !defined(lint) + static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; + #endif /* LIBC_SCCS and not lint */ + + #include + + char * + strerror(num) + int num; + { + extern int sys_nerr; + extern char *sys_errlist[]; + #define UPREFIX "Unknown error: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + register unsigned int errnum; + register char *p, *t; + char tmp[40]; + + errnum = num; /* convert to unsigned */ + if (errnum < sys_nerr) + return(sys_errlist[errnum]); + + /* Do this by hand, so we don't include stdio(3). */ + t = tmp; + do { + *t++ = "0123456789"[errnum % 10]; + } while (errnum /= 10); + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + return(ebuf); + } *** tags.c 1997/09/26 18:28:17 1.1 --- tags.c 1997/10/16 19:03:57 1.3 *************** *** 1 **** --- 1,2 ---- + #include #include *************** *** 7,10 **** #endif /*VMS*/ - #include #include #include "../util/DialogF.h" --- 8,11 ---- #endif /*VMS*/ #include + #include #include "../util/DialogF.h" *************** *** 18,19 **** --- 19,21 ---- #include "selection.h" + #include "preferences.h" #include "tags.h" *************** *** 31,35 **** ! static void findDefCB(Widget widget, WindowInfo *window, Atom *sel, ! Atom *type, char *value, int *length, int *format); ! static void findDef(Widget dialogParent, char *string); static void setTag(tag *t, char *name, char *file, char *searchString); --- 33,40 ---- ! typedef struct _SelectionInfo { ! int done; ! WindowInfo* window; ! char* selection; ! } SelectionInfo; ! static void setTag(tag *t, char *name, char *file, char *searchString); *************** *** 38,39 **** --- 43,46 ---- int *start, int *end); + static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *selection, + Atom *type, char *value, int *length, int *format); *************** *** 52,54 **** int i, nTags, nRead; - WindowInfo *w; --- 59,60 ---- *************** *** 82,83 **** --- 88,90 ---- freeTagList(tags); + fclose(fp); return FALSE; *************** *** 88,89 **** --- 95,97 ---- freeTagList(tags); + fclose(fp); return FALSE; *************** *** 92,93 **** --- 100,102 ---- } + fclose(fp); *************** *** 105,109 **** - /* Undim the "Find Definition" menu item in the existing windows */ - for (w=WindowList; w!=NULL; w=w->next) - XtSetSensitive(w->findDefItem, TRUE); return TRUE; --- 114,115 ---- *************** *** 122,135 **** { - int i; tag *t; ! if (!TagsFileLoaded()) ! return FALSE; ! ! for (i=0, t=Tags; t->name!=NULL; i++, t++) { ! if (!strcmp(t->name, name)) { ! *file = t->file; ! *searchString = t->searchString; ! return TRUE; ! } } --- 128,139 ---- { tag *t; ! if(Tags) { ! for (t=Tags; t->name!=NULL; t++) { ! if (!strcmp(t->name, name)) { ! *file = t->file; ! *searchString = t->searchString; ! return TRUE; ! } ! } } *************** *** 138,193 **** - /* - ** Lookup the definition for the current primary selection the currently - ** loaded tags file and bring up the file and line that the tags file - ** indicates. - */ void FindDefinition(WindowInfo *window, Time time) { - XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, - (XtSelectionCallbackProc)findDefCB, window, time); - } - - static void findDefCB(Widget widget, WindowInfo *window, Atom *sel, - Atom *type, char *value, int *length, int *format) - { - char tagText[MAX_TAG_LEN+1]; - - /* skip if we can't get the selection data, or it's obviously too long */ - if (*type == XT_CONVERT_FAIL || value == NULL) { - XBell(TheDisplay, 0); - return; - } - if (*length > MAX_TAG_LEN) { - XBell(TheDisplay, 0); - XtFree(value); - return; - } - /* should be of type text??? */ - if (*format != 8) { - fprintf(stderr, "NEdit: Can't handle non 8-bit text\n"); - XBell(TheDisplay, 0); - XtFree(value); - return; - } - - /* Copy the string just to make space for the null character (this may - not be necessary, XLib documentation claims a NULL is already added, - but the Xt documentation for this routine makes no such claim) */ - strncpy(tagText, value, *length); - tagText[*length] = '\0'; - - /* Lookup the tag and put up the window */ - findDef(window->textArea, tagText); - - /* The selection requstor is required to free the memory passed - to it via value */ - XtFree((char *)value); - } - - /* - ** Lookup the definition for "string" in the currently loaded tags file - ** and bring up the file and line that the tags file indicates - */ - static void findDef(Widget dialogParent, char *string) - { int startPos, endPos, found, lineNum, rows; --- 142,145 ---- *************** *** 196,206 **** char filename[MAXPATHLEN], pathname[MAXPATHLEN], temp[MAXPATHLEN]; ! ! /* verify that the string is reasonable as a tag */ ! if (*string == '\0') { ! XBell(TheDisplay, 0); ! return; } ! if (strlen(string) > MAX_TAG_LEN) { ! XBell(TheDisplay, 0); ! return; } --- 148,170 ---- char filename[MAXPATHLEN], pathname[MAXPATHLEN], temp[MAXPATHLEN]; ! SelectionInfo selectionInfo; ! ! /* Warn if the tags file has not been loaded */ ! if(!TagsFileLoaded()) { ! DialogF(DF_WARN, window->shell, 1, "Tags file has not been loaded.", "OK"); ! return; } ! ! /* get the name to match from the primary selection */ ! selectionInfo.window = window; ! selectionInfo.selection = 0; ! selectionInfo.done = 0; ! XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING, ! (XtSelectionCallbackProc)getSelectionCB, &selectionInfo, CurrentTime); ! while (selectionInfo.done == 0) { ! XEvent nextEvent; ! XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), &nextEvent); ! XtDispatchEvent(&nextEvent); ! } ! if(selectionInfo.selection == 0) { ! return; } *************** *** 208,213 **** /* lookup the name in the tags file */ ! found = LookupTag(string, &fileToSearch, &searchString); if (!found) { ! DialogF(DF_WARN, dialogParent, 1, "%s not found in tags file", "OK", ! string); return; --- 172,178 ---- /* lookup the name in the tags file */ ! found = LookupTag(selectionInfo.selection, &fileToSearch, &searchString); if (!found) { ! DialogF(DF_WARN, window->shell, 1, "%s not found in tags file", "OK", ! selectionInfo.selection); ! XtFree(selectionInfo.selection); return; *************** *** 226,232 **** /* open the file containing the definition */ ! EditExistingFile(WindowList, filename, pathname, FALSE); ! windowToSearch = FindWindowWithFile(filename, pathname); if (windowToSearch == NULL) { ! DialogF(DF_WARN, dialogParent, 1, "File %s not found", "OK", fileToSearch); return; --- 191,197 ---- /* open the file containing the definition */ ! windowToSearch = EditExistingFile(WindowList, filename, pathname, 0, True); if (windowToSearch == NULL) { ! DialogF(DF_WARN, window->shell, 1, "File %s not found", "OK", fileToSearch); + XtFree(selectionInfo.selection); return; *************** *** 238,239 **** --- 203,205 ---- SelectNumberedLine(windowToSearch, lineNum); + XtFree(selectionInfo.selection); return; *************** *** 245,252 **** DialogF(DF_WARN, windowToSearch->shell, 1,"Definition for %s\nnot found in %s", ! "OK", string, fileToSearch); return; } /* select the matched string */ ! BufSelect(windowToSearch->buffer, startPos, endPos); --- 211,220 ---- DialogF(DF_WARN, windowToSearch->shell, 1,"Definition for %s\nnot found in %s", ! "OK", selectionInfo.selection, fileToSearch); ! XtFree(selectionInfo.selection); return; } + XtFree(selectionInfo.selection); /* select the matched string */ ! BufSelect(windowToSearch->editorInfo->buffer, startPos, endPos, CHAR_SELECT); *************** *** 254,256 **** top */ ! lineNum = BufCountLines(windowToSearch->buffer, 0, startPos); XtVaGetValues(windowToSearch->lastFocus, textNrows, &rows, 0); --- 222,224 ---- top */ ! lineNum = BufCountLines(windowToSearch->editorInfo->buffer, 0, startPos); XtVaGetValues(windowToSearch->lastFocus, textNrows, &rows, 0); *************** *** 258,259 **** --- 226,228 ---- TextSetCursorPos(windowToSearch->lastFocus, endPos); + return; } *************** *** 293,298 **** char *fileString, searchSubs[MAXLINE]; /* get the entire (sigh) text buffer from the text area widget */ ! fileString = BufGetAll(window->buffer); ! fileLen = window->buffer->length; --- 262,270 ---- char *fileString, searchSubs[MAXLINE]; + /* .b: char pointers for copying */ + char *inChar, *outChar; + /* .e */ /* get the entire (sigh) text buffer from the text area widget */ ! fileString = BufGetAll(window->editorInfo->buffer); ! fileLen = window->editorInfo->buffer->length; *************** *** 305,307 **** else { ! fprintf(stderr, "NEdit: Error parsing tag file search string"); return FALSE; --- 277,279 ---- else { ! DialogF(DF_WARN, window->shell, 1, "Error parsing search string from tag file.", "OK"); return FALSE; *************** *** 309,311 **** searchLen -= 2; ! strncpy(searchSubs, &searchString[1], searchLen); searchSubs[searchLen] = '\0'; --- 281,296 ---- searchLen -= 2; ! ! /* .b: Remove backslashes and copy search string. */ ! inChar = &searchString[1]; ! outChar = searchSubs; ! while (*inChar != '\0') { ! if (*inChar == '\\') { ! inChar++; ! searchLen--; ! } ! *outChar = *inChar; ! inChar++; ! outChar++; ! } ! /* .e */ searchSubs[searchLen] = '\0'; *************** *** 353,354 **** --- 338,344 ---- } + + /* save the search string in the history minus the added newlines */ + if(hasEOL) searchSubs[searchLen-1] = 0; + SaveSearchHistory(hasBOL ? searchSubs+1 : searchSubs, NULL, SEARCH_CASE_SENSE); + *start = startPos; *************** *** 356,357 **** --- 346,396 ---- return TRUE; + } + + static void getSelectionCB(Widget w, SelectionInfo *selectionInfo, Atom *selection, + Atom *type, char *value, int *length, int *format) + { + WindowInfo *window = selectionInfo->window; + + /* skip if we can't get the selection data or it's too long */ + if (*type == XT_CONVERT_FAIL || *type != XA_STRING || value == NULL) { + if (GetPrefSearchDlogs()) + DialogF(DF_WARN, window->shell, 1, + "Selection not appropriate for searching", "OK"); + else + XBell(TheDisplay, 0); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + if (*length > SEARCHMAX) { + if (GetPrefSearchDlogs()) + DialogF(DF_WARN, window->shell, 1, "Selection too long", "OK"); + else + XBell(TheDisplay, 0); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + if (*length == 0) { + XBell(TheDisplay, 0); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + /* should be of type text??? */ + if (*format != 8) { + DialogF(DF_WARN, window->shell, 1, "NEdit can't handle non 8-bit text", "OK"); + XtFree(value); + selectionInfo->selection = 0; + selectionInfo->done = 1; + return; + } + selectionInfo->selection = XtMalloc(*length+1); + memcpy(selectionInfo->selection, value, *length); + selectionInfo->selection[*length] = 0; + XtFree(value); + selectionInfo->done = 1; } *** text.c 1997/09/26 18:28:17 1.1 --- text.c 1997/10/24 00:52:56 1.4 *************** *** 28,32 **** *******************************************************************************/ #include #include ! #include #include --- 28,35 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 48,56 **** ! /* Number of pixels of motion from the initial (grab-focus) button press ! required to begin recognizing a mouse drag for the purpose of making a ! selection */ ! #define SELECT_THRESHOLD 5 ! ! /* Length of delay in milliseconds for vertical autoscrolling */ ! #define VERTICAL_SCROLL_DELAY 50 --- 51,54 ---- ! /* Forcibly disable the XmIm...() stuff. */ ! #undef HAVE_XMIMREGISTER *************** *** 76,77 **** --- 74,81 ---- Cardinal *nArgs); + static void dragOrGrabFocusAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static void dragOrExtendAdjustAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static void dragOrExtendEndAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void processCancelAP(Widget w, XEvent *event, String *args, *************** *** 86,87 **** --- 90,97 ---- Cardinal *nArgs); + static Boolean blockDragStart(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static Boolean blockDragAdjust(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static Boolean blockDragEnd(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void copyToAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); *************** *** 105,106 **** --- 115,122 ---- Cardinal *nArgs); + static void secondaryOrClipboardAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static void copySecondaryAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); + static void moveSecondaryAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void insertStringAP(Widget w, XEvent *event, String *args, *************** *** 189,191 **** static void selectWord(Widget w, int pointerX); ! static void selectLine(Widget w); static int whiteSpaceAtPos(textBuffer *buf, int pos); --- 205,209 ---- static void selectWord(Widget w, int pointerX); ! static void selectSecondaryWord(Widget w, int pos); ! static void selectLine(Widget w, int pos); ! static void selectSecondaryLine(Widget w, int pos); static int whiteSpaceAtPos(textBuffer *buf, int pos); *************** *** 193,194 **** --- 211,216 ---- static int endOfWord(TextWidget w, int pos); + static void selectGroup(Widget w, int pos); + static void selectSecondaryGroup(Widget w, int pos); + static int startOfGroup(TextWidget w, int pos); + static int endOfGroup(TextWidget w, int pos); static void checkAutoScroll(TextWidget w, int x, int y); *************** *** 198,200 **** static void adjustSelection(TextWidget tw, int x, int y); - static void adjustSecondarySelection(TextWidget tw, int x, int y); static void autoScrollTimerProc(XtPointer clientData, XtIntervalId *id); --- 220,221 ---- *************** *** 213,349 **** ! static char defaultTranslations[] = ! "CtrlosfBackSpace: delete_previous_word()\n\ ! osfBackSpace: delete_previous_character()\n\ ! Alt Shift CtrlosfDelete: cut_primary(\"rect\")\n\ ! Meta Shift CtrlosfDelete: cut_primary(\"rect\")\n\ ! Shift CtrlosfDelete: cut_primary()\n\ ! CtrlosfDelete: delete_to_end_of_line()\n\ ! ShiftosfDelete: cut_clipboard()\n\ ! osfDelete: delete_next_character()\n\ ! Alt Shift CtrlosfInsert: copy_primary(\"rect\")\n\ ! Meta Shift CtrlosfInsert: copy_primary(\"rect\")\n\ ! Shift CtrlosfInsert: copy_primary()\n\ ! ShiftosfInsert: paste_clipboard()\n\ ! CtrlosfInsert: copy_clipboard()\n\ ! Shift CtrlosfCut: cut_primary()\n\ ! osfCut: cut_clipboard()\n\ ! osfCopy: copy_clipboard()\n\ ! osfPaste: paste_clipboard()\n\ ! osfPrimaryPaste: copy_primary()\n\ ! Alt Shift CtrlosfBeginLine: beginning_of_file(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfBeginLine: beginning_of_file(\"extend\" \"rect\")\n\ ! Alt ShiftosfBeginLine: beginning_of_line(\"extend\", \"rect\")\n\ ! Meta ShiftosfBeginLine: beginning_of_line(\"extend\", \"rect\")\n\ ! Shift CtrlosfBeginLine: beginning_of_file(\"extend\")\n\ ! CtrlosfBeginLine: beginning_of_file()\n\ ! ShiftosfBeginLine: beginning_of_line(\"extend\")\n\ ! osfBeginLine: beginning_of_line()\n\ ! Alt Shift CtrlosfEndLine: end_of_file(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfEndLine: end_of_file(\"extend\", \"rect\")\n\ ! Alt ShiftosfEndLine: end_of_line(\"extend\", \"rect\")\n\ ! Meta ShiftosfEndLine: end_of_line(\"extend\", \"rect\")\n\ ! Shift CtrlosfEndLine: end_of_file(\"extend\")\n\ ! CtrlosfEndLine: end_of_file()\n\ ! ShiftosfEndLine: end_of_line(\"extend\")\n\ ! osfEndLine: end_of_line()\n\ ! Alt Shift CtrlosfLeft: backward_word(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfLeft: backward_word(\"extend\", \"rect\")\n\ ! Alt ShiftosfLeft: key_select(\"left\", \"rect\")\n\ ! Meta ShiftosfLeft: key_select(\"left\", \"rect\")\n\ ! Shift CtrlosfLeft: backward_word(\"extend\")\n\ ! CtrlosfLeft: backward_word()\n\ ! ShiftosfLeft: key_select(\"left\")\n\ ! osfLeft: backward_character()\n\ ! Alt Shift CtrlosfRight: forward_word(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfRight: forward_word(\"extend\", \"rect\")\n\ ! Alt ShiftosfRight: key_select(\"right\", \"rect\")\n\ ! Meta ShiftosfRight: key_select(\"right\", \"rect\")\n\ ! Shift CtrlosfRight: forward_word(\"extend\")\n\ ! CtrlosfRight: forward_word()\n\ ! ShiftosfRight: key_select(\"right\")\n\ ! osfRight: forward_character()\n\ ! Alt Shift CtrlosfUp: backward_paragraph(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfUp: backward_paragraph(\"extend\", \"rect\")\n\ ! Alt ShiftosfUp: process_shift_up(\"rect\")\n\ ! Meta ShiftosfUp: process_shift_up(\"rect\")\n\ ! Shift CtrlosfUp: backward_paragraph(\"extend\")\n\ ! CtrlosfUp: backward_paragraph()\n\ ! ShiftosfUp: process_shift_up()\n\ ! osfUp: process_up()\n\ ! Alt Shift CtrlosfDown: forward_paragraph(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfDown: forward_paragraph(\"extend\", \"rect\")\n\ ! Alt ShiftosfDown: process_shift_down(\"rect\")\n\ ! Meta ShiftosfDown: process_shift_down(\"rect\")\n\ ! Shift CtrlosfDown: forward_paragraph(\"extend\")\n\ ! CtrlosfDown: forward_paragraph()\n\ ! ShiftosfDown: process_shift_down()\n\ ! osfDown: process_down()\n\ ! Alt ShiftosfPageLeft: page_left(\"extend\", \"rect\")\n\ ! Meta ShiftosfPageLeft: page_left(\"extend\", \"rect\")\n\ ! ShiftosfPageLeft: page_left(\"extend\")\n\ ! osfPageLeft: page_left()\n\ ! Alt ShiftosfPageRight: page_right(\"extend\", \"rect\")\n\ ! Meta ShiftosfPageRight: page_right(\"extend\", \"rect\")\n\ ! ShiftosfPageRight: page_right(\"extend\")\n\ ! osfPageRight: page_right()\n\ ! Alt Shift CtrlosfPageUp: page_left(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfPageUp: page_left(\"extend\", \"rect\")\n\ ! Alt ShiftosfPageUp: previous_page(\"extend\", \"rect\")\n\ ! Meta ShiftosfPageUp: previous_page(\"extend\", \"rect\")\n\ ! Shift CtrlosfPageUp: page_left(\"extend\")\n\ ! CtrlosfPageUp: page_left()\n\ ! ShiftosfPageUp: previous_page(\"extend\")\n\ ! osfPageUp: previous_page()\n\ ! Alt Shift CtrlosfPageDown: page_right(\"extend\", \"rect\")\n\ ! Meta Shift CtrlosfPageDown: page_right(\"extend\", \"rect\")\n\ ! Alt ShiftosfPageDown: next_page(\"extend\", \"rect\")\n\ ! Meta ShiftosfPageDown: next_page(\"extend\", \"rect\")\n\ ! Shift CtrlosfPageDown: page_right(\"extend\")\n\ ! CtrlosfPageDown: page_right()\n\ ! ShiftosfPageDown: next_page(\"extend\")\n\ ! osfPageDown: next_page()\n\ ! ShiftosfSelect: key_select()\n\ ! osfCancel: process_cancel()\n\ ! Ctrl~Alt~Metav: paste_clipboard()\n\ ! Ctrl~Alt~Metac: copy_clipboard()\n\ ! Ctrl~Alt~Metax: cut_clipboard()\n\ ! Ctrl~Alt~Metau: delete_to_start_of_line()\n\ ! CtrlReturn: newline_and_indent()\n\ ! ShiftReturn: newline_no_indent()\n\ ! Return: newline()\n\ ! CtrlTab: self_insert()\n\ ! Tab: process_tab()\n\ ! Alt Shift Ctrlspace: key_select(\"rect\")\n\ ! Meta Shift Ctrlspace: key_select(\"rect\")\n\ ! Shift Ctrl~Meta~Altspace: key_select()\n\ ! Ctrl~Meta~Altslash: select_all()\n\ ! Ctrl~Meta~Altbackslash: deselect_all()\n\ ! : self_insert()\n\ ! Alt Ctrl: move_destination()\n\ ! Meta Ctrl: move_destination()\n\ ! Shift Ctrl: extend_start(\"rect\")\n\ ! Shift: extend_start()\n\ ! : grab_focus()\n\ ! Button1 Ctrl: extend_adjust(\"rect\")\n\ ! Button1~Ctrl: extend_adjust()\n\ ! : extend_end()\n\ ! : secondary_or_drag_start()\n\ ! Shift Ctrl Button2: secondary_or_drag_adjust(\"rect\", \ ! \"copy\", \"overlay\")\n\ ! Shift Button2: secondary_or_drag_adjust(\"copy\")\n\ ! Ctrl Button2: secondary_or_drag_adjust(\"rect\", \ ! \"overlay\")\n\ ! Button2: secondary_or_drag_adjust()\n\ ! Shift Ctrl: move_to_or_end_drag(\"copy\", \"overlay\")\n\ ! Shift : move_to_or_end_drag(\"copy\")\n\ ! Alt: exchange()\n\ ! Meta: exchange()\n\ ! Ctrl: copy_to_or_end_drag(\"overlay\")\n\ ! : copy_to_or_end_drag()\n\ ! Ctrl~Meta~Alt: mouse_pan()\n\ ! Ctrl~Meta~Alt Button3: mouse_pan()\n\ ! : end_drag()\n\ ! : focusIn()\n\ ! : focusOut()\n"; ! /* some of the translations from the Motif text widget were not picked up: :osfSelect: set-anchor()\n\ --- 234,369 ---- ! static char defaultTranslations[] = "\ ! Ctrl osfBackSpace: delete_previous_word()\n\ ! osfBackSpace: delete_previous_character()\n\ ! Alt Shift Ctrl osfDelete: cut_primary(rect)\n\ ! Meta Shift Ctrl osfDelete: cut_primary(rect)\n\ ! Shift Ctrl osfDelete: cut_primary()\n\ ! Ctrl osfDelete: delete_to_end_of_line()\n\ ! Shift osfDelete: cut_clipboard()\n\ ! osfDelete: delete_next_character()\n\ ! Alt Shift Ctrl osfInsert: copy_primary(rect)\n\ ! Meta Shift Ctrl osfInsert: copy_primary(rect)\n\ ! Shift Ctrl osfInsert: copy_primary()\n\ ! Shift osfInsert: paste_clipboard()\n\ ! Ctrl osfInsert: copy_clipboard()\n\ ! Shift Ctrl osfCut: cut_primary()\n\ ! osfCut: cut_clipboard()\n\ ! osfCopy: copy_clipboard()\n\ ! osfPaste: paste_clipboard()\n\ ! osfPrimaryPaste: copy_primary()\n\ ! Alt Shift Ctrl osfBeginLine: beginning_of_file(extend, rect)\n\ ! Meta Shift Ctrl osfBeginLine: beginning_of_file(extend rect)\n\ ! Shift Ctrl osfBeginLine: beginning_of_file(extend)\n\ ! Ctrl osfBeginLine: beginning_of_file()\n\ ! Alt Shift osfBeginLine: beginning_of_line(extend, rect)\n\ ! Meta Shift osfBeginLine: beginning_of_line(extend, rect)\n\ ! Shift osfBeginLine: beginning_of_line(extend)\n\ ! osfBeginLine: beginning_of_line()\n\ ! Alt Shift Ctrl osfEndLine: end_of_file(extend, rect)\n\ ! Meta Shift Ctrl osfEndLine: end_of_file(extend, rect)\n\ ! Shift Ctrl osfEndLine: end_of_file(extend)\n\ ! Ctrl osfEndLine: end_of_file()\n\ ! Alt Shift osfEndLine: end_of_line(extend, rect)\n\ ! Meta Shift osfEndLine: end_of_line(extend, rect)\n\ ! Shift osfEndLine: end_of_line(extend)\n\ ! osfEndLine: end_of_line()\n\ ! Alt Shift Ctrl osfLeft: backward_word(extend, rect)\n\ ! Meta Shift Ctrl osfLeft: backward_word(extend, rect)\n\ ! Alt Shift osfLeft: key_select(left, rect)\n\ ! Meta Shift osfLeft: key_select(left, rect)\n\ ! Shift Ctrl osfLeft: backward_word(extend)\n\ ! Ctrl osfLeft: backward_word()\n\ ! Shift osfLeft: key_select(left)\n\ ! osfLeft: backward_character()\n\ ! Alt Shift Ctrl osfRight: forward_word(extend, rect)\n\ ! Meta Shift Ctrl osfRight: forward_word(extend, rect)\n\ ! Alt Shift osfRight: key_select(right, rect)\n\ ! Meta Shift osfRight: key_select(right, rect)\n\ ! Shift Ctrl osfRight: forward_word(extend)\n\ ! Ctrl osfRight: forward_word()\n\ ! Shift osfRight: key_select(right)\n\ ! osfRight: forward_character()\n\ ! Alt Shift Ctrl osfUp: backward_paragraph(extend, rect)\n\ ! Meta Shift Ctrl osfUp: backward_paragraph(extend, rect)\n\ ! Alt Shift osfUp: process_shift_up(rect)\n\ ! Meta Shift osfUp: process_shift_up(rect)\n\ ! Shift Ctrl osfUp: backward_paragraph(extend)\n\ ! Ctrl osfUp: backward_paragraph()\n\ ! Shift osfUp: process_shift_up()\n\ ! osfUp: process_up()\n\ ! Alt Shift Ctrl osfDown: forward_paragraph(extend, rect)\n\ ! Meta Shift Ctrl osfDown: forward_paragraph(extend, rect)\n\ ! Alt Shift osfDown: process_shift_down(rect)\n\ ! Meta Shift osfDown: process_shift_down(rect)\n\ ! Shift Ctrl osfDown: forward_paragraph(extend)\n\ ! Ctrl osfDown: forward_paragraph()\n\ ! Shift osfDown: process_shift_down()\n\ ! osfDown: process_down()\n\ ! Alt Shift osfPageLeft: page_left(extend, rect)\n\ ! Meta Shift osfPageLeft: page_left(extend, rect)\n\ ! Shift osfPageLeft: page_left(extend)\n\ ! osfPageLeft: page_left()\n\ ! Alt Shift osfPageRight: page_right(extend, rect)\n\ ! Meta Shift osfPageRight: page_right(extend, rect)\n\ ! Shift osfPageRight: page_right(extend)\n\ ! osfPageRight: page_right()\n\ ! Alt Shift Ctrl osfPageUp: page_left(extend, rect)\n\ ! Meta Shift Ctrl osfPageUp: page_left(extend, rect)\n\ ! Alt Shift osfPageUp: previous_page(extend, rect)\n\ ! Meta Shift osfPageUp: previous_page(extend, rect)\n\ ! Shift Ctrl osfPageUp: page_left(extend)\n\ ! Ctrl osfPageUp: page_left()\n\ ! Shift osfPageUp: previous_page(extend)\n\ ! osfPageUp: previous_page()\n\ ! Alt Shift Ctrl osfPageDown: page_right(extend, rect)\n\ ! Meta Shift Ctrl osfPageDown: page_right(extend, rect)\n\ ! Alt Shift osfPageDown: next_page(extend, rect)\n\ ! Meta Shift osfPageDown: next_page(extend, rect)\n\ ! Shift Ctrl osfPageDown: page_right(extend)\n\ ! Ctrl osfPageDown: page_right()\n\ ! Shift osfPageDown: next_page(extend)\n\ ! osfPageDown: next_page()\n\ ! Shift osfSelect: key_select()\n\ ! osfCancel: process_cancel()\n\ ! ~Alt~Meta Ctrl v: paste_clipboard()\n\ ! ~Alt~Meta Ctrl c: copy_clipboard()\n\ ! ~Alt~Meta Ctrl x: cut_clipboard()\n\ ! ~Alt~Meta Ctrl u: delete_to_start_of_line()\n\ ! Ctrl Return: newline_and_indent()\n\ ! Shift Return: newline_no_indent()\n\ ! Return: newline()\n\ ! Ctrl Tab: self_insert()\n\ ! Tab: process_tab()\n\ ! Alt Shift Ctrl space: key_select(rect)\n\ ! Meta Shift Ctrl space: key_select(rect)\n\ ! ~Meta~Alt Shift Ctrlspace: key_select()\n\ ! ~Alt~Meta Ctrl slash: select_all()\n\ ! ~Alt~Meta Ctrl backslash: deselect_all()\n\ ! : self_insert()\n\ ! Alt Ctrl : move_destination()\n\ ! Meta Ctrl : move_destination()\n\ ! Shift Ctrl : extend_start(rect)\n\ ! Shift : extend_start()\n\ ! : grab_focus()\n\ ! Ctrl Button1: extend_adjust(rect)\n\ ! ~Ctrl Button1: extend_adjust()\n\ ! : extend_end()\n\ ! : secondary_or_drag_start()\n\ ! Shift Ctrl Button2: secondary_or_drag_adjust(rect, copy, overlay)\n\ ! Shift Button2: secondary_or_drag_adjust(copy)\n\ ! Ctrl Button2: secondary_or_drag_adjust(rect, overlay)\n\ ! Button2: secondary_or_drag_adjust()\n\ ! Shift Ctrl : move_to_or_end_drag(copy, overlay)\n\ ! Shift : move_to_or_end_drag(copy)\n\ ! Alt : exchange()\n\ ! Meta : exchange()\n\ ! Ctrl : copy_to_or_end_drag(overlay)\n\ ! : copy_to_or_end_drag()\n\ ! ~Alt~Meta Ctrl : mouse_pan()\n\ ! ~Alt~Meta Ctrl Button3: mouse_pan()\n\ ! : end_drag()\n\ ! : focusIn()\n\ ! : focusOut()\n" ! ; ! /* some of the translations from the Motif text widget were not picked up: :osfSelect: set-anchor()\n\ *************** *** 359,362 **** : leave()\n ! */ ! --- 379,381 ---- : leave()\n ! */ *************** *** 373,374 **** --- 392,399 ---- {"extend_end", extendEndAP}, + {"drag-or-grab-focus", dragOrGrabFocusAP}, + {"drag_or_grab_focus", dragOrGrabFocusAP}, + {"drag-or-extend-adjust", dragOrExtendAdjustAP}, + {"drag_or_extend_adjust", dragOrExtendAdjustAP}, + {"drag-or-extend-end", dragOrExtendEndAP}, + {"drag_or_extend_end", dragOrExtendEndAP}, {"secondary-adjust", secondaryAdjustAP}, *************** *** 389,391 **** --- 414,419 ---- {"move_to_or_end_drag", moveToOrEndDragAP}, + {"end-drag", endDragAP}, {"end_drag", endDragAP}, + {"move-secondary", moveSecondaryAP}, + {"move_secondary", moveSecondaryAP}, {"copy-to", copyToAP}, *************** *** 394,396 **** --- 422,429 ---- {"copy_to_or_end_drag", copyToOrEndDragAP}, + {"copy-secondary", copySecondaryAP}, + {"copy_secondary", copySecondaryAP}, + {"exchange", exchangeAP}, {"exchange", exchangeAP}, + {"secondary-or-clipboard", secondaryOrClipboardAP}, + {"secondary_or_clipboard", secondaryOrClipboardAP}, {"process-cancel", processCancelAP}, *************** *** 408,409 **** --- 441,443 ---- {"newline", newlineAP}, + {"newline", newlineAP}, {"newline-and-indent", newlineAndIndentAP}, *************** *** 479,480 **** --- 513,516 ---- {"focusIn", focusInAP}, + {"focusIn", focusInAP}, + {"focusOut", focusOutAP}, {"focusOut", focusOutAP}, *************** *** 486,487 **** --- 522,524 ---- {"insert_string", insertStringAP}, + {"mouse-pan", mousePanAP}, {"mouse_pan", mousePanAP}, *************** *** 566,567 **** --- 603,608 ---- XtOffset(TextWidget, text.readOnly), XmRString, "False"}, + {textNdragStartsOnCharacter, textCDragStartsOnCharacter, XmRBoolean, sizeof(Boolean), + XtOffset(TextWidget, text.dragStartsOnCharacter), XmRString, "False"}, + {textNenableQuadrupleClick, textCEnableQuadrupleClick, XmRBoolean, sizeof(Boolean), + XtOffset(TextWidget, text.enableQuadrupleClick), XmRString, "True"}, {textNwrapMargin, textCWrapMargin, XmRInt, sizeof(int), *************** *** 569,573 **** {textNhScrollBar, textCHScrollBar, XmRWidget, sizeof(Widget), ! XtOffset(TextWidget, text.hScrollBar), XmRString, ""}, {textNvScrollBar, textCVScrollBar, XmRWidget, sizeof(Widget), ! XtOffset(TextWidget, text.vScrollBar), XmRString, ""}, {textNautoShowInsertPos, textCAutoShowInsertPos, XmRBoolean, --- 610,614 ---- {textNhScrollBar, textCHScrollBar, XmRWidget, sizeof(Widget), ! XtOffset(TextWidget, text.hScrollBar), XmRPointer, NULL}, {textNvScrollBar, textCVScrollBar, XmRWidget, sizeof(Widget), ! XtOffset(TextWidget, text.vScrollBar), XmRPointer, NULL}, {textNautoShowInsertPos, textCAutoShowInsertPos, XmRBoolean, *************** *** 599,600 **** --- 640,645 ---- NULL}, + {textNselectThreshold, textCSelectThreshold, XmRInt, sizeof(int), + XtOffset(TextWidget, text.selectThreshold), XmRString, "5"}, + {textNverticalScrollDelay, textCVerticalScrollDelay, XmRInt, sizeof(int), + XtOffset(TextWidget, text.verticalScrollDelay), XmRString, "50"}, }; *************** *** 605,607 **** (WidgetClass) &xmPrimitiveClassRec, /* superclass */ ! "Text", /* class_name */ sizeof(TextRec), /* widget_size */ --- 650,652 ---- (WidgetClass) &xmPrimitiveClassRec, /* superclass */ ! "NEditText", /* class_name */ sizeof(TextRec), /* widget_size */ *************** *** 693,696 **** /* Create and initialize the text-display part of the widget */ ! new->text.textD = TextDCreate((Widget)new, new->text.hScrollBar, ! new->text.vScrollBar, new->text.marginWidth, new->text.marginHeight, new->core.width - new->text.marginWidth * 2, --- 738,741 ---- /* Create and initialize the text-display part of the widget */ ! new->text.textD = TextDCreate((Widget)new, ! new->text.marginWidth, new->text.marginHeight, new->core.width - new->text.marginWidth * 2, *************** *** 703,704 **** --- 748,769 ---- + /* Record the scrollbar widgets created in TextDCreate() for calls + ** to XtVaGetValues() for textNhScrollBar and textNvScrollBar. */ + new->text.hScrollBar = new->text.textD->hScrollBar; + new->text.vScrollBar = new->text.textD->vScrollBar; + + /* Create a list of the delimiters that does not contain whitespace. */ + { + char *s, *d; + + delimiters = XtMalloc(strlen(new->text.delimiters)+1); + for(s = new->text.delimiters, d = delimiters; *s; s++) { + if(!(*s == ' ' || *s == '\t' || *s == '\n')) { + *d = *s; + d++; + } + } + *d = 0; + new->text.nonWhiteSpaceDelimiters = delimiters; + } + /* Add mandatory delimiters blank, tab, and newline to the list of *************** *** 720,722 **** new->text.multiClickState = NO_CLICKS; ! new->text.lastBtnDown = 0; new->text.selectionOwner = False; --- 785,788 ---- new->text.multiClickState = NO_CLICKS; ! new->text.lastBtnDown = -1; ! new->text.lastBtnDownTime = 0; new->text.selectionOwner = False; *************** *** 724,727 **** new->text.emTabsBeforeCursor = 0; ! #ifdef USE_XMIM /* Register the widget to the input manager */ --- 790,796 ---- new->text.emTabsBeforeCursor = 0; + + /* Setup selection handling */ + HandleXSelections((Widget)new); ! #ifdef HAVE_XMIMREGISTER /* Register the widget to the input manager */ *************** *** 754,755 **** --- 823,825 ---- XtFree(w->text.delimiters); + XtFree(w->text.nonWhiteSpaceDelimiters); XtRemoveAllCallbacks((Widget)w, textNfocusCallback); *************** *** 760,762 **** ! #ifdef USE_XMIM /* Unregister the widget from the input manager */ --- 830,832 ---- ! #ifdef HAVE_XMIMREGISTER /* Unregister the widget from the input manager */ *************** *** 865,867 **** attributes->bit_gravity = NorthWestGravity; ! /* Continue with realize method from superclass */ --- 935,937 ---- attributes->bit_gravity = NorthWestGravity; ! /* Continue with realize method from superclass */ *************** *** 901,903 **** } ! /* --- 971,982 ---- } ! ! /* ! ** Set the contents of the widget to the contents of the character string ! ** string. ! */ ! void TextSetString(Widget w, char *string) ! { ! BufSetAll(TextGetBuffer(w), string); ! } ! /* *************** *** 914,915 **** --- 993,995 ---- TextDSetBuffer(((TextWidget)w)->text.textD, buffer); + HandleXSelections(w); if (oldBuf->nModifyProcs == 0) *************** *** 958,959 **** --- 1038,1044 ---- + int TextGetLastCursorPos(Widget w) + { + return TextDGetLastInsertPosition(((TextWidget)w)->text.textD); + } + /* *************** *** 1116,1118 **** if (replaceSel) { ! BufReplaceSelected(buf, wrappedText); TextDSetInsertPosition(textD, buf->cursorPosHint); --- 1201,1203 ---- if (replaceSel) { ! BufReplaceSelected(buf, wrappedText, False); TextDSetInsertPosition(textD, buf->cursorPosHint); *************** *** 1205,1207 **** --- 1290,1294 ---- int lastBtnDown = tw->text.lastBtnDown; + int lastBtnDownTime = tw->text.lastBtnDownTime; int row, column; + int secondary = (hasKey("secondary", args, nArgs) || hasKey("sec", args, nArgs)); *************** *** 1210,1213 **** multi-clicking. Also record the timestamp for multi-click processing */ ! tw->text.dragState = PRIMARY_CLICKED; ! tw->text.lastBtnDown = e->time; --- 1297,1301 ---- multi-clicking. Also record the timestamp for multi-click processing */ ! tw->text.dragState = secondary ? SECONDARY_CLICKED : PRIMARY_CLICKED; ! tw->text.lastBtnDown = e->button; ! tw->text.lastBtnDownTime = e->time; *************** *** 1216,1218 **** widgets and in other NEdit text widgets */ ! TakeMotifDestination(w, e->time); --- 1304,1307 ---- widgets and in other NEdit text widgets */ ! if(!secondary) ! TakeMotifDestination(w, e->time); *************** *** 1220,1236 **** if (tw->text.multiClickState != NO_CLICKS) { ! if (e->time < lastBtnDown + XtGetMultiClickTime(XtDisplay(w))) { ! if (tw->text.multiClickState == ONE_CLICK) { ! selectWord(w, e->x); ! callCursorMovementCBs(w, event); ! return; ! } else if (tw->text.multiClickState == TWO_CLICKS) { ! selectLine(w); ! callCursorMovementCBs(w, event); ! return; ! } else if (tw->text.multiClickState == THREE_CLICKS) { ! BufSelect(textD->buffer, 0, textD->buffer->length); ! return; ! } else if (tw->text.multiClickState > THREE_CLICKS) ! tw->text.multiClickState = NO_CLICKS; ! } else tw->text.multiClickState = NO_CLICKS; --- 1309,1340 ---- if (tw->text.multiClickState != NO_CLICKS) { ! if (e->button == lastBtnDown && e->time < lastBtnDownTime + XtGetMultiClickTime(XtDisplay(w))) { ! if (tw->text.multiClickState == ONE_CLICK) { ! if(secondary) { ! tw->text.anchor = TextDXYToCharPosition(textD, tw->text.btnDownX, tw->text.btnDownY); ! selectSecondaryGroup(w, tw->text.anchor); ! } else { ! tw->text.anchor = TextDXYToCharPosition(textD, tw->text.btnDownX, tw->text.btnDownY); ! selectGroup(w, tw->text.anchor); ! callCursorMovementCBs(w, event); ! } ! return; ! } else if (tw->text.multiClickState == TWO_CLICKS) { ! if(secondary) { ! selectSecondaryLine(w, tw->text.anchor); ! } else { ! selectLine(w, tw->text.anchor); ! callCursorMovementCBs(w, event); ! } ! return; ! } else if (tw->text.enableQuadrupleClick && tw->text.multiClickState == THREE_CLICKS) { ! if(secondary) { ! BufSecondarySelect(textD->buffer, 0, textD->buffer->length, CHAR_SELECT); ! } else { ! BufSelect(textD->buffer, 0, textD->buffer->length, CHAR_SELECT); ! } ! return; ! } else { ! tw->text.multiClickState = NO_CLICKS; ! } ! } else tw->text.multiClickState = NO_CLICKS; *************** *** 1238,1244 **** ! /* Clear any existing selections */ ! BufUnselect(textD->buffer); ! ! /* Move the cursor to the pointer location */ ! moveDestinationAP(w, event, args, nArgs); --- 1342,1357 ---- ! if(!secondary) { ! /* Clear any existing selections */ ! BufUnselect(textD->buffer); ! ! /* Move the cursor to the pointer location */ ! moveDestinationAP(w, event, args, nArgs); ! ! tw->text.anchor = TextDGetInsertPosition(textD); ! } else { ! /* Clear any existing selections */ ! BufSecondaryUnselect(textD->buffer); ! ! tw->text.anchor = TextDXYToPosition(textD, e->x, e->y); ! } *************** *** 1249,1251 **** tw->text.btnDownY = e->y; ! tw->text.anchor = TextDGetInsertPosition(textD); TextDXYToUnconstrainedPosition(textD, e->x, e->y, &row, &column); --- 1362,1364 ---- tw->text.btnDownY = e->y; ! TextDXYToUnconstrainedPosition(textD, e->x, e->y, &row, &column); *************** *** 1276,1282 **** int dragState = tw->text.dragState; ! int rectDrag = hasKey("rect", args, nArgs); /* Make sure the proper initialization was done on mouse down */ ! if (dragState != PRIMARY_DRAG && dragState != PRIMARY_CLICKED && ! dragState != PRIMARY_RECT_DRAG) return; --- 1389,1398 ---- int dragState = tw->text.dragState; ! int rectDrag = (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs)); ! int secondary = (hasKey("secondary", args, nArgs) || hasKey("sec", args, nArgs)); /* Make sure the proper initialization was done on mouse down */ ! if ((!secondary && (dragState != PRIMARY_DRAG && dragState != PRIMARY_CLICKED && ! dragState != PRIMARY_RECT_DRAG)) || ! (secondary && (dragState != SECONDARY_DRAG && dragState != SECONDARY_CLICKED && ! dragState != SECONDARY_RECT_DRAG))) return; *************** *** 1285,1291 **** far enough from the initial mouse down to be considered a drag */ ! if (tw->text.dragState == PRIMARY_CLICKED) { ! if (abs(e->x - tw->text.btnDownX) > SELECT_THRESHOLD || ! abs(e->y - tw->text.btnDownY) > SELECT_THRESHOLD) ! tw->text.dragState = rectDrag ? PRIMARY_RECT_DRAG : PRIMARY_DRAG; ! else return; --- 1401,1414 ---- far enough from the initial mouse down to be considered a drag */ ! if ((!secondary && tw->text.dragState == PRIMARY_CLICKED) ! || (secondary && tw->text.dragState == SECONDARY_CLICKED)) { ! if (abs(e->x - tw->text.btnDownX) > tw->text.selectThreshold || ! abs(e->y - tw->text.btnDownY) > tw->text.selectThreshold) { ! if(tw->text.dragStartsOnCharacter && (e->x > tw->text.btnDownX || e->y > tw->text.btnDownY)) { ! tw->text.anchor = TextDXYToCharPosition( ! tw->text.textD, tw->text.btnDownX, tw->text.btnDownY); ! } else { ! tw->text.anchor = TextDXYToPosition( ! tw->text.textD, tw->text.btnDownX, tw->text.btnDownY); ! } ! } else return; *************** *** 1295,1297 **** to date about which type of drag this is */ ! tw->text.dragState = rectDrag ? PRIMARY_RECT_DRAG : PRIMARY_DRAG; --- 1418,1423 ---- to date about which type of drag this is */ ! tw->text.dragState = !secondary && rectDrag ? PRIMARY_RECT_DRAG : ! !secondary && !rectDrag ? PRIMARY_DRAG : ! secondary && rectDrag ? SECONDARY_RECT_DRAG : ! SECONDARY_DRAG; *************** *** 1311,1317 **** textBuffer *buf = textD->buffer; ! selection *sel = &buf->primary; int anchor, rectAnchor, anchorLineStart, newPos, row, column; /* Find the new anchor point for the rest of this drag operation */ - newPos = TextDXYToPosition(textD, e->x, e->y); TextDXYToUnconstrainedPosition(textD, e->x, e->y, &row, &column); --- 1437,1452 ---- textBuffer *buf = textD->buffer; ! selection *sel; int anchor, rectAnchor, anchorLineStart, newPos, row, column; + selType selType = CHAR_SELECT; + int rectangular = (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs)); + int secondary = (hasKey("secondary", args, nArgs) || hasKey("sec", args, nArgs)); + enum dragStates dragState; + + if(secondary) { + sel = &buf->secondary; + } else { + sel = &buf->primary; + } /* Find the new anchor point for the rest of this drag operation */ TextDXYToUnconstrainedPosition(textD, e->x, e->y, &row, &column); *************** *** 1320,1321 **** --- 1455,1457 ---- if (sel->rectangular) { + newPos = TextDXYToPosition(textD, e->x, e->y); rectAnchor = column < (sel->rectEnd + sel->rectStart) / 2 ? *************** *** 1326,1336 **** } else { ! if (abs(newPos - sel->start) < abs(newPos - sel->end)) ! anchor = sel->end; ! else ! anchor = sel->start; ! anchorLineStart = BufStartOfLine(buf, anchor); rectAnchor = BufCountDispChars(buf, anchorLineStart, anchor); } } else { ! anchor = TextDGetInsertPosition(textD); anchorLineStart = BufStartOfLine(buf, anchor); --- 1462,1523 ---- } else { ! TextWidget tw = (TextWidget)w; ! int startPos, endPos, countBefore, countAfter; ! if (sel->type == WORD_SELECT) { ! newPos = TextDXYToCharPosition(textD, e->x, e->y); ! startPos = startOfGroup(tw, newPos); ! endPos = endOfGroup(tw, newPos); ! countBefore = abs(sel->start - newPos); ! countAfter = abs(sel->end - newPos); ! } else if (sel->type == LINE_SELECT) { ! newPos = TextDXYToPosition(textD, e->x, e->y); ! startPos = BufStartOfLine(buf, newPos); ! endPos = BufEndOfLine(buf, newPos); ! endPos = min(endPos+1, buf->length); ! countBefore = BufCountLines(buf, min(sel->start, newPos), max(sel->start, newPos)); ! countAfter = BufCountLines(buf, min(sel->end, newPos), max(sel->end, newPos)) - 1; ! if(newPos >= sel->start && newPos <= sel->end && (countBefore + countAfter) <= 2 && (countBefore + countAfter) >= 1) { ! if(newPos < ((TextWidget)w)->text.anchor) { ! countBefore = 0; ! countAfter = 1; ! } else { ! countBefore = 1; ! countAfter = 0; ! } ! } ! } else { ! newPos = TextDXYToPosition(textD, e->x, e->y); ! /* Select the newline if we are past the end of the line. */ ! if(newPos > ((TextWidget)w)->text.anchor) { ! int posX, posY; ! if(TextDPositionToXY(textD, newPos, &posX, &posY)) { ! if(e->x > posX) { ! newPos++; ! } ! } ! } ! startPos = endPos = newPos; ! countBefore = abs(sel->start - newPos); ! countAfter = abs(sel->end - newPos); ! } ! ! /* Extend/reduce the selection from the side of the selection ! ** that the new position is closer based on displayed characters. ! ** If in LINE_SELECT mode then base it on the number of lines. ! */ ! if (countBefore <= countAfter) { ! /* closer to start */ ! anchor = sel->end; ! newPos = startPos; ! } else { ! /* closer to end */ ! anchor = sel->start; ! newPos = endPos; ! } ! anchorLineStart = BufStartOfLine(buf, anchor); rectAnchor = BufCountDispChars(buf, anchorLineStart, anchor); } + selType = sel->type; } else { ! newPos = TextDXYToPosition(textD, e->x, e->y); ! anchor = secondary ? ((TextWidget)w)->text.anchor : TextDGetInsertPosition(textD); anchorLineStart = BufStartOfLine(buf, anchor); *************** *** 1342,1349 **** /* Make the new selection */ ! if (hasKey("rect", args, nArgs)) ! BufRectSelect(buf, BufStartOfLine(buf, min(anchor, newPos)), ! BufEndOfLine(buf, max(anchor, newPos)), ! min(rectAnchor, column), max(rectAnchor, column)); ! else ! BufSelect(buf, min(anchor, newPos), max(anchor, newPos)); --- 1529,1549 ---- /* Make the new selection */ ! if (rectangular) { ! if(secondary) { ! BufSecRectSelect(buf, BufStartOfLine(buf, min(anchor, newPos)), ! BufEndOfLine(buf, max(anchor, newPos)), ! min(rectAnchor, column), max(rectAnchor, column)); ! dragState = SECONDARY_RECT_DRAG; ! } else { ! BufRectSelect(buf, BufStartOfLine(buf, min(anchor, newPos)), ! BufEndOfLine(buf, max(anchor, newPos)), ! min(rectAnchor, column), max(rectAnchor, column)); ! dragState = PRIMARY_RECT_DRAG; ! } ! } else if(secondary) { ! BufSecondarySelect(buf, min(anchor, newPos), max(anchor, newPos), selType); ! dragState = SECONDARY_DRAG; ! } else { ! BufSelect(buf, min(anchor, newPos), max(anchor, newPos), selType); ! dragState = PRIMARY_DRAG; ! } *************** *** 1351,1353 **** extend-start is unambiguously the start of a selection */ ! ((TextWidget)w)->text.dragState = PRIMARY_DRAG; --- 1551,1553 ---- extend-start is unambiguously the start of a selection */ ! ((TextWidget)w)->text.dragState = dragState; *************** *** 1357,1360 **** /* Move the cursor */ ! TextDSetInsertPosition(textD, newPos); ! callCursorMovementCBs(w, event); } --- 1557,1562 ---- /* Move the cursor */ ! if(!secondary) { ! TextDSetInsertPosition(textD, newPos); ! callCursorMovementCBs(w, event); ! } } *************** *** 1366,1370 **** TextWidget tw = (TextWidget)w; ! if (tw->text.dragState == PRIMARY_CLICKED && ! tw->text.lastBtnDown <= e->time + XtGetMultiClickTime(XtDisplay(w))) tw->text.multiClickState++; --- 1568,1574 ---- TextWidget tw = (TextWidget)w; + int secondary = (hasKey("secondary", args, nArgs) || hasKey("sec", args, nArgs)); ! if(((secondary && tw->text.dragState == SECONDARY_CLICKED) ! || (!secondary && tw->text.dragState == PRIMARY_CLICKED)) && ! e->button == tw->text.lastBtnDown) tw->text.multiClickState++; *************** *** 1373,1374 **** --- 1577,1605 ---- + static void dragOrGrabFocusAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + /* If we can't start a block drag then just call grab-focus. */ + if(!blockDragStart(w, event, args, nArgs)) { + grabFocusAP(w, event, args, nArgs); + } + } + + static void dragOrExtendAdjustAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + /* If we can't do a block drag adjust then just call extend-adjust. */ + if(!blockDragAdjust(w, event, args, nArgs)) { + extendAdjustAP(w, event, args, nArgs); + } + } + + static void dragOrExtendEndAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + /* If we can't do a block drag end then just call extend-end. */ + if(!blockDragEnd(w, event, args, nArgs)) { + extendEndAP(w, event, args, nArgs); + } + } + static void processCancelAP(Widget w, XEvent *event, String *args, *************** *** 1387,1415 **** { ! XMotionEvent *e = (XMotionEvent *)event; ! textDisp *textD = ((TextWidget)w)->text.textD; ! textBuffer *buf = textD->buffer; ! selection *sel = &buf->secondary; ! int anchor, pos, row, column; ! ! /* Find the new anchor point and make the new selection */ ! pos = TextDXYToPosition(textD, e->x, e->y); ! if (sel->selected) { ! if (abs(pos - sel->start) < abs(pos - sel->end)) ! anchor = sel->end; ! else ! anchor = sel->start; ! BufSecondarySelect(buf, anchor, pos); ! } else ! anchor = pos; ! /* Record the site of the initial button press and the initial character ! position so subsequent motion events can decide when to begin a ! selection, (and where the selection began) */ ! ((TextWidget)w)->text.btnDownX = e->x; ! ((TextWidget)w)->text.btnDownY = e->y; ! ((TextWidget)w)->text.anchor = pos; ! TextDXYToUnconstrainedPosition(textD, e->x, e->y, &row, &column); ! column = TextDOffsetWrappedColumn(textD, row, column); ! ((TextWidget)w)->text.rectAnchor = column; ! ((TextWidget)w)->text.dragState = SECONDARY_CLICKED; } --- 1618,1638 ---- { ! String *params; ! Cardinal argc = *nArgs + 1; ! params = (String*)XtMalloc(argc * sizeof(String)); ! memcpy(params, args, (argc - 1) * sizeof(String)); ! params[argc-1] = "secondary"; ! grabFocusAP(w, event, params, &argc); ! XtFree((char*)params); ! } ! static void secondaryAdjustAP(Widget w, XEvent *event, String *args, ! Cardinal *nArgs) ! { ! String *params; ! Cardinal argc = *nArgs + 1; ! params = (String*)XtMalloc(argc * sizeof(String)); ! memcpy(params, args, (argc - 1) * sizeof(String)); ! params[argc-1] = "secondary"; ! extendAdjustAP(w, event, params, &argc); ! XtFree((char*)params); } *************** *** 1419,1478 **** { ! XMotionEvent *e = (XMotionEvent *)event; ! textDisp *textD = ((TextWidget)w)->text.textD; ! textBuffer *buf = textD->buffer; ! ! /* If the click was outside of the primary selection, this is not ! a drag, start a secondary selection */ ! if (!buf->primary.selected || !TextDInSelection(textD, e->x, e->y)) { secondaryStartAP(w, event, args, nArgs); - return; } ! if (checkReadOnly(w)) ! return; ! ! /* Record the site of the initial button press and the initial character ! position so subsequent motion events can decide when to begin a ! drag, and where to drag to */ ! ((TextWidget)w)->text.btnDownX = e->x; ! ((TextWidget)w)->text.btnDownY = e->y; ! ((TextWidget)w)->text.dragState = CLICKED_IN_SELECTION; } ! static void secondaryAdjustAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { TextWidget tw = (TextWidget)w; ! XMotionEvent *e = (XMotionEvent *)event; ! int dragState = tw->text.dragState; ! int rectDrag = hasKey("rect", args, nArgs); ! /* Make sure the proper initialization was done on mouse down */ ! if (dragState != SECONDARY_DRAG && dragState != SECONDARY_RECT_DRAG && ! dragState != SECONDARY_CLICKED) ! return; ! ! /* If the selection hasn't begun, decide whether the mouse has moved ! far enough from the initial mouse down to be considered a drag */ ! if (tw->text.dragState == SECONDARY_CLICKED) { ! if (abs(e->x - tw->text.btnDownX) > SELECT_THRESHOLD || ! abs(e->y - tw->text.btnDownY) > SELECT_THRESHOLD) ! tw->text.dragState = rectDrag ? SECONDARY_RECT_DRAG: SECONDARY_DRAG; ! else ! return; } ! ! /* If "rect" argument has appeared or disappeared, keep dragState up ! to date about which type of drag this is */ ! tw->text.dragState = rectDrag ? SECONDARY_RECT_DRAG : SECONDARY_DRAG; ! ! /* Record the new position for the autoscrolling timer routine, and ! engage or disengage the timer if the mouse is in/out of the window */ ! checkAutoScroll(tw, e->x, e->y); ! ! /* Adjust the selection */ ! adjustSecondarySelection(tw, e->x, e->y); } ! static void secondaryOrDragAdjustAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) --- 1642,1690 ---- { ! if(!blockDragStart(w, event, args, nArgs)) { secondaryStartAP(w, event, args, nArgs); } + } ! static void secondaryOrDragAdjustAP(Widget w, XEvent *event, String *args, ! Cardinal *nArgs) ! { ! if(!blockDragAdjust(w, event, args, nArgs)) { ! secondaryAdjustAP(w, event, args, nArgs); ! } } ! static Boolean blockDragStart(Widget w, XEvent *event, String *args, Cardinal *nArgs) { + XButtonEvent *e = (XButtonEvent *)event; TextWidget tw = (TextWidget)w; ! textDisp *textD = tw->text.textD; ! int lastBtnDown = tw->text.lastBtnDown; ! int lastBtnDownTime = tw->text.lastBtnDownTime; ! int secondary = (hasKey("secondary", args, nArgs) || hasKey("sec", args, nArgs)); ! /* See if this is the start of a drag operation. ! ** If the widget is not read only and the multi-click time has expired ! ** and this isn't for the secondary selection and the click was inside the ! ** primary selection then this is a drag operations. */ ! if(!tw->text.readOnly && ! !(e->button == lastBtnDown && e->time <= (lastBtnDownTime + XtGetMultiClickTime(XtDisplay(w)))) && ! !secondary && TextDInSelection(textD, e->x, e->y)) { ! /* Record the site of the initial button press and the initial character ! position so subsequent motion events can decide when to begin a ! drag, and where to drag to */ ! tw->text.btnDownX = e->x; ! tw->text.btnDownY = e->y; ! tw->text.lastBtnDown = e->button; ! tw->text.lastBtnDownTime = e->time; ! tw->text.dragState = CLICKED_IN_SELECTION; ! ! /* This should still be treated as the first click of a selection. */ ! tw->text.multiClickState = ONE_CLICK; ! return TRUE; } ! return FALSE; } ! static Boolean blockDragAdjust(Widget w, XEvent *event, String *args, Cardinal *nArgs) *************** *** 1483,1489 **** ! /* Only dragging of blocks of text is handled in this action proc. ! Otherwise, defer to secondaryAdjust to handle the rest */ if (dragState != CLICKED_IN_SELECTION && dragState != PRIMARY_BLOCK_DRAG) { ! secondaryAdjustAP(w, event, args, nArgs); ! return; } --- 1695,1699 ---- ! /* Only dragging of blocks of text is handled in this action proc. */ if (dragState != CLICKED_IN_SELECTION && dragState != PRIMARY_BLOCK_DRAG) { ! return FALSE; } *************** *** 1493,1499 **** if (tw->text.dragState == CLICKED_IN_SELECTION) { ! if (abs(e->x - tw->text.btnDownX) > SELECT_THRESHOLD || ! abs(e->y - tw->text.btnDownY) > SELECT_THRESHOLD) BeginBlockDrag(tw); else ! return; } --- 1703,1709 ---- if (tw->text.dragState == CLICKED_IN_SELECTION) { ! if (abs(e->x - tw->text.btnDownX) > tw->text.selectThreshold || ! abs(e->y - tw->text.btnDownY) > tw->text.selectThreshold) BeginBlockDrag(tw); else ! return FALSE; } *************** *** 1508,1509 **** --- 1718,1746 ---- (hasKey("copy", args, nArgs) ? DRAG_COPY : DRAG_MOVE)); + + return TRUE; + } + + static Boolean blockDragEnd(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + TextWidget tw = (TextWidget)w; + textDisp *textD = tw->text.textD; + int dragState = ((TextWidget)w)->text.dragState; + + /* deselect the selection if we didn't leave the CLICKED_IN_SELECTION + ** state. */ + if (dragState == CLICKED_IN_SELECTION) { + BufUnselect(textD->buffer); + + /* Move the cursor to the pointer location */ + moveDestinationAP(w, event, args, nArgs); + + tw->text.anchor = TextDGetInsertPosition(textD); + return TRUE; + } + else if(dragState == PRIMARY_BLOCK_DRAG) { + FinishBlockDrag((TextWidget)w); + return TRUE; + } + return FALSE; } *************** *** 1539,1541 **** insertPos = TextDGetInsertPosition(textD); ! BufReplaceSelected(buf, textToCopy); TextDSetInsertPosition(textD, buf->cursorPosHint); --- 1776,1778 ---- insertPos = TextDGetInsertPosition(textD); ! BufReplaceSelected(buf, textToCopy, False); TextDSetInsertPosition(textD, buf->cursorPosHint); *************** *** 1606,1608 **** insertPos = TextDGetInsertPosition(textD); ! BufReplaceSelected(buf, textToCopy); TextDSetInsertPosition(textD, buf->cursorPosHint); --- 1843,1845 ---- insertPos = TextDGetInsertPosition(textD); ! BufReplaceSelected(buf, textToCopy, False); TextDSetInsertPosition(textD, buf->cursorPosHint); *************** *** 1692,1694 **** newPrimaryStart = primary->start; ! BufReplaceSelected(buf, secText); newPrimaryEnd = newPrimaryStart + strlen(secText); --- 1929,1931 ---- newPrimaryStart = primary->start; ! BufReplaceSelected(buf, secText, False); newPrimaryEnd = newPrimaryStart + strlen(secText); *************** *** 1700,1702 **** } else { ! BufSelect(buf, newPrimaryStart, newPrimaryEnd); TextDSetInsertPosition(textD, newPrimaryEnd); --- 1937,1939 ---- } else { ! BufSelect(buf, newPrimaryStart, newPrimaryEnd, CHAR_SELECT); TextDSetInsertPosition(textD, newPrimaryEnd); *************** *** 1714,1716 **** selection *primary = &buf->primary; ! int rectangular = hasKey("rect", args, nArgs); char *textToCopy; --- 1951,1953 ---- selection *primary = &buf->primary; ! int rectangular = (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs)); char *textToCopy; *************** *** 1753,1755 **** char *textToCopy; ! int rectangular = hasKey("rect", args, nArgs); int insertPos, col; --- 1990,1992 ---- char *textToCopy; ! int rectangular = (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs)); int insertPos, col; *************** *** 1817,1819 **** { ! if (hasKey("rect", args, nArgs)) TextColPasteClipboard(w, ((XKeyEvent *)event)->time); --- 2054,2056 ---- { ! if ((hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs))) TextColPasteClipboard(w, ((XKeyEvent *)event)->time); *************** *** 1835,1836 **** --- 2072,2193 ---- + /* + ** Perform the secondary operation specified by the first arg if + ** there is a secondary selection otherwise perform the clipboard + ** operation specified by the second arg. + */ + static void secondaryOrClipboardAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) + { + if(*nArgs != 2) return; + + if (((TextWidget)w)->text.textD->buffer->secondary.selected) { + if(!strCaseCmp(args[0], "copy")) { + copySecondaryAP(w, event, args, nArgs); + } + else if(!strCaseCmp(args[0], "move")) { + moveSecondaryAP(w, event, args, nArgs); + } + else if(!strCaseCmp(args[0], "exchange")) { + exchangeAP(w, event, args, nArgs); + } + } else { + if(!strCaseCmp(args[1], "copy")) { + copyClipboardAP(w, event, args, nArgs); + } + else if(!strCaseCmp(args[1], "paste")) { + pasteClipboardAP(w, event, args, nArgs); + } + else if(!strCaseCmp(args[1], "cut")) { + cutClipboardAP(w, event, args, nArgs); + } + } + } + + /* Copy the secondary selection into the primary selection or + into the insertion cursor */ + static void copySecondaryAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) + { + XButtonEvent *e = (XButtonEvent *)event; + TextWidget tw = (TextWidget)w; + textDisp *textD = tw->text.textD; + textBuffer *buf = textD->buffer; + selection *secondary = &buf->secondary, *primary = &buf->primary; + int rectangular = secondary->rectangular; + char *textToCopy; + int insertPos, lineStart, column; + + if (secondary->selected) { + endDrag(w); + if (((TextWidget)w)->text.motifDestOwner) { + if (checkReadOnly(w)) { + BufSecondaryUnselect(buf); + return; + } + TextDBlankCursor(textD); + textToCopy = BufGetSecSelectText(buf); + if (primary->selected && rectangular) { + insertPos = TextDGetInsertPosition(textD); + BufReplaceSelected(buf, textToCopy, False); + TextDSetInsertPosition(textD, buf->cursorPosHint); + } else if (rectangular) { + insertPos = TextDGetInsertPosition(textD); + lineStart = BufStartOfLine(buf, insertPos); + column = BufCountDispChars(buf, lineStart, insertPos); + BufInsertCol(buf, column, lineStart, textToCopy, NULL, NULL); + TextDSetInsertPosition(textD, buf->cursorPosHint); + } else + TextInsertAtCursor(w, textToCopy, event, True, + tw->text.autoWrapPastedText); + XtFree(textToCopy); + BufSecondaryUnselect(buf); + TextDUnblankCursor(textD); + } else + SendSecondarySelection(w, e->time, False); + } + } + + /* Move the secondary selection in place of the primary selection or + move to the insertion cursor */ + static void moveSecondaryAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) + { + XButtonEvent *e = (XButtonEvent *)event; + TextWidget tw = (TextWidget)w; + textDisp *textD = tw->text.textD; + textBuffer *buf = textD->buffer; + selection *secondary = &buf->secondary, *primary = &buf->primary; + int rectangular = secondary->rectangular; + char *textToCopy; + int insertPos, lineStart, column; + + if (secondary->selected) { + endDrag(w); + if (((TextWidget)w)->text.motifDestOwner) { + if (checkReadOnly(w)) { + BufSecondaryUnselect(buf); + return; + } + TextDBlankCursor(textD); + textToCopy = BufGetSecSelectText(buf); + if (primary->selected && rectangular) { + insertPos = TextDGetInsertPosition(textD); + BufReplaceSelected(buf, textToCopy, False); + TextDSetInsertPosition(textD, buf->cursorPosHint); + } else if (rectangular) { + insertPos = TextDGetInsertPosition(textD); + lineStart = BufStartOfLine(buf, insertPos); + column = BufCountDispChars(buf, lineStart, insertPos); + BufInsertCol(buf, column, lineStart, textToCopy, NULL, NULL); + TextDSetInsertPosition(textD, buf->cursorPosHint); + } else + TextInsertAtCursor(w, textToCopy, event, True, + tw->text.autoWrapPastedText); + XtFree(textToCopy); + BufRemoveSecSelect(buf); + BufSecondaryUnselect(buf); + TextDUnblankCursor(textD); + } else + SendSecondarySelection(w, e->time, True); + } + } + static void insertStringAP(Widget w, XEvent *event, String *args, *************** *** 1849,1852 **** { ! #ifdef USE_XMIM Status status; #endif --- 2206,2211 ---- { ! #ifdef HAVE_XMIMREGISTER Status status; + #else + static XComposeStatus compose = {NULL, 0}; #endif *************** *** 1856,1858 **** int nChars; - static XComposeStatus compose = {NULL, 0}; smartIndentCBStruct smartIndent; --- 2215,2216 ---- *************** *** 1860,1862 **** ! #ifdef USE_XMIM nChars = XmImMbLookupString(w, (XKeyEvent *)event, chars, 19, &keysym, --- 2218,2220 ---- ! #ifdef HAVE_XMIMREGISTER nChars = XmImMbLookupString(w, (XKeyEvent *)event, chars, 19, &keysym, *************** *** 2099,2101 **** while (strchr(delimiters, BufGetCharacter(textD->buffer, pos)) != NULL && ! pos != lineStart) pos--; --- 2457,2459 ---- while (strchr(delimiters, BufGetCharacter(textD->buffer, pos)) != NULL && ! pos > lineStart) pos--; *************** *** 2208,2209 **** --- 2566,2570 ---- + /* + ** Move the cursor to the end of the current or the next word. + */ static void forwardWordAP(Widget w, XEvent *event, String *args, *************** *** 2222,2229 **** pos = insertPos; ! if (strchr(delimiters, BufGetCharacter(buf, pos)) == NULL) ! pos = endOfWord((TextWidget)w, pos); ! for (; poslength; pos++) { ! if (strchr(delimiters, BufGetCharacter(buf, pos)) == NULL) ! break; } TextDSetInsertPosition(textD, pos); --- 2583,2592 ---- pos = insertPos; ! ! /* Skip the first set of delimiters */ ! while(strchr(delimiters, BufGetCharacter(buf, pos)) != NULL) { ! pos++; } + + /* Move the cursor to the end of the word. */ + pos = endOfWord((TextWidget)w, pos); TextDSetInsertPosition(textD, pos); *************** *** 2234,2235 **** --- 2597,2601 ---- + /* + ** Move the cursor to the beginning of the currrent or the previous word. + */ static void backwardWordAP(Widget w, XEvent *event, String *args, *************** *** 2363,2365 **** XBell(XtDisplay(w), 0); ! keyMoveExtendSelection(w, event, insertPos, hasKey("rect", args, nArgs)); checkAutoShowInsertPos(w); --- 2729,2731 ---- XBell(XtDisplay(w), 0); ! keyMoveExtendSelection(w, event, insertPos, (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs))); checkAutoShowInsertPos(w); *************** *** 2389,2391 **** XBell(XtDisplay(w), 0); ! keyMoveExtendSelection(w, event, insertPos, hasKey("rect", args, nArgs)); checkAutoShowInsertPos(w); --- 2755,2757 ---- XBell(XtDisplay(w), 0); ! keyMoveExtendSelection(w, event, insertPos, (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs))); checkAutoShowInsertPos(w); *************** *** 2399,2403 **** int insertPos = TextDGetInsertPosition(textD); ! cancelDrag(w); ! TextDSetInsertPosition(textD, TextDStartOfLine(textD, insertPos)); checkMoveSelectionChange(w, event, insertPos, args, nArgs); --- 2765,2802 ---- int insertPos = TextDGetInsertPosition(textD); ! int newInsertPos; ! int toggle = hasKey("toggle", args, nArgs); ! int firstNonWhite = hasKey("non-space", args, nArgs); ! cancelDrag(w); ! if(toggle || firstNonWhite) { ! int startOfLine; ! int firstNonWhitePos; ! ! startOfLine = TextDStartOfLine(textD, insertPos); ! ! /* Find the first non-whitespace character after the start of ! the line. */ ! for(firstNonWhitePos = startOfLine; startOfLine < textD->buffer->length; firstNonWhitePos++) { ! char ch = BufGetCharacter(textD->buffer, firstNonWhitePos); ! if(!(ch == ' ' || ch == '\t')) ! break; ! } ! ! /* Toggle the insert position between the start of the line and the ! first non-whitespace character */ ! if(toggle) { ! if(firstNonWhite) { ! newInsertPos = (insertPos == firstNonWhitePos) ? startOfLine : firstNonWhitePos; ! } ! else { ! newInsertPos = (insertPos == startOfLine) ? firstNonWhitePos : startOfLine; ! } ! } else { ! newInsertPos = firstNonWhitePos; ! } ! } ! else { ! newInsertPos = TextDStartOfLine(textD, insertPos); ! } ! TextDSetInsertPosition(textD, newInsertPos); checkMoveSelectionChange(w, event, insertPos, args, nArgs); *************** *** 2411,2415 **** int insertPos = TextDGetInsertPosition(textD); cancelDrag(w); ! TextDSetInsertPosition(textD, TextDEndOfLine(textD, insertPos, False)); checkMoveSelectionChange(w, event, insertPos, args, nArgs); --- 2810,2848 ---- int insertPos = TextDGetInsertPosition(textD); + int newInsertPos; + int toggle = hasKey("toggle", args, nArgs); + int lastNonWhite = hasKey("non-space", args, nArgs); cancelDrag(w); ! if(toggle || lastNonWhite) { ! int endOfLine; ! int lastNonWhitePos; ! ! endOfLine = TextDEndOfLine(textD, insertPos, False); ! ! /* Find the last non-whitespace character before the end of ! the line. */ ! for(lastNonWhitePos = endOfLine; lastNonWhitePos > 0; lastNonWhitePos--) { ! char ch; ! ch = BufGetCharacter(textD->buffer, lastNonWhitePos - 1); ! if(!(ch == ' ' || ch == '\t')) ! break; ! } ! ! /* Toggle the insert position between the end of the line and the ! last non-whitespace character */ ! if(toggle) { ! if(lastNonWhite) { ! newInsertPos = (insertPos == lastNonWhitePos) ? endOfLine : lastNonWhitePos; ! } ! else { ! newInsertPos = (insertPos == endOfLine) ? lastNonWhitePos : endOfLine; ! } ! } else { ! newInsertPos = lastNonWhitePos; ! } ! } ! else { ! newInsertPos = TextDEndOfLine(textD, insertPos, False); ! } ! TextDSetInsertPosition(textD, newInsertPos); checkMoveSelectionChange(w, event, insertPos, args, nArgs); *************** *** 2598,2600 **** cancelDrag(w); ! BufSelect(buf, 0, buf->length); } --- 3031,3033 ---- cancelDrag(w); ! BufSelect(buf, 0, buf->length, CHAR_SELECT); } *************** *** 2619,2622 **** #if XmVersion >= 1002 ! if (w != XmGetFocusWidget(w)) ! return; #endif --- 3052,3055 ---- #if XmVersion >= 1002 ! if (w != XmGetFocusWidget(w)) ! return; #endif *************** *** 2631,2640 **** /* Change the cursor to active style */ ! if (((TextWidget)w)->text.overstrike) ! TextDSetCursorStyle(textD, BLOCK_CURSOR); ! else ! TextDSetCursorStyle(textD, ((TextWidget)w)->text.heavyCursor ? ! HEAVY_CURSOR : NORMAL_CURSOR); TextDUnblankCursor(textD); ! #ifdef USE_XMIM /* Notify Motif input manager that widget has focus */ --- 3064,3073 ---- /* Change the cursor to active style */ ! if (((TextWidget)w)->text.overstrike) ! TextDSetCursorStyle(textD, BLOCK_CURSOR); ! else ! TextDSetCursorStyle(textD, ((TextWidget)w)->text.heavyCursor ? ! HEAVY_CURSOR : NORMAL_CURSOR); TextDUnblankCursor(textD); ! #ifdef HAVE_XMIMREGISTER /* Notify Motif input manager that widget has focus */ *************** *** 2657,2660 **** /* Leave a dim or destination cursor */ ! TextDSetCursorStyle(textD, ((TextWidget)w)->text.motifDestOwner ? ! CARET_CURSOR : DIM_CURSOR); TextDUnblankCursor(textD); --- 3090,3093 ---- /* Leave a dim or destination cursor */ ! TextDSetCursorStyle(textD, ((TextWidget)w)->text.motifDestOwner ? ! CARET_CURSOR : DIM_CURSOR); TextDUnblankCursor(textD); *************** *** 2674,2676 **** if (hasKey("extend", args, nArgs)) ! keyMoveExtendSelection(w, event, startPos, hasKey("rect", args, nArgs)); else --- 3107,3109 ---- if (hasKey("extend", args, nArgs)) ! keyMoveExtendSelection(w, event, startPos, (hasKey("rect", args, nArgs) || hasKey("rectangular", args, nArgs))); else *************** *** 2724,2726 **** anchor = startPos; ! BufSelect(buf, anchor, newPos); } else if (sel->selected && rectangular) { /* plain -> rect */ --- 3157,3159 ---- anchor = startPos; ! BufSelect(buf, anchor, newPos, CHAR_SELECT); } else if (sel->selected && rectangular) { /* plain -> rect */ *************** *** 2739,2741 **** anchor = sel->start; ! BufSelect(buf, anchor, newPos); } else if (rectangular) { /* no sel -> rect */ --- 3172,3174 ---- anchor = sel->start; ! BufSelect(buf, anchor, newPos, CHAR_SELECT); } else if (rectangular) { /* no sel -> rect */ *************** *** 2750,2752 **** anchor = origPos; ! BufSelect(buf, anchor, newPos); } --- 3183,3185 ---- anchor = origPos; ! BufSelect(buf, anchor, newPos, CHAR_SELECT); } *************** *** 2782,2784 **** if (allowPendingDelete && pendingSelection(w)) { ! BufReplaceSelected(buf, chars); TextDSetInsertPosition(textD, buf->cursorPosHint); --- 3215,3217 ---- if (allowPendingDelete && pendingSelection(w)) { ! BufReplaceSelected(buf, chars, False); TextDSetInsertPosition(textD, buf->cursorPosHint); *************** *** 2935,2937 **** } ! BufSelect(textD->buffer, startPos, endPos); TextDSetInsertPosition(textD, endPos); --- 3368,3370 ---- } ! BufSelect(textD->buffer, startPos, endPos, WORD_SELECT); TextDSetInsertPosition(textD, endPos); *************** *** 2946,2947 **** --- 3379,3392 ---- + /* + ** Select the word adjacent to the cursor + */ + static void selectSecondaryWord(Widget w, int pos) + { + int startPos, endPos; + + startPos = startOfWord((TextWidget)w, pos); + endPos = endOfWord((TextWidget)w, pos); + BufSecondarySelect(((TextWidget)w)->text.textD->buffer, startPos, endPos, WORD_SELECT); + } + static int startOfWord(TextWidget w, int pos) *************** *** 2967,2968 **** --- 3412,3594 ---- /* + ** Select the group of like chars around the cursor. Like characters + ** are newline, space or tab, non-delimiter characters and the delimiter + ** characters minus the newline, space and tab. + */ + static void selectGroup(Widget w, int pos) + { + int startPos, endPos, insertPos; + + startPos = startOfGroup((TextWidget)w, pos); + endPos = endOfGroup((TextWidget)w, pos); + insertPos = pos < (startPos + (endPos - startPos) / 2) ? startPos : endPos; + BufSelect(((TextWidget)w)->text.textD->buffer, startPos, endPos, WORD_SELECT); + TextDSetInsertPosition(((TextWidget)w)->text.textD, insertPos); + } + + /* + ** Select the group of like chars around the cursor. Like characters + ** are newline, space or tab, non-delimiter characters and the delimiter + ** characters minus the newline, space and tab. + */ + static void selectSecondaryGroup(Widget w, int pos) + { + int startPos, endPos; + + startPos = startOfGroup((TextWidget)w, pos); + endPos = endOfGroup((TextWidget)w, pos); + BufSecondarySelect(((TextWidget)w)->text.textD->buffer, startPos, endPos, WORD_SELECT); + } + + /* + ** Returns the position of the start of a group of like characters. Like + ** characters are newline, space or tab, non-delimiter characters and the + ** delimiter characters minus the newline, space and tab. + */ + static int startOfGroup(TextWidget w, int pos) + { + textBuffer *buf = w->text.textD->buffer; + int startPos; + char c; + char *whiteSpace = " \t"; + int isWhiteSpace = 0; + int isDelimiter = 0; + char *searchChars = whiteSpace; + + /* return the start of the buffer if pos was out of range */ + if(pos < 0) { + return 0; + } + + /* return the end of the buffer if pos was out of range */ + if(pos >= buf->length) { + return buf->length; + } + + c = BufGetCharacter(buf, pos); + + /* A newline is considered a word so just return its position. */ + if(c == '\n') { + return pos; + } + + /* if the character at pos is a word, that is, it is not one of the + delimiter characters, then return its start */ + if(strchr(w->text.delimiters, c) == NULL) { + if(BufSearchBackward(w->text.textD->buffer, pos, w->text.delimiters, + &startPos)) + return min(pos, startPos+1); + else + return 0; + } + + /* If it is not a word then see if the character at pos is a + whitespace character. */ + if(strchr(whiteSpace, c) != NULL) { + isWhiteSpace = 1; + searchChars = whiteSpace; + } + /* If is not whitespace then see if it is a delimiter */ + else { + if(strchr(w->text.nonWhiteSpaceDelimiters, c) != NULL) { + isDelimiter = 1; + searchChars = w->text.nonWhiteSpaceDelimiters; + } + } + + /* If pos was white space or a delimiter then return the start of + the whitespace or the start of the group of delimiters */ + if(isWhiteSpace || isDelimiter) { + int foundPos; + startPos = pos; + while(BufSearchBackward(w->text.textD->buffer, startPos, searchChars, + &foundPos)) { + if(foundPos != startPos-1) + break; + startPos = foundPos; + } + } + /* else return the original position. This shouldn't happen */ + else { + startPos = pos; + } + + return startPos; + } + + /* + ** Returns the position of the end of a group of like characters. Like + ** characters are newline, space or tab, non-delimiter characters and the + ** delimiter characters minus the newline, space and tab. + */ + static int endOfGroup(TextWidget w, int pos) + { + textBuffer *buf = w->text.textD->buffer; + int endPos; + char c; + char *whiteSpace = " \t"; + int isWhiteSpace = 0; + int isDelimiter = 0; + char *searchChars = whiteSpace; + + /* return the start of the buffer if pos was out of range */ + if(pos < 0) { + return 0; + } + + /* return the end of the buffer if pos was out of range */ + if(pos >= buf->length) { + return buf->length; + } + + c = BufGetCharacter(buf, pos); + + /* A newline is considered a word so just return its position + 1. */ + if(c == '\n') { + return pos + 1; + } + + /* if the character at pos is a word, that is, it is not one of the + delimiter characters, then return its end */ + if(strchr(w->text.delimiters, c) == NULL) { + if (!BufSearchForward(buf, pos, w->text.delimiters, &endPos)) + endPos = buf->length; + return endPos; + } + + /* If it is not a word then see if the character at pos is a + whitespace character. */ + if(strchr(whiteSpace, c) != NULL) { + isWhiteSpace = 1; + searchChars = whiteSpace; + } + /* If is not whitespace then see if it is a delimiter */ + else { + if(strchr(w->text.nonWhiteSpaceDelimiters, c) != NULL) { + isDelimiter = 1; + searchChars = w->text.nonWhiteSpaceDelimiters; + } + } + + /* If pos was white space or a delimiter then return the end of + the whitespace or the end of the group of delimiters */ + if(isWhiteSpace || isDelimiter) { + int foundPos; + endPos = pos; + while(BufSearchForward(w->text.textD->buffer, endPos, searchChars, + &foundPos)) { + if(foundPos != endPos) + break; + endPos = foundPos + 1; + } + endPos = min(endPos, buf->length); + } + /* else return the original position + 1. This shouldn't happen */ + else { + endPos = pos + 1; + } + + return endPos; + } + + /* ** Select the line containing the cursor, including the terminating newline, *************** *** 2970,2981 **** */ ! static void selectLine(Widget w) { ! textDisp *textD = ((TextWidget)w)->text.textD; ! int insertPos = TextDGetInsertPosition(textD); ! int endPos, startPos; ! endPos = TextDEndOfLine(textD, insertPos, False); ! startPos = TextDStartOfLine(textD, insertPos); ! BufSelect(textD->buffer, startPos, min(endPos+1, textD->buffer->length)); ! TextDSetInsertPosition(textD, endPos); } --- 3596,3622 ---- */ ! static void selectLine(Widget w, int pos) { ! textBuffer *buf = ((TextWidget)w)->text.textD->buffer; ! int startPos, endPos, insertPos; ! startPos = BufStartOfLine(buf, pos); ! endPos = BufEndOfLine(buf, pos); ! endPos = min(endPos+1, buf->length); ! insertPos = pos <= (startPos + (endPos - startPos) / 2) ? startPos : endPos; ! BufSelect(buf, startPos, endPos, LINE_SELECT); ! TextDSetInsertPosition(((TextWidget)w)->text.textD, insertPos); ! } ! ! /* ! ** Select the line containing the cursor, including the terminating newline ! */ ! static void selectSecondaryLine(Widget w, int pos) ! { ! textBuffer *buf = ((TextWidget)w)->text.textD->buffer; ! int startPos, endPos; ! ! startPos = BufStartOfLine(buf, pos); ! endPos = BufEndOfLine(buf, pos); ! endPos = min(endPos+1, buf->length); ! BufSecondarySelect(buf, startPos, endPos, LINE_SELECT); } *************** *** 2993,2997 **** inWindow = x >= w->text.marginWidth && ! x < w->core.width - w->text.marginWidth && y >= w->text.marginHeight && ! y < w->core.height - w->text.marginHeight; --- 3634,3638 ---- inWindow = x >= w->text.marginWidth && ! x < (w->core.width - w->text.marginWidth) && y >= w->text.marginHeight && ! y < (w->core.height - w->text.marginHeight); *************** *** 3070,3118 **** textBuffer *buf = textD->buffer; ! int row, col, startCol, endCol, startPos, endPos; ! int newPos = TextDXYToPosition(textD, x, y); - /* Adjust the selection */ if (tw->text.dragState == PRIMARY_RECT_DRAG) { ! TextDXYToUnconstrainedPosition(textD, x, y, &row, &col); ! col = TextDOffsetWrappedColumn(textD, row, col); ! startCol = min(tw->text.rectAnchor, col); ! endCol = max(tw->text.rectAnchor, col); ! startPos = BufStartOfLine(buf, min(tw->text.anchor, newPos)); ! endPos = BufEndOfLine(buf, max(tw->text.anchor, newPos)); ! BufRectSelect(buf, startPos, endPos, startCol, endCol); ! } else if (tw->text.multiClickState == ONE_CLICK) { ! startPos = startOfWord(tw, min(tw->text.anchor, newPos)); ! endPos = endOfWord(tw, max(tw->text.anchor, newPos)); ! BufSelect(buf, startPos, endPos); ! newPos = newPos < tw->text.anchor ? startPos : endPos; ! } else if (tw->text.multiClickState == TWO_CLICKS) { ! startPos = BufStartOfLine(buf, min(tw->text.anchor, newPos)); ! endPos = BufEndOfLine(buf, max(tw->text.anchor, newPos)); ! BufSelect(buf, startPos, min(endPos+1, buf->length)); ! newPos = newPos < tw->text.anchor ? startPos : endPos; ! } else ! BufSelect(buf, tw->text.anchor, newPos); ! ! /* Move the cursor */ ! TextDSetInsertPosition(textD, newPos); ! callCursorMovementCBs((Widget)tw, NULL); ! } ! ! static void adjustSecondarySelection(TextWidget tw, int x, int y) ! { ! textDisp *textD = tw->text.textD; ! textBuffer *buf = textD->buffer; ! int row, col, startCol, endCol, startPos, endPos; ! int newPos = TextDXYToPosition(textD, x, y); ! if (tw->text.dragState == SECONDARY_RECT_DRAG) { ! TextDXYToUnconstrainedPosition(textD, x, y, &row, &col); ! col = TextDOffsetWrappedColumn(textD, row, col); ! startCol = min(tw->text.rectAnchor, col); ! endCol = max(tw->text.rectAnchor, col); ! startPos = BufStartOfLine(buf, min(tw->text.anchor, newPos)); ! endPos = BufEndOfLine(buf, max(tw->text.anchor, newPos)); ! BufSecRectSelect(buf, startPos, endPos, startCol, endCol); ! } else ! BufSecondarySelect(textD->buffer, tw->text.anchor, newPos); } --- 3711,3773 ---- textBuffer *buf = textD->buffer; ! int row, col, startCol = 0, endCol = 0, startPos = 0, endPos = 0; ! int newPos = 0; ! selType selType = CHAR_SELECT; ! ! if(tw->text.dragState == PRIMARY_RECT_DRAG || tw->text.dragState == PRIMARY_DRAG) ! selType = BufGetSelectionType(buf); ! else if(tw->text.dragState == SECONDARY_RECT_DRAG || tw->text.dragState == SECONDARY_DRAG) ! selType = BufGetSecSelectType(buf); ! ! if (tw->text.dragState == PRIMARY_RECT_DRAG || tw->text.dragState == SECONDARY_RECT_DRAG) { ! newPos = TextDXYToPosition(textD, x, y); ! TextDXYToUnconstrainedPosition(textD, x, y, &row, &col); ! col = TextDOffsetWrappedColumn(textD, row, col); ! startCol = min(tw->text.rectAnchor, col); ! endCol = max(tw->text.rectAnchor, col); ! startPos = BufStartOfLine(buf, min(tw->text.anchor, newPos)); ! endPos = BufEndOfLine(buf, max(tw->text.anchor, newPos)); ! } else if (tw->text.dragState == PRIMARY_DRAG || tw->text.dragState == SECONDARY_DRAG) { ! if (selType == WORD_SELECT) { ! newPos = TextDXYToCharPosition(textD, x, y); ! startPos = startOfGroup(tw, min(tw->text.anchor, newPos)); ! endPos = endOfGroup(tw, max(tw->text.anchor, newPos)); ! newPos = newPos < (startPos + (endPos - startPos) / 2) ? startPos : endPos; ! } else if (selType == LINE_SELECT) { ! newPos = TextDXYToPosition(textD, x, y); ! startPos = BufStartOfLine(buf, min(tw->text.anchor, newPos)); ! endPos = BufEndOfLine(buf, max(tw->text.anchor - 1, newPos)); ! endPos = min(endPos+1, buf->length); ! newPos = newPos < tw->text.anchor ? startPos : endPos; ! } else { ! newPos = TextDXYToPosition(textD, x, y); ! /* Select the newline if we are past the end of the line. */ ! if(newPos > tw->text.anchor) { ! int posX, posY; ! if(TextDPositionToXY(textD, newPos, &posX, &posY)) { ! if(x > posX) { ! newPos++; ! } ! } ! } ! startPos = tw->text.anchor; ! endPos = newPos; ! } ! } if (tw->text.dragState == PRIMARY_RECT_DRAG) { ! BufRectSelect(buf, startPos, endPos, startCol, endCol); ! } else if (tw->text.dragState == SECONDARY_RECT_DRAG) { ! BufSecRectSelect(buf, startPos, endPos, startCol, endCol); ! } else if (tw->text.dragState == PRIMARY_DRAG) { ! BufSelect(buf, startPos, endPos, selType); ! } else if (tw->text.dragState == SECONDARY_DRAG) { ! BufSecondarySelect(buf, startPos, endPos, selType); ! } ! /* Move the cursor */ ! if (tw->text.dragState == PRIMARY_RECT_DRAG ! || tw->text.dragState == PRIMARY_DRAG) { ! TextDSetInsertPosition(textD, newPos); ! callCursorMovementCBs((Widget)tw, NULL); ! } } *************** *** 3342,3348 **** horizOffset -= fontWidth; ! if (w->text.mouseY >= (int)w->core.height - w->text.marginHeight) ! topLineNum += 1 + ((w->text.mouseY - (int)w->core.height - ! w->text.marginHeight) / fontHeight) + 1; ! else if (w->text.mouseY < w->text.marginHeight) ! topLineNum -= 1 + ((w->text.marginHeight-w->text.mouseY) / fontHeight); TextDSetScroll(textD, topLineNum, horizOffset); --- 3997,4003 ---- horizOffset -= fontWidth; ! newPos = w->text.mouseY - w->text.marginHeight; ! if (newPos >= (int)w->core.height) ! topLineNum += ((newPos - (int)w->core.height) / fontHeight) + 1; ! else if (newPos < 0) ! topLineNum += (newPos / fontHeight) - 1; TextDSetScroll(textD, topLineNum, horizOffset); *************** *** 3356,3360 **** } else if (w->text.dragState == SECONDARY_DRAG) { ! adjustSecondarySelection(w, w->text.mouseX, w->text.mouseY); } else if (w->text.dragState == SECONDARY_RECT_DRAG) { ! adjustSecondarySelection(w, w->text.mouseX, w->text.mouseY); } else if (w->text.dragState == PRIMARY_BLOCK_DRAG) { --- 4011,4015 ---- } else if (w->text.dragState == SECONDARY_DRAG) { ! adjustSelection(w, w->text.mouseX, w->text.mouseY); } else if (w->text.dragState == SECONDARY_RECT_DRAG) { ! adjustSelection(w, w->text.mouseX, w->text.mouseY); } else if (w->text.dragState == PRIMARY_BLOCK_DRAG) { *************** *** 3370,3374 **** w->text.mouseY >= w->text.marginHeight && ! w->text.mouseY < w->core.height - w->text.marginHeight ? ! (VERTICAL_SCROLL_DELAY*fontWidth) / fontHeight : ! VERTICAL_SCROLL_DELAY, autoScrollTimerProc, w); } --- 4025,4029 ---- w->text.mouseY >= w->text.marginHeight && ! w->text.mouseY < (w->core.height - w->text.marginHeight) ? ! (w->text.verticalScrollDelay*fontWidth) / fontHeight : ! w->text.verticalScrollDelay, autoScrollTimerProc, w); } *** text.h 1997/09/26 18:28:17 1.1 --- text.h 1997/10/10 00:15:48 1.2 *************** *** 93,94 **** --- 93,102 ---- #define textCEmulateTabs "EmulateTabs" + #define textNselectThreshold "selectThreshold" + #define textCSelectThreshold "SelectThreshold" + #define textNverticalScrollDelay "verticalScrollDelay" + #define textCVerticalScrollDelay "VerticalScrollDelay" + #define textNdragStartsOnCharacter "dragStartsOnCharacter" + #define textCDragStartsOnCharacter "DragStartsOnCharacter" + #define textNenableQuadrupleClick "enableQuadrupleClick" + #define textCEnableQuadrupleClick "EnableQuadrupleClick" *************** *** 115,116 **** --- 123,125 ---- /* User callable routines */ + void TextSetString(Widget w, char *string); void TextSetBuffer(Widget w, textBuffer *buffer); *************** *** 120,121 **** --- 129,131 ---- int TextGetCursorPos(Widget w); + int TextGetLastCursorPos(Widget w); void TextSetCursorPos(Widget w, int pos); *** textBuf.c 1997/09/26 18:28:17 1.1 --- textBuf.c 1997/10/23 21:59:18 1.4 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 34,35 **** --- 35,55 ---- + #define normalizePosition(buf, pos) \ + if (*(pos) > (buf)->length) *(pos) = (buf)->length; \ + if (*(pos) < 0) *(pos) = 0; + + #define normalizePositions(buf, start, end) \ + normalizePosition((buf), (start)); \ + normalizePosition((buf), (end)); \ + if (*(start) > *(end)) { \ + int temp = *(start); \ + *(start) = *(end); \ + *(end) = temp; \ + } + + #ifndef normalizePosition + static void normalizePosition(textBuffer *buf, int *pos); + #endif + #ifndef normalizePositions + static void normalizePositions(textBuffer *buf, int *start, int *end); + #endif static void histogramCharacters(char *string, int length, char hist[256], *************** *** 43,45 **** static void insertCol(textBuffer *buf, int column, int startPos, char *insText, ! int *nDeleted, int *nInserted, int *endPos); static void overlayRect(textBuffer *buf, int startPos, int rectStart, --- 63,65 ---- static void insertCol(textBuffer *buf, int column, int startPos, char *insText, ! int *nDeleted, int *nInserted, int *endPos, int *insertWidth); static void overlayRect(textBuffer *buf, int startPos, int rectStart, *************** *** 61,63 **** static void reallocateBuf(textBuffer *buf, int newGapStart, int newGapLen); ! static void setSelection(selection *sel, int start, int end); static void setRectSelect(selection *sel, int start, int end, --- 81,83 ---- static void reallocateBuf(textBuffer *buf, int newGapStart, int newGapLen); ! static void setSelection(selection *sel, int start, int end, selType type); static void setRectSelect(selection *sel, int start, int end, *************** *** 72,74 **** static void removeSelected(textBuffer *buf, selection *sel); ! static void replaceSelected(textBuffer *buf, selection *sel, char *text); static void addPadding(char *string, int startIndent, int toIndent, --- 92,94 ---- static void removeSelected(textBuffer *buf, selection *sel); ! static void replaceSelected(textBuffer *buf, selection *sel, char *text, Boolean staySelected); static void addPadding(char *string, int startIndent, int toIndent, *************** *** 123,133 **** buf->useTabs = True; ! buf->primary.selected = False; ! buf->primary.rectangular = False; ! buf->primary.start = buf->primary.end = 0; ! buf->secondary.selected = False; ! buf->secondary.start = buf->secondary.end = 0; ! buf->secondary.rectangular = False; ! buf->highlight.selected = False; ! buf->highlight.start = buf->highlight.end = 0; ! buf->highlight.rectangular = False; buf->modifyProcs = NULL; --- 143,147 ---- buf->useTabs = True; ! setSelection(&buf->primary, 0, 0, CHAR_SELECT); ! setSelection(&buf->secondary, 0, 0, CHAR_SELECT); ! setSelection(&buf->highlight, 0, 0, CHAR_SELECT); buf->modifyProcs = NULL; *************** *** 157,159 **** ** Get the entire contents of a text buffer. Memory is allocated to contain ! ** the returned string, which the caller must free. */ --- 171,175 ---- ** Get the entire contents of a text buffer. Memory is allocated to contain ! ** the returned string, which the caller must free. An additional byte is ! ** also allocated in case the caller wants to add a newline at the end of ! ** the buffer. */ *************** *** 163,165 **** ! text = XtMalloc(buf->length+1); memcpy(text, buf->buf, buf->gapStart); --- 179,181 ---- ! text = XtMalloc(buf->length+2); memcpy(text, buf->buf, buf->gapStart); *************** *** 207,209 **** ** from text buffer "buf". Positions start at 0, and the range does not ! ** include the character pointed to by "end" */ --- 223,227 ---- ** from text buffer "buf". Positions start at 0, and the range does not ! ** include the character pointed to by "end". Characters are always returned ! ** going forward in the buffer, meaning if end is greater that start then ! ** start become the end and end becomes the start. */ *************** *** 221,229 **** } ! if (end < start) { ! int temp = start; ! start = end; ! end = temp; ! } ! if (end > buf->length) ! end = buf->length; length = end - start; --- 239,241 ---- } ! normalizePositions(buf, &start, &end); length = end - start; *************** *** 248,257 **** */ ! char BufGetCharacter(textBuffer *buf, int pos) { ! if (pos < 0 || pos > buf->length) return '\0'; ! if (pos < buf->gapStart) ! return buf->buf[pos]; ! else ! return buf->buf[pos + buf->gapEnd-buf->gapStart]; } --- 260,320 ---- */ ! #ifndef BufGetCharacter ! unsigned char BufGetCharacter(textBuffer *buf, int pos) { ! /* Guard against array bounds reads. Note that pos == buf->length ! ** is also and array bounds read. ! */ ! if (pos < 0 || pos >= buf->length) { ! #ifdef PURIFY ! purify_printf_with_call_chain("Internal error: BufGetCharacter(pos < 0 || pos >= buf->length): pos: %d buf->length: %d\n", pos, buf->length); ! #endif return '\0'; ! } ! return _BufGetCharacter(buf, pos); ! } ! #endif ! ! /* ! ** Return a copy of the text from the start of line "startLineNum" to ! ** the end of line "endLineNum". The line at "endLineNum" is included. ! ** Lines are numbered starting at 1. Negative line numbers are used ! ** to count lines from the end of the file. Line number 0 refers to the ! ** end of the file. When endLineNum is greater than startLineNum it means ! ** you will get the text from the end of endLineNum to the beginning of ! ** startLineNum. ! */ ! char *BufGetLines(textBuffer *buf, int startLineNum, int endLineNum) ! { ! int lineStart, lineEnd; ! ! if(startLineNum == 0) { /* EOF */ ! lineStart = buf->length; ! } else if(startLineNum < 0) { /* startLineNum is from the end of the file */ ! lineStart = BufCountBackwardNLines(buf, buf->length-1, -startLineNum - 1); ! } else { ! lineStart = BufCountForwardNLines(buf, 0, startLineNum - 1); ! } ! /* lineEnd should be 1 character greater than the actual end of line */ ! if(endLineNum == 0 || endLineNum == -1) { ! /* EOF and end of line -1 are the same place. */ ! lineEnd = buf->length; ! } else if(endLineNum < 0) { ! /* endLineNum is from the end of the file */ ! /* nLines == 0 means beginning of the last line. endLineNum == -2 is also ! ** the beginning of the last line. So adjust. */ ! lineEnd = BufCountBackwardNLines(buf, buf->length-1, -endLineNum - 2); ! } else { ! /* Find the end position relative to the starting line if ! ** the ending line is greater that the starting line. If it is less ! ** than then just count from the begining of the file. */ ! int nLines = endLineNum - startLineNum; ! if(nLines >= 0) { ! lineEnd = BufCountForwardNLines(buf, lineStart, nLines + 1); ! } else { ! lineEnd = BufCountForwardNLines(buf, 0, endLineNum); ! } ! } ! ! /* BufGetRange will handle if lineEnd is greater than lineStart */ ! return BufGetRange(buf, lineStart, lineEnd); } *************** *** 266,269 **** /* if pos is not contiguous to existing text, make it */ ! if (pos > buf->length) pos = buf->length; ! if (pos < 0 ) pos = 0; --- 329,331 ---- /* if pos is not contiguous to existing text, make it */ ! normalizePosition(buf, &pos); *************** *** 279,281 **** */ ! void BufReplace(textBuffer *buf, int start, int end, char *text) { --- 341,343 ---- */ ! int BufReplace(textBuffer *buf, int start, int end, char *text) { *************** *** 284,285 **** --- 346,348 ---- + normalizePositions(buf, &start, &end); deletedText = BufGetRange(buf, start, end); *************** *** 290,291 **** --- 353,355 ---- XtFree(deletedText); + return nInserted; } *************** *** 297,307 **** /* Make sure the arguments make sense */ ! if (start > end) { ! int temp = start; ! start = end; ! end = temp; ! } ! if (start > buf->length) start = buf->length; ! if (start < 0) start = 0; ! if (end > buf->length) end = buf->length; ! if (end < 0) end = 0; --- 361,363 ---- /* Make sure the arguments make sense */ ! normalizePositions(buf, &start, &end); *************** *** 360,362 **** { ! int nLines, lineStartPos, nDeleted, insertDeleted, nInserted; char *deletedText; --- 416,418 ---- { ! int nLines, lineStartPos, nDeleted, insertDeleted, nInserted, insertWidth; char *deletedText; *************** *** 369,371 **** insertCol(buf, column, lineStartPos, text, &insertDeleted, &nInserted, ! &buf->cursorPosHint); if (nDeleted != insertDeleted) --- 425,427 ---- insertCol(buf, column, lineStartPos, text, &insertDeleted, &nInserted, ! &buf->cursorPosHint, &insertWidth); if (nDeleted != insertDeleted) *************** *** 415,417 **** void BufReplaceRect(textBuffer *buf, int start, int end, int rectStart, ! int rectEnd, char *text) { --- 471,473 ---- void BufReplaceRect(textBuffer *buf, int start, int end, int rectStart, ! int rectEnd, char *text, BufRectangle *rectReturn) { *************** *** 419,421 **** int i, nInsertedLines, nDeletedLines, insLen, hint; ! int insertDeleted, insertInserted, deleteInserted; int linesPadded = 0; --- 475,477 ---- int i, nInsertedLines, nDeletedLines, insLen, hint; ! int insertDeleted, insertInserted, deleteInserted, insertWidth; int linesPadded = 0; *************** *** 457,459 **** insertCol(buf, rectStart, start, insText, &insertDeleted, &insertInserted, ! &buf->cursorPosHint); --- 513,515 ---- insertCol(buf, rectStart, start, insText, &insertDeleted, &insertInserted, ! &buf->cursorPosHint, &insertWidth); *************** *** 466,467 **** --- 522,528 ---- XtFree(insText); + + rectReturn->start = start; + rectReturn->end = buf->cursorPosHint; + rectReturn->rectStart = rectStart; + rectReturn->rectEnd = rectStart + insertWidth; } *************** *** 498,499 **** --- 559,561 ---- + normalizePositions(buf, &start, &end); nLines = BufCountLines(buf, start, end); *************** *** 569,571 **** ! void BufSelect(textBuffer *buf, int start, int end) { --- 631,633 ---- ! void BufSelect(textBuffer *buf, int start, int end, selType type) { *************** *** 573,575 **** ! setSelection(&buf->primary, start, end); redisplaySelection(buf, &oldSelection, &buf->primary); --- 635,638 ---- ! normalizePositions(buf, &start, &end); ! setSelection(&buf->primary, start, end, type); redisplaySelection(buf, &oldSelection, &buf->primary); *************** *** 582,583 **** --- 645,647 ---- buf->primary.selected = False; + buf->primary.type = CHAR_SELECT; redisplaySelection(buf, &oldSelection, &buf->primary); *************** *** 590,591 **** --- 654,656 ---- + normalizePositions(buf, &start, &end); setRectSelect(&buf->primary, start, end, rectStart, rectEnd); *************** *** 606,607 **** --- 671,677 ---- + selType BufGetSelectionType(textBuffer *buf) + { + return buf->primary.type; + } + void BufRemoveSelected(textBuffer *buf) *************** *** 611,618 **** ! void BufReplaceSelected(textBuffer *buf, char *text) { ! replaceSelected(buf, &buf->primary, text); } ! void BufSecondarySelect(textBuffer *buf, int start, int end) { --- 681,688 ---- ! void BufReplaceSelected(textBuffer *buf, char *text, Boolean staySelected) { ! replaceSelected(buf, &buf->primary, text, staySelected); } ! void BufSecondarySelect(textBuffer *buf, int start, int end, selType type) { *************** *** 620,622 **** ! setSelection(&buf->secondary, start, end); redisplaySelection(buf, &oldSelection, &buf->secondary); --- 690,693 ---- ! normalizePositions(buf, &start, &end); ! setSelection(&buf->secondary, start, end, type); redisplaySelection(buf, &oldSelection, &buf->secondary); *************** *** 629,630 **** --- 700,702 ---- buf->secondary.selected = False; + buf->secondary.type = CHAR_SELECT; redisplaySelection(buf, &oldSelection, &buf->secondary); *************** *** 637,638 **** --- 709,711 ---- + normalizePositions(buf, &start, &end); setRectSelect(&buf->secondary, start, end, rectStart, rectEnd); *************** *** 653,654 **** --- 726,732 ---- + selType BufGetSecSelectType(textBuffer *buf) + { + return buf->secondary.type; + } + void BufRemoveSecSelect(textBuffer *buf) *************** *** 660,662 **** { ! replaceSelected(buf, &buf->secondary, text); } --- 738,740 ---- { ! replaceSelected(buf, &buf->secondary, text, False); } *************** *** 667,669 **** ! setSelection(&buf->highlight, start, end); redisplaySelection(buf, &oldSelection, &buf->highlight); --- 745,748 ---- ! normalizePositions(buf, &start, &end); ! setSelection(&buf->highlight, start, end, CHAR_SELECT); redisplaySelection(buf, &oldSelection, &buf->highlight); *************** *** 676,677 **** --- 755,757 ---- buf->highlight.selected = False; + buf->highlight.type = CHAR_SELECT; redisplaySelection(buf, &oldSelection, &buf->highlight); *************** *** 684,685 **** --- 764,766 ---- + normalizePositions(buf, &start, &end); setRectSelect(&buf->highlight, start, end, rectStart, rectEnd); *************** *** 729,731 **** void BufRemoveModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, ! void *cbArg) { --- 810,812 ---- void BufRemoveModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, ! void *cbArg, Boolean warnIfNotFound) { *************** *** 743,745 **** if (toRemove == -1) { ! fprintf(stderr, "Internal Error: Can't find modify CB to remove\n"); return; --- 824,828 ---- if (toRemove == -1) { ! if(warnIfNotFound) { ! fprintf(stderr, "Internal Error: Can't find modify CB to remove\n"); ! } return; *************** *** 792,793 **** --- 875,879 ---- + /* if pos is not contiguous to existing text, make it */ + normalizePosition(buf, &pos); + if (!searchBackward(buf, pos, '\n', &startPos)) *************** *** 807,808 **** --- 893,897 ---- + /* if pos is not contiguous to existing text, make it */ + normalizePosition(buf, &pos); + if (!searchForward(buf, pos, '\n', &endPos)) *************** *** 850,852 **** if (((unsigned char)c) <= 31) { ! sprintf(outStr, "<%s>", ControlCodeTable[c]); return strlen(outStr); --- 939,941 ---- if (((unsigned char)c) <= 31) { ! sprintf(outStr, "<%s>", ControlCodeTable[(unsigned char)c]); return strlen(outStr); *************** *** 872,874 **** */ ! int BufCharWidth(char c, int indent, int tabDist, char nullSubsChar) { --- 961,963 ---- */ ! int BufCharWidth(unsigned char c, int indent, int tabDist, char nullSubsChar) { *************** *** 877,883 **** return tabDist - (indent % tabDist); ! else if (((unsigned char)c) <= 31) ! return strlen(ControlCodeTable[c]) + 2; else if (c == 127) return 5; ! else if (c == nullSubsChar) return 5; --- 966,972 ---- return tabDist - (indent % tabDist); ! else if ((unsigned char)c <= 31) ! return strlen(ControlCodeTable[(unsigned char)c]) + 2; else if (c == 127) return 5; ! else if (c == (unsigned char)nullSubsChar) return 5; *************** *** 897,898 **** --- 986,988 ---- + normalizePositions(buf, &lineStartPos, &targetPos); pos = lineStartPos; *************** *** 913,917 **** pos = lineStartPos; while (charCount < nChars && pos < buf->length) { ! c = BufGetCharacter(buf, pos); if (c == '\n') --- 1003,1008 ---- + normalizePosition(buf, &lineStartPos); pos = lineStartPos; while (charCount < nChars && pos < buf->length) { ! c = _BufGetCharacter(buf, pos); if (c == '\n') *************** *** 933,934 **** --- 1024,1026 ---- + normalizePositions(buf, &startPos, &endPos); pos = startPos; *************** *** 961,962 **** --- 1053,1055 ---- + normalizePosition(buf, &startPos); pos = startPos; *************** *** 990,992 **** ! pos = startPos - 1; if (pos <= 0) --- 1083,1090 ---- ! normalizePosition(buf, &startPos); ! /* backup one if startPos is pointing at a newline or at EOF. */ ! pos = startPos; ! if(pos == buf->length || _BufGetCharacter(buf, pos) == '\n') { ! pos = startPos - 1; ! } if (pos <= 0) *************** *** 1083,1084 **** --- 1181,1214 ---- + #ifndef normalizePosition + /* + ** Routine to make sure the position make sense for the current buffer. + */ + static void normalizePosition(textBuffer *buf, int *pos) + { + /* Make sure the position does not exceed the dimensions of the buffer. */ + if (*pos > buf->length) *pos = buf->length; + if (*pos < 0) *pos = 0; + } + #endif + + #ifndef normalizePositions + /* + ** Routine to make sure the start and end positions make sense for + ** the current buffer. + */ + static void normalizePositions(textBuffer *buf, int *start, int *end) + { + /* Make sure neither start nor end exceed the dimensions of the buffer. */ + normalizePosition(buf, start); + normalizePosition(buf, end); + + /* Make sure end is greater than start */ + if (*start > *end) { + int temp = *start; + *start = *end; + *end = temp; + } + } + #endif + /* *************** *** 1264,1266 **** static void insertCol(textBuffer *buf, int column, int startPos, char *insText, ! int *nDeleted, int *nInserted, int *endPos) { --- 1394,1396 ---- static void insertCol(textBuffer *buf, int column, int startPos, char *insText, ! int *nDeleted, int *nInserted, int *endPos, int *insertWidth) { *************** *** 1333,1334 **** --- 1463,1465 ---- *endPos = start + (outPtr - outStr) - len + endOffset; + *insertWidth = insWidth; XtFree(outStr); *************** *** 1708,1710 **** ! static void setSelection(selection *sel, int start, int end) { --- 1839,1841 ---- ! static void setSelection(selection *sel, int start, int end, selType type) { *************** *** 1714,1715 **** --- 1845,1847 ---- sel->end = max(start, end); + sel->type = type; } *************** *** 1725,1726 **** --- 1857,1859 ---- sel->rectEnd = rectEnd; + sel->type = CHAR_SELECT; } *************** *** 1774,1779 **** ! static void replaceSelected(textBuffer *buf, selection *sel, char *text) { int start, end, isRect, rectStart, rectEnd; ! selection oldSelection = *sel; --- 1907,1912 ---- ! static void replaceSelected(textBuffer *buf, selection *sel, char *text, Boolean staySelected) { int start, end, isRect, rectStart, rectEnd; ! selection oldSelection; *************** *** 1784,1793 **** /* Do the appropriate type of replace */ ! if (isRect) ! BufReplaceRect(buf, start, end, rectStart, rectEnd, text); ! else ! BufReplace(buf, start, end, text); - /* Unselect (happens automatically in BufReplace, but BufReplaceRect - can't detect when the contents of a selection goes away) */ - sel->selected = False; redisplaySelection(buf, &oldSelection, sel); --- 1917,1940 ---- /* Do the appropriate type of replace */ ! if (isRect) { ! BufRectangle rect; ! BufReplaceRect(buf, start, end, rectStart, rectEnd, text, &rect); ! oldSelection = *sel; ! if(staySelected) { ! setRectSelect(sel, rect.start, rect.end, rect.rectStart, rect.rectEnd); ! } ! } ! else { ! int nInserted; ! nInserted = BufReplace(buf, start, end, text); ! oldSelection = *sel; ! if(staySelected) { ! setSelection(sel, start, start+nInserted, sel->type); ! } ! } ! ! if(!staySelected) { ! sel->selected = False; ! sel->type = CHAR_SELECT; ! } redisplaySelection(buf, &oldSelection, sel); *************** *** 1910,1912 **** memmove(&buf->buf[buf->gapStart], &buf->buf[buf->gapEnd], ! pos - buf->gapStart); else --- 2057,2059 ---- memmove(&buf->buf[buf->gapStart], &buf->buf[buf->gapEnd], ! pos - buf->gapStart); else *************** *** 1977,1978 **** --- 2124,2126 ---- sel->selected = False; + sel->type = CHAR_SELECT; } else if (pos <= sel->start && pos+nDeleted < sel->end) { *************** *** 1984,1985 **** --- 2132,2134 ---- sel->selected = False; + sel->type = CHAR_SELECT; } *************** *** 2130,2132 **** for (pos=lineStartPos; poslength; pos++) { ! c = BufGetCharacter(buf, pos); if (c == '\n') --- 2279,2281 ---- for (pos=lineStartPos; poslength; pos++) { ! c = _BufGetCharacter(buf, pos); if (c == '\n') *************** *** 2147,2149 **** for (; poslength; pos++) { ! c = BufGetCharacter(buf, pos); if (c == '\n') --- 2296,2298 ---- for (; poslength; pos++) { ! c = _BufGetCharacter(buf, pos); if (c == '\n') *** textBuf.h 1997/09/26 18:28:17 1.1 --- textBuf.h 1997/10/14 04:53:39 1.3 *************** *** 29,30 **** --- 29,32 ---- + typedef enum _selType {CHAR_SELECT, WORD_SELECT, LINE_SELECT} selType; + typedef struct { *************** *** 36,39 **** --- 38,49 ---- int rectEnd; + selType type; } selection; + typedef struct _BufRectangle { + int start; + int end; + int rectStart; + int rectEnd; + } BufRectangle; + typedef void (*bufModifyCallbackProc)(int pos, int nInserted, int nDeleted, *************** *** 67,68 **** --- 77,88 ---- + /* Faster version of BufGetCharacter(). + ** Used to get a character from the buffer without bounds checking. */ + #define _BufGetCharacter(buffer, pos) \ + (unsigned char)(((pos) < (buffer)->gapStart) ? (buffer)->buf[(pos)] : \ + ((buffer)->buf[(pos) + (buffer)->gapEnd - (buffer)->gapStart])) + + #if 0 + #define BufGetCharacter(buf, pos) _BufGetCharacter(buf, pos) + #endif + textBuffer *BufCreate(void); *************** *** 73,75 **** char *BufGetRange(textBuffer *buf, int start, int end); ! char BufGetCharacter(textBuffer *buf, int pos); char *BufGetTextInRect(textBuffer *buf, int start, int end, --- 93,98 ---- char *BufGetRange(textBuffer *buf, int start, int end); ! char *BufGetLines(textBuffer *buf, int startLineNum, int endLineNum); ! #ifndef BufGetCharacter ! unsigned char BufGetCharacter(textBuffer *buf, int pos); ! #endif char *BufGetTextInRect(textBuffer *buf, int start, int end, *************** *** 78,80 **** void BufRemove(textBuffer *buf, int start, int end); ! void BufReplace(textBuffer *buf, int start, int end, char *text); void BufCopyFromBuf(textBuffer *fromBuf, textBuffer *toBuf, int fromStart, --- 101,103 ---- void BufRemove(textBuffer *buf, int start, int end); ! int BufReplace(textBuffer *buf, int start, int end, char *text); void BufCopyFromBuf(textBuffer *fromBuf, textBuffer *toBuf, int fromStart, *************** *** 84,86 **** void BufReplaceRect(textBuffer *buf, int start, int end, int rectStart, ! int rectEnd, char *text); void BufRemoveRect(textBuffer *buf, int start, int end, int rectStart, --- 107,109 ---- void BufReplaceRect(textBuffer *buf, int start, int end, int rectStart, ! int rectEnd, char *text, BufRectangle *rectReturn); void BufRemoveRect(textBuffer *buf, int start, int end, int rectStart, *************** *** 93,95 **** void BufSetTabDistance(textBuffer *buf, int tabDist); ! void BufSelect(textBuffer *buf, int start, int end); void BufUnselect(textBuffer *buf); --- 116,118 ---- void BufSetTabDistance(textBuffer *buf, int tabDist); ! void BufSelect(textBuffer *buf, int start, int end, selType type); void BufUnselect(textBuffer *buf); *************** *** 100,104 **** char *BufGetSelectionText(textBuffer *buf); void BufRemoveSelected(textBuffer *buf); ! void BufReplaceSelected(textBuffer *buf, char *text); ! void BufSecondarySelect(textBuffer *buf, int start, int end); void BufSecondaryUnselect(textBuffer *buf); --- 123,128 ---- char *BufGetSelectionText(textBuffer *buf); + selType BufGetSelectionType(textBuffer *buf); void BufRemoveSelected(textBuffer *buf); ! void BufReplaceSelected(textBuffer *buf, char *text, Boolean staySelected); ! void BufSecondarySelect(textBuffer *buf, int start, int end, selType type); void BufSecondaryUnselect(textBuffer *buf); *************** *** 109,110 **** --- 133,135 ---- char *BufGetSecSelectText(textBuffer *buf); + selType BufGetSecSelectType(textBuffer *buf); void BufRemoveSecSelect(textBuffer *buf); *************** *** 121,123 **** void BufRemoveModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, ! void *cbArg); char *BufGetLineText(textBuffer *buf, int pos); --- 146,148 ---- void BufRemoveModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, ! void *cbArg, Boolean warnIfNotFound); char *BufGetLineText(textBuffer *buf, int pos); *************** *** 128,130 **** char nullSubsChar); ! int BufCharWidth(char c, int indent, int tabDist, char nullSubsChar); int BufCountDispChars(textBuffer *buf, int lineStartPos, int targetPos); --- 153,155 ---- char nullSubsChar); ! int BufCharWidth(unsigned char c, int indent, int tabDist, char nullSubsChar); int BufCountDispChars(textBuffer *buf, int lineStartPos, int targetPos); *** textBufTest.c 1997/10/09 23:29:19 1.1 --- textBufTest.c 1997/10/10 00:15:48 1.2 *************** *** 0 **** --- 1,94 ---- + /* + ** Test the BufGetLines() function. + */ + #include "textBuf.h" + + char buf40[] = "\ + This is line 1 line -40\n\ + This is line 2 line -39\n\ + This is line 3 line -38\n\ + This is line 4 line -37\n\ + This is line 5 line -36\n\ + This is line 6 line -35\n\ + This is line 7 line -34\n\ + This is line 8 line -33\n\ + This is line 9 line -32\n\ + This is line 10 line -31\n\ + This is line 11 line -30\n\ + This is line 12 line -29\n\ + This is line 13 line -28\n\ + This is line 14 line -27\n\ + This is line 15 line -26\n\ + This is line 16 line -25\n\ + This is line 17 line -24\n\ + This is line 18 line -23\n\ + This is line 19 line -22\n\ + This is line 20 line -21\n\ + This is line 21 line -20\n\ + This is line 22 line -19\n\ + This is line 23 line -18\n\ + This is line 24 line -17\n\ + This is line 25 line -16\n\ + This is line 26 line -15\n\ + This is line 27 line -14\n\ + This is line 28 line -13\n\ + This is line 29 line -12\n\ + This is line 30 line -11\n\ + This is line 31 line -10\n\ + This is line 32 line -9\n\ + This is line 33 line -8\n\ + This is line 34 line -7\n\ + This is line 35 line -6\n\ + This is line 36 line -5\n\ + This is line 37 line -4\n\ + This is line 38 line -3\n\ + This is line 39 line -2\n\ + This is line 40 line -1\n\ + "; + + typedef struct _TestInfo { + int startLine; + int endLine; + char *buffer; + } TestInfo; + + TestInfo testInfo[] = { + {1, 1, buf40}, + {1, 0, buf40}, + {1, 20, buf40}, + {10, 30, buf40}, + {20, 20, buf40}, + {20, 10, buf40}, + {-1, 0, buf40}, + {-1, -1, buf40}, + {-5, 0, buf40}, + {-25, -20, buf40}, + {20, -30, buf40}, + {0, 0, buf40}, + {0, 1, buf40}, + {0, -1, buf40}, + {0, -2, buf40}, + {0, 0, 0}, + }; + + void testCase1(void) + { + textBuffer *buf; + TestInfo *testInfoP; + + buf = BufCreate(); + for(testInfoP = testInfo; testInfoP->buffer; testInfoP++) { + char *lines; + BufSetAll(buf, testInfoP->buffer); + lines = BufGetLines(buf, testInfoP->startLine, testInfoP->endLine); + printf("%d,%d\n:%s:\n", testInfoP->startLine, testInfoP->endLine, lines); + XtFree(lines); + } + BufFree(buf); + } + + void main(void) + { + testCase1(); + } + *** textDisp.c 1997/09/26 18:28:17 1.1 --- textDisp.c 1997/10/21 21:58:08 1.3 *************** *** 24,28 **** *******************************************************************************/ #include #include ! #include #include --- 24,31 ---- *******************************************************************************/ + #include #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 112,114 **** ! textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar, Position left, Position top, Position width, Position height, --- 115,117 ---- ! textDisp *TextDCreate(Widget widget, Position left, Position top, Position width, Position height, *************** *** 122,123 **** --- 125,127 ---- int i; + unsigned char visualPolicy; *************** *** 131,132 **** --- 135,137 ---- textD->cursorPos = 0; + textD->cursorLastPos = 0; textD->cursorX = -100; *************** *** 143,146 **** textD->visibility = VisibilityUnobscured; - textD->hScrollBar = hScrollBar; - textD->vScrollBar = vScrollBar; textD->fontStruct = fontStruct; --- 148,149 ---- *************** *** 152,154 **** --- 155,159 ---- textD->bgPixel = bgPixel; + textD->selectFGPixel = selectFGPixel; textD->selectBGPixel = selectBGPixel; + textD->highlightFGPixel = highlightFGPixel; textD->highlightBGPixel = highlightBGPixel; *************** *** 164,165 **** --- 169,199 ---- textD->cursorFGGC = XtGetGC(widget, GCForeground, &gcValues); + + /* Add scroll bars to the parent if it is a scrolled window. */ + XtVaGetValues(XtParent(widget), XmNvisualPolicy, &visualPolicy, 0); + if (XtClass(XtParent(widget)) == xmScrolledWindowWidgetClass && + visualPolicy == XmVARIABLE) + { + Pixel troughColor; + + textD->hScrollBar = XtVaCreateManagedWidget("textHorScrollBar", + xmScrollBarWidgetClass, XtParent(widget), + XmNorientation, XmHORIZONTAL, + XmNhighlightThickness, 1, + XmNrepeatDelay, 10, 0); + textD->vScrollBar = XtVaCreateManagedWidget("textVertScrollBar", + xmScrollBarWidgetClass, XtParent(widget), + XmNorientation, XmVERTICAL, + XmNhighlightThickness, 1, + XmNrepeatDelay, 10, 0); + /* Set the little square in the corner between the scroll + bars to be the same color as the scroll bar interiors + and set the scrolled window areas */ + XtVaGetValues(textD->vScrollBar, XmNtroughColor, &troughColor, 0); + XtVaSetValues(XtParent(widget), + XmNhorizontalScrollBar, textD->hScrollBar, + XmNverticalScrollBar, textD->vScrollBar, + XmNworkWindow, widget, + 0); + } + textD->lineStarts = (int *)XtMalloc(sizeof(int) * textD->nVisibleLines); *************** *** 180,194 **** /* Initialize the scroll bars and attach movement callbacks */ ! if (vScrollBar != NULL) { ! XtVaSetValues(vScrollBar, XmNminimum, 1, XmNmaximum, 2, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 1, 0); ! XtAddCallback(vScrollBar, XmNdragCallback, vScrollCB, (XtPointer)textD); ! XtAddCallback(vScrollBar, XmNvalueChangedCallback, vScrollCB, (XtPointer)textD); } ! if (hScrollBar != NULL) { ! XtVaSetValues(hScrollBar, XmNminimum, 0, XmNmaximum, 1, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 0, XmNincrement, fontStruct->max_bounds.width, 0); ! XtAddCallback(hScrollBar, XmNdragCallback, hScrollCB, (XtPointer)textD); ! XtAddCallback(hScrollBar, XmNvalueChangedCallback, hScrollCB, (XtPointer)textD); --- 214,228 ---- /* Initialize the scroll bars and attach movement callbacks */ ! if (textD->vScrollBar != NULL) { ! XtVaSetValues(textD->vScrollBar, XmNminimum, 1, XmNmaximum, 2, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 1, 0); ! XtAddCallback(textD->vScrollBar, XmNdragCallback, vScrollCB, (XtPointer)textD); ! XtAddCallback(textD->vScrollBar, XmNvalueChangedCallback, vScrollCB, (XtPointer)textD); } ! if (textD->hScrollBar != NULL) { ! XtVaSetValues(textD->hScrollBar, XmNminimum, 0, XmNmaximum, 1, XmNsliderSize, 1, XmNrepeatDelay, 10, XmNvalue, 0, XmNincrement, fontStruct->max_bounds.width, 0); ! XtAddCallback(textD->hScrollBar, XmNdragCallback, hScrollCB, (XtPointer)textD); ! XtAddCallback(textD->hScrollBar, XmNvalueChangedCallback, hScrollCB, (XtPointer)textD); *************** *** 213,215 **** { ! BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD); releaseGC(textD->w, textD->gc); --- 247,249 ---- { ! BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD, True); releaseGC(textD->w, textD->gc); *************** *** 233,235 **** bufModifiedCB(0, 0, textD->buffer->length, 0, NULL, textD); ! BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD); } --- 267,269 ---- bufModifiedCB(0, 0, textD->buffer->length, 0, NULL, textD); ! BufRemoveModifyCB(textD->buffer, bufModifiedCB, textD, True); } *************** *** 258,260 **** ** a style table which translates style buffer codes (indexed by buffer ! ** character - 'a') into fonts and colors; and a callback mechanism for ** as-needed highlighting, triggered by a style buffer entry of --- 292,294 ---- ** a style table which translates style buffer codes (indexed by buffer ! ** character - UNFINISHED_STYLE) into fonts and colors; and a callback mechanism for ** as-needed highlighting, triggered by a style buffer entry of *************** *** 355,356 **** --- 389,391 ---- + /* update width and height, height to an exact multiple of font height */ textD->width = width; *************** *** 542,547 **** /* make sure new position is ok, do nothing if it hasn't changed */ - if (newPos == textD->cursorPos) - return; if (newPos < 0) newPos = 0; if (newPos > textD->buffer->length) newPos = textD->buffer->length; --- 577,582 ---- /* make sure new position is ok, do nothing if it hasn't changed */ if (newPos < 0) newPos = 0; if (newPos > textD->buffer->length) newPos = textD->buffer->length; + if (newPos == textD->cursorPos) + return; *************** *** 553,554 **** --- 588,592 ---- + /* store the old position */ + textD->cursorLastPos = textD->cursorPos; + /* draw it at its new position */ *************** *** 571,576 **** { ! if (!textD->cursorOn) { ! textD->cursorOn = True; ! TextDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1); ! } } --- 609,612 ---- { ! textD->cursorOn = True; ! TextDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1); } *************** *** 621,622 **** --- 657,663 ---- + int TextDGetLastInsertPosition(textDisp *textD) + { + return textD->cursorLastPos; + } + /* *************** *** 699,700 **** --- 740,749 ---- /* + ** Translate window coordinates to the nearest character position. + */ + int TextDXYToCharPosition(textDisp *textD, int x, int y) + { + return xyToPos(textD, x, y, CHARACTER_POS); + } + + /* ** Translate window coordinates to the nearest row and column number for *************** *** 1187,1188 **** --- 1236,1240 ---- TextDRedisplayRange(textD, startDispPos, endDispPos); + + /* Make sure the cursor is redisplayed */ + TextDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1); } *************** *** 1239,1241 **** int stdCharWidth, charWidth, startIndex, charStyle, style; ! int charLen, outStartIndex, outIndex, cursorX, hasCursor = False; int dispIndexOffset, cursorPos = textD->cursorPos; --- 1291,1293 ---- int stdCharWidth, charWidth, startIndex, charStyle, style; ! int charLen, outStartIndex, outIndex, cursorX = 0, hasCursor = False; int dispIndexOffset, cursorPos = textD->cursorPos; *************** *** 1260,1261 **** --- 1312,1314 ---- lineStr = BufGetRange(buf, lineStartPos, lineStartPos + lineLen); + lineLen = strlen(lineStr); } *************** *** 1412,1414 **** if (style & FILL_MASK) { ! clearRect(textD, style, x, y, toX - x, textD->ascent + textD->descent); return; --- 1465,1473 ---- if (style & FILL_MASK) { ! if(style & SECONDARY_MASK) { ! XDrawLine(XtDisplay(textD->w), XtWindow(textD->w), textD->gc, x, ! y + textD->ascent, x + nChars * fs->max_bounds.width, ! y + fs->ascent); ! } ! else ! clearRect(textD, style, x, y, toX - x, textD->ascent + textD->descent); return; *************** *** 1421,1423 **** if (style & STYLE_LOOKUP_MASK) { ! styleRec = &textD->styleTable[(style & STYLE_LOOKUP_MASK) - 'a']; fs = styleRec->font; --- 1480,1482 ---- if (style & STYLE_LOOKUP_MASK) { ! styleRec = &textD->styleTable[(style & STYLE_LOOKUP_MASK) - UNFINISHED_STYLE]; fs = styleRec->font; *************** *** 1425,1427 **** gcValues.font = fs->fid; ! gcValues.foreground = styleRec->color; gcValues.background = style&PRIMARY_MASK ? textD->selectBGPixel : --- 1484,1493 ---- gcValues.font = fs->fid; ! gcValues.foreground = ! #ifndef IGNORE_SELECT_FOREGROUND_COLOR ! style&PRIMARY_MASK ? textD->selectFGPixel : ! #endif ! #ifndef IGNORE_HIGHLIGHT_FOREGROUND_COLOR ! style&HIGHLIGHT_MASK ? textD->highlightFGPixel : ! #endif ! styleRec->color; gcValues.background = style&PRIMARY_MASK ? textD->selectBGPixel : *************** *** 1485,1487 **** { ! XSegment segs[5]; int left, right, cursorWidth, midY; --- 1551,1553 ---- { ! XSegment segs[10]; int left, right, cursorWidth, midY; *************** *** 1524,1529 **** midY = y + fontHeight/2; ! segs[0].x1 = x; segs[0].y1 = y; segs[0].x2 = x; segs[0].y2 = y; ! segs[1].x1 = x; segs[1].y1 = midY; segs[1].x2 = x; segs[1].y2 = midY; ! segs[2].x1 = x; segs[2].y1 = bot; segs[2].x2 = x; segs[2].y2 = bot; ! nSegs = 3; } else if (textD->cursorStyle == BLOCK_CURSOR) { --- 1590,1599 ---- midY = y + fontHeight/2; ! nSegs = 0; ! segs[nSegs].x1 = left; segs[nSegs].y1 = y; segs[nSegs].x2 = x-1; segs[nSegs].y2 = y; nSegs++; ! segs[nSegs].x1 = x+1; segs[nSegs].y1 = y; segs[nSegs].x2 = right; segs[nSegs].y2 = y; nSegs++; ! segs[nSegs].x1 = x; segs[nSegs].y1 = y+1; segs[nSegs].x2 = x; segs[nSegs].y2 = y+2; nSegs++; ! segs[nSegs].x1 = x; segs[nSegs].y1 = midY; segs[nSegs].x2 = x; segs[nSegs].y2 = midY; nSegs++; ! segs[nSegs].x1 = x; segs[nSegs].y1 = bot-2; segs[nSegs].x2 = x; segs[nSegs].y2 = bot-1; nSegs++; ! segs[nSegs].x1 = left; segs[nSegs].y1 = bot; segs[nSegs].x2 = x-1; segs[nSegs].y2 = bot; nSegs++; ! segs[nSegs].x1 = x+1; segs[nSegs].y1 = bot; segs[nSegs].x2 = right; segs[nSegs].y2 = bot; nSegs++; } else if (textD->cursorStyle == BLOCK_CURSOR) { *************** *** 1575,1577 **** else if (styleBuf != NULL) { ! style = BufGetCharacter(styleBuf, pos); if (style == textD->unfinishedStyle) { --- 1645,1647 ---- else if (styleBuf != NULL) { ! style = _BufGetCharacter(styleBuf, pos); if (style == textD->unfinishedStyle) { *************** *** 1579,1581 **** (textD->unfinishedHighlightCB)(textD, pos, textD->highlightCBArg); ! style = BufGetCharacter(styleBuf, pos); } --- 1649,1651 ---- (textD->unfinishedHighlightCB)(textD, pos, textD->highlightCBArg); ! style = _BufGetCharacter(styleBuf, pos); } *************** *** 1599,1601 **** if (style & STYLE_LOOKUP_MASK) ! fs = textD->styleTable[(style & STYLE_LOOKUP_MASK) - 'a'].font; else --- 1669,1671 ---- if (style & STYLE_LOOKUP_MASK) ! fs = textD->styleTable[(style & STYLE_LOOKUP_MASK) - UNFINISHED_STYLE].font; else *************** *** 1650,1651 **** --- 1720,1722 ---- lineStr = BufGetRange(textD->buffer, lineStart, lineStart + lineLen); + lineLen = strlen(lineStr); *************** *** 1660,1662 **** charWidth = stringWidth(textD, expandedChar, charLen, charStyle); ! if (x < xStep + (posType == CURSOR_POS ? charWidth/2 : charWidth)) { XtFree(lineStr); --- 1731,1733 ---- charWidth = stringWidth(textD, expandedChar, charLen, charStyle); ! if (x <= xStep + (posType == CURSOR_POS ? charWidth/2 : charWidth)) { XtFree(lineStr); *************** *** 2199,2201 **** charCount, expandedChar); ! style = BufGetCharacter(textD->styleBuffer, lineStartPos+i) - 'a'; width += XTextWidth(textD->styleTable[style].font, expandedChar, --- 2270,2273 ---- charCount, expandedChar); ! style = BufGetCharacter(textD->styleBuffer, lineStartPos+i) - UNFINISHED_STYLE; ! /* printf("visLineNum: %2d lineStartPos: %4d i: %2d style: %d\n", visLineNum, lineStartPos, i, style); */ width += XTextWidth(textD->styleTable[style].font, expandedChar, *************** *** 2346,2348 **** ! if (lineStartPos == -1) return 0; --- 2418,2420 ---- ! if (lineStartPos == -1 || lineStartPos > textD->buffer->length) return 0; *************** *** 2495,2497 **** { ! int lineStart, newLineStart, b, p, colNum, wrapMargin; int maxWidth, width, countPixels, expLen, i, foundBreak; --- 2567,2569 ---- { ! int lineStart, newLineStart = 0, b, p, colNum, wrapMargin; int maxWidth, width, countPixels, expLen, i, foundBreak; *** textDisp.h 1997/09/26 18:28:17 1.1 --- textDisp.h 1997/10/10 00:15:48 1.2 *************** *** 24,25 **** --- 24,28 ---- *******************************************************************************/ + #ifndef _textDisp_h_ + #define _textDisp_h_ + enum cursorStyles {NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR, BLOCK_CURSOR, *************** *** 27,28 **** --- 30,35 ---- + /* Meanings of style buffer characters (styles) */ + #define UNFINISHED_STYLE '0' + #define PLAIN_STYLE '1' + #define NO_HINT -1 *************** *** 40,41 **** --- 47,49 ---- int cursorPos; + int cursorLastPos; /* The previous position of the cursor */ int cursorOn; *************** *** 77,79 **** Widget hScrollBar, vScrollBar; ! Pixel bgPixel, selectBGPixel; /* Background colors */ Pixel highlightBGPixel; --- 85,90 ---- Widget hScrollBar, vScrollBar; ! Pixel bgPixel; /* Background/Foreground colors */ ! Pixel selectFGPixel; ! Pixel selectBGPixel; ! Pixel highlightFGPixel; Pixel highlightBGPixel; *************** *** 86,88 **** ! textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar, Position left, Position top, Position width, Position height, --- 97,99 ---- ! textDisp *TextDCreate(Widget widget, Position left, Position top, Position width, Position height, *************** *** 109,111 **** --- 120,124 ---- int TextDGetInsertPosition(textDisp *textD); + int TextDGetLastInsertPosition(textDisp *textD); int TextDXYToPosition(textDisp *textD, int x, int y); + int TextDXYToCharPosition(textDisp *textD, int x, int y); void TextDXYToUnconstrainedPosition(textDisp *textD, int x, int y, int *row, *************** *** 133 **** --- 146,148 ---- int startPosIsLineStart); + + #endif /* _textDisp_h_ */ *** textDrag.c 1997/09/26 18:28:17 1.1 --- textDrag.c 1997/10/10 00:15:48 1.2 *************** *** 24,27 **** *******************************************************************************/ #include ! #include #include --- 24,30 ---- *******************************************************************************/ + #include #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 77,79 **** else ! BufSelect(tw->text.dragOrigBuf, sel->start, sel->end); --- 80,82 ---- else ! BufSelect(tw->text.dragOrigBuf, sel->start, sel->end, sel->type); *************** *** 374,376 **** } else { ! BufSelect(buf, insStart, insStart + origSel->end - origSel->start); TextDSetInsertPosition(textD, insStart + origSel->end - origSel->start); --- 377,379 ---- } else { ! BufSelect(buf, insStart, insStart + origSel->end - origSel->start, origSel->type); TextDSetInsertPosition(textD, insStart + origSel->end - origSel->start); *************** *** 454,456 **** else ! BufSelect(buf, origSel->start, origSel->end); TextDSetInsertPosition(tw->text.textD, buf->cursorPosHint); --- 457,459 ---- else ! BufSelect(buf, origSel->start, origSel->end, origSel->type); TextDSetInsertPosition(tw->text.textD, buf->cursorPosHint); *** textP.h 1997/09/26 18:28:17 1.1 --- textP.h 1997/10/10 00:15:48 1.2 *************** *** 62,63 **** --- 62,68 ---- Boolean readOnly; + Boolean dragStartsOnCharacter; /* If drag select start with the character + under the mouse cursor or with the + cursor position set by the mouse cursor */ + Boolean enableQuadrupleClick; /* If quadruple click is allowed. Quadruple + click will selects all of the text */ int rows, columns; *************** *** 68,69 **** --- 73,81 ---- char *delimiters; + char *nonWhiteSpaceDelimiters; + int selectThreshold; /* Number of pixels of motion from the initial + (grab-focus) button press required to begin + recognizing a mouse drag for the purpose of + making a selection */ + int verticalScrollDelay; /* Length of delay in milliseconds for vertical + autoscrolling */ Widget hScrollBar, vScrollBar; *************** *** 87,89 **** and where to paste columns */ ! Time lastBtnDown; /* Timestamp of last button down event for multi-click recognition */ --- 99,103 ---- and where to paste columns */ ! int lastBtnDown; /* The button that caused the last button ! down event for multi-click recognition */ ! Time lastBtnDownTime; /* Timestamp of last button down event for multi-click recognition */ *** textSel.c 1997/09/26 18:28:17 1.1 --- textSel.c 1997/10/10 00:15:48 1.2 *************** *** 1,3 **** #include ! #include #include --- 1,7 ---- + #include #include ! #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 77,80 **** if (buf->modifyProcs[i] == modifiedCB) { ! BufRemoveModifyCB(buf, modifiedCB, buf->cbArgs[i]); ! break; } --- 81,83 ---- if (buf->modifyProcs[i] == modifiedCB) { ! BufRemoveModifyCB(buf, modifiedCB, buf->cbArgs[i], False); } *************** *** 92,102 **** { ! int i; ! textBuffer *buf = ((TextWidget)w)->text.textD->buffer; ! ! for (i=0; inModifyProcs; i++) { ! if (buf->modifyProcs[i] == modifiedCB && buf->cbArgs[i] == w) { ! BufRemoveModifyCB(buf, modifiedCB, buf->cbArgs[i]); ! return; ! } ! } } --- 95,97 ---- { ! BufRemoveModifyCB(((TextWidget)w)->text.textD->buffer, modifiedCB, w, False); } *************** *** 766,768 **** selEnd = selStart + cbInfo->length; ! BufSelect(buf, selStart, selEnd); TextDSetInsertPosition(((TextWidget)w)->text.textD, selEnd); --- 761,763 ---- selEnd = selStart + cbInfo->length; ! BufSelect(buf, selStart, selEnd, CHAR_SELECT); TextDSetInsertPosition(((TextWidget)w)->text.textD, selEnd); *** undo.c 1997/09/26 18:28:17 1.1 --- undo.c 1997/10/10 00:15:48 1.2 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #ifdef VMS *************** *** 55,57 **** { ! UndoInfo *undo = window->undo; --- 56,58 ---- { ! UndoInfo *undo = window->editorInfo->undo; *************** *** 69,71 **** /* use the saved undo information to reverse changes */ ! BufReplace(window->buffer, undo->startPos, undo->endPos, (undo->oldText != NULL ? undo->oldText : "")); --- 70,72 ---- /* use the saved undo information to reverse changes */ ! BufReplace(window->editorInfo->buffer, undo->startPos, undo->endPos, (undo->oldText != NULL ? undo->oldText : "")); *************** *** 92,97 **** { ! UndoInfo *redo = window->redo; /* return if nothing to redo */ ! if (window->redo == NULL) return; --- 93,98 ---- { ! UndoInfo *redo = window->editorInfo->redo; /* return if nothing to redo */ ! if (window->editorInfo->redo == NULL) return; *************** *** 104,106 **** /* use the saved redo information to reverse changes */ ! BufReplace(window->buffer, redo->startPos, redo->endPos, (redo->oldText != NULL ? redo->oldText : "")); --- 105,107 ---- /* use the saved redo information to reverse changes */ ! BufReplace(window->editorInfo->buffer, redo->startPos, redo->endPos, (redo->oldText != NULL ? redo->oldText : "")); *************** *** 133,137 **** int newType, oldType; ! UndoInfo *u, *undo = window->undo; int isUndo = (undo != NULL && undo->inUndo); ! int isRedo = (window->redo != NULL && window->redo->inUndo); --- 134,138 ---- int newType, oldType; ! UndoInfo *u, *undo = window->editorInfo->undo; int isUndo = (undo != NULL && undo->inUndo); ! int isRedo = (window->editorInfo->redo != NULL && window->editorInfo->redo->inUndo); *************** *** 140,142 **** list still exists, clear it and dim the redo menu item */ ! if (!(isUndo || isRedo) && window->redo != NULL) ClearRedoList(window); --- 141,143 ---- list still exists, clear it and dim the redo menu item */ ! if (!(isUndo || isRedo) && window->editorInfo->redo != NULL) ClearRedoList(window); *************** *** 157,159 **** */ ! if (window->fileChanged) { --- 158,160 ---- */ ! if (window->editorInfo->fileChanged) { *************** *** 163,165 **** undo->endPos++; ! window->autoSaveCharCount++; return; --- 164,166 ---- undo->endPos++; ! window->editorInfo->autoSaveCharCount++; return; *************** *** 172,174 **** undo->endPos++; ! window->autoSaveCharCount++; return; --- 173,175 ---- undo->endPos++; ! window->editorInfo->autoSaveCharCount++; return; *************** *** 214,216 **** /* increment the operation count for the autosave feature */ ! window->autoSaveOpCount++; --- 215,217 ---- /* increment the operation count for the autosave feature */ ! window->editorInfo->autoSaveOpCount++; *************** *** 218,224 **** restoresToSaved marker, and set it on this record */ ! if (!window->fileChanged) { undo->restoresToSaved = True; ! for (u=window->undo; u!=NULL; u=u->next) u->restoresToSaved = False; ! for (u=window->redo; u!=NULL; u=u->next) u->restoresToSaved = False; --- 219,225 ---- restoresToSaved marker, and set it on this record */ ! if (!window->editorInfo->fileChanged) { undo->restoresToSaved = True; ! for (u=window->editorInfo->undo; u!=NULL; u=u->next) u->restoresToSaved = False; ! for (u=window->editorInfo->redo; u!=NULL; u=u->next) u->restoresToSaved = False; *************** *** 243,245 **** { ! while (window->undo != NULL) removeUndoItem(window); --- 244,246 ---- { ! while (window->editorInfo->undo != NULL) removeUndoItem(window); *************** *** 248,250 **** { ! while (window->redo != NULL) removeRedoItem(window); --- 249,251 ---- { ! while (window->editorInfo->redo != NULL) removeRedoItem(window); *************** *** 261,265 **** /* Make the undo menu item sensitive now that there's something to undo */ ! if (window->undo == NULL) { ! XtSetSensitive(window->undoItem, True); ! SetBackgroundMenuUndoSensitivity(window, True); } --- 262,268 ---- /* Make the undo menu item sensitive now that there's something to undo */ ! if (window->editorInfo->undo == NULL) { ! WindowInfo *w; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtSetSensitive(w->undoItem, True); ! } } *************** *** 267,281 **** /* Add the item to the beginning of the list */ ! undo->next = window->undo; ! window->undo = undo; /* Increment the operation and memory counts */ ! window->undoOpCount++; ! window->undoMemUsed += undo->oldLen; /* Trim the list if it exceeds any of the limits */ ! if (window->undoOpCount > UNDO_OP_LIMIT) trimUndoList(window, UNDO_OP_TRIMTO); ! if (window->undoMemUsed > UNDO_WORRY_LIMIT) trimUndoList(window, UNDO_WORRY_TRIMTO); ! if (window->undoMemUsed > UNDO_PURGE_LIMIT) trimUndoList(window, UNDO_PURGE_TRIMTO); --- 270,284 ---- /* Add the item to the beginning of the list */ ! undo->next = window->editorInfo->undo; ! window->editorInfo->undo = undo; /* Increment the operation and memory counts */ ! window->editorInfo->undoOpCount++; ! window->editorInfo->undoMemUsed += undo->oldLen; /* Trim the list if it exceeds any of the limits */ ! if (window->editorInfo->undoOpCount > UNDO_OP_LIMIT) trimUndoList(window, UNDO_OP_TRIMTO); ! if (window->editorInfo->undoMemUsed > UNDO_WORRY_LIMIT) trimUndoList(window, UNDO_WORRY_TRIMTO); ! if (window->editorInfo->undoMemUsed > UNDO_PURGE_LIMIT) trimUndoList(window, UNDO_PURGE_TRIMTO); *************** *** 289,293 **** /* Make the redo menu item sensitive now that there's something to redo */ ! if (window->redo == NULL) { ! XtSetSensitive(window->redoItem, True); ! SetBackgroundMenuRedoSensitivity(window, True); } --- 292,298 ---- /* Make the redo menu item sensitive now that there's something to redo */ ! if (window->editorInfo->redo == NULL) { ! WindowInfo *w; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtSetSensitive(w->redoItem, True); ! } } *************** *** 295,298 **** /* Add the item to the beginning of the list */ ! redo->next = window->redo; ! window->redo = redo; } --- 300,303 ---- /* Add the item to the beginning of the list */ ! redo->next = window->editorInfo->redo; ! window->editorInfo->redo = redo; } *************** *** 304,306 **** { ! UndoInfo *undo = window->undo; --- 309,311 ---- { ! UndoInfo *undo = window->editorInfo->undo; *************** *** 310,316 **** /* Decrement the operation and memory counts */ ! window->undoOpCount--; ! window->undoMemUsed -= undo->oldLen; /* Remove and free the item */ ! window->undo = undo->next; freeUndoRecord(undo); --- 315,321 ---- /* Decrement the operation and memory counts */ ! window->editorInfo->undoOpCount--; ! window->editorInfo->undoMemUsed -= undo->oldLen; /* Remove and free the item */ ! window->editorInfo->undo = undo->next; freeUndoRecord(undo); *************** *** 318,322 **** /* if there are no more undo records left, dim the Undo menu item */ ! if (window->undo == NULL) { ! XtSetSensitive(window->undoItem, False); ! SetBackgroundMenuUndoSensitivity(window, False); } --- 323,329 ---- /* if there are no more undo records left, dim the Undo menu item */ ! if (window->editorInfo->undo == NULL) { ! WindowInfo *w; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtSetSensitive(w->undoItem, False); ! } } *************** *** 329,334 **** { ! UndoInfo *redo = window->redo; /* Remove and free the item */ ! window->redo = redo->next; freeUndoRecord(redo); --- 336,341 ---- { ! UndoInfo *redo = window->editorInfo->redo; /* Remove and free the item */ ! window->editorInfo->redo = redo->next; freeUndoRecord(redo); *************** *** 336,340 **** /* if there are no more redo records left, dim the Redo menu item */ ! if (window->redo == NULL) { ! XtSetSensitive(window->redoItem, False); ! SetBackgroundMenuRedoSensitivity(window, False); } --- 343,349 ---- /* if there are no more redo records left, dim the Redo menu item */ ! if (window->editorInfo->redo == NULL) { ! WindowInfo *w; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtSetSensitive(w->redoItem, False); ! } } *************** *** 351,353 **** { ! UndoInfo *undo = window->undo; char *comboText; --- 360,362 ---- { ! UndoInfo *undo = window->editorInfo->undo; char *comboText; *************** *** 367,369 **** /* keep track of the additional memory now used by the undo list */ ! window->undoMemUsed++; --- 376,378 ---- /* keep track of the additional memory now used by the undo list */ ! window->editorInfo->undoMemUsed++; *************** *** 384,386 **** ! if (window->undo == NULL) return; --- 393,395 ---- ! if (window->editorInfo->undo == NULL) return; *************** *** 388,390 **** /* Find last item on the list to leave intact */ ! for (i=1, u=window->undo; inext); if (u == NULL) --- 397,399 ---- /* Find last item on the list to leave intact */ ! for (i=1, u=window->editorInfo->undo; inext); if (u == NULL) *************** *** 397,400 **** lastRec->next = u->next; ! window->undoOpCount--; ! window->undoMemUsed -= u->oldLen; freeUndoRecord(u); --- 406,409 ---- lastRec->next = u->next; ! window->editorInfo->undoOpCount--; ! window->editorInfo->undoMemUsed -= u->oldLen; freeUndoRecord(u); *** userCmds.c 1997/09/26 18:28:17 1.1 --- userCmds.c 1997/10/23 21:57:36 1.4 *************** *** 19,21 **** * Fermilab Nirvana GUI Library * ! * April, 1997 * * * --- 19,21 ---- * Fermilab Nirvana GUI Library * ! * November, 1995 * * * *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 1032,1035 **** if (!strcmp(ShellMenuItems[i]->name, itemName)) { ! if (ShellMenuItems[i]->output == TO_SAME_WINDOW && ! CheckReadOnly(window)) return False; --- 1033,1040 ---- if (!strcmp(ShellMenuItems[i]->name, itemName)) { ! if ((ShellMenuItems[i]->output == TO_SAME_WINDOW || ! (ShellMenuItems[i]->repInput && ! ShellMenuItems[i]->input != FROM_NONE ! ) ! ) && CheckReadOnly(window) ! ) return False; *************** *** 1145,1146 **** --- 1150,1157 ---- subSep = strchr(namePtr, '>'); + /* Make it possible to have '>' in the menu label. + ** Use backslash to escape > */ + while(subSep != NULL && subSep > strippedName && subSep[-1] == '\\') { + strcpy(subSep-1, subSep); + subSep = strchr(subSep, '>'); + } if (subSep == NULL) { *************** *** 1180,1182 **** SetBackgroundMenuRedoSensitivity(window, XtIsSensitive(window->redoItem)); ! DimSelectionDepUserMenuItems(window, window->buffer->primary.selected); } --- 1191,1193 ---- SetBackgroundMenuRedoSensitivity(window, XtIsSensitive(window->redoItem)); ! DimSelectionDepUserMenuItems(window, window->editorInfo->buffer->primary.selected); } *************** *** 1843,1845 **** generateAcceleratorString(accStr, f->modifiers, f->keysym); ! length += strlen(f->name); length += strlen(accStr); --- 1854,1856 ---- generateAcceleratorString(accStr, f->modifiers, f->keysym); ! length += strlen(f->name) * 2; /* allow for \> expansions */ length += strlen(accStr); *************** *** 1859,1862 **** *outPtr++ = '\t'; ! strcpy(outPtr, f->name); ! outPtr += strlen(f->name); *outPtr++ = ':'; --- 1870,1876 ---- *outPtr++ = '\t'; ! for (c=f->name; *c!='\0'; c++) { /* Copy the menu name string, changing */ ! if (*c == '\\') /* backslashes to double backslashes */ ! *outPtr++ = '\\'; /* and newlines to backslash-n's, */ ! *outPtr++ = *c; ! } *outPtr++ = ':'; *** version.h 1997/10/09 23:29:19 1.1 --- version.h 1997/10/10 00:15:48 1.2 *************** *** 0 **** --- 1 ---- + extern const char *version_string; *** window.c 1997/09/26 18:28:17 1.1 --- window.c 1997/10/27 22:06:03 1.7 *************** *** 24,25 **** --- 24,26 ---- *******************************************************************************/ + #include #include *************** *** 28,33 **** #include "../util/VMSparam.h" #else #include #endif /*VMS*/ ! #include #include --- 29,39 ---- #include "../util/VMSparam.h" + #include #else #include + #include #endif /*VMS*/ ! #include ! #ifdef HAVE_LIMITS_H ! # include ! #endif #include *************** *** 38,41 **** --- 44,49 ---- #include + #include #include #include + #include #include *************** *** 45,50 **** #include ! #ifdef EDITRES ! #include extern void _XEditResCheckMessages(); ! #endif /* EDITRES */ #include "../util/DialogF.h" --- 53,62 ---- #include ! #include ! #ifdef HAVE_X11_XMU_EDITRES_H ! # include ! #else ! # ifdef HAVE__XEDITRESCHECKMESSAGES extern void _XEditResCheckMessages(); ! # endif ! #endif #include "../util/DialogF.h" *************** *** 69,70 **** --- 81,87 ---- #include "n.bm" + #include "clearcase.h" + #include "server.h" + #include "shell.h" + + #define MAIN_WINDOW_NAME "mainWindow" *************** *** 93,94 **** --- 110,113 ---- #endif + static void iSearchToggleCB(Widget w, WindowInfo *window, XtPointer callData); + static void iSearchHideCB(Widget w, WindowInfo *window, XtPointer callData); *************** *** 97,101 **** */ ! WindowInfo *CreateWindow(char *name) { Widget appShell, main, menuBar, pane, text, stats; WindowInfo *window; --- 116,122 ---- */ ! WindowInfo *CreateWindow(char *name, EditorInfo *editorInfo) { Widget appShell, main, menuBar, pane, text, stats; + Widget mainForm, iSearchForm, iSearchLabel, iSearchText; + Widget iSearchRadioBox, iSearchCaseToggle, iSearchRegExpToggle; WindowInfo *window; *************** *** 111,112 **** --- 132,169 ---- /* initialize window structure */ + if(editorInfo) { + window->editorInfo = editorInfo; + } + else { + window->editorInfo = (EditorInfo *)XtMalloc(sizeof(EditorInfo)); + window->editorInfo->path[0] = 0; + window->editorInfo->mtime = 0; + window->editorInfo->st_mode = 0; + window->editorInfo->checkingMode = CHECKING_MODE_DISABLED; + window->editorInfo->tailMinusFTimeoutID = 0; + window->editorInfo->undo = NULL; + window->editorInfo->redo = NULL; + window->editorInfo->autoSaveCharCount = 0; + window->editorInfo->autoSaveOpCount = 0; + window->editorInfo->undoOpCount = 0; + window->editorInfo->undoMemUsed = 0; + window->editorInfo->flashTimeoutID = 0; + window->editorInfo->flashPos = 0; + window->editorInfo->filenameSet = FALSE; + strcpy(window->editorInfo->filename, name); + window->editorInfo->fileChanged = FALSE; + window->editorInfo->readOnly = FALSE; + window->editorInfo->lockWrite = FALSE; + window->editorInfo->autoSave = GetPrefAutoSave(); + window->editorInfo->saveOldVersion = GetPrefSaveOldVersion(); + window->editorInfo->overstrike = False; + window->editorInfo->showMatching = GetPrefShowMatching(); + window->editorInfo->ignoreModify = FALSE; + window->editorInfo->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); + window->editorInfo->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); + window->editorInfo->smartIndentData = NULL; + window->editorInfo->fileOpenAtom = None; + window->editorInfo->master = window; + } + + window->nextSlave = NULL; window->replaceDlog = NULL; *************** *** 117,150 **** window->replaceRegExpBtn = NULL; ! window->findDlog = NULL; ! window->findText = NULL; ! window->findLiteralBtn = NULL; ! window->findCaseBtn = NULL; ! window->findRegExpBtn = NULL; ! window->fileChanged = FALSE; ! window->fileMode = 0; ! window->filenameSet = FALSE; ! strcpy(window->filename, name); ! window->undo = NULL; ! window->redo = NULL; ! window->nPanes = 0; ! window->autoSaveCharCount = 0; ! window->autoSaveOpCount = 0; ! window->undoOpCount = 0; ! window->undoMemUsed = 0; ! window->readOnly = FALSE; ! window->lockWrite = FALSE; ! window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); ! window->autoSave = GetPrefAutoSave(); ! window->saveOldVersion = GetPrefSaveOldVersion(); ! window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); ! window->overstrike = False; ! window->showMatching = GetPrefShowMatching(); ! window->showStats = GetPrefStatsLine(); ! window->highlightSyntax = GetPrefHighlightSyntax(); ! window->modeMessageDisplayed = FALSE; ! window->ignoreModify = FALSE; window->windowMenuValid = FALSE; window->prevOpenMenuValid = FALSE; ! window->flashTimeoutID = 0; window->wasSelected = FALSE; strcpy(window->fontName, GetPrefFontName()); --- 174,190 ---- window->replaceRegExpBtn = NULL; ! window->replaceBtns = NULL; ! window->replaceBtn = NULL; ! window->replaceFindBtn = NULL; ! window->replaceInSelBtn = NULL; ! window->replaceSearchTypeBox = NULL; ! window->findBtn = NULL; window->windowMenuValid = FALSE; window->prevOpenMenuValid = FALSE; ! window->rHistIndex = 0; window->wasSelected = FALSE; + window->showStats = GetPrefStatsLine(); + window->highlightSyntax = GetPrefHighlightSyntax(); + window->showISearchLine = GetPrefShowISearchLine(); + window->modeMessageDisplayed = FALSE; + window->nPanes = 0; strcpy(window->fontName, GetPrefFontName()); *************** *** 163,166 **** window->macroCmdData = NULL; - window->smartIndentData = NULL; window->languageMode = PLAIN_LANGUAGE_MODE; --- 203,211 ---- window->macroCmdData = NULL; window->languageMode = PLAIN_LANGUAGE_MODE; + window->iSearchDirection = SEARCH_FORWARD; + window->iSearchLastSearchString[0] = 0; + window->iSearchLastSearchType = GetPrefSearch(); + window->iSearchForm = NULL; + window->iSearchText = NULL; + window->iSearchHistIndex = 0; *************** *** 186,188 **** ! #ifdef EDITRES XtAddEventHandler (appShell, (EventMask)0, True, --- 231,233 ---- ! #ifdef HAVE__XEDITRESCHECKMESSAGES XtAddEventHandler (appShell, (EventMask)0, True, *************** *** 199,203 **** XtSetArg(al[ac], XmNuserData, window); ac++; ! main = XmCreateMainWindow(appShell, "main", al, ac); XtManageChild(main); ! /* Create file statistics display area. Using a text widget rather than --- 244,322 ---- XtSetArg(al[ac], XmNuserData, window); ac++; ! main = XmCreateMainWindow(appShell, MAIN_WINDOW_NAME, al, ac); XtManageChild(main); ! ! mainForm = XtVaCreateWidget("mainForm", ! xmRowColumnWidgetClass, main, ! XmNpacking, XmPACK_COLUMN, ! NULL); ! ! iSearchForm = XtVaCreateWidget("iSearchForm", ! xmFormWidgetClass, mainForm, NULL); ! window->iSearchForm = iSearchForm; ! iSearchLabel = XtVaCreateManagedWidget("iSearchLabel", ! xmPushButtonWidgetClass, iSearchForm, ! XmNmarginHeight, 1, ! XmNshadowThickness, 0, ! NULL); ! XtAddCallback(iSearchLabel, XmNactivateCallback, (XtCallbackProc)iSearchHideCB, window); ! iSearchText = XtVaCreateManagedWidget("iSearchText", ! xmTextFieldWidgetClass, iSearchForm, ! XmNfontList, window->fontList, ! XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, ! NULL); ! window->iSearchText = iSearchText; ! iSearchRadioBox = XtVaCreateManagedWidget("iSearchRadioBox", ! xmRowColumnWidgetClass, iSearchForm, ! XmNorientation, XmHORIZONTAL, ! XmNpacking, XmPACK_TIGHT, ! NULL); ! iSearchCaseToggle = XtVaCreateManagedWidget("iSearchCaseToggle", ! xmToggleButtonWidgetClass, iSearchRadioBox, ! XmNtraversalOn, True, ! XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, ! XmNhighlightThickness, 2, ! XmNmarginHeight, 0, ! XmNset, GetPrefSearch() == SEARCH_CASE_SENSE || GetPrefSearch() == SEARCH_REGEX, ! NULL); ! XtAddCallback(iSearchCaseToggle, XmNvalueChangedCallback, (XtCallbackProc)iSearchToggleCB, window); ! window->iSearchCaseToggle = iSearchCaseToggle; ! iSearchRegExpToggle = XtVaCreateManagedWidget("iSearchRegExpToggle", ! xmToggleButtonWidgetClass, iSearchRadioBox, ! XmNtraversalOn, True, ! XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, ! XmNhighlightThickness, 2, ! XmNmarginHeight, 0, ! XmNset, GetPrefSearch() == SEARCH_REGEX, ! NULL); ! XtAddCallback(iSearchRegExpToggle, XmNvalueChangedCallback, (XtCallbackProc)iSearchToggleCB, window); ! window->iSearchRegExpToggle = iSearchRegExpToggle; ! XtManageChild(iSearchRadioBox); ! XtVaSetValues(iSearchLabel, ! XmNtopAttachment, XmATTACH_FORM, ! XmNbottomAttachment, XmATTACH_FORM, ! XmNleftAttachment, XmATTACH_FORM, ! XmNrightAttachment, XmATTACH_NONE, ! NULL); ! XtVaSetValues(iSearchText, ! XmNtopAttachment, XmATTACH_NONE, ! XmNtopOffset, 2, ! XmNbottomAttachment, XmATTACH_FORM, ! XmNbottomOffset, 2, ! XmNleftAttachment, XmATTACH_WIDGET, ! XmNleftWidget, iSearchLabel, ! XmNrightAttachment, XmATTACH_WIDGET, ! XmNrightWidget, iSearchRadioBox, ! NULL); ! XtVaSetValues(iSearchRadioBox, ! XmNtopAttachment, XmATTACH_NONE, ! XmNbottomAttachment, XmATTACH_FORM, ! XmNleftAttachment, XmATTACH_NONE, ! XmNrightAttachment, XmATTACH_FORM, ! NULL); ! ! SetISearchTextCallbacks(window); ! if(window->showISearchLine) { ! XtManageChild(iSearchForm); ! } ! /* Create file statistics display area. Using a text widget rather than *************** *** 206,210 **** the length when the window changed size).*/ ! stats = XtVaCreateWidget("statsLine", xmTextWidgetClass, main, ! XmNshadowThickness, 0, ! XmNmarginHeight, 0, XmNscrollHorizontal, False, --- 325,327 ---- the length when the window changed size).*/ ! stats = XtVaCreateWidget("statsLine", xmTextFieldWidgetClass, mainForm, XmNscrollHorizontal, False, *************** *** 216,219 **** window->statsLine = stats; ! if (GetPrefStatsLine()) ! XtManageChild(stats); --- 333,341 ---- window->statsLine = stats; ! if (window->showStats) { ! XtManageChild(stats); ! } ! if (window->showISearchLine || window->showStats) { ! XtManageChild(mainForm); ! } ! *************** *** 234,236 **** window->splitPane = pane; ! XmMainWindowSetAreas(main, menuBar, stats, NULL, NULL, pane); --- 356,358 ---- window->splitPane = pane; ! XmMainWindowSetAreas(main, menuBar, mainForm, NULL, NULL, pane); *************** *** 240,242 **** GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(), ! GetPrefWrapMargin()); XtManageChild(text); --- 362,364 ---- GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(), ! GetPrefWrapMargin()); XtManageChild(text); *************** *** 256,270 **** the text display's callback is called upon to display a modification */ ! window->buffer = BufCreate(); ! BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window); /* Attach the buffer to the text widget, and add callbacks for modify */ ! TextSetBuffer(text, window->buffer); ! BufAddModifyCB(window->buffer, modifiedCB, window); ! ! /* Designate the permanent text area as the owner for selections */ ! HandleXSelections(text); /* Set the requested hardware tab distance and useTabs in the text buffer */ ! BufSetTabDistance(window->buffer, GetPrefTabDist(PLAIN_LANGUAGE_MODE)); ! window->buffer->useTabs = GetPrefInsertTabs(); --- 378,393 ---- the text display's callback is called upon to display a modification */ ! if(!editorInfo) { ! window->editorInfo->buffer = BufCreate(); ! } ! BufAddModifyCB(window->editorInfo->buffer, SyntaxHighlightModifyCB, window); /* Attach the buffer to the text widget, and add callbacks for modify */ ! TextSetBuffer(text, window->editorInfo->buffer); ! BufAddModifyCB(window->editorInfo->buffer, modifiedCB, window); /* Set the requested hardware tab distance and useTabs in the text buffer */ ! if(!editorInfo) { ! BufSetTabDistance(window->editorInfo->buffer, GetPrefTabDist(PLAIN_LANGUAGE_MODE)); ! window->editorInfo->buffer->useTabs = GetPrefInsertTabs(); ! } *************** *** 286,287 **** --- 409,414 ---- + /* make sure the window has been drawn before returning */ + UpdateDisplay(); + + XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT); return window; *************** *** 294,311 **** { /* if this is the last window, don't close it, make it Untitled */ if (WindowList == window && window->next == NULL) { ! window->readOnly = FALSE; ! window->lockWrite = FALSE; ! window->fileMode = 0; ! strcpy(window->filename, "Untitled"); ! strcpy(window->path, ""); ! window->ignoreModify = TRUE; ! BufSetAll(window->buffer, ""); ! window->ignoreModify = FALSE; ! window->filenameSet = FALSE; ! window->fileChanged = FALSE; StopHighlighting(window); EndSmartIndent(window); ! UpdateWindowTitle(window); UpdateWindowReadOnly(window); XtSetSensitive(window->closeItem, FALSE); --- 421,449 ---- { + EditorInfo *editorInfo = window->editorInfo; + + /* Don't close the window if a shell command is in progress for + ** this window. */ + if(IsShellCommandInProgress(window)) { + XBell(TheDisplay, 0); + return; + } + /* if this is the last window, don't close it, make it Untitled */ if (WindowList == window && window->next == NULL) { ! /* Destroy the file open property for this file */ ! DestroyFileOpenProperty(window); ! editorInfo->readOnly = FALSE; ! editorInfo->lockWrite = FALSE; ! strcpy(editorInfo->filename, "Untitled"); ! /*strcpy(editorInfo->path, "");*//* leave the path set to its last value. */ ! editorInfo->ignoreModify = TRUE; ! BufSetAll(editorInfo->buffer, ""); ! editorInfo->ignoreModify = FALSE; ! editorInfo->filenameSet = FALSE; ! editorInfo->fileChanged = FALSE; StopHighlighting(window); EndSmartIndent(window); ! SetCheckingMode(window, CHECKING_MODE_DISABLED); UpdateWindowReadOnly(window); + UpdateWindowTitle(window); XtSetSensitive(window->closeItem, FALSE); *************** *** 322,323 **** --- 460,465 ---- + /* make sure the window has been removed before continuing */ + XtUnmapWidget(window->shell); + UpdateDisplay(); + /* Free syntax highlighting patterns, if any. w/o redisplaying */ *************** *** 330,333 **** deallocated when the last text widget is destroyed */ ! BufRemoveModifyCB(window->buffer, modifiedCB, window); ! BufRemoveModifyCB(window->buffer, SyntaxHighlightModifyCB, window); --- 472,475 ---- deallocated when the last text widget is destroyed */ ! BufRemoveModifyCB(editorInfo->buffer, modifiedCB, window, True); ! BufRemoveModifyCB(editorInfo->buffer, SyntaxHighlightModifyCB, window, True); *************** *** 344,348 **** ! /* free the undo and redo lists */ ! ClearUndoList(window); ! ClearRedoList(window); --- 486,526 ---- ! /* Update the slave window linked list */ ! if(window == editorInfo->master) { ! /* If we are the master then make the next slave the master. */ ! editorInfo->master = editorInfo->master->nextSlave; ! } ! else { ! /* If we are a slave then remove ourself from the slave list. */ ! WindowInfo *w; ! for(w = editorInfo->master; w->nextSlave; w = w->nextSlave) { ! if(w->nextSlave == window) { ! w->nextSlave = window->nextSlave; ! break; ! } ! } ! } ! ! /* If there are still slave windows then make sure selections ! are still attached and the title is updated else free ! the editorInfo stuff. */ ! if(editorInfo->master != NULL) { ! TextHandleXSelections(editorInfo->master->textArea); ! UpdateWindowTitle(editorInfo->master); ! } ! else { ! /* Remove the file checking time out. */ ! if(editorInfo->tailMinusFTimeoutID) { ! XtRemoveTimeOut(editorInfo->tailMinusFTimeoutID); ! } ! editorInfo->tailMinusFTimeoutID = 0; ! ! /* Destroy the file open property for this file */ ! DestroyFileOpenProperty(window); ! ! /* free the undo and redo lists */ ! ClearUndoList(window); ! ClearRedoList(window); ! ! XtFree((char *)editorInfo); ! } *************** *** 353,354 **** --- 531,601 ---- /* + ** Create a slave editor window + */ + WindowInfo *CreateSlaveWindow(WindowInfo *window) + { + WindowInfo *newWindow; + int i, topLine, horizOffset; + int emTabDist, wrapMargin; + char *delimiters; + WindowInfo *w; + + /* create a new window and transfer values from the old one */ + newWindow = CreateWindow("", window->editorInfo); + + /* Add window to end of slave list */ + for(w = newWindow->editorInfo->master; w->nextSlave != NULL; w = w->nextSlave) + ; + w->nextSlave = newWindow; + newWindow->nextSlave = NULL; + + SetFonts(newWindow, + window->fontName, + window->italicFontName, + window->boldFontName, + window->boldItalicFontName + ); + XtVaGetValues(window->textArea, + textNemulateTabs, &emTabDist, + textNwrapMargin, &wrapMargin, + textNwordDelimiters, &delimiters, + 0); + XtVaSetValues(newWindow->textArea, + textNemulateTabs, emTabDist, + textNwrapMargin, wrapMargin, + textNwordDelimiters, delimiters, + 0); + XtSetSensitive(newWindow->undoItem, XtIsSensitive(window->undoItem)); + XtSetSensitive(newWindow->redoItem, XtIsSensitive(window->redoItem)); + TextSetCursorPos(newWindow->textArea, TextGetCursorPos(window->textArea)); + TextGetScroll(window->textArea, &topLine, &horizOffset); + TextSetScroll(newWindow->textArea, topLine, horizOffset); + for (i=0; inMarks; i++) + newWindow->markTable[i] = window->markTable[i]; + newWindow->nMarks = window->nMarks; + newWindow->iSearchDirection = window->iSearchDirection; + strcpy(newWindow->iSearchLastSearchString, window->iSearchLastSearchString); + newWindow->iSearchLastSearchType = window->iSearchLastSearchType; + + /* Retain the current language mode and syntax highlighting. */ + newWindow->languageMode = window->languageMode; + newWindow->highlightSyntax = window->highlightSyntax; + if (newWindow->highlightSyntax) { + StartHighlighting(newWindow, False); + } + + /* Update the checking mode toggle buttons */ + SetCheckingMode(newWindow, window->editorInfo->checkingMode); + UpdateWindowReadOnly(newWindow); + UpdateWindowTitle(newWindow); + + /* Add/remove language specific menu items */ + UpdateShellMenu(newWindow); + UpdateMacroMenu(newWindow); + UpdateBGMenu(newWindow); + + return newWindow; + } + + + /* ** Check if there is already a window open for a given file *************** *** 360,362 **** for (w=WindowList; w!=NULL; w=w->next) { ! if (!strcmp(w->filename, name) && !strcmp(w->path, path)) { return w; --- 607,609 ---- for (w=WindowList; w!=NULL; w=w->next) { ! if (!strcmp(w->editorInfo->filename, name) && !strcmp(w->editorInfo->path, path)) { return w; *************** *** 373,375 **** { ! short paneHeights[MAX_PANES+1]; int insertPositions[MAX_PANES+1], topLines[MAX_PANES+1]; --- 620,622 ---- { ! Dimension paneHeights[MAX_PANES+1]; int insertPositions[MAX_PANES+1], topLines[MAX_PANES+1]; *************** *** 406,408 **** delimiters, wrapMargin); ! TextSetBuffer(text, window->buffer); if (window->highlightData != NULL) --- 653,655 ---- delimiters, wrapMargin); ! TextSetBuffer(text, window->editorInfo->buffer); if (window->highlightData != NULL) *************** *** 455,457 **** { ! short paneHeights[MAX_PANES+1]; int insertPositions[MAX_PANES+1], topLines[MAX_PANES+1]; --- 702,704 ---- { ! Dimension paneHeights[MAX_PANES+1]; int insertPositions[MAX_PANES+1], topLines[MAX_PANES+1]; *************** *** 526,528 **** { ! Widget mainW = XtParent(window->statsLine); --- 773,775 ---- { ! Widget mainW = XtParent(XtParent(window->statsLine)); *************** *** 531,544 **** status line when it is managed and unmanaged */ if (state) { - XtVaSetValues(mainW, XmNcommandWindowLocation, - XmCOMMAND_ABOVE_WORKSPACE, 0); - XtVaSetValues(mainW, XmNshowSeparator, True, 0); XtManageChild(window->statsLine); ! XtVaSetValues(mainW, XmNshowSeparator, False, 0); ! UpdateStatsLine(window); } else { XtUnmanageChild(window->statsLine); ! XtVaSetValues(mainW, XmNcommandWindowLocation, ! XmCOMMAND_BELOW_WORKSPACE, 0); } --- 778,827 ---- status line when it is managed and unmanaged */ + XtVaSetValues(mainW, XmNshowSeparator, True, 0); if (state) { XtManageChild(window->statsLine); ! XtManageChild(XtParent(window->statsLine)); ! UpdateStatsLine(window); } else { XtUnmanageChild(window->statsLine); ! if(!XtIsManaged(window->iSearchForm)) { ! XtUnmanageChild(XtParent(window->statsLine)); ! } } + XtVaSetValues(mainW, XmNshowSeparator, False, 0); + + /* Tell WM that the non-expandable part of the window has changed size */ + UpdateWMSizeHints(window); + } + + /* + ** Turn on and off the display of the incremental search line + */ + void ShowISearchLine(WindowInfo *window, int state) + { + Widget mainW = XtParent(XtParent(window->iSearchForm)); + + /* Return if the iSearchForm was not created or if the new state + matches the current state. */ + if(window->iSearchForm == NULL || window->showISearchLine == state) + return; + + window->showISearchLine = state; + + /* The very silly use of XmNcommandWindowLocation and XmNshowSeparator + below are to kick the main window widget to position and remove the + status line when it is managed and unmanaged */ + XtVaSetValues(mainW, XmNshowSeparator, True, 0); + if (state) { + XtManageChild(window->iSearchForm); + XtManageChild(XtParent(window->iSearchForm)); + } else { + XtUnmanageChild(window->iSearchForm); + if(!XtIsManaged(window->statsLine)) { + XtUnmanageChild(XtParent(window->iSearchForm)); + } + } + XtVaSetValues(mainW, XmNshowSeparator, False, 0); + + /* Set the menu item to the current state. */ + XmToggleButtonSetState(window->iSearchLineItem, state, FALSE); *************** *** 590,596 **** ! if (window->indentStyle == SMART_INDENT && !smartIndent) EndSmartIndent(window); ! else if (smartIndent && window->indentStyle != SMART_INDENT) BeginSmartIndent(window, True); ! window->indentStyle = state; XtVaSetValues(window->textArea, textNautoIndent, autoIndent, --- 873,879 ---- ! if (window->editorInfo->indentStyle == SMART_INDENT && !smartIndent) EndSmartIndent(window); ! else if (smartIndent && window->editorInfo->indentStyle != SMART_INDENT) BeginSmartIndent(window, True); ! window->editorInfo->indentStyle = state; XtVaSetValues(window->textArea, textNautoIndent, autoIndent, *************** *** 712,718 **** int i; ! XtVaSetValues(window->textArea, textNoverstrike, overstrike, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(window->textPanes[i], textNoverstrike, overstrike, 0); ! window->overstrike = overstrike; } --- 995,1005 ---- int i; + WindowInfo *win; ! window->editorInfo->overstrike = overstrike; ! for(win = window->editorInfo->master; win; win = win->nextSlave) { ! XtVaSetValues(win->textArea, textNoverstrike, overstrike, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(win->textPanes[i], textNoverstrike, overstrike, 0); ! XmToggleButtonSetState(win->overstrikeItem, overstrike, FALSE); ! } } *************** *** 726,728 **** int autoWrap = state == NEWLINE_WRAP, contWrap = state == CONTINUOUS_WRAP; ! XtVaSetValues(window->textArea, textNautoWrap, autoWrap, --- 1013,1015 ---- int autoWrap = state == NEWLINE_WRAP, contWrap = state == CONTINUOUS_WRAP; ! XtVaSetValues(window->textArea, textNautoWrap, autoWrap, *************** *** 732,735 **** textNcontinuousWrap, contWrap, 0); ! window->wrapMode = state; ! XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False); --- 1019,1022 ---- textNcontinuousWrap, contWrap, 0); ! window->editorInfo->wrapMode = state; ! XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False); *************** *** 745,750 **** int i; ! ! XtVaSetValues(window->textArea, textNwrapMargin, margin, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(window->textPanes[i], textNwrapMargin, margin, 0); } --- 1032,1076 ---- int i; ! WindowInfo *w; ! ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtVaSetValues(w->textArea, textNwrapMargin, margin, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(w->textPanes[i], textNwrapMargin, margin, 0); ! } ! } ! ! /* ! ** Set auto save mode. ! */ ! void SetAutoSave(WindowInfo *window, int state) ! { ! WindowInfo *win; ! window->editorInfo->autoSave = state; ! for(win = window->editorInfo->master; win; win = win->nextSlave) { ! XmToggleButtonSetState(win->autoSaveItem, state, False); ! } ! } ! ! /* ! ** Set save old version mode. ! */ ! void SetSaveOldVersion(WindowInfo *window, int state) ! { ! WindowInfo *win; ! window->editorInfo->saveOldVersion = state; ! for(win = window->editorInfo->master; win; win = win->nextSlave) { ! XmToggleButtonSetState(win->saveLastItem, state, False); ! } ! } ! ! /* ! ** Set show matching mode. ! */ ! void SetShowMatching(WindowInfo *window, int state) ! { ! WindowInfo *win; ! window->editorInfo->showMatching = state; ! for(win = window->editorInfo->master; win; win = win->nextSlave) { ! XmToggleButtonSetState(win->showMatchingItem, state, False); ! } } *************** *** 759,772 **** WindowInfo *window; ! Widget parent; ! ! while (True) { ! parent = XtParent(w); ! if (parent == NULL) ! return NULL; ! if (XtClass(parent) == applicationShellWidgetClass) ! break; ! w = parent; ! } ! XtVaGetValues(w, XmNuserData, &window, 0); ! return window; } --- 1085,1094 ---- WindowInfo *window; ! ! for(; w; w = XtParent(w)) { ! if(strcmp(XtName(w), MAIN_WINDOW_NAME) == 0) { ! XtVaGetValues(w, XmNuserData, &window, 0); ! return window; ! } ! } ! return NULL; } *************** *** 779,786 **** { ! if (window->fileChanged == FALSE && modified == TRUE) { ! XtSetSensitive(window->closeItem, TRUE); ! window->fileChanged = TRUE; UpdateWindowTitle(window); ! } else if (window->fileChanged == TRUE && modified == FALSE) { ! window->fileChanged = FALSE; UpdateWindowTitle(window); --- 1101,1112 ---- { ! ! if (window->editorInfo->fileChanged == FALSE && modified == TRUE) { ! WindowInfo *w; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtSetSensitive(w->closeItem, TRUE); ! } ! window->editorInfo->fileChanged = TRUE; UpdateWindowTitle(window); ! } else if (window->editorInfo->fileChanged == TRUE && modified == FALSE) { ! window->editorInfo->fileChanged = FALSE; UpdateWindowTitle(window); *************** *** 790,791 **** --- 1116,1153 ---- /* + ** Format the title of a window. Returns a pointer to static storage that + ** will be overwritten on the next call. + */ + char *FormatWindowTitle(WindowInfo *window) + { + static char title[MAXPATHLEN + 35 + 1]; /* strlen(":1 (read only)(locked)(modified)" */ + char slaveNumber[10]; + + /* Figure out which slave we are. */ + slaveNumber[0] = 0; + if(window->editorInfo->master->nextSlave != NULL) { + WindowInfo *w; + int num; + num = 0; + for(w = window->editorInfo->master; w; w = w->nextSlave) { + num++; + if(w == window) { + break; + } + } + sprintf(slaveNumber, ":%d", num); + } + + /* Set the window title, adding annotations for "modified" or "read-only" */ + sprintf(title, "%s%s%s%s%s%s", + window->editorInfo->filename, + slaveNumber, + (window->editorInfo->readOnly || window->editorInfo->lockWrite || window->editorInfo->fileChanged) ? " " : "", + window->editorInfo->readOnly ? "(read only)" : "", + window->editorInfo->lockWrite ? "(locked)" : "", + window->editorInfo->fileChanged ? "(modified)" : "" + ); + return title; + } + + /* ** Update the window title to reflect the filename, read-only, and modified *************** *** 795,817 **** { ! char title[MAXPATHLEN + 14]; /* 11: strlen("Replace (in )") */ ! /* Set the window title, adding annotations for "modified" or "read-only" */ ! strcpy(title, window->filename); ! if (window->readOnly) ! strcat(title, " (read only)"); ! else if (window->lockWrite) ! strcat(title, " (locked)"); ! else if (window->fileChanged) ! strcat(title, " (modified)"); ! SetWindowTitle(window, title); ! ! /* If there's a find or replace dialog up in "Keep Up" mode, with a ! file name in the title, update it too */ ! if (window->findDlog && XmToggleButtonGetState(window->findKeepBtn)) { ! sprintf(title, "Find (in %s)", window->filename); ! XtVaSetValues(XtParent(window->findDlog), XmNtitle, title, 0); ! } ! if (window->replaceDlog && XmToggleButtonGetState(window->replaceKeepBtn)) { ! sprintf(title, "Replace (in %s)", window->filename); ! XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title, 0); } --- 1157,1194 ---- { ! char title[MAXPATHLEN * 4 + 1]; ! char icontitle[MAXPATHLEN + 1 + 1]; /* strlen(">") */ ! char *ccaseViewTag; ! WindowInfo *w; ! /* Generate title. ! ** NEdit[server_name]: file_info - [view_name]path ! */ ! ccaseViewTag = GetClearCaseViewTag(); ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! strcpy(title, "NEdit"); ! if(isServer) { ! sprintf(title + strlen(title), "[%s]", GetPrefServerName()); ! } ! if(ccaseViewTag && ccaseViewTag[0] != 0) { ! sprintf(title + strlen(title), "{%s}", ccaseViewTag); ! } ! strcat(title, ": "); ! strcat(title, FormatWindowTitle(w)); ! if(window->editorInfo->filenameSet) { ! strcat(title, " - "); ! strcat(title, window->editorInfo->path); ! } ! ! strcpy(icontitle, ""); ! if (window->editorInfo->fileChanged) ! strcat(icontitle, ">"); ! strcat(icontitle, window->editorInfo->filename); ! SetWindowTitle(w, title, icontitle); ! ! /* If there's a find or replace dialog up in "Keep Up" mode, with a ! file name in the title, update it too */ ! if (w->replaceDlog) { ! sprintf(title, "NEdit - Find/Replace (%s)", window->editorInfo->filename); ! XtVaSetValues(XtParent(w->replaceDlog), XmNtitle, title, 0); ! } } *************** *** 827,850 **** int i, state; ! ! state = window->readOnly || window->lockWrite; ! XtVaSetValues(window->textArea, textNreadOnly, state, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(window->textPanes[i], textNreadOnly, state, 0); ! XmToggleButtonSetState(window->readOnlyItem, state, FALSE); ! XtSetSensitive(window->readOnlyItem, !window->readOnly); } ! void SetWindowTitle(WindowInfo *window, char *title) { - #ifdef SGI_CUSTOM - char sgi_title[MAXPATHLEN + 14 + SGI_WINDOW_TITLE_LEN] = SGI_WINDOW_TITLE; - strcat(sgi_title, title); - #endif - /* Set both the window title and the icon title */ ! #ifdef SGI_CUSTOM ! XtVaSetValues(window->shell, XmNtitle, sgi_title, XmNiconName, title, 0); ! #else ! XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, title, 0); ! #endif --- 1204,1222 ---- int i, state; ! WindowInfo *w; ! ! state = (!GetPrefAllowReadOnlyEdits() && window->editorInfo->readOnly) || window->editorInfo->lockWrite; ! for(w = window->editorInfo->master; w; w = w->nextSlave) { ! XtVaSetValues(w->textArea, textNreadOnly, state, 0); ! for (i=0; inPanes; i++) ! XtVaSetValues(w->textPanes[i], textNreadOnly, state, 0); ! XmToggleButtonSetState(w->readOnlyItem, state, FALSE); ! XtSetSensitive(w->readOnlyItem, (GetPrefAllowReadOnlyEdits() || !w->editorInfo->readOnly)); ! } ! UpdateWindowTitle(window); } ! void SetWindowTitle(WindowInfo *window, char *title, char *icontitle) { /* Set both the window title and the icon title */ ! XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, icontitle, 0); *************** *** 911,913 **** int topLineNum, lastLineNum, rightLineNum, leftLineNum, linesToScroll; ! textBuffer *buf = window->buffer; int topChar = TextFirstVisiblePos(textPane); --- 1283,1285 ---- int topLineNum, lastLineNum, rightLineNum, leftLineNum, linesToScroll; ! textBuffer *buf = window->editorInfo->buffer; int topChar = TextFirstVisiblePos(textPane); *************** *** 917,919 **** /* find out where the selection is */ ! if (!BufGetSelectionPos(window->buffer, &left, &right, &isRect, &rectStart, &rectEnd)) { --- 1289,1291 ---- /* find out where the selection is */ ! if (!BufGetSelectionPos(window->editorInfo->buffer, &left, &right, &isRect, &rectStart, &rectEnd)) { *************** *** 985,988 **** { ! Widget text, sw, hScrollBar, vScrollBar; ! Pixel troughColor; --- 1357,1362 ---- { ! Widget text, sw, hScrollBar; ! XFontStruct *fs; ! int marginHeight; ! Dimension hsbHeight, swMarginHeight; *************** *** 992,999 **** XmNpaneMinimum, PANE_MIN_HEIGHT, XmNhighlightThickness, 0, 0); - hScrollBar = XtVaCreateManagedWidget("textHorScrollBar", - xmScrollBarWidgetClass, sw, XmNorientation, XmHORIZONTAL, - XmNrepeatDelay, 10, 0); - vScrollBar = XtVaCreateManagedWidget("textVertScrollBar", - xmScrollBarWidgetClass, sw, XmNorientation, XmVERTICAL, - XmNrepeatDelay, 10, 0); text = XtVaCreateManagedWidget("text", textWidgetClass, sw, --- 1366,1367 ---- *************** *** 1002,1013 **** textNfont, GetDefaultFontStruct(window->fontList), - textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar, textNwordDelimiters, delimiters, textNwrapMargin, wrapMargin, ! textNautoIndent, window->indentStyle == AUTO_INDENT, ! textNsmartIndent, window->indentStyle == SMART_INDENT, ! textNautoWrap, window->wrapMode == NEWLINE_WRAP, ! textNcontinuousWrap, window->wrapMode == CONTINUOUS_WRAP, ! textNoverstrike, window->overstrike, 0); ! XtVaSetValues(sw, XmNworkWindow, text, XmNhorizontalScrollBar, hScrollBar, ! XmNverticalScrollBar, vScrollBar, 0); --- 1370,1378 ---- textNfont, GetDefaultFontStruct(window->fontList), textNwordDelimiters, delimiters, textNwrapMargin, wrapMargin, ! textNautoIndent, window->editorInfo->indentStyle == AUTO_INDENT, ! textNsmartIndent, window->editorInfo->indentStyle == SMART_INDENT, ! textNautoWrap, window->editorInfo->wrapMode == NEWLINE_WRAP, ! textNcontinuousWrap, window->editorInfo->wrapMode == CONTINUOUS_WRAP, ! textNoverstrike, window->editorInfo->overstrike, 0); *************** *** 1027,1032 **** ! /* Set the little square in the corner between the scroll ! bars to be the same color as the scroll bar interiors */ ! XtVaGetValues(vScrollBar, XmNtroughColor, &troughColor, 0); ! XtVaSetValues(sw, XmNbackground, troughColor, 0); --- 1392,1400 ---- ! /* set the minimum size of a pane */ ! XtVaGetValues(sw, XmNhorizontalScrollBar, &hScrollBar, ! XmNscrolledWindowMarginHeight, &swMarginHeight, 0); ! XtVaGetValues(text, textNmarginHeight, &marginHeight, textNfont, &fs, 0); ! XtVaGetValues(hScrollBar, XmNheight, &hsbHeight, 0); ! setPaneMinHeight(sw, fs->ascent + fs->descent + marginHeight*2 + ! swMarginHeight*2 + hsbHeight); *************** *** 1043,1045 **** { ! if (window->ignoreModify) return; --- 1411,1413 ---- { ! if (window->editorInfo->ignoreModify) return; *************** *** 1057,1059 **** WindowInfo *window = (WindowInfo *)cbArg; ! int selected = window->buffer->primary.selected; --- 1425,1427 ---- WindowInfo *window = (WindowInfo *)cbArg; ! int selected = window->editorInfo->buffer->primary.selected; *************** *** 1063,1065 **** /* Check and dim/undim selection related menu items */ ! if (window->wasSelected && !selected || !window->wasSelected && selected) { window->wasSelected = selected; --- 1431,1433 ---- /* Check and dim/undim selection related menu items */ ! if ((window->wasSelected && !selected) || (!window->wasSelected && selected)) { window->wasSelected = selected; *************** *** 1072,1074 **** ! DimSelectionDepUserMenuItems(window, selected); if (window->replaceDlog != NULL) --- 1440,1442 ---- ! DimSelectionDepUserMenuItems(window, selected); if (window->replaceDlog != NULL) *************** *** 1079,1094 **** recording it for undo or marking file as changed it sets ignoreModify */ ! if (window->ignoreModify || (nDeleted == 0 && nInserted == 0)) return; ! /* Save information for undoing this operation (this call also counts ! characters and editing operations for triggering autosave */ ! SaveUndoInformation(window, pos, nInserted, nDeleted, deletedText); ! ! /* Trigger automatic backup if operation or character limits reached */ ! if (window->autoSave && ! (window->autoSaveCharCount > AUTOSAVE_CHAR_LIMIT || ! window->autoSaveOpCount > AUTOSAVE_OP_LIMIT)) { ! WriteBackupFile(window); ! window->autoSaveCharCount = 0; ! window->autoSaveOpCount = 0; } --- 1447,1465 ---- recording it for undo or marking file as changed it sets ignoreModify */ ! if (window->editorInfo->ignoreModify || (nDeleted == 0 && nInserted == 0)) return; ! /* Only the master keeps track of the undo info */ ! if(window == window->editorInfo->master) { ! /* Save information for undoing this operation (this call also counts ! characters and editing operations for triggering autosave */ ! SaveUndoInformation(window, pos, nInserted, nDeleted, deletedText); ! ! /* Trigger automatic backup if operation or character limits reached */ ! if (window->editorInfo->autoSave && ! (window->editorInfo->autoSaveCharCount > AUTOSAVE_CHAR_LIMIT || ! window->editorInfo->autoSaveOpCount > AUTOSAVE_OP_LIMIT)) { ! WriteBackupFile(window); ! window->editorInfo->autoSaveCharCount = 0; ! window->editorInfo->autoSaveOpCount = 0; ! } } *************** *** 1109,1110 **** --- 1480,1483 ---- UpdateStatsLine(window); + + CheckForChangesInFile(window); } *************** *** 1114,1116 **** /* don't record all of the intermediate drag steps for undo */ ! window->ignoreModify = True; } --- 1487,1489 ---- /* don't record all of the intermediate drag steps for undo */ ! window->editorInfo->ignoreModify = True; } *************** *** 1120,1122 **** /* restore recording of undo information */ ! window->ignoreModify = False; --- 1493,1495 ---- /* restore recording of undo information */ ! window->editorInfo->ignoreModify = False; *************** *** 1134,1139 **** { if (WindowList->next == NULL) { ! if (!CheckPrefsChangesSaved(window->shell)) return; ! if (!WindowList->fileChanged) exit(0); --- 1507,1519 ---- { + /* Don't close the window if a shell command is in progress for + ** this window. */ + if(IsShellCommandInProgress(window)) { + XBell(TheDisplay, 0); + return; + } + if (WindowList->next == NULL) { ! if (!CheckPrefsChangesSaved(window->shell)) return; ! if (!WindowList->editorInfo->fileChanged) exit(0); *************** *** 1185,1186 **** --- 1565,1567 ---- Widget statW = window->statsLine; + char *path; #ifdef SGI_CUSTOM *************** *** 1197,1205 **** pos = TextGetCursorPos(window->lastFocus); ! string = XtMalloc(strlen(window->filename) + strlen(window->path) + 45); if (!TextPosToLineAndCol(window->lastFocus, pos, &line, &colNum)) ! sprintf(string, "%s%s %d bytes", window->path, window->filename, ! window->buffer->length); ! else ! sprintf(string, "%s%s line %d, col %d, %d bytes", window->path, ! window->filename, line, colNum, window->buffer->length); --- 1578,1593 ---- pos = TextGetCursorPos(window->lastFocus); ! /* Display the path only if filenameSet is set. path can be set for use ! as the current directory for shell command and for the initial ! directory of the open dialog but it shouldn't be displayed as the ! path of the file if filenameSet is not set. This is normally the case ! with the Untitled window. */ ! path = window->editorInfo->filenameSet ? window->editorInfo->path : ""; ! string = XtMalloc(strlen(window->editorInfo->filename) + strlen(path) + 45); if (!TextPosToLineAndCol(window->lastFocus, pos, &line, &colNum)) ! sprintf(string, "%s%s %d bytes", path, window->editorInfo->filename, ! window->editorInfo->buffer->length); ! else { ! sprintf(string, "%s%s line %d, col %d, %d bytes", path, ! window->editorInfo->filename, line, colNum, window->editorInfo->buffer->length); ! } *************** *** 1267,1269 **** totalHeight += textHeight - 2*marginHeight; ! if (!XtIsManaged(hScrollBar)) { XtVaGetValues(hScrollBar, XmNheight, &hScrollBarHeight, 0); --- 1655,1657 ---- totalHeight += textHeight - 2*marginHeight; ! if (hScrollBar != NULL && !XtIsManaged(hScrollBar)) { XtVaGetValues(hScrollBar, XmNheight, &hScrollBarHeight, 0); *************** *** 1390 **** --- 1778,1813 ---- #endif /* ROWCOLPATCH */ + + static void iSearchToggleCB(Widget w, WindowInfo *window, XtPointer callData) + { + XmToggleButtonCallbackStruct *cbs = (XmToggleButtonCallbackStruct*)callData; + if(w == window->iSearchCaseToggle) { + /* disable the RegEx toggle anytime the case toggle is toggled */ + XmToggleButtonSetState(window->iSearchRegExpToggle, False, False); + } else if(w == window->iSearchRegExpToggle) { + /* Set the case toggle whenever the RegEx button is set to indicate that + ** RegEx searches are always case sensitive */ + if(cbs->set) { + XmToggleButtonSetState(window->iSearchCaseToggle, True, False); + } + } + } + + static void iSearchHideCB(Widget w, WindowInfo *window, XtPointer callData) + { + ShowISearchLine(window, False); + } + + /* + ** Block until all of the expose events are processed. + ** This is a copy of the code in XmUpdateDisplay with the + ** display value hardcoded and the XSync() commented out. + */ + void UpdateDisplay(void) + { + XEvent event; + #if 0 + XSync (TheDisplay, 0); + #endif + while (XCheckMaskEvent(TheDisplay, ExposureMask, &event)) + XtDispatchEvent(&event); + } *** window.h 1997/09/26 18:28:17 1.1 --- window.h 1997/10/21 23:29:53 1.4 *************** *** 24,29 **** *******************************************************************************/ ! WindowInfo *CreateWindow(char *title); void CloseWindow(WindowInfo *window); int NWindows(void); ! void SetWindowTitle(WindowInfo *window, char *title); void UpdateWindowTitle(WindowInfo *window); --- 24,30 ---- *******************************************************************************/ ! WindowInfo *CreateWindow(char *name, EditorInfo *editorInfo); void CloseWindow(WindowInfo *window); + WindowInfo *CreateSlaveWindow(WindowInfo *window); int NWindows(void); ! void SetWindowTitle(WindowInfo *window, char *title, char *icontitle); void UpdateWindowTitle(WindowInfo *window); *************** *** 42,43 **** --- 43,46 ---- char *boldName, char *boldItalicName); + void SetItalicFontByName(WindowInfo *window, char *fontName); + void SetBoldFontByName(WindowInfo *window, char *fontName); void SetOverstrike(WindowInfo *window, int overstrike); *************** *** 45,46 **** --- 48,52 ---- void SetWrapMargin(WindowInfo *window, int margin); + void SetAutoSave(WindowInfo *window, int state); + void SetSaveOldVersion(WindowInfo *window, int state); + void SetShowMatching(WindowInfo *window, int state); void SplitWindow(WindowInfo *window); *************** *** 48,49 **** --- 54,56 ---- void ShowStatsLine(WindowInfo *window, int state); + void ShowISearchLine(WindowInfo *window, int state); void SetModeMessage(WindowInfo *window, char *message); *************** *** 52 **** --- 59,61 ---- void AddSmallIcon(Widget shell); + char *FormatWindowTitle(WindowInfo *window); + void UpdateDisplay(void);